Google Pagespeed Insights - Version 4.0.5

Version Description

  • Bugfix some validation rule reports not showing properly (some results may need to be rechecked to see the fixes)
  • Better styling for readability in report details
  • Additional validating, sanitizing, and escaping the plugin codebase
Download this release

Release Info

Developer mattkeys
Plugin Icon 128x128 Google Pagespeed Insights
Version 4.0.5
Comparing to
See all releases

Code changes from version 4.0.4 to 4.0.5

assets/css/gpagespeedi_styles.css CHANGED
@@ -415,7 +415,8 @@ h3.subTitle {
415
  margin: 0;
416
  }
417
  .row.framed .details {
418
- padding: 0 10px 10px;
 
419
  }
420
  .row.framed .details p.description {
421
  font-weight: normal;
@@ -432,6 +433,7 @@ h3.subTitle {
432
  max-width: 100%;
433
  }
434
  .row .accordion h3 {
 
435
  font-weight: normal;
436
  cursor: pointer;
437
  margin: 0;
@@ -453,16 +455,31 @@ h3.subTitle {
453
  background-position: center center;
454
  }
455
  .row .accordion h3.ui-state-active .toggle {
456
- background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAgNTEyIj48cGF0aCBkPSJNMjg4LjY2MiAzNTJIMzEuMzM4Yy0xNy44MTggMC0yNi43NDEtMjEuNTQzLTE0LjE0Mi0zNC4xNDJsMTI4LjY2Mi0xMjguNjYyYzcuODEtNy44MSAyMC40NzQtNy44MSAyOC4yODQgMGwxMjguNjYyIDEyOC42NjJjMTIuNiAxMi41OTkgMy42NzYgMzQuMTQyLTE0LjE0MiAzNC4xNDJ6Ii8+PC9zdmc+');
 
 
457
  }
458
  .row .accordion h3:hover {
459
- background: #cff0cf;
460
  }
461
  .row .accordion h3:first-of-type {
462
  border-top: none;
463
  }
464
  .row .accordion h3.ui-state-active {
465
  font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  }
467
  @media only screen and (max-width: 500px) {
468
  .row .accordion h3 span.right {
@@ -769,6 +786,82 @@ table#tblMain span.checkmark {
769
  width: 0px;
770
  }
771
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  .crc, .crc ul, .crc li {
773
  position: relative;
774
  }
415
  margin: 0;
416
  }
417
  .row.framed .details {
418
+ position: relative;
419
+ padding: 10px;
420
  }
421
  .row.framed .details p.description {
422
  font-weight: normal;
433
  max-width: 100%;
434
  }
435
  .row .accordion h3 {
436
+ position: relative;
437
  font-weight: normal;
438
  cursor: pointer;
439
  margin: 0;
455
  background-position: center center;
456
  }
457
  .row .accordion h3.ui-state-active .toggle {
458
+ -webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAgNTEyIj48cGF0aCBkPSJNMjg4LjY2MiAzNTJIMzEuMzM4Yy0xNy44MTggMC0yNi43NDEtMjEuNTQzLTE0LjE0Mi0zNC4xNDJsMTI4LjY2Mi0xMjguNjYyYzcuODEtNy44MSAyMC40NzQtNy44MSAyOC4yODQgMGwxMjguNjYyIDEyOC42NjJjMTIuNiAxMi41OTkgMy42NzYgMzQuMTQyLTE0LjE0MiAzNC4xNDJ6Ii8+PC9zdmc+');
459
+ mask-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAgNTEyIj48cGF0aCBkPSJNMjg4LjY2MiAzNTJIMzEuMzM4Yy0xNy44MTggMC0yNi43NDEtMjEuNTQzLTE0LjE0Mi0zNC4xNDJsMTI4LjY2Mi0xMjguNjYyYzcuODEtNy44MSAyMC40NzQtNy44MSAyOC4yODQgMGwxMjguNjYyIDEyOC42NjJjMTIuNiAxMi41OTkgMy42NzYgMzQuMTQyLTE0LjE0MiAzNC4xNDJ6Ii8+PC9zdmc+');
460
+ background: white;
461
  }
462
  .row .accordion h3:hover {
463
+ background: rgba( 51, 102, 204, .39 );
464
  }
465
  .row .accordion h3:first-of-type {
466
  border-top: none;
467
  }
468
  .row .accordion h3.ui-state-active {
469
  font-weight: bold;
470
+ background: #3366cc;
471
+ color: white;
472
+ padding: 8px;
473
+ }
474
+ .row .accordion h3.ui-state-active + .details {
475
+ border-bottom: 2px solid #3366cc;
476
+ }
477
+ .row .accordion h3.ui-state-active,
478
+ .row .accordion h3.ui-state-active + .details,
479
+ .row .accordion h3.ui-state-active,
480
+ .row .accordion h3.ui-state-active + .details {
481
+ border-left: 2px solid #3366cc;
482
+ border-right: 2px solid #3366cc;
483
  }
484
  @media only screen and (max-width: 500px) {
485
  .row .accordion h3 span.right {
786
  width: 0px;
787
  }
788
 
789
+ .nitropack-blurb {
790
+ margin-top: 30px;
791
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #E9DEFC 100%);
792
+ border: 1px solid #E9DEFC;
793
+ padding: 20px 30px;
794
+ border-radius: 10px;
795
+ display: flex;
796
+ align-items: center;
797
+ flex-direction: row;
798
+ text-decoration: none;
799
+ }
800
+ .nitropack-blurb .copy {
801
+ padding: 0 30px;
802
+ }
803
+ .nitropack-blurb .copy span {
804
+ background-image: linear-gradient(120deg, #25f5ce 0%, #25f5ce 100%);
805
+ background-repeat: no-repeat;
806
+ background-size: 100% 0.25em;
807
+ background-position: 0 90%;
808
+ }
809
+ .nitropack-blurb .copy h1 {
810
+ font-size: 26px;
811
+ color: #212529;
812
+ padding-top: 0;
813
+ }
814
+ .nitropack-blurb .copy p {
815
+ font-size: 16px;
816
+ color: #212529;
817
+ max-width: 600px;
818
+ }
819
+ .nitropack-blurb .copy p.small {
820
+ font-size: 13px;
821
+ }
822
+ .nitropack-blurb .logo {
823
+ flex: 0 0 142px;
824
+ width: 142px;
825
+ height: 54px;
826
+ background: url(../images/nitropack.svg) no-repeat;
827
+ background-size: contain;
828
+ align-self: flex-start;
829
+ margin-top: 10px;
830
+ }
831
+ .nitropack-blurb .link {
832
+ flex: 1;
833
+ text-align: center;
834
+ }
835
+ .nitropack-blurb .btn {
836
+ display: inline-block;
837
+ background: #4600CC;
838
+ border-radius: 19px;
839
+ padding: 10px 19px;
840
+ font-size: 19px;
841
+ white-space: nowrap;
842
+ color: white;
843
+ margin: 0 auto;
844
+ }
845
+ .nitropack-blurb:hover .btn {
846
+ background: #4b00d9;
847
+ }
848
+ @media only screen and (max-width: 767px) {
849
+ .nitropack-blurb {
850
+ flex-direction: column;
851
+ align-items: flex-start;
852
+ }
853
+ .nitropack-blurb .copy {
854
+ padding: 0;
855
+ }
856
+ .nitropack-blurb .logo {
857
+ margin-top: 0;
858
+ flex: 0 0 90px;
859
+ }
860
+ .nitropack-blurb .link {
861
+ margin-top: 20px;
862
+ }
863
+ }
864
+
865
  .crc, .crc ul, .crc li {
866
  position: relative;
867
  }
assets/images/nitropack.svg ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="142px" height="54px" viewBox="0 0 142 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>48A4A6D9-06F0-4C86-86A9-D11130A50175</title>
4
+ <g id="Design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Home-design" transform="translate(-252.000000, -21.000000)">
6
+ <g id="NitroPack-logo-full" transform="translate(252.000000, 21.000000)">
7
+ <g id="wordmark" transform="translate(0.000000, 32.000000)" fill="#1B004E">
8
+ <polygon id="n" points="19.4864437 21.2395048 15.5947323 21.2395048 4.68182802 7.24686141 4.68182802 21.1831334 0 21.1831334 0 0.945787444 5.44405813 0.945787444 14.91926 13.3443719 14.91926 0.945787444 19.4864437 0.945787444"></polygon>
9
+ <path d="M21.3455415,0.939523951 L25.9932861,0.939523951 L25.9932861,4.50971497 L21.3455415,4.50971497 L21.3455415,0.939523951 Z M21.3455415,6.41694859 L25.9932861,6.41694859 L25.9932861,21.1800016 L21.3455415,21.1800016 L21.3455415,6.41694859 Z" id="i"></path>
10
+ <path d="M40.568613,21.1831334 L36.0014294,21.1831334 C32.5930834,21.1831334 31.0097517,19.5577569 31.0097517,16.4855136 L31.0097517,10.265865 L27.2326846,10.265865 L27.2326846,6.42008033 L31.0097517,6.42008033 L31.0097517,0.945787444 L35.6079203,0.945787444 L35.6079203,6.42008033 L40.5655145,6.42008033 L40.5655145,10.265865 L35.6079203,10.265865 L35.6079203,14.8538737 C35.6079203,16.4510644 36.0850888,17.1055994 37.8047543,17.1055994 L40.568613,17.1055994 L40.568613,21.1831334 Z" id="t"></path>
11
+ <path d="M46.6881434,21.1831334 L42.1178612,21.1831334 L42.1178612,6.42008033 L46.6881434,6.42008033 L46.6881434,8.72817751 C46.997993,8.04232502 48.0390878,6.39189461 51.1127962,6.39189461 L54.2422775,6.39189461 L54.2422775,10.9517175 L50.2390202,10.9517175 C47.6455788,10.9517175 46.6881434,11.9194272 46.6881434,13.9707212 L46.6881434,21.1831334 Z" id="r"></path>
12
+ <path d="M70.6116339,13.8016068 C70.6116339,18.3614298 67.2032879,21.5526794 62.6020208,21.5526794 C58.0007536,21.5526794 54.5955061,18.3614298 54.5955061,13.8016068 C54.5955061,9.24178393 58.0038521,6.0474025 62.6020208,6.0474025 C67.2001894,6.0474025 70.6116339,9.24178393 70.6116339,13.8016068 Z M66.0134653,13.8016068 C66.0134653,11.662624 64.6625208,10.068565 62.6051193,10.068565 C60.5477177,10.068565 59.1657883,11.662624 59.1657883,13.8016068 C59.1657883,15.9405897 60.5756041,17.5346487 62.6051193,17.5346487 C64.6346344,17.5346487 66.0134653,15.937458 66.0134653,13.8016068 L66.0134653,13.8016068 Z" id="o"></path>
13
+ <path d="M72.4707317,0.945787444 L84.170654,0.945787444 C88.7130497,0.945787444 91.3622641,3.2256989 91.3622641,7.47234716 C91.3622641,11.7189954 88.7130497,14.0490148 84.170654,14.0490148 L77.2362191,14.0490148 L77.2362191,21.1737381 L72.4707317,21.1737381 L72.4707317,0.945787444 Z M77.2362191,5.16424998 L77.2362191,9.83994751 L83.7213721,9.83994751 C85.5525834,9.83994751 86.4573444,8.956795 86.4573444,7.50053288 C86.4573444,5.93465962 85.5525834,5.16424998 83.7213721,5.16424998 L77.2362191,5.16424998 Z" id="p"></path>
14
+ <path d="M102.66248,19.0159648 C102.408404,19.5013855 101.026474,21.496308 97.9527659,21.496308 C94.2872447,21.496308 91.3250822,18.5900472 91.3250822,13.8016068 C91.3250822,9.01316644 94.2872447,6.1350914 97.9806524,6.1350914 C100.942815,6.1350914 102.352631,7.98595358 102.606707,8.47137429 L102.606707,6.42008033 L107.173891,6.42008033 L107.173891,21.1831334 L102.66248,21.1831334 L102.66248,19.0159648 Z M99.3346953,10.0842237 C97.3051802,10.0842237 95.9511372,11.6782827 95.9511372,13.8172656 C95.9511372,15.9562484 97.3051802,17.5503074 99.3346953,17.5503074 C101.36421,17.5503074 102.66248,15.9531167 102.66248,13.8172656 C102.66248,11.6814145 101.36421,10.0842237 99.3346953,10.0842237 Z" id="a"></path>
15
+ <path d="M119.183663,11.5780668 C118.618174,10.5975654 117.556401,10.0204505 116.435297,10.0842237 C114.517328,10.0842237 113.305815,11.6782827 113.305815,13.8172656 C113.305815,15.9562484 114.545214,17.5753614 116.463183,17.5753614 C118.269607,17.5753614 119.08761,16.4072199 119.227042,16.0658596 L123.626907,16.0658596 C123.484376,18.1171535 121.510634,21.5652064 116.351637,21.5652064 C112.066417,21.5652064 108.710745,18.4866996 108.710745,13.8141338 C108.710745,9.14156804 112.03853,6.05992948 116.295864,6.05992948 C121.454861,6.05992948 123.400717,9.45161095 123.626907,11.5905938 L119.183663,11.5780668 Z" id="c"></path>
16
+ <polygon id="k" points="129.712354 14.6002022 129.712354 21.1768699 125.14517 21.1768699 125.14517 0.194168283 129.712354 0.194168283 129.712354 12.1918891 135.549921 6.40755335 141.30073 6.40755335 134.307424 13.219102 141.669451 21.1706064 135.748225 21.1706064"></polygon>
17
+ </g>
18
+ <g id="glyph" transform="translate(21.000000, 0.000000)" fill="#25F5CE">
19
+ <path d="M28.1586276,4.65016905 C40.9913765,4.65016905 51.3943749,15.0599271 51.3943749,27.9010143 L56.0415244,27.9010143 C56.0415244,12.4917096 43.5579263,0 28.1586276,0 C12.759329,0 0.275730868,12.4917096 0.275730868,27.9010143 L4.92288033,27.9010143 C4.92288033,15.0599271 15.3258787,4.65016905 28.1586276,4.65016905 L28.1586276,4.65016905 Z" id="dash"></path>
20
+ <path d="M23.8522691,25.7929377 L23.8522691,25.7929377 C23.3807596,24.7797664 23.4019201,23.6057418 23.9096338,22.610243 C24.4173474,21.6147441 25.3550123,20.9087528 26.4515747,20.6963524 L42.8002465,16.9514162 L42.8002465,16.9514162 L29.4257504,27.0887848 C28.5566054,27.792436 27.4117896,28.0557981 26.3228115,27.8026082 C25.2338334,27.5494183 24.3223375,26.8079591 23.8522691,25.7929377 L23.8522691,25.7929377 Z" id="arrow"></path>
21
+ </g>
22
+ </g>
23
+ </g>
24
+ </g>
25
+ </svg>
assets/js/details.js CHANGED
@@ -67,7 +67,11 @@
67
  } else if ( 'diagnostic' == type ) {
68
  $('#diagnostics').append( audits( data ) );
69
  } else if ( 'opportunity' == type && 0.9 > audit.rule_score ) {
70
- $('#opportunities').append( audits( data ) );
 
 
 
 
71
  } else if ( 'opportunity' != type && 0.9 > audit.rule_score ) {
72
  $('#diagnostics').append( audits( data ) );
73
  } else if ( 'informative' == mode || 'not_applicable' == mode ) {
67
  } else if ( 'diagnostic' == type ) {
68
  $('#diagnostics').append( audits( data ) );
69
  } else if ( 'opportunity' == type && 0.9 > audit.rule_score ) {
70
+ if ( audit.rule_blocks.details.items.length < 1 ) {
71
+ $('#diagnostics').append( audits( data ) );
72
+ } else {
73
+ $('#opportunities').append( audits( data ) );
74
+ }
75
  } else if ( 'opportunity' != type && 0.9 > audit.rule_score ) {
76
  $('#diagnostics').append( audits( data ) );
77
  } else if ( 'informative' == mode || 'not_applicable' == mode ) {
assets/js/summary.js CHANGED
@@ -1,10 +1,4 @@
1
  ( function( $ ) {
2
-
3
- // if ( GPI_Summary.snapshot ) {
4
- // GPI_Summary.summary_stats = JSON.parse( GPI_Summary.summary_stats );
5
- // GPI_Summary.summary_reports = JSON.parse( GPI_Summary.summary_reports );
6
- // }
7
-
8
  var no_results = $.isEmptyObject( GPI_Summary.summary_stats );
9
  var dataVersion;
10
 
1
  ( function( $ ) {
 
 
 
 
 
 
2
  var no_results = $.isEmptyObject( GPI_Summary.summary_stats );
3
  var dataVersion;
4
 
assets/js/templates/details/audits-criticalrequestchain.php CHANGED
@@ -1,5 +1,5 @@
1
  <script type="text/html" id="tmpl-audits-criticalrequestchain">
2
- <h3>{{data.name}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
1
  <script type="text/html" id="tmpl-audits-criticalrequestchain">
2
+ <h3>{{{data.name}}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
assets/js/templates/details/audits-diagnostic.php CHANGED
@@ -1,5 +1,5 @@
1
  <script type="text/html" id="tmpl-audits-diagnostic">
2
- <h3>{{data.name}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
1
  <script type="text/html" id="tmpl-audits-diagnostic">
2
+ <h3>{{{data.name}}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
assets/js/templates/details/audits-opportunity.php CHANGED
@@ -1,5 +1,5 @@
1
  <script type="text/html" id="tmpl-audits-opportunity">
2
- <h3>{{data.name}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
1
  <script type="text/html" id="tmpl-audits-opportunity">
2
+ <h3>{{{data.name}}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
assets/js/templates/details/audits-table.php CHANGED
@@ -1,5 +1,5 @@
1
  <script type="text/html" id="tmpl-audits-table">
2
- <h3>{{data.name}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
@@ -9,10 +9,18 @@
9
  <tr>
10
  <# var keys = []; #>
11
  <# for (i = 0; i < data.details.headings.length; i++ ) { #>
12
- <# if ( typeof data.details.headings[ i ].text != 'undefined' ) { #>
13
- <th class="{{data.details.headings[ i ].key}}">{{data.details.headings[ i ].text}}</th>
14
- <# keys.push( data.details.headings[ i ].key ); #>
15
- <# } #>
 
 
 
 
 
 
 
 
16
  <# } #>
17
  </tr>
18
  </thead>
@@ -21,10 +29,53 @@
21
  <tr>
22
  <# for (x = 0; x < keys.length; x++ ) {
23
  if ( 'object' == typeof data.details.items[ i ][keys[ x ]] ) {
 
24
  if ( 'url' == keys[ x ] ) {
25
  #>
26
  <td class="{{keys[ x ]}}">{{{data.details.items[ i ][keys[ x ]].value}}}</td>
27
  <#
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  } else {
29
  #>
30
  <td class="{{keys[ x ]}}">{{data.details.items[ i ][keys[ x ]].value}}</td>
@@ -35,6 +86,12 @@
35
  #>
36
  <td class="{{keys[ x ]}}">{{{data.details.items[ i ][keys[ x ]]}}}</td>
37
  <#
 
 
 
 
 
 
38
  } else {
39
  #>
40
  <td class="{{keys[ x ]}}">{{data.details.items[ i ][keys[ x ]]}}</td>
1
  <script type="text/html" id="tmpl-audits-table">
2
+ <h3>{{{data.name}}} <span class="toggle"></span><span class="right">{{data.displayValue}}</span></h3>
3
  <div class="details">
4
  <p class="description">
5
  {{{data.description}}}
9
  <tr>
10
  <# var keys = []; #>
11
  <# for (i = 0; i < data.details.headings.length; i++ ) { #>
12
+ <th class="{{data.details.headings[ i ].key}}">
13
+ <# if ( typeof data.details.headings[ i ].text != 'undefined' ) { #>
14
+ {{data.details.headings[ i ].text}}
15
+ <# } #>
16
+ </th>
17
+ <#
18
+ if ( '' == data.details.headings[ i ].key && 'subItemsHeading' in data.details.headings[ i ] ) {
19
+ keys.push( data.details.headings[ i ].subItemsHeading );
20
+ } else {
21
+ keys.push( data.details.headings[ i ].key );
22
+ }
23
+ #>
24
  <# } #>
25
  </tr>
26
  </thead>
29
  <tr>
30
  <# for (x = 0; x < keys.length; x++ ) {
31
  if ( 'object' == typeof data.details.items[ i ][keys[ x ]] ) {
32
+
33
  if ( 'url' == keys[ x ] ) {
34
  #>
35
  <td class="{{keys[ x ]}}">{{{data.details.items[ i ][keys[ x ]].value}}}</td>
36
  <#
37
+ } else if ( 'node' == keys[ x ] ) {
38
+ #>
39
+ <td class="{{keys[ x ]}}">
40
+ {{{data.details.items[ i ][keys[ x ]]['nodeLabel']}}}
41
+ <br>
42
+ <code>{{{data.details.items[ i ][keys[ x ]]['snippet']}}}</code>
43
+ <#
44
+ if ( 'subItems' in data.details.items[ i ] && 'items' in data.details.items[ i ].subItems ) {
45
+ for (y = 0; y < data.details.items[ i ].subItems.items.length; y++ ) {
46
+ if ( 'failureReason' in data.details.items[ i ].subItems.items[ y ] ) {
47
+ #>
48
+ <br><br>
49
+ {{{data.details.items[ i ].subItems.items[ y ].failureReason}}}
50
+ <#
51
+ }
52
+ }
53
+ }
54
+ #>
55
+ </td>
56
+ <#
57
+ } else if ( 'source' == keys[ x ] ) {
58
+ if ( 'source-location' == data.details.items[ i ][keys[ x ]]['type'] ) {
59
+ #>
60
+ <td class="{{keys[ x ]}}">
61
+ {{{data.details.items[ i ][keys[ x ]]['url']}}}
62
+ <code>{{{data.details.items[ i ][keys[ x ]]['line']}}}:{{{data.details.items[ i ][keys[ x ]]['column']}}}</code>
63
+ </td>
64
+ <#
65
+ }
66
+ } else if ( 'entity' == keys[ x ] ) {
67
+ #>
68
+ <td class="{{keys[ x ]}}">
69
+ {{{data.details.items[ i ][keys[ x ] ].text}}}
70
+ <#
71
+ if ( 'url' in data.details.items[ i ][keys[ x ] ] ) {
72
+ #>
73
+ ({{{data.details.items[ i ][keys[ x ] ].url}}})
74
+ <#
75
+ }
76
+ #>
77
+ </td>
78
+ <#
79
  } else {
80
  #>
81
  <td class="{{keys[ x ]}}">{{data.details.items[ i ][keys[ x ]].value}}</td>
86
  #>
87
  <td class="{{keys[ x ]}}">{{{data.details.items[ i ][keys[ x ]]}}}</td>
88
  <#
89
+ } else if ( 'object' == typeof keys[ x ] && data.details.items[ i ].subItems ) {
90
+ for (y = 0; y < data.details.items[ i ].subItems.items.length; y++ ) {
91
+ #>
92
+ <td class="{{keys[ x ]}}">{{{data.details.items[ i ].subItems.items[ y ][ keys[ x ].key ]}}}</td>
93
+ <#
94
+ }
95
  } else {
96
  #>
97
  <td class="{{keys[ x ]}}">{{data.details.items[ i ][keys[ x ]]}}</td>
assets/js/view-snapshot.js CHANGED
@@ -1,13 +1,4 @@
1
  ( function( $ ) {
2
-
3
- GPI_View_Snapshot.snapshot.summary_stats = JSON.parse( GPI_View_Snapshot.snapshot.summary_stats );
4
- GPI_View_Snapshot.snapshot.summary_reports = JSON.parse( GPI_View_Snapshot.snapshot.summary_reports );
5
-
6
- if ( GPI_View_Snapshot.compare ) {
7
- GPI_View_Snapshot.compare.summary_stats = JSON.parse( GPI_View_Snapshot.compare.summary_stats );
8
- GPI_View_Snapshot.compare.summary_reports = JSON.parse( GPI_View_Snapshot.compare.summary_reports );
9
- }
10
-
11
  $( document ).ready( function() {
12
  if ( GPI_View_Snapshot.comments.snapshot ) {
13
  $('.comment[data-selector="snapshot"]').html( '<strong>' + GPI_View_Snapshot.strings.comment + ':</strong>' + GPI_View_Snapshot.comments.snapshot );
1
  ( function( $ ) {
 
 
 
 
 
 
 
 
 
2
  $( document ).ready( function() {
3
  if ( GPI_View_Snapshot.comments.snapshot ) {
4
  $('.comment[data-selector="snapshot"]').html( '<strong>' + GPI_View_Snapshot.strings.comment + ':</strong>' + GPI_View_Snapshot.comments.snapshot );
classes/class-GPI-Actions.php CHANGED
@@ -119,14 +119,10 @@ class GPI_Actions
119
  do_action( 'run_gpi', true );
120
  $action_message = __( 'Successfully initiated Insights from Google PageSpeed to recheck all reports. Full plugin functionality will be restored after all pages have been rechecked.', 'gpagespeedi' );
121
  break;
122
-
123
- case apply_filters( 'gpi_custom_actions', $this->action ):
124
- $action_message = apply_filters( 'gpi_action_' . $this->action, '', $this->gpi_options, $this->gpi_ui_options, $this->page_id, $this->bulk_pages, $this->bulk_pages_count );
125
- break;
126
  }
127
 
128
  if ( $action_message ) {
129
- do_action( 'gpi_update_option', 'action_message', $action_message, 'gpagespeedi_ui_options' );
130
  }
131
 
132
  wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce', 'action', 'id', 'gpi_page_report', 'single-recheck', 'strategy' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
@@ -163,10 +159,11 @@ class GPI_Actions
163
 
164
  // Check for 'purge all data' option and truncate tables if checked
165
  if ( isset( $_POST['purge_all_data'] ) ) {
166
- if ( 'purge_reports' == $_POST['purge_all_data'] ) {
 
167
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_stats" );
168
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_reports" );
169
- } else if ( 'purge_everything' == $_POST['purge_all_data'] ) {
170
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_stats" );
171
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_reports" );
172
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_blacklist" );
@@ -181,22 +178,22 @@ class GPI_Actions
181
  $old_options = $this->gpi_options;
182
 
183
  $gpagespeedi_options = array(
184
- 'google_developer_key' => ! empty( $_POST['google_developer_key'] ) ? sanitize_text_field( $_POST['google_developer_key'] ) : $this->gpi_options['google_developer_key'],
185
- 'response_language' => ! empty( $_POST['response_language'] ) ? sanitize_text_field( $_POST['response_language'] ) : $this->gpi_options['response_language'],
186
- 'strategy' => ! empty( $_POST['strategy'] ) ? sanitize_text_field( $_POST['strategy'] ) : $this->gpi_options['strategy'],
187
  'store_screenshots' => ! empty( $_POST['store_screenshots'] ) ? true : false,
188
- 'max_execution_time' => ! empty( $_POST['max_execution_time'] ) ? intval( $_POST['max_execution_time'] ) : $this->gpi_options['max_execution_time'],
189
- 'max_run_time' => isset( $_POST['max_run_time'] ) ? intval( $_POST['max_run_time'] ) : $this->gpi_options['max_run_time'],
190
- 'sleep_time' => isset( $_POST['sleep_time'] ) ? intval( $_POST['sleep_time'] ) : $this->gpi_options['sleep_time'],
191
- 'recheck_interval' => ! empty( $_POST['recheck_interval'] ) ? intval( $_POST['recheck_interval'] ) : $this->gpi_options['recheck_interval'],
192
  'use_schedule' => isset( $_POST['use_schedule'] ) ? true : false,
193
  'check_pages' => isset( $_POST['check_pages'] ) ? true : false,
194
  'check_posts' => isset( $_POST['check_posts'] ) ? true : false,
195
  'cpt_whitelist' => isset( $_POST['cpt_whitelist'] ) ? serialize( array_map( 'sanitize_text_field', $_POST['cpt_whitelist'] ) ) : false,
196
  'check_categories' => isset( $_POST['check_categories'] ) ? true : false,
197
  'check_custom_urls' => isset( $_POST['check_custom_urls'] ) ? true : false,
198
- 'first_run_complete' => $this->gpi_options['first_run_complete'],
199
- 'last_run_finished' => $this->gpi_options['last_run_finished'],
200
  'bad_api_key' => false,
201
  'pagespeed_disabled' => false,
202
  'api_restriction' => false,
@@ -205,7 +202,7 @@ class GPI_Actions
205
  'log_api_errors' => isset( $_POST['log_api_errors'] ) ? true : false,
206
  'new_activation_message' => false,
207
  'heartbeat' => isset( $_POST['heartbeat'] ) ? sanitize_text_field( $_POST['heartbeat'] ) : 'standard',
208
- 'mutex_id' => $this->gpi_options['mutex_id'],
209
  'version' => GPI_VERSION
210
  );
211
  update_option( 'gpagespeedi_options', $gpagespeedi_options );
@@ -213,18 +210,18 @@ class GPI_Actions
213
 
214
  $gpagespeedi_ui_options = array(
215
  'action_message' => false,
216
- 'view_preference' => 'both' != $_POST['strategy'] ? sanitize_text_field( $_POST['strategy'] ) : $this->gpi_ui_options['view_preference']
217
  );
218
 
219
  update_option( 'gpagespeedi_ui_options', $gpagespeedi_ui_options );
220
  $this->gpi_ui_options = $gpagespeedi_ui_options;
221
 
222
- if ( $gpagespeedi_options['use_schedule'] && ! wp_next_scheduled('googlepagespeedinsightsworker') ) {
223
  wp_schedule_event( time() + $gpagespeedi_options['recheck_interval'], 'gpi_scheduled_interval', 'googlepagespeedinsightsworker' );
224
- } else if ( $gpagespeedi_options['use_schedule'] && ( $gpagespeedi_options['recheck_interval'] != $old_options['recheck_interval'] ) ) {
225
  wp_clear_scheduled_hook( 'googlepagespeedinsightsworker' );
226
  wp_schedule_event( time() + $gpagespeedi_options['recheck_interval'], 'gpi_scheduled_interval', 'googlepagespeedinsightsworker' );
227
- } else if ( ! $gpagespeedi_options['use_schedule'] ) {
228
  wp_clear_scheduled_hook( 'googlepagespeedinsightsworker' );
229
  }
230
 
@@ -240,47 +237,51 @@ class GPI_Actions
240
  global $wpdb;
241
 
242
  if ( ! empty( $this->page_id ) ) {
243
- $page_stats = $wpdb->get_row( $wpdb->prepare(
244
- "
245
- SELECT URL, type, object_id, term_id, custom_id
246
- FROM $this->gpi_page_stats
247
- WHERE ID = %d
248
- ",
249
- $this->page_id
250
- ), ARRAY_A );
 
 
251
 
252
  if ( ! is_null( $page_stats['object_id'] ) ) {
253
- $objectid = $page_stats['object_id'];
254
  } else if ( ! is_null( $page_stats['term_id'] ) ) {
255
- $objectid = $page_stats['term_id'];
256
  } else {
257
- $objectid = $page_stats['custom_id'];
258
  $custom = true;
259
  }
260
 
261
- $urls_to_recheck = array(
262
- $page_stats['type'] => array(
263
- array(
264
- 'url' => $page_stats['URL'],
265
- 'objectid' => $objectid,
266
- 'custom' => $custom
267
- )
268
- ),
269
- 'total_url_count' => 1
270
- );
 
271
 
272
- $checkstatus = apply_filters( 'gpi_check_status', false );
273
 
274
- if ( $checkstatus ) {
275
- $message = __( 'The API is busy checking other pages, please try again later.', 'gpagespeedi' );
276
- } else {
277
- update_option( 'gpi_recheck_urls', $urls_to_recheck, false );
278
- do_action( 'run_gpi', true, false, $urls_to_recheck );
279
 
280
- $message = __( 'This URL has been scheduled for a recheck.', 'gpagespeedi' );
281
- }
282
 
283
- return $message;
 
284
  }
285
  }
286
 
@@ -374,14 +375,16 @@ class GPI_Actions
374
  global $wpdb;
375
 
376
  foreach ( $this->bulk_pages as $page_id ) {
377
- $page_info = $wpdb->get_row( $wpdb->prepare(
378
- "
379
- SELECT ID, URL, type, object_id, term_id, custom_id
380
- FROM $this->gpi_page_stats
381
- WHERE ID = %d
382
- ",
383
- $page_id
384
- ), ARRAY_A );
 
 
385
 
386
  $wpdb->delete( $this->gpi_page_stats, array( 'ID' => $page_id ), array( '%d' ) );
387
  $wpdb->delete( $this->gpi_page_reports, array( 'page_id' => $page_id ), array( '%d' ) );
@@ -460,7 +463,7 @@ class GPI_Actions
460
  global $wpdb;
461
 
462
  $snapshot_data = array(
463
- 'strategy' => $this->gpi_ui_options['view_preference'],
464
  'type' => isset( $_GET['filter'] ) ? sanitize_text_field( $_GET['filter'] ) : 'all',
465
  'snaptime' => current_time( 'timestamp' ),
466
  'comment' => isset( $_POST['comment'] ) ? sanitize_text_field( $_POST['comment'] ) : false,
@@ -531,14 +534,14 @@ class GPI_Actions
531
  );
532
  }
533
 
534
- $custom_url_label = $_POST['custom_url_label'];
 
 
 
 
535
 
536
  if ( empty( $custom_url_label ) ) {
537
  $custom_url_label = 'custom';
538
- } else {
539
- $custom_url_label = preg_replace( '/[^a-zA-Z0-9\s]/', '', $custom_url_label );
540
- $custom_url_label = str_replace( ' ', '_', $custom_url_label );
541
- $custom_url_label = substr( $custom_url_label, 0, 20 );
542
  }
543
 
544
  foreach ( $_POST['custom_urls'] as $custom_url ) {
@@ -554,9 +557,11 @@ class GPI_Actions
554
 
555
  foreach ( $urls_to_store as $key => $url ) {
556
 
557
- $url_already_exist = $wpdb->get_var( $wpdb->prepare(
558
- "SELECT ( SELECT COUNT(*) FROM $this->gpi_custom_urls WHERE URL = %s ) + ( SELECT COUNT(*) FROM $this->gpi_page_stats WHERE URL = %s )",
559
- $url, $url
 
 
560
  )
561
  );
562
 
@@ -643,14 +648,14 @@ class GPI_Actions
643
 
644
  if ( ! empty( $urls_to_store ) ) {
645
 
646
- $custom_url_label = isset( $_POST['custom_url_label'] ) ? $_POST['custom_url_label'] : false;
 
 
 
 
647
 
648
  if ( ! $custom_url_label ) {
649
  $custom_url_label = 'custom';
650
- } else {
651
- $custom_url_label = preg_replace( '/[^a-zA-Z0-9\s]/', '', $custom_url_label );
652
- $custom_url_label = str_replace( ' ', '_', $custom_url_label );
653
- $custom_url_label = substr( $custom_url_label, 0, 20 );
654
  }
655
 
656
  global $wpdb;
@@ -658,9 +663,11 @@ class GPI_Actions
658
  foreach ( $urls_to_store as $key => $url ) {
659
 
660
  // Make sure the URL does not already exist
661
- $url_already_exist = $wpdb->get_var( $wpdb->prepare(
662
- "SELECT ( SELECT COUNT(*) FROM $this->gpi_custom_urls WHERE URL = %s ) + ( SELECT COUNT(*) FROM $this->gpi_page_stats WHERE URL = %s )",
663
- $url, $url
 
 
664
  )
665
  );
666
 
@@ -696,113 +703,57 @@ class GPI_Actions
696
 
697
  private function delete_page()
698
  {
699
- global $wpdb;
700
-
701
  if ( is_array( $this->bulk_pages ) && ! empty( $this->bulk_pages ) ) {
702
- $x = 1;
703
- $custom_id_where_clause = '';
704
- $select_id_where_clause = '';
705
- foreach ( $this->bulk_pages as $page ) {
706
- $page = intval( $page );
707
-
708
- if ( ! $page ) {
709
- continue;
710
- }
711
 
712
- if ( $x < $this->bulk_pages_count ) {
713
- $custom_id_where_clause .= 'custom_id = ' . $page . ' OR ';
714
- $select_id_where_clause .= 'ID = ' . $page . ' OR ';
715
- } else {
716
- $custom_id_where_clause .= 'custom_id = ' . $page;
717
- $select_id_where_clause .= 'ID = ' . $page;
718
- }
719
- $x++;
720
  }
721
 
722
- // Get the URLs for all pages being deleted
723
- $delete_array = $wpdb->get_results( "SELECT URL FROM $this->gpi_custom_urls WHERE $select_id_where_clause", ARRAY_A );
724
- $delete_array_count = count( $delete_array );
725
- if ( ! empty( $delete_array ) ) {
726
- $z = 1;
727
- $select_url_where_clause = '';
728
- foreach ( $delete_array as $delete_url ) {
729
- if ( $z < $delete_array_count ) {
730
- $select_url_where_clause .= 'URL = "' . $delete_url['URL'] . '" OR ';
731
- } else {
732
- $select_url_where_clause .= 'URL = "' . $delete_url['URL'] . '"';
733
- }
734
- $z++;
735
- }
736
 
737
- // Get IDs for all the pages to be deleted
738
- $page_stats_ids = $wpdb->get_results( "SELECT ID FROM $this->gpi_page_stats WHERE $select_url_where_clause", ARRAY_A );
739
-
740
- if ( ! empty( $page_stats_ids ) ) {
741
-
742
- $page_stats_ids_count = count( $page_stats_ids );
743
- $y = 1;
744
- $where_string = '';
745
- foreach ( $page_stats_ids as $id ) {
746
- if ( $y < $page_stats_ids_count ) {
747
- $where_string .= $this->gpi_page_stats . '.ID = ' . $id['ID'] . ' OR ';
748
- } else {
749
- $where_string .= $this->gpi_page_stats . '.ID = ' . $id['ID'];
750
- }
751
- $y++;
752
- }
753
-
754
- // Delete page stats and page reports if they exist
755
- $wpdb->query("
756
- DELETE $this->gpi_page_stats, $this->gpi_page_reports
757
- FROM $this->gpi_page_stats, $this->gpi_page_reports
758
- WHERE $this->gpi_page_stats.ID = $this->gpi_page_reports.page_id
759
- AND ($where_string)
760
- ");
761
- }
762
 
763
- // Delete blacklisted URLs if exist
764
- $wpdb->query("
765
- DELETE $this->gpi_page_blacklist
766
- FROM $this->gpi_page_blacklist
767
- WHERE $custom_id_where_clause
768
- ");
769
-
770
- // Delete custom URLs from gpi_custom_urls table
771
- $wpdb->query("
772
- DELETE $this->gpi_custom_urls
773
- FROM $this->gpi_custom_urls
774
- WHERE $select_id_where_clause
775
- ");
776
- }
777
 
778
- return $delete_array_count . ' ' . __( 'URLs have been deleted.', 'gpagespeedi' );
 
 
779
 
780
- } else if ( ! empty( $this->page_id ) ) {
781
 
782
- // Get the URL for the page being deleted
783
- $page_url = $wpdb->get_var( "SELECT URL FROM $this->gpi_custom_urls WHERE ID = $this->page_id" );
784
-
785
- // Get ID for the page to be deleted
786
- $page_stats_id = $wpdb->get_var( "SELECT ID FROM $this->gpi_page_stats WHERE URL = '$page_url'" );
787
-
788
- // Delete page stats and page reports if they exist
789
- if ( ! empty( $page_stats_id ) ) {
790
- $wpdb->query("
791
- DELETE $this->gpi_page_stats, $this->gpi_page_reports
792
- FROM $this->gpi_page_stats, $this->gpi_page_reports
793
- WHERE $this->gpi_page_stats.ID = $this->gpi_page_reports.page_id
794
- AND $this->gpi_page_stats.ID = $page_stats_id
795
- ");
796
- }
797
 
798
- // Delete blacklisted URL if exist
799
- $wpdb->delete( $this->gpi_page_blacklist, array( 'custom_id' => $this->page_id ), array( '%d' ) );
 
 
 
 
 
 
 
 
 
800
 
801
- // Delete custom URL
802
- $wpdb->delete( $this->gpi_custom_urls, array( 'ID' => $this->page_id ), array( '%d' ) );
 
803
 
804
- return '1 ' . __( 'URLs have been deleted.', 'gpagespeedi' );
 
805
  }
 
 
 
 
 
 
806
  }
807
  }
808
 
119
  do_action( 'run_gpi', true );
120
  $action_message = __( 'Successfully initiated Insights from Google PageSpeed to recheck all reports. Full plugin functionality will be restored after all pages have been rechecked.', 'gpagespeedi' );
121
  break;
 
 
 
 
122
  }
123
 
124
  if ( $action_message ) {
125
+ do_action( 'gpi_update_option', 'action_message', sanitize_text_field( $action_message ), 'gpagespeedi_ui_options' );
126
  }
127
 
128
  wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce', 'action', 'id', 'gpi_page_report', 'single-recheck', 'strategy' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
159
 
160
  // Check for 'purge all data' option and truncate tables if checked
161
  if ( isset( $_POST['purge_all_data'] ) ) {
162
+ $purge_type = sanitize_text_field( $_POST['purge_all_data'] );
163
+ if ( 'purge_reports' == $purge_type ) {
164
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_stats" );
165
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_reports" );
166
+ } else if ( 'purge_everything' == $purge_type ) {
167
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_stats" );
168
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_reports" );
169
  $wpdb->query( "TRUNCATE TABLE $this->gpi_page_blacklist" );
178
  $old_options = $this->gpi_options;
179
 
180
  $gpagespeedi_options = array(
181
+ 'google_developer_key' => ! empty( $_POST['google_developer_key'] ) ? sanitize_text_field( $_POST['google_developer_key'] ) : sanitize_text_field( $this->gpi_options['google_developer_key'] ),
182
+ 'response_language' => ! empty( $_POST['response_language'] ) ? sanitize_text_field( $_POST['response_language'] ) : sanitize_text_field( $this->gpi_options['response_language'] ),
183
+ 'strategy' => ! empty( $_POST['strategy'] ) ? sanitize_text_field( $_POST['strategy'] ) : sanitize_text_field( $this->gpi_options['strategy'] ),
184
  'store_screenshots' => ! empty( $_POST['store_screenshots'] ) ? true : false,
185
+ 'max_execution_time' => ! empty( $_POST['max_execution_time'] ) ? intval( $_POST['max_execution_time'] ) : intval( $this->gpi_options['max_execution_time'] ),
186
+ 'max_run_time' => isset( $_POST['max_run_time'] ) ? intval( $_POST['max_run_time'] ) : intval( $this->gpi_options['max_run_time'] ),
187
+ 'sleep_time' => isset( $_POST['sleep_time'] ) ? intval( $_POST['sleep_time'] ) : intval( $this->gpi_options['sleep_time'] ),
188
+ 'recheck_interval' => ! empty( $_POST['recheck_interval'] ) ? intval( $_POST['recheck_interval'] ) : intval( $this->gpi_options['recheck_interval'] ),
189
  'use_schedule' => isset( $_POST['use_schedule'] ) ? true : false,
190
  'check_pages' => isset( $_POST['check_pages'] ) ? true : false,
191
  'check_posts' => isset( $_POST['check_posts'] ) ? true : false,
192
  'cpt_whitelist' => isset( $_POST['cpt_whitelist'] ) ? serialize( array_map( 'sanitize_text_field', $_POST['cpt_whitelist'] ) ) : false,
193
  'check_categories' => isset( $_POST['check_categories'] ) ? true : false,
194
  'check_custom_urls' => isset( $_POST['check_custom_urls'] ) ? true : false,
195
+ 'first_run_complete' => (bool) $this->gpi_options['first_run_complete'],
196
+ 'last_run_finished' => (bool) $this->gpi_options['last_run_finished'],
197
  'bad_api_key' => false,
198
  'pagespeed_disabled' => false,
199
  'api_restriction' => false,
202
  'log_api_errors' => isset( $_POST['log_api_errors'] ) ? true : false,
203
  'new_activation_message' => false,
204
  'heartbeat' => isset( $_POST['heartbeat'] ) ? sanitize_text_field( $_POST['heartbeat'] ) : 'standard',
205
+ 'mutex_id' => intval( $this->gpi_options['mutex_id'] ),
206
  'version' => GPI_VERSION
207
  );
208
  update_option( 'gpagespeedi_options', $gpagespeedi_options );
210
 
211
  $gpagespeedi_ui_options = array(
212
  'action_message' => false,
213
+ 'view_preference' => 'both' != $_POST['strategy'] ? sanitize_text_field( $_POST['strategy'] ) : sanitize_text_field( $this->gpi_ui_options['view_preference'] )
214
  );
215
 
216
  update_option( 'gpagespeedi_ui_options', $gpagespeedi_ui_options );
217
  $this->gpi_ui_options = $gpagespeedi_ui_options;
218
 
219
+ if ( (bool) $gpagespeedi_options['use_schedule'] && ! wp_next_scheduled('googlepagespeedinsightsworker') ) {
220
  wp_schedule_event( time() + $gpagespeedi_options['recheck_interval'], 'gpi_scheduled_interval', 'googlepagespeedinsightsworker' );
221
+ } else if ( (bool) $gpagespeedi_options['use_schedule'] && ( $gpagespeedi_options['recheck_interval'] != $old_options['recheck_interval'] ) ) {
222
  wp_clear_scheduled_hook( 'googlepagespeedinsightsworker' );
223
  wp_schedule_event( time() + $gpagespeedi_options['recheck_interval'], 'gpi_scheduled_interval', 'googlepagespeedinsightsworker' );
224
+ } else if ( ! (bool) $gpagespeedi_options['use_schedule'] ) {
225
  wp_clear_scheduled_hook( 'googlepagespeedinsightsworker' );
226
  }
227
 
237
  global $wpdb;
238
 
239
  if ( ! empty( $this->page_id ) ) {
240
+ $page_stats = $wpdb->get_row(
241
+ $wpdb->prepare(
242
+ "
243
+ SELECT URL, type, object_id, term_id, custom_id
244
+ FROM $this->gpi_page_stats
245
+ WHERE ID = %d
246
+ ",
247
+ $this->page_id
248
+ ), ARRAY_A
249
+ );
250
 
251
  if ( ! is_null( $page_stats['object_id'] ) ) {
252
+ $objectid = intval( $page_stats['object_id'] );
253
  } else if ( ! is_null( $page_stats['term_id'] ) ) {
254
+ $objectid = intval( $page_stats['term_id'] );
255
  } else {
256
+ $objectid = intval( $page_stats['custom_id'] );
257
  $custom = true;
258
  }
259
 
260
+ if ( $objectid ) {
261
+ $urls_to_recheck = array(
262
+ $page_stats['type'] => array(
263
+ array(
264
+ 'url' => esc_url_raw( $page_stats['URL'] ),
265
+ 'objectid' => $objectid,
266
+ 'custom' => (bool) $custom
267
+ )
268
+ ),
269
+ 'total_url_count' => 1
270
+ );
271
 
272
+ $checkstatus = apply_filters( 'gpi_check_status', false );
273
 
274
+ if ( $checkstatus ) {
275
+ $message = __( 'The API is busy checking other pages, please try again later.', 'gpagespeedi' );
276
+ } else {
277
+ update_option( 'gpi_recheck_urls', $urls_to_recheck, false );
278
+ do_action( 'run_gpi', true, false, $urls_to_recheck );
279
 
280
+ $message = __( 'This URL has been scheduled for a recheck.', 'gpagespeedi' );
281
+ }
282
 
283
+ return $message;
284
+ }
285
  }
286
  }
287
 
375
  global $wpdb;
376
 
377
  foreach ( $this->bulk_pages as $page_id ) {
378
+ $page_info = $wpdb->get_row(
379
+ $wpdb->prepare(
380
+ "
381
+ SELECT ID, URL, type, object_id, term_id, custom_id
382
+ FROM $this->gpi_page_stats
383
+ WHERE ID = %d
384
+ ",
385
+ $page_id
386
+ ), ARRAY_A
387
+ );
388
 
389
  $wpdb->delete( $this->gpi_page_stats, array( 'ID' => $page_id ), array( '%d' ) );
390
  $wpdb->delete( $this->gpi_page_reports, array( 'page_id' => $page_id ), array( '%d' ) );
463
  global $wpdb;
464
 
465
  $snapshot_data = array(
466
+ 'strategy' => sanitize_text_field( $this->gpi_ui_options['view_preference'] ),
467
  'type' => isset( $_GET['filter'] ) ? sanitize_text_field( $_GET['filter'] ) : 'all',
468
  'snaptime' => current_time( 'timestamp' ),
469
  'comment' => isset( $_POST['comment'] ) ? sanitize_text_field( $_POST['comment'] ) : false,
534
  );
535
  }
536
 
537
+ $custom_url_label = sanitize_title( $_POST['custom_url_label'] );
538
+
539
+ if ( strlen( $custom_url_label ) > 40 ) {
540
+ $custom_url_label = substr( $custom_url_label, 0, 40 );
541
+ }
542
 
543
  if ( empty( $custom_url_label ) ) {
544
  $custom_url_label = 'custom';
 
 
 
 
545
  }
546
 
547
  foreach ( $_POST['custom_urls'] as $custom_url ) {
557
 
558
  foreach ( $urls_to_store as $key => $url ) {
559
 
560
+ $url_already_exist = $wpdb->get_var(
561
+ $wpdb->prepare(
562
+ "
563
+ SELECT ( SELECT COUNT(*) FROM $this->gpi_custom_urls WHERE URL = %s ) + ( SELECT COUNT(*) FROM $this->gpi_page_stats WHERE URL = %s )
564
+ ", $url, $url
565
  )
566
  );
567
 
648
 
649
  if ( ! empty( $urls_to_store ) ) {
650
 
651
+ $custom_url_label = isset( $_POST['custom_url_label'] ) ? sanitize_title( $_POST['custom_url_label'] ) : false;
652
+
653
+ if ( strlen( $custom_url_label ) > 40 ) {
654
+ $custom_url_label = substr( $custom_url_label, 0, 40 );
655
+ }
656
 
657
  if ( ! $custom_url_label ) {
658
  $custom_url_label = 'custom';
 
 
 
 
659
  }
660
 
661
  global $wpdb;
663
  foreach ( $urls_to_store as $key => $url ) {
664
 
665
  // Make sure the URL does not already exist
666
+ $url_already_exist = $wpdb->get_var(
667
+ $wpdb->prepare(
668
+ "
669
+ SELECT ( SELECT COUNT(*) FROM $this->gpi_custom_urls WHERE URL = %s ) + ( SELECT COUNT(*) FROM $this->gpi_page_stats WHERE URL = %s )
670
+ ", $url, $url
671
  )
672
  );
673
 
703
 
704
  private function delete_page()
705
  {
 
 
706
  if ( is_array( $this->bulk_pages ) && ! empty( $this->bulk_pages ) ) {
707
+ $delete_array_count = count( $this->bulk_pages );
 
 
 
 
 
 
 
 
708
 
709
+ foreach ( $this->bulk_pages as $custom_id ) {
710
+ $this->delete_helper( $custom_id );
 
 
 
 
 
 
711
  }
712
 
713
+ return $delete_array_count . ' ' . __( 'URLs have been deleted.', 'gpagespeedi' );
 
 
 
 
 
 
 
 
 
 
 
 
 
714
 
715
+ } else if ( ! empty( $this->page_id ) ) {
716
+ $this->delete_helper( $this->page_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717
 
718
+ return '1 ' . __( 'URLs have been deleted.', 'gpagespeedi' );
719
+ }
720
+ }
 
 
 
 
 
 
 
 
 
 
 
721
 
722
+ private function delete_helper( $custom_id )
723
+ {
724
+ global $wpdb;
725
 
726
+ $custom_id = intval( $custom_id );
727
 
728
+ if ( ! $custom_id ) {
729
+ return;
730
+ }
 
 
 
 
 
 
 
 
 
 
 
 
731
 
732
+ // Get the internal ID for this custom url
733
+ $internal_id = $wpdb->get_var(
734
+ $wpdb->prepare(
735
+ "
736
+ SELECT ID
737
+ FROM $this->gpi_page_stats
738
+ WHERE custom_id = %d
739
+ ",
740
+ $custom_id
741
+ )
742
+ );
743
 
744
+ if ( $internal_id ) {
745
+ // Delete any page reports for this custom url
746
+ $wpdb->delete( $this->gpi_page_reports, array( 'page_id' => $internal_id ), array( '%d' ) );
747
 
748
+ // Delete any page stats for this custom url
749
+ $wpdb->delete( $this->gpi_page_stats, array( 'ID' => $internal_id ), array( '%d' ) );
750
  }
751
+
752
+ // Delete any blacklist rows for this custom url
753
+ $wpdb->delete( $this->gpi_page_blacklist, array( 'custom_id' => $custom_id ), array( '%d' ) );
754
+
755
+ // Delete from custom urls
756
+ $wpdb->delete( $this->gpi_custom_urls, array( 'ID' => $custom_id ), array( '%d' ) );
757
  }
758
  }
759
 
classes/class-GPI-Activation.php CHANGED
@@ -17,7 +17,7 @@ class GPI_Activation
17
 
18
  static function upgrade( $gpagespeedi_options, $gpagespeedi_ui_options, $update_options = true )
19
  {
20
- // In v4.0 data structure for page/summary stats changed dramaticly and existing reports/snapshots are now longer compatible and must be removed
21
  if ( ! isset( $gpagespeedi_options['version'] ) || version_compare( $gpagespeedi_options['version'], '4.0', '<' ) ) {
22
  global $wpdb;
23
  $gpi_page_stats_table = $wpdb->prefix . 'gpi_page_stats';
@@ -35,31 +35,31 @@ class GPI_Activation
35
 
36
  if ( $update_options ) {
37
  $update_values = array(
38
- 'google_developer_key' => isset( $gpagespeedi_options['google_developer_key'] ) ? $gpagespeedi_options['google_developer_key'] : '',
39
- 'response_language' => isset( $gpagespeedi_options['response_language'] ) ? $gpagespeedi_options['response_language'] : 'en_US',
40
- 'strategy' => isset( $gpagespeedi_options['strategy'] ) ? $gpagespeedi_options['strategy'] : 'desktop',
41
- 'store_screenshots' => isset( $gpagespeedi_options['store_screenshots'] ) ? $gpagespeedi_options['store_screenshots'] : 0,
42
- 'max_execution_time' => isset( $gpagespeedi_options['max_execution_time'] ) ? $gpagespeedi_options['max_execution_time'] : 300,
43
- 'max_run_time' => isset( $gpagespeedi_options['max_run_time'] ) ? $gpagespeedi_options['max_run_time'] : 0,
44
- 'sleep_time' => isset( $gpagespeedi_options['sleep_time'] ) ? $gpagespeedi_options['sleep_time'] : 0,
45
- 'recheck_interval' => isset( $gpagespeedi_options['recheck_interval'] ) ? $gpagespeedi_options['recheck_interval'] : 86400,
46
- 'use_schedule' => isset( $gpagespeedi_options['use_schedule'] ) ? $gpagespeedi_options['use_schedule'] : true,
47
- 'check_pages' => isset( $gpagespeedi_options['check_pages'] ) ? $gpagespeedi_options['check_pages'] : true,
48
- 'check_posts' => isset( $gpagespeedi_options['check_posts'] ) ? $gpagespeedi_options['check_posts'] : true,
49
  'cpt_whitelist' => isset( $gpagespeedi_options['cpt_whitelist'] ) ? $gpagespeedi_options['cpt_whitelist'] : '',
50
- 'check_categories' => isset( $gpagespeedi_options['check_categories'] ) ? $gpagespeedi_options['check_categories'] : true,
51
- 'check_custom_urls' => isset( $gpagespeedi_options['check_custom_urls'] ) ? $gpagespeedi_options['check_custom_urls'] : true,
52
- 'first_run_complete' => isset( $gpagespeedi_options['first_run_complete'] ) ? $gpagespeedi_options['first_run_complete'] : false,
53
- 'last_run_finished' => isset( $gpagespeedi_options['last_run_finished'] ) ? $gpagespeedi_options['last_run_finished'] : true,
54
- 'bad_api_key' => isset( $gpagespeedi_options['bad_api_key'] ) ? $gpagespeedi_options['bad_api_key'] : false,
55
- 'pagespeed_disabled' => isset( $gpagespeedi_options['pagespeed_disabled'] ) ? $gpagespeedi_options['pagespeed_disabled'] : false,
56
- 'api_restriction' => isset( $gpagespeedi_options['api_restriction'] ) ? $gpagespeedi_options['api_restriction'] : false,
57
- 'new_ignored_items' => isset( $gpagespeedi_options['new_ignored_items'] ) ? $gpagespeedi_options['new_ignored_items'] : false,
58
- 'backend_error' => isset( $gpagespeedi_options['backend_error'] ) ? $gpagespeedi_options['backend_error'] : false,
59
- 'log_api_errors' => isset( $gpagespeedi_options['log_api_errors'] ) ? $gpagespeedi_options['log_api_errors'] : false,
60
  'new_activation_message' => false,
61
- 'heartbeat' => isset( $gpagespeedi_options['heartbeat'] ) ? $gpagespeedi_options['heartbeat'] : 'fast',
62
- 'mutex_id' => isset( $gpagespeedi_options['mutex_id'] ) ? $gpagespeedi_options['mutex_id'] : time() . rand(),
63
  'version' => GPI_VERSION
64
  );
65
  update_option( 'gpagespeedi_options', $update_values );
17
 
18
  static function upgrade( $gpagespeedi_options, $gpagespeedi_ui_options, $update_options = true )
19
  {
20
+ // In v4.0 data structure for page/summary stats changed dramaticly and existing reports/snapshots are no longer compatible and must be removed
21
  if ( ! isset( $gpagespeedi_options['version'] ) || version_compare( $gpagespeedi_options['version'], '4.0', '<' ) ) {
22
  global $wpdb;
23
  $gpi_page_stats_table = $wpdb->prefix . 'gpi_page_stats';
35
 
36
  if ( $update_options ) {
37
  $update_values = array(
38
+ 'google_developer_key' => isset( $gpagespeedi_options['google_developer_key'] ) ? sanitize_text_field( $gpagespeedi_options['google_developer_key'] ) : '',
39
+ 'response_language' => isset( $gpagespeedi_options['response_language'] ) ? sanitize_text_field( $gpagespeedi_options['response_language'] ) : 'en_US',
40
+ 'strategy' => isset( $gpagespeedi_options['strategy'] ) ? sanitize_text_field( $gpagespeedi_options['strategy'] ) : 'desktop',
41
+ 'store_screenshots' => isset( $gpagespeedi_options['store_screenshots'] ) ? 1 : 0,
42
+ 'max_execution_time' => isset( $gpagespeedi_options['max_execution_time'] ) ? intval( $gpagespeedi_options['max_execution_time'] ) : 300,
43
+ 'max_run_time' => isset( $gpagespeedi_options['max_run_time'] ) ? intval( $gpagespeedi_options['max_run_time'] ) : 0,
44
+ 'sleep_time' => isset( $gpagespeedi_options['sleep_time'] ) ? intval( $gpagespeedi_options['sleep_time'] ) : 0,
45
+ 'recheck_interval' => isset( $gpagespeedi_options['recheck_interval'] ) ? intval( $gpagespeedi_options['recheck_interval'] ) : 86400,
46
+ 'use_schedule' => isset( $gpagespeedi_options['use_schedule'] ) ? 1 : 0,
47
+ 'check_pages' => isset( $gpagespeedi_options['check_pages'] ) ? 1 : 0,
48
+ 'check_posts' => isset( $gpagespeedi_options['check_posts'] ) ? 1 : 0,
49
  'cpt_whitelist' => isset( $gpagespeedi_options['cpt_whitelist'] ) ? $gpagespeedi_options['cpt_whitelist'] : '',
50
+ 'check_categories' => isset( $gpagespeedi_options['check_categories'] ) ? 1 : 0,
51
+ 'check_custom_urls' => isset( $gpagespeedi_options['check_custom_urls'] ) ? 1 : 0,
52
+ 'first_run_complete' => isset( $gpagespeedi_options['first_run_complete'] ) ? 1 : 0,
53
+ 'last_run_finished' => isset( $gpagespeedi_options['last_run_finished'] ) ? 1 : 0,
54
+ 'bad_api_key' => isset( $gpagespeedi_options['bad_api_key'] ) ? 1 : 0,
55
+ 'pagespeed_disabled' => isset( $gpagespeedi_options['pagespeed_disabled'] ) ? 1 : 0,
56
+ 'api_restriction' => isset( $gpagespeedi_options['api_restriction'] ) ? 1 : 0,
57
+ 'new_ignored_items' => isset( $gpagespeedi_options['new_ignored_items'] ) ? 1 : 0,
58
+ 'backend_error' => isset( $gpagespeedi_options['backend_error'] ) ? 1 : 0,
59
+ 'log_api_errors' => isset( $gpagespeedi_options['log_api_errors'] ) ? 1 : 0,
60
  'new_activation_message' => false,
61
+ 'heartbeat' => isset( $gpagespeedi_options['heartbeat'] ) ? sanitize_text_field( $gpagespeedi_options['heartbeat'] ) : 'fast',
62
+ 'mutex_id' => isset( $gpagespeedi_options['mutex_id'] ) ? intval( $gpagespeedi_options['mutex_id'] ) : time() . rand(),
63
  'version' => GPI_VERSION
64
  );
65
  update_option( 'gpagespeedi_options', $update_values );
classes/class-GPI-Admin.php CHANGED
@@ -23,7 +23,7 @@ class GPI_Admin
23
  {
24
  $this->gpi_options = get_option( 'gpagespeedi_options' );
25
  $this->gpi_ui_options = get_option( 'gpagespeedi_ui_options' );
26
- $this->strategy = ( isset( $_GET['strategy'] ) ) ? sanitize_text_field( $_GET['strategy'] ) : $this->gpi_ui_options['view_preference'];
27
 
28
  if ( 'desktop' != $this->strategy && 'mobile' != $this->strategy ) {
29
  $this->strategy = 'desktop';
@@ -129,7 +129,7 @@ class GPI_Admin
129
  {
130
  ?>
131
  <div class="notice notice-error is-dismissible">
132
- <p><?php _e( 'The plugin "Google Pagespeed Insights Addon" has automatically been deactivated. As of v3.0 Insights from Google PageSpeed now includes all "addon" functionality for free. The "Google Pagespeed Insights Addon" can be uninstalled from the plugins page.', 'gpagespeedi' ); ?></p>
133
  </div>
134
  <?php
135
  }
@@ -145,24 +145,38 @@ class GPI_Admin
145
  ?>
146
  <div class="wrap">
147
  <h2>
148
- <?php _e( 'Insights from Google PageSpeed', 'gpagespeedi' ); ?>
149
  <div class="global-actions">
150
  <?php
151
  if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) :
152
  if ( ! get_option( 'gpi_abort_scan' ) ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  ?>
154
- <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=<?php echo $admin_page; ?>&amp;action=abort-scan" class="button-gpi abort"><?php _e( 'Abort Current Scan', 'gpagespeedi' ); ?></a>
155
  <?php
156
  else :
157
  ?>
158
- <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=<?php echo $admin_page; ?>" class="button-gpi abort" disabled><?php _e( 'Abort Current Scan', 'gpagespeedi' ); ?></a>
159
  <?php
160
  endif;
161
- elseif ( $this->gpi_options['google_developer_key'] ) :
162
  ?>
163
- <a id="start_scan" href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=<?php echo $admin_page; ?>&amp;action=start-scan" class="button-gpi run"><?php _e( 'Start Reporting', 'gpagespeedi' ); ?></a>
164
- <input type="checkbox" name="recheck_all_pages" id="recheck_all_pages" />
165
- <label for="recheck_all_pages"><?php _e( 'Recheck All', 'gpagespeedi' ); ?> <span class="tooltip" title="<?php _e( 'Ignore last checked date to generate new reports for all pages', 'gpagespeedi' ); ?>">(?)</span></label>
166
  <?php
167
  endif;
168
  ?>
@@ -185,13 +199,13 @@ class GPI_Admin
185
 
186
  public function admin_notice()
187
  {
188
- if ( $this->gpi_options['new_activation_message'] == false ) {
189
  return;
190
  }
191
  ?>
192
  <div id="message" class="updated">
193
  <p>
194
- <?php _e( 'Insights from Google PageSpeed has been activated. It can be accessed via Tools', 'gpagespeedi' ); ?> -> <a href="<?php echo admin_url('/tools.php?page=google-pagespeed-insights&render=options'); ?>">Pagespeed Insights</a>
195
  </p>
196
  </div>
197
  <?php
@@ -211,7 +225,7 @@ class GPI_Admin
211
  return;
212
  }
213
 
214
- wp_enqueue_style( 'gpagespeedi_css', plugins_url( '/assets/css/gpagespeedi_styles.css', GPI_PLUGIN_FILE ), false, GPI_VERSION );
215
 
216
  wp_register_script( 'gpagespeedi_google_charts', 'https://www.gstatic.com/charts/loader.js' );
217
  }
@@ -228,27 +242,27 @@ class GPI_Admin
228
 
229
  $recheck_url = admin_url( '/tools.php?page=google-pagespeed-insights&render=details&page_id=' . intval( $_GET['page_id'] ) . '&action=single-recheck' );
230
 
231
- wp_enqueue_script( 'gpagespeedi_details_js', plugins_url( '/assets/js/details.js', GPI_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-accordion', 'gpagespeedi_google_charts', 'wp-util' ), GPI_VERSION, true );
232
  wp_localize_script( 'gpagespeedi_details_js', 'GPI_Details', array(
233
  'page_stats' => $this->get_page_stats( intval( $_GET['page_id'] ) ),
234
  'page_reports' => $this->get_page_reports( intval( $_GET['page_id'] ) ),
235
  'recheck_url' => wp_nonce_url( $recheck_url, 'gpi-single-recheck' ),
236
- 'public_path' => GPI_PUBLIC_PATH,
237
  'strings' => array(
238
- 'old_format_notice' => sprintf( __( 'Insights from Google PageSpeed has detected an outdated format in this report due to an update in version %s of this plugin. Some report features are unavailable. Please recheck results to resolve this problem.', 'gpagespeedi' ), '4.0' ),
239
- 'insufficient_field_data' => __( 'The Chrome User Experience Report <a href="https://developers.google.com/speed/docs/insights/about#faq" target="_blank">does not have sufficient real-world speed data</a> for this page.', 'gpagespeedi' ),
240
- 'FCP' => __( 'First Contentful Paint', 'gpagespeedi' ),
241
- 'FID' => __( 'First Input Delay', 'gpagespeedi' ),
242
  'field_data_labels' => array(
243
- __( 'of loads for this page have a fast', 'gpagespeedi' ),
244
- __( 'of loads for this page have an average', 'gpagespeedi' ),
245
- __( 'of loads for this page have a slow', 'gpagespeedi' )
246
  ),
247
  'shortpixel' => array(
248
- 'title' => __( 'Auto-Optimize Images', 'gpagespeedi' ),
249
- 'description' => __( 'Unoptimized images are often one of the <strong>biggest</strong> negative factors in pagespeed scores. Insights from Google PageSpeed has partnered with ShortPixel to provide an easy and affordable solution to <em>automatically</em> optimize all images.', 'gpagespeedi' ),
250
- 'signup_desc' => __( 'Sign up using the button below and receive <strong>150 free image optimization credits</strong>.', 'gpagespeedi' ),
251
- 'signup_btn' => __( 'Free Sign Up', 'gpagespeedi' )
252
  )
253
  )
254
  )
@@ -265,15 +279,15 @@ class GPI_Admin
265
  return;
266
  }
267
 
268
- wp_enqueue_script( 'gpagespeedi_summary_js', plugins_url( '/assets/js/summary.js', GPI_PLUGIN_FILE ), array( 'jquery', 'gpagespeedi_google_charts', 'wp-util' ), GPI_VERSION );
269
  wp_localize_script( 'gpagespeedi_summary_js', 'GPI_Summary', array(
270
  'summary_stats' => $this->get_summary_stats(),
271
  'summary_reports' => $this->get_summary_reports(),
272
  'strings' => array(
273
- 'average_score' => __( 'Average Score', 'gpagespeedi' ),
274
- 'best_performing' => __( 'View Best Performing', 'gpagespeedi' ),
275
- 'worst_performing' => __( 'View Worst Performing', 'gpagespeedi' ),
276
- 'old_format_notice' => __( 'Insights from Google PageSpeed has detected an outdated format in one or more reports due to an update in version 2.0 of this plugin. Some report features are unavailable. Please force recheck all reports from the options page to resolve this problem.', 'gpagespeedi' )
277
  )
278
  )
279
  );
@@ -292,20 +306,20 @@ class GPI_Admin
292
  $snapshot_data = $this->get_snapshot_data();
293
  $strings = array(
294
  'strings' => array(
295
- 'comment' => __( 'Comment', 'gpagespeedi' ),
296
- 'average_score' => __( 'Average Score', 'gpagespeedi' ),
297
- 'best_performing' => __( 'View Best Performing', 'gpagespeedi' ),
298
- 'worst_performing' => __( 'View Worst Performing', 'gpagespeedi' )
299
  ),
300
  'comments' => array(
301
- 'snapshot' => isset( $snapshot_data['snapshot']['comment'] ) ? esc_textarea( $snapshot_data['snapshot']['comment'] ) : false,
302
- 'compare' => isset( $snapshot_data['compare']['comment'] ) ? esc_textarea( $snapshot_data['compare']['comment'] ) : false
303
  )
304
  );
305
 
306
  $localize_data = array_merge( $snapshot_data, $strings );
307
 
308
- wp_enqueue_script( 'gpagespeedi_view_snapshot_js', plugins_url( '/assets/js/view-snapshot.js', GPI_PLUGIN_FILE ), array( 'jquery', 'gpagespeedi_google_charts', 'wp-util' ), GPI_VERSION );
309
  wp_localize_script( 'gpagespeedi_view_snapshot_js', 'GPI_View_Snapshot', $localize_data );
310
  }
311
 
@@ -315,10 +329,10 @@ class GPI_Admin
315
  return;
316
  }
317
 
318
- wp_enqueue_script( 'gpagespeedi_global_js', plugins_url( '/assets/js/global.js', GPI_PLUGIN_FILE ), array( 'jquery', 'heartbeat', 'jquery-ui-tooltip' ), GPI_VERSION );
319
  wp_localize_script( 'gpagespeedi_global_js', 'GPI_Global', array(
320
- 'heartbeat' => $this->gpi_options['heartbeat'],
321
- 'progress' => get_option( 'gpi_progress' )
322
  )
323
  );
324
  }
@@ -414,24 +428,24 @@ class GPI_Admin
414
  public function get_filter_options( $options, $flatlist = false )
415
  {
416
  if ( ! $flatlist ) {
417
- $options['all'] = __( 'All Reports', 'gpagespeedi' );
418
  }
419
 
420
- if ( $this->gpi_options['check_pages'] ) {
421
- $options['page'] = __( 'Pages', 'gpagespeedi' );
422
  }
423
 
424
- if ( $this->gpi_options['check_posts'] ) {
425
- $options['post'] = __( 'Posts', 'gpagespeedi' );
426
  }
427
 
428
- if ( $this->gpi_options['check_categories'] ) {
429
- $options['category'] = __( 'Categories', 'gpagespeedi' );
430
  }
431
 
432
  if ( ! empty( $this->gpi_options['cpt_whitelist'] ) ) {
433
  if ( ! $flatlist ) {
434
- $cpt_options = array( 'gpi_custom_posts' => __( 'All Custom Post Types', 'gpagespeedi' ) );
435
  }
436
 
437
  $cpt_whitelist = maybe_unserialize( $this->gpi_options['cpt_whitelist'] );
@@ -441,7 +455,7 @@ class GPI_Admin
441
 
442
  if ( ! $flatlist ) {
443
  $options['custom_post_types'] = array(
444
- 'optgroup_label' => __( 'Custom Post Types', 'gpagespeedi' ),
445
  'options' => $cpt_options
446
  );
447
  } else {
@@ -449,20 +463,20 @@ class GPI_Admin
449
  }
450
  }
451
 
452
- if ( $this->gpi_options['check_custom_urls'] ) {
453
  global $wpdb;
454
 
455
  $gpi_custom_urls = $wpdb->prefix . 'gpi_custom_urls';
456
  $custom_url_types = $wpdb->get_col(
457
  "
458
- SELECT DISTINCT type
459
- FROM $gpi_custom_urls
460
  "
461
  );
462
 
463
  if ( ! empty( $custom_url_types ) ) {
464
  if ( ! $flatlist ) {
465
- $custom_url_options = array( 'gpi_custom_urls' => __( 'All Custom URLs', 'gpagespeedi' ) );
466
  }
467
 
468
  foreach ( $custom_url_types as $custom_url_type ) {
@@ -471,7 +485,7 @@ class GPI_Admin
471
 
472
  if ( ! $flatlist ) {
473
  $options['custom_urls'] = array(
474
- 'optgroup_label' => __( 'Custom URLs', 'gpagespeedi' ),
475
  'options' => $custom_url_options
476
  );
477
  } else {
@@ -522,8 +536,8 @@ class GPI_Admin
522
 
523
  return $wpdb->get_var(
524
  "
525
- SELECT COUNT(*)
526
- FROM $gpi_custom_urls
527
  "
528
  );
529
  }
@@ -565,16 +579,18 @@ class GPI_Admin
565
  $all_page_stats = array();
566
 
567
  if ( $filter ) {
568
- $all_page_stats = $wpdb->get_results( $wpdb->prepare(
569
- "
570
- SELECT ID, URL, {$this->strategy}_score as score, {$this->strategy}_lab_data as labData
571
- FROM $gpi_page_stats
572
- WHERE type REGEXP %s
573
- AND {$this->strategy}_score IS NOT NULL
574
- ORDER BY score DESC
575
- ",
576
- $filter
577
- ), ARRAY_A );
 
 
578
  }
579
 
580
  if ( ! $all_page_stats ) {
@@ -595,9 +611,9 @@ class GPI_Admin
595
  $report_url = admin_url( '/tools.php?page=google-pagespeed-insights&render=details&page_id=' . $page_stats['ID'] );
596
 
597
  $page_scores[] = array(
598
- 'score' => $page_stats['score'],
599
- 'report_url' => $report_url,
600
- 'page_url' => $page_stats['URL']
601
  );
602
 
603
  // flag if pre 2.0 data structure is detected
@@ -611,19 +627,19 @@ class GPI_Admin
611
  $avg_lab_data[ $data['title'] ] = array( 'lowest' => array( 'value' => false, 'url' => false ), 'average' => false, 'highest' => array( 'value' => false, 'url' => false ) );
612
  }
613
 
614
- $avg_lab_data[ $data['title'] ]['average'] += $data['score'];
615
 
616
  if ( false === $avg_lab_data[ $data['title'] ]['highest']['value'] || $data['score'] > $avg_lab_data[ $data['title'] ]['highest']['value'] ) {
617
  $avg_lab_data[ $data['title'] ]['highest'] = array(
618
- 'value' => $data['displayValue'],
619
- 'url' => $report_url
620
  );
621
  }
622
 
623
  if ( false === $avg_lab_data[ $data['title'] ]['lowest']['value'] || $data['score'] < $avg_lab_data[ $data['title'] ]['lowest']['value'] ) {
624
  $avg_lab_data[ $data['title'] ]['lowest'] = array(
625
- 'value' => $data['displayValue'],
626
- 'url' => $report_url
627
  );
628
  }
629
  }
@@ -631,7 +647,7 @@ class GPI_Admin
631
  }
632
 
633
  foreach ( $avg_lab_data as &$data ) {
634
- $data['average'] = $data['average'] / $pages;
635
  }
636
 
637
  $score = round( $score / $pages );
@@ -645,9 +661,9 @@ class GPI_Admin
645
  'lowest' => array_slice( $low_scores, 0, 5 )
646
  ),
647
  'labData' => $avg_lab_data,
648
- 'score' => $score,
649
- 'odometer_rotation' => ( ( 3.38 * $score ) + 11 ) . 'deg',
650
- 'data_format' => ( $old_format_detected ) ? '1.0' : GPI_VERSION
651
  );
652
  }
653
 
@@ -669,23 +685,25 @@ class GPI_Admin
669
  $all_page_reports = array();
670
 
671
  if ( $filter ) {
672
- $all_page_reports = $wpdb->get_results( $wpdb->prepare(
673
- "
674
- SELECT r.rule_key, r.rule_name, r.rule_score
675
- FROM $gpi_page_stats as s
676
- INNER JOIN $gpi_page_reports as r
677
- ON r.page_id = s.ID
678
- AND r.strategy = %s
679
- AND r.rule_type = %s
680
- AND r.rule_score < .9
681
- WHERE type REGEXP %s
682
- AND s.{$this->strategy}_score IS NOT NULL
683
- ORDER BY r.rule_score DESC
684
- ",
685
- $this->strategy,
686
- 'opportunity',
687
- $filter
688
- ), ARRAY_A );
 
 
689
  }
690
 
691
  if ( ! $all_page_reports ) {
@@ -698,7 +716,7 @@ class GPI_Admin
698
  $summary_reports[ $page_report['rule_key'] ]['occurances']++;
699
  } else {
700
  $summary_reports[ $page_report['rule_key'] ] = array(
701
- 'rule_name' => ( 'uses-optimized-images' != $page_report['rule_key'] ) ? $page_report['rule_name'] : $page_report['rule_name'] . '<span class="shortpixel_blurb"> &ndash; <a href="https://shortpixel.com/h/af/PCFTWNN142247" target="_blank">' . __( 'Auto-Optimize images with ShortPixel. Sign up for 150 free credits!', 'gpagespeedi') . '</a></span>',
702
  'avg_score' => $page_report['rule_score'],
703
  'occurances' => 1
704
  );
@@ -707,7 +725,7 @@ class GPI_Admin
707
 
708
  foreach ( $summary_reports as &$summary_report ) {
709
  $summary_report['avg_score'] = round( $summary_report['avg_score'] / $summary_report['occurances'], 2 );
710
- $summary_report['avg_score'] = $summary_report['avg_score'] * 100;
711
  }
712
 
713
  $summary_reports = $this->sort_array( $summary_reports, 'avg_score' );
@@ -757,9 +775,9 @@ class GPI_Admin
757
 
758
  $error_logs = $wpdb->get_results(
759
  "
760
- SELECT URL, strategy, is_update, type, timestamp, error
761
- FROM $gpi_api_error_logs
762
- ORDER BY timestamp DESC
763
  ", ARRAY_A
764
  );
765
 
@@ -772,14 +790,16 @@ class GPI_Admin
772
 
773
  $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
774
 
775
- $page_stats = $wpdb->get_row( $wpdb->prepare(
776
- "
777
- SELECT URL, {$this->strategy}_lab_data as labData, {$this->strategy}_field_data as fieldData, {$this->strategy}_score as score, {$this->strategy}_last_modified as last_modified
778
- FROM $gpi_page_stats
779
- WHERE ID = %d
780
- ",
781
- $page_id
782
- ), ARRAY_A );
 
 
783
 
784
  if ( empty( $page_stats ) ) {
785
  return false;
@@ -789,7 +809,7 @@ class GPI_Admin
789
  if ( strpos( $page_stats['labData'], 'numberHosts' ) !== false ) {
790
  $page_stats['data_format'] = '1.0';
791
  } else {
792
- $page_stats['data_format'] = GPI_VERSION;
793
  }
794
 
795
  if ( ! empty( $page_stats['score'] ) ) {
@@ -803,10 +823,18 @@ class GPI_Admin
803
  if ( ! empty( $page_stats['last_modified'] ) ) {
804
  $page_stats['last_modified'] = date_i18n( 'M d g:ia', $page_stats['last_modified'] );
805
  } else {
806
- $page_stats['last_modified'] = __( 'N/A', 'gpagespeedi' );
 
 
 
 
 
 
807
  }
808
 
809
- return array_map( 'maybe_unserialize', $page_stats );
 
 
810
  }
811
 
812
  private function get_page_reports( $page_id )
@@ -815,22 +843,30 @@ class GPI_Admin
815
 
816
  $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
817
 
818
- $page_reports = $wpdb->get_results( $wpdb->prepare(
819
- "
820
- SELECT rule_key, rule_name, rule_score, rule_blocks
821
- FROM $gpi_page_reports
822
- WHERE page_id = %d
823
- AND strategy = %s
824
- ORDER BY rule_score ASC
825
- ",
826
- $page_id,
827
- $this->strategy
828
- ), ARRAY_A );
 
 
829
 
830
  if ( $page_reports ) {
831
- foreach ( $page_reports as &$page_report ) {
832
  $page_report['rule_blocks'] = unserialize( $page_report['rule_blocks'] );
833
 
 
 
 
 
 
 
834
  if ( 'uses-optimized-images' == $page_report['rule_key'] ) {
835
  $page_report['rule_blocks'] = $this->shortpixel_image_rule_blocks( $page_report['rule_blocks'] );
836
  }
@@ -847,31 +883,69 @@ class GPI_Admin
847
  $gpi_summary_snapshots = $wpdb->prefix . 'gpi_summary_snapshots';
848
 
849
  if ( isset( $_GET['snapshot_id'] ) ) {
850
- $snapshot = $wpdb->get_row( $wpdb->prepare(
851
- "
852
- SELECT strategy, type, snaptime, comment, summary_stats, summary_reports
853
- FROM $gpi_summary_snapshots
854
- WHERE ID = %d
855
- ",
856
- $_GET['snapshot_id']
857
- ), ARRAY_A );
 
 
858
  } else {
859
  $snapshot = false;
860
  }
861
 
862
  if ( isset( $_GET['compare_id'] ) ) {
863
- $compare_snapshot = $wpdb->get_row( $wpdb->prepare(
864
- "
865
- SELECT strategy, type, snaptime, comment, summary_stats, summary_reports
866
- FROM $gpi_summary_snapshots
867
- WHERE ID = %d
868
- ",
869
- $_GET['compare_id']
870
- ), ARRAY_A );
 
 
871
  } else {
872
  $compare_snapshot = false;
873
  }
874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875
  return array(
876
  'snapshot' => $snapshot,
877
  'compare' => $compare_snapshot
@@ -885,25 +959,29 @@ class GPI_Admin
885
 
886
  $gpi_summary_snapshots = $wpdb->prefix . 'gpi_summary_snapshots';
887
 
888
- $current_snapshot = $wpdb->get_row( $wpdb->prepare(
889
- "
890
- SELECT strategy, type
891
- FROM $gpi_summary_snapshots
892
- WHERE ID = %d
893
- ",
894
- $current_snapshot_id
895
- ), ARRAY_A );
 
 
896
 
897
- $similar_snapshots = $wpdb->get_results( $wpdb->prepare(
898
- "
899
- SELECT ID, snaptime
900
- FROM $gpi_summary_snapshots
901
- WHERE strategy = %s
902
- AND type = %s
903
- ",
904
- $current_snapshot['strategy'],
905
- $current_snapshot['type']
906
- ), ARRAY_A );
 
 
907
  }
908
 
909
  return $similar_snapshots;
@@ -943,6 +1021,95 @@ class GPI_Admin
943
  return $array;
944
  }
945
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
946
  }
947
 
948
  add_action( 'plugins_loaded', array( new GPI_Admin, 'init' ) );
23
  {
24
  $this->gpi_options = get_option( 'gpagespeedi_options' );
25
  $this->gpi_ui_options = get_option( 'gpagespeedi_ui_options' );
26
+ $this->strategy = ( isset( $_GET['strategy'] ) ) ? sanitize_text_field( $_GET['strategy'] ) : sanitize_text_field( $this->gpi_ui_options['view_preference'] );
27
 
28
  if ( 'desktop' != $this->strategy && 'mobile' != $this->strategy ) {
29
  $this->strategy = 'desktop';
129
  {
130
  ?>
131
  <div class="notice notice-error is-dismissible">
132
+ <p><?php esc_html_e( 'The plugin "Google Pagespeed Insights Addon" has automatically been deactivated. As of v3.0 Insights from Google PageSpeed now includes all "addon" functionality for free. The "Google Pagespeed Insights Addon" can be uninstalled from the plugins page.', 'gpagespeedi' ); ?></p>
133
  </div>
134
  <?php
135
  }
145
  ?>
146
  <div class="wrap">
147
  <h2>
148
+ <?php esc_html_e( 'Insights from Google PageSpeed', 'gpagespeedi' ); ?>
149
  <div class="global-actions">
150
  <?php
151
  if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) :
152
  if ( ! get_option( 'gpi_abort_scan' ) ) :
153
+ if ( isset( $_GET['page_id'] ) ) :
154
+ ?>
155
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=' . $admin_page . '&amp;page_id=' . intval( $_GET['page_id'] ) . '&amp;action=abort-scan' ); ?>" class="button-gpi abort"><?php esc_html_e( 'Abort Current Scan', 'gpagespeedi' ); ?></a>
156
+ <?php
157
+ else :
158
+ ?>
159
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=' . $admin_page . '&amp;action=abort-scan' ); ?>" class="button-gpi abort"><?php esc_html_e( 'Abort Current Scan', 'gpagespeedi' ); ?></a>
160
+ <?php
161
+ endif;
162
+ else :
163
+ ?>
164
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=' . $admin_page ); ?>" class="button-gpi abort" disabled><?php esc_html_e( 'Abort Current Scan', 'gpagespeedi' ); ?></a>
165
+ <?php
166
+ endif;
167
+ elseif ( $this->gpi_options['google_developer_key'] ) :
168
+ if ( isset( $_GET['page_id'] ) ) :
169
  ?>
170
+ <a id="start_scan" href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=' . $admin_page . '&amp;page_id=' . intval( $_GET['page_id'] ) . '&amp;action=start-scan' ); ?>" class="button-gpi run"><?php esc_html_e( 'Start Reporting', 'gpagespeedi' ); ?></a>
171
  <?php
172
  else :
173
  ?>
174
+ <a id="start_scan" href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=' . $admin_page . '&amp;action=start-scan' ); ?>" class="button-gpi run"><?php esc_html_e( 'Start Reporting', 'gpagespeedi' ); ?></a>
175
  <?php
176
  endif;
 
177
  ?>
178
+ <input type="checkbox" name="recheck_all_pages" id="recheck_all_pages" />
179
+ <label for="recheck_all_pages"><?php esc_html_e( 'Recheck All', 'gpagespeedi' ); ?> <span class="tooltip" title="<?php esc_html_e( 'Ignore last checked date to generate new reports for all pages', 'gpagespeedi' ); ?>">(?)</span></label>
 
180
  <?php
181
  endif;
182
  ?>
199
 
200
  public function admin_notice()
201
  {
202
+ if ( ! (bool) $this->gpi_options['new_activation_message'] ) {
203
  return;
204
  }
205
  ?>
206
  <div id="message" class="updated">
207
  <p>
208
+ <?php esc_html_e( 'Insights from Google PageSpeed has been activated. It can be accessed via Tools', 'gpagespeedi' ); ?> -> <a href="<?php echo esc_url( admin_url('/tools.php?page=google-pagespeed-insights&render=options') ); ?>">Pagespeed Insights</a>
209
  </p>
210
  </div>
211
  <?php
225
  return;
226
  }
227
 
228
+ wp_enqueue_style( 'gpagespeedi_css', plugins_url( '/assets/css/gpagespeedi_styles.css', GPI_PLUGIN_FILE ), false, esc_attr( GPI_VERSION ) );
229
 
230
  wp_register_script( 'gpagespeedi_google_charts', 'https://www.gstatic.com/charts/loader.js' );
231
  }
242
 
243
  $recheck_url = admin_url( '/tools.php?page=google-pagespeed-insights&render=details&page_id=' . intval( $_GET['page_id'] ) . '&action=single-recheck' );
244
 
245
+ wp_enqueue_script( 'gpagespeedi_details_js', plugins_url( '/assets/js/details.js', GPI_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-accordion', 'gpagespeedi_google_charts', 'wp-util' ), esc_attr( GPI_VERSION ), true );
246
  wp_localize_script( 'gpagespeedi_details_js', 'GPI_Details', array(
247
  'page_stats' => $this->get_page_stats( intval( $_GET['page_id'] ) ),
248
  'page_reports' => $this->get_page_reports( intval( $_GET['page_id'] ) ),
249
  'recheck_url' => wp_nonce_url( $recheck_url, 'gpi-single-recheck' ),
250
+ 'public_path' => esc_url( GPI_PUBLIC_PATH ),
251
  'strings' => array(
252
+ 'old_format_notice' => sprintf( esc_html__( 'Insights from Google PageSpeed has detected an outdated format in this report due to an update in version %s of this plugin. Some report features are unavailable. Please recheck results to resolve this problem.', 'gpagespeedi' ), '4.0' ),
253
+ 'insufficient_field_data' => wp_kses_post( 'The Chrome User Experience Report <a href="https://developers.google.com/speed/docs/insights/about#faq" target="_blank">does not have sufficient real-world speed data</a> for this page.', 'gpagespeedi' ),
254
+ 'FCP' => esc_html__( 'First Contentful Paint', 'gpagespeedi' ),
255
+ 'FID' => esc_html__( 'First Input Delay', 'gpagespeedi' ),
256
  'field_data_labels' => array(
257
+ esc_html__( 'of loads for this page have a fast', 'gpagespeedi' ),
258
+ esc_html__( 'of loads for this page have an average', 'gpagespeedi' ),
259
+ esc_html__( 'of loads for this page have a slow', 'gpagespeedi' )
260
  ),
261
  'shortpixel' => array(
262
+ 'title' => esc_html__( 'Auto-Optimize Images', 'gpagespeedi' ),
263
+ 'description' => wp_kses_data( 'Unoptimized images are often one of the <strong>biggest</strong> negative factors in pagespeed scores. Insights from Google PageSpeed has partnered with ShortPixel to provide an easy and affordable solution to <em>automatically</em> optimize all images.', 'gpagespeedi' ),
264
+ 'signup_desc' => wp_kses_data( 'Sign up using the button below and receive <strong>150 free image optimization credits</strong>.', 'gpagespeedi' ),
265
+ 'signup_btn' => esc_html__( 'Free Sign Up', 'gpagespeedi' )
266
  )
267
  )
268
  )
279
  return;
280
  }
281
 
282
+ wp_enqueue_script( 'gpagespeedi_summary_js', plugins_url( '/assets/js/summary.js', GPI_PLUGIN_FILE ), array( 'jquery', 'gpagespeedi_google_charts', 'wp-util' ), esc_attr( GPI_VERSION ) );
283
  wp_localize_script( 'gpagespeedi_summary_js', 'GPI_Summary', array(
284
  'summary_stats' => $this->get_summary_stats(),
285
  'summary_reports' => $this->get_summary_reports(),
286
  'strings' => array(
287
+ 'average_score' => esc_html__( 'Average Score', 'gpagespeedi' ),
288
+ 'best_performing' => esc_html__( 'View Best Performing', 'gpagespeedi' ),
289
+ 'worst_performing' => esc_html__( 'View Worst Performing', 'gpagespeedi' ),
290
+ 'old_format_notice' => esc_html__( 'Insights from Google PageSpeed has detected an outdated format in one or more reports due to an update in version 2.0 of this plugin. Some report features are unavailable. Please force recheck all reports from the options page to resolve this problem.', 'gpagespeedi' )
291
  )
292
  )
293
  );
306
  $snapshot_data = $this->get_snapshot_data();
307
  $strings = array(
308
  'strings' => array(
309
+ 'comment' => esc_html__( 'Comment', 'gpagespeedi' ),
310
+ 'average_score' => esc_html__( 'Average Score', 'gpagespeedi' ),
311
+ 'best_performing' => esc_html__( 'View Best Performing', 'gpagespeedi' ),
312
+ 'worst_performing' => esc_html__( 'View Worst Performing', 'gpagespeedi' )
313
  ),
314
  'comments' => array(
315
+ 'snapshot' => isset( $snapshot_data['snapshot']['comment'] ) ? esc_html( $snapshot_data['snapshot']['comment'] ) : false,
316
+ 'compare' => isset( $snapshot_data['compare']['comment'] ) ? esc_html( $snapshot_data['compare']['comment'] ) : false
317
  )
318
  );
319
 
320
  $localize_data = array_merge( $snapshot_data, $strings );
321
 
322
+ wp_enqueue_script( 'gpagespeedi_view_snapshot_js', plugins_url( '/assets/js/view-snapshot.js', GPI_PLUGIN_FILE ), array( 'jquery', 'gpagespeedi_google_charts', 'wp-util' ), esc_attr( GPI_VERSION ) );
323
  wp_localize_script( 'gpagespeedi_view_snapshot_js', 'GPI_View_Snapshot', $localize_data );
324
  }
325
 
329
  return;
330
  }
331
 
332
+ wp_enqueue_script( 'gpagespeedi_global_js', plugins_url( '/assets/js/global.js', GPI_PLUGIN_FILE ), array( 'jquery', 'heartbeat', 'jquery-ui-tooltip' ), esc_attr( GPI_VERSION ) );
333
  wp_localize_script( 'gpagespeedi_global_js', 'GPI_Global', array(
334
+ 'heartbeat' => esc_attr( $this->gpi_options['heartbeat'] ),
335
+ 'progress' => esc_html( get_option( 'gpi_progress' ) )
336
  )
337
  );
338
  }
428
  public function get_filter_options( $options, $flatlist = false )
429
  {
430
  if ( ! $flatlist ) {
431
+ $options['all'] = esc_html__( 'All Reports', 'gpagespeedi' );
432
  }
433
 
434
+ if ( (bool) $this->gpi_options['check_pages'] ) {
435
+ $options['page'] = esc_html__( 'Pages', 'gpagespeedi' );
436
  }
437
 
438
+ if ( (bool) $this->gpi_options['check_posts'] ) {
439
+ $options['post'] = esc_html__( 'Posts', 'gpagespeedi' );
440
  }
441
 
442
+ if ( (bool) $this->gpi_options['check_categories'] ) {
443
+ $options['category'] = esc_html__( 'Categories', 'gpagespeedi' );
444
  }
445
 
446
  if ( ! empty( $this->gpi_options['cpt_whitelist'] ) ) {
447
  if ( ! $flatlist ) {
448
+ $cpt_options = array( 'gpi_custom_posts' => esc_html__( 'All Custom Post Types', 'gpagespeedi' ) );
449
  }
450
 
451
  $cpt_whitelist = maybe_unserialize( $this->gpi_options['cpt_whitelist'] );
455
 
456
  if ( ! $flatlist ) {
457
  $options['custom_post_types'] = array(
458
+ 'optgroup_label' => esc_html__( 'Custom Post Types', 'gpagespeedi' ),
459
  'options' => $cpt_options
460
  );
461
  } else {
463
  }
464
  }
465
 
466
+ if ( (bool) $this->gpi_options['check_custom_urls'] ) {
467
  global $wpdb;
468
 
469
  $gpi_custom_urls = $wpdb->prefix . 'gpi_custom_urls';
470
  $custom_url_types = $wpdb->get_col(
471
  "
472
+ SELECT DISTINCT type
473
+ FROM $gpi_custom_urls
474
  "
475
  );
476
 
477
  if ( ! empty( $custom_url_types ) ) {
478
  if ( ! $flatlist ) {
479
+ $custom_url_options = array( 'gpi_custom_urls' => esc_html__( 'All Custom URLs', 'gpagespeedi' ) );
480
  }
481
 
482
  foreach ( $custom_url_types as $custom_url_type ) {
485
 
486
  if ( ! $flatlist ) {
487
  $options['custom_urls'] = array(
488
+ 'optgroup_label' => esc_html__( 'Custom URLs', 'gpagespeedi' ),
489
  'options' => $custom_url_options
490
  );
491
  } else {
536
 
537
  return $wpdb->get_var(
538
  "
539
+ SELECT COUNT( ID )
540
+ FROM $gpi_custom_urls
541
  "
542
  );
543
  }
579
  $all_page_stats = array();
580
 
581
  if ( $filter ) {
582
+ $all_page_stats = $wpdb->get_results(
583
+ $wpdb->prepare(
584
+ "
585
+ SELECT ID, URL, {$this->strategy}_score as score, {$this->strategy}_lab_data as labData
586
+ FROM $gpi_page_stats
587
+ WHERE type REGEXP %s
588
+ AND {$this->strategy}_score IS NOT NULL
589
+ ORDER BY score DESC
590
+ ",
591
+ $filter
592
+ ), ARRAY_A
593
+ );
594
  }
595
 
596
  if ( ! $all_page_stats ) {
611
  $report_url = admin_url( '/tools.php?page=google-pagespeed-insights&render=details&page_id=' . $page_stats['ID'] );
612
 
613
  $page_scores[] = array(
614
+ 'score' => intval( $page_stats['score'] ),
615
+ 'report_url' => esc_url_raw( $report_url ),
616
+ 'page_url' => esc_url( $page_stats['URL'] )
617
  );
618
 
619
  // flag if pre 2.0 data structure is detected
627
  $avg_lab_data[ $data['title'] ] = array( 'lowest' => array( 'value' => false, 'url' => false ), 'average' => false, 'highest' => array( 'value' => false, 'url' => false ) );
628
  }
629
 
630
+ $avg_lab_data[ $data['title'] ]['average'] += floatval( $data['score'] );
631
 
632
  if ( false === $avg_lab_data[ $data['title'] ]['highest']['value'] || $data['score'] > $avg_lab_data[ $data['title'] ]['highest']['value'] ) {
633
  $avg_lab_data[ $data['title'] ]['highest'] = array(
634
+ 'value' => esc_html( $data['displayValue'] ),
635
+ 'url' => esc_url_raw( $report_url )
636
  );
637
  }
638
 
639
  if ( false === $avg_lab_data[ $data['title'] ]['lowest']['value'] || $data['score'] < $avg_lab_data[ $data['title'] ]['lowest']['value'] ) {
640
  $avg_lab_data[ $data['title'] ]['lowest'] = array(
641
+ 'value' => esc_html( $data['displayValue'] ),
642
+ 'url' => esc_url_raw( $report_url )
643
  );
644
  }
645
  }
647
  }
648
 
649
  foreach ( $avg_lab_data as &$data ) {
650
+ $data['average'] = floatval( $data['average'] / $pages );
651
  }
652
 
653
  $score = round( $score / $pages );
661
  'lowest' => array_slice( $low_scores, 0, 5 )
662
  ),
663
  'labData' => $avg_lab_data,
664
+ 'score' => intval( $score ),
665
+ 'odometer_rotation' => esc_html( ( ( 3.38 * $score ) + 11 ) . 'deg' ),
666
+ 'data_format' => ( $old_format_detected ) ? '1.0' : esc_html( GPI_VERSION )
667
  );
668
  }
669
 
685
  $all_page_reports = array();
686
 
687
  if ( $filter ) {
688
+ $all_page_reports = $wpdb->get_results(
689
+ $wpdb->prepare(
690
+ "
691
+ SELECT r.rule_key, r.rule_name, r.rule_score
692
+ FROM $gpi_page_stats as s
693
+ INNER JOIN $gpi_page_reports as r
694
+ ON r.page_id = s.ID
695
+ AND r.strategy = %s
696
+ AND r.rule_type = %s
697
+ AND r.rule_score < .9
698
+ WHERE type REGEXP %s
699
+ AND s.{$this->strategy}_score IS NOT NULL
700
+ ORDER BY r.rule_score DESC
701
+ ",
702
+ $this->strategy,
703
+ 'opportunity',
704
+ $filter
705
+ ), ARRAY_A
706
+ );
707
  }
708
 
709
  if ( ! $all_page_reports ) {
716
  $summary_reports[ $page_report['rule_key'] ]['occurances']++;
717
  } else {
718
  $summary_reports[ $page_report['rule_key'] ] = array(
719
+ 'rule_name' => ( 'uses-optimized-images' != $page_report['rule_key'] ) ? wp_kses_post( $page_report['rule_name'] ) : wp_kses_post( $page_report['rule_name'] . '<span class="shortpixel_blurb"> &ndash; <a href="https://shortpixel.com/h/af/PCFTWNN142247" target="_blank">' . __( 'Auto-Optimize images with ShortPixel. Sign up for 150 free credits!', 'gpagespeedi') . '</a></span>' ),
720
  'avg_score' => $page_report['rule_score'],
721
  'occurances' => 1
722
  );
725
 
726
  foreach ( $summary_reports as &$summary_report ) {
727
  $summary_report['avg_score'] = round( $summary_report['avg_score'] / $summary_report['occurances'], 2 );
728
+ $summary_report['avg_score'] = intval( $summary_report['avg_score'] * 100 );
729
  }
730
 
731
  $summary_reports = $this->sort_array( $summary_reports, 'avg_score' );
775
 
776
  $error_logs = $wpdb->get_results(
777
  "
778
+ SELECT URL, strategy, is_update, type, timestamp, error
779
+ FROM $gpi_api_error_logs
780
+ ORDER BY timestamp DESC
781
  ", ARRAY_A
782
  );
783
 
790
 
791
  $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
792
 
793
+ $page_stats = $wpdb->get_row(
794
+ $wpdb->prepare(
795
+ "
796
+ SELECT URL, {$this->strategy}_lab_data as labData, {$this->strategy}_field_data as fieldData, {$this->strategy}_score as score, {$this->strategy}_last_modified as last_modified
797
+ FROM $gpi_page_stats
798
+ WHERE ID = %d
799
+ ",
800
+ $page_id
801
+ ), ARRAY_A
802
+ );
803
 
804
  if ( empty( $page_stats ) ) {
805
  return false;
809
  if ( strpos( $page_stats['labData'], 'numberHosts' ) !== false ) {
810
  $page_stats['data_format'] = '1.0';
811
  } else {
812
+ $page_stats['data_format'] = esc_html( GPI_VERSION );
813
  }
814
 
815
  if ( ! empty( $page_stats['score'] ) ) {
823
  if ( ! empty( $page_stats['last_modified'] ) ) {
824
  $page_stats['last_modified'] = date_i18n( 'M d g:ia', $page_stats['last_modified'] );
825
  } else {
826
+ $page_stats['last_modified'] = esc_html__( 'N/A', 'gpagespeedi' );
827
+ }
828
+
829
+ $page_stats = array_map( 'maybe_unserialize', $page_stats );
830
+
831
+ if ( isset( $page_stats['fieldData'] ) && ! empty( $page_stats['fieldData'] ) ) {
832
+ $page_stats['fieldData'] = $this->object_to_array( $page_stats['fieldData'] );
833
  }
834
 
835
+ array_walk_recursive( $page_stats, [ $this, 'escape_and_format_recursive' ], 'page_stats' );
836
+
837
+ return $page_stats;
838
  }
839
 
840
  private function get_page_reports( $page_id )
843
 
844
  $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
845
 
846
+ $page_reports = $wpdb->get_results(
847
+ $wpdb->prepare(
848
+ "
849
+ SELECT rule_key, rule_name, rule_score, rule_blocks
850
+ FROM $gpi_page_reports
851
+ WHERE page_id = %d
852
+ AND strategy = %s
853
+ ORDER BY rule_score ASC
854
+ ",
855
+ $page_id,
856
+ $this->strategy
857
+ ), ARRAY_A
858
+ );
859
 
860
  if ( $page_reports ) {
861
+ foreach ( $page_reports as $index => &$page_report ) {
862
  $page_report['rule_blocks'] = unserialize( $page_report['rule_blocks'] );
863
 
864
+ if ( isset( $page_report['rule_blocks'] ) && ! empty( $page_report['rule_blocks'] ) ) {
865
+ $page_report['rule_blocks'] = $this->object_to_array( $page_report['rule_blocks'] );
866
+ }
867
+
868
+ array_walk_recursive( $page_report, [ $this, 'escape_and_format_recursive' ], 'page_reports' );
869
+
870
  if ( 'uses-optimized-images' == $page_report['rule_key'] ) {
871
  $page_report['rule_blocks'] = $this->shortpixel_image_rule_blocks( $page_report['rule_blocks'] );
872
  }
883
  $gpi_summary_snapshots = $wpdb->prefix . 'gpi_summary_snapshots';
884
 
885
  if ( isset( $_GET['snapshot_id'] ) ) {
886
+ $snapshot = $wpdb->get_row(
887
+ $wpdb->prepare(
888
+ "
889
+ SELECT strategy, type, snaptime, comment, summary_stats, summary_reports
890
+ FROM $gpi_summary_snapshots
891
+ WHERE ID = %d
892
+ ",
893
+ $_GET['snapshot_id']
894
+ ), ARRAY_A
895
+ );
896
  } else {
897
  $snapshot = false;
898
  }
899
 
900
  if ( isset( $_GET['compare_id'] ) ) {
901
+ $compare_snapshot = $wpdb->get_row(
902
+ $wpdb->prepare(
903
+ "
904
+ SELECT strategy, type, snaptime, comment, summary_stats, summary_reports
905
+ FROM $gpi_summary_snapshots
906
+ WHERE ID = %d
907
+ ",
908
+ $_GET['compare_id']
909
+ ), ARRAY_A
910
+ );
911
  } else {
912
  $compare_snapshot = false;
913
  }
914
 
915
+ if ( isset( $snapshot['summary_stats'] ) ) {
916
+ $snapshot['summary_stats'] = json_decode( $snapshot['summary_stats'] );
917
+ }
918
+ if ( isset( $snapshot['summary_reports'] ) ) {
919
+ $snapshot['summary_reports'] = json_decode( $snapshot['summary_reports'] );
920
+ }
921
+
922
+ $snapshot = $this->object_to_array( $snapshot );
923
+
924
+ if ( ! $snapshot ) {
925
+ wp_redirect( admin_url( 'tools.php?page=google-pagespeed-insights&render=snapshots' ) );
926
+ exit;
927
+ }
928
+
929
+ array_walk_recursive( $snapshot, [ $this, 'escape_and_format_recursive' ], 'snapshot' );
930
+
931
+ if ( $compare_snapshot ) {
932
+ if ( isset( $compare_snapshot['summary_stats'] ) ) {
933
+ $compare_snapshot['summary_stats'] = json_decode( $compare_snapshot['summary_stats'] );
934
+ }
935
+ if ( isset( $compare_snapshot['summary_reports'] ) ) {
936
+ $compare_snapshot['summary_reports'] = json_decode( $compare_snapshot['summary_reports'] );
937
+ }
938
+
939
+ $compare_snapshot = $this->object_to_array( $compare_snapshot );
940
+
941
+ array_walk_recursive( $compare_snapshot, [ $this, 'escape_and_format_recursive' ], 'snapshot' );
942
+ } else if ( isset( $_GET['compare_id'] ) ) {
943
+ if ( ! $compare_snapshot ) {
944
+ wp_redirect( admin_url( 'tools.php?page=google-pagespeed-insights&render=snapshots' ) );
945
+ exit;
946
+ }
947
+ }
948
+
949
  return array(
950
  'snapshot' => $snapshot,
951
  'compare' => $compare_snapshot
959
 
960
  $gpi_summary_snapshots = $wpdb->prefix . 'gpi_summary_snapshots';
961
 
962
+ $current_snapshot = $wpdb->get_row(
963
+ $wpdb->prepare(
964
+ "
965
+ SELECT strategy, type
966
+ FROM $gpi_summary_snapshots
967
+ WHERE ID = %d
968
+ ",
969
+ $current_snapshot_id
970
+ ), ARRAY_A
971
+ );
972
 
973
+ $similar_snapshots = $wpdb->get_results(
974
+ $wpdb->prepare(
975
+ "
976
+ SELECT ID, snaptime
977
+ FROM $gpi_summary_snapshots
978
+ WHERE strategy = %s
979
+ AND type = %s
980
+ ",
981
+ $current_snapshot['strategy'],
982
+ $current_snapshot['type']
983
+ ), ARRAY_A
984
+ );
985
  }
986
 
987
  return $similar_snapshots;
1021
  return $array;
1022
  }
1023
 
1024
+ private function object_to_array( $obj )
1025
+ {
1026
+ if ( is_object( $obj ) || is_array( $obj ) ) {
1027
+ $ret = (array) $obj;
1028
+ foreach ( $ret as &$item ) {
1029
+ $item = $this->object_to_array( $item );
1030
+ }
1031
+ return $ret;
1032
+ } else {
1033
+ return $obj;
1034
+ }
1035
+ }
1036
+
1037
+ private function escape_and_format_recursive( &$value, $key, $type )
1038
+ {
1039
+ switch ( $key ) {
1040
+ case 'URL':
1041
+ $value = esc_url( $value );
1042
+ break;
1043
+
1044
+ case 'url':
1045
+ if ( 'snapshot' == $type ) {
1046
+ $value = esc_url_raw( $value );
1047
+ } else {
1048
+ $value = wp_kses_post( $value );
1049
+ }
1050
+ break;
1051
+
1052
+ case 'report_url':
1053
+ $value = esc_url_raw( $value );
1054
+ break;
1055
+
1056
+ case 'groupLabel':
1057
+ $value = esc_html( $value );
1058
+ $value = str_replace( ' &amp; ', ' & ', $value );
1059
+ break;
1060
+
1061
+ case 'rule_name':
1062
+ case 'description':
1063
+ $value = wp_kses_post( $value );
1064
+ break;
1065
+
1066
+ case 'min':
1067
+ case 'max':
1068
+ case 'percentile':
1069
+ $value = intval( $value );
1070
+ break;
1071
+
1072
+ case 'proportion':
1073
+ case 'average':
1074
+ $value = floatval( $value );
1075
+ break;
1076
+
1077
+ case 'score':
1078
+ $value = floatval( $value );
1079
+ $value = (float) number_format( $value, 3 );
1080
+ break;
1081
+
1082
+ case 'blockingTime':
1083
+ case 'wastedMs':
1084
+ case 'startTime':
1085
+ case 'duration':
1086
+ case 'total':
1087
+ case 'scripting':
1088
+ case 'scriptParseCompile':
1089
+ $value = floatval( $value );
1090
+ $value = (float) number_format( $value, 3 );
1091
+ $value = $value . ' ' . 'ms';
1092
+ break;
1093
+
1094
+ case 'wastedBytes':
1095
+ case 'totalBytes':
1096
+ $value = intval( $value );
1097
+ $value = number_format( $value / 1024, 2 );
1098
+ $value = $value . ' ' . 'KiB';
1099
+ break;
1100
+
1101
+ case 'transferSize':
1102
+ $value = intval( $value );
1103
+ $value = number_format( $value / 1024, 2 );
1104
+ $value = $value . ' ' . 'KiB';
1105
+ break;
1106
+
1107
+ default:
1108
+ $value = esc_html( $value );
1109
+ break;
1110
+ }
1111
+ }
1112
+
1113
  }
1114
 
1115
  add_action( 'plugins_loaded', array( new GPI_Admin, 'init' ) );
classes/class-GPI-Core.php CHANGED
@@ -71,8 +71,8 @@ class GPI_Core
71
  {
72
  if ( ! isset( $schedules['gpi_scheduled_interval'] ) ) {
73
  $schedules['gpi_scheduled_interval'] = array(
74
- 'interval' => $this->gpi_options['recheck_interval'],
75
- 'display' => __( 'Interval set in GPI options', 'gpagespeedi' )
76
  );
77
  }
78
 
@@ -99,7 +99,12 @@ class GPI_Core
99
  {
100
  global $wpdb;
101
 
102
- $lock = $wpdb->get_var( $wpdb->prepare( 'SELECT GET_LOCK(%s, %d)', 'gpi_lock_' . $this->gpi_options['mutex_id'], 0 ) );
 
 
 
 
 
103
 
104
  return $lock == 1;
105
  }
@@ -108,7 +113,12 @@ class GPI_Core
108
  {
109
  global $wpdb;
110
 
111
- $wpdb->get_var( $wpdb->prepare( 'SELECT RELEASE_LOCK(%s)', 'gpi_lock_' . $this->gpi_options['mutex_id'] ) );
 
 
 
 
 
112
  }
113
 
114
  public function check_status( $busy )
@@ -152,7 +162,7 @@ class GPI_Core
152
  $busy = true;
153
  } else {
154
  self::$force_recheck_urls = $force_recheck_all_urls;
155
- $this->worker( $urls_to_check, $this->gpi_options['strategy'], $force_recheck_all_urls, $timeout_respawn );
156
  }
157
 
158
  return $busy;
@@ -167,7 +177,7 @@ class GPI_Core
167
  // Add a shutdown function to check if the last scan finished successfully, and relaunch the scan if it did not.
168
  register_shutdown_function( array( 'GPI_Core', 'shutdown_checker' ) );
169
 
170
- if ( $max_runtime = $this->gpi_options['max_run_time'] ) {
171
  $start_runtime = time();
172
  }
173
 
@@ -176,10 +186,10 @@ class GPI_Core
176
  require_once GPI_DIRECTORY . '/classes/class-GPI-Pagespeed-API.php';
177
  }
178
 
179
- $developer_key = $this->gpi_options['google_developer_key'];
180
  $Pagespeed_API = new GPI_Pagespeed_API( $developer_key );
181
 
182
- $recheck_interval = $this->gpi_options['recheck_interval'];
183
 
184
  // Don't stop the script when the connection is closed
185
  ignore_user_abort( true );
@@ -281,7 +291,7 @@ class GPI_Core
281
 
282
  // If we skipped all URLs because there are no expired reports, alert the user
283
  if ( self::$skipped_all ) {
284
- update_option( 'gpi_error_message', __( 'There are no new pages, or pages with expired pagespeed reports to recheck. To force a recheck of all pages, check the "Recheck All" box before starting reporting.', 'gpagespeedi' ) );
285
  }
286
 
287
  // Release our lock on the DB
@@ -306,7 +316,7 @@ class GPI_Core
306
  global $wpdb;
307
 
308
  // Use max_execution_time set in settings.
309
- @set_time_limit( $this->gpi_options['max_execution_time'] );
310
 
311
  $object_url = $item['url'];
312
 
@@ -317,9 +327,14 @@ class GPI_Core
317
  $where_column = $this->get_where_column( $custom_url, $group_type );
318
 
319
  $existing_url_info = $wpdb->get_row(
320
- "SELECT {$strategy}_last_modified, force_recheck
321
- FROM $gpi_page_stats
322
- WHERE $where_column = $object_id"
 
 
 
 
 
323
  );
324
 
325
  $property = $strategy . '_last_modified';
@@ -336,7 +351,7 @@ class GPI_Core
336
 
337
  self::$skipped_all = false;
338
 
339
- $result = $Pagespeed_API->run_pagespeed( $object_url, array( 'locale' => $this->gpi_options['response_language'], 'strategy' => $strategy ) );
340
  if ( ! empty( $result ) ) {
341
  if ( isset( $result['responseCode'] ) && $result['responseCode'] >= 200 && $result['responseCode'] < 300 ) {
342
  $result['type'] = $group_type;
@@ -352,7 +367,7 @@ class GPI_Core
352
  }
353
 
354
  // Some web servers seem to have a difficult time responding to the constant requests from the Google API, sleeping inbetween each URL helps
355
- sleep( $this->gpi_options['sleep_time'] );
356
 
357
  return $continue;
358
  }
@@ -361,7 +376,13 @@ class GPI_Core
361
  {
362
  global $wpdb;
363
 
364
- $abort_scan = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->options WHERE option_name = 'gpi_abort_scan'" );
 
 
 
 
 
 
365
 
366
  if ( $abort_scan ) {
367
  delete_option( 'gpi_abort_scan' );
@@ -398,14 +419,16 @@ class GPI_Core
398
  $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
399
  $types = implode( '|', $types );
400
 
401
- $reports = $wpdb->get_results( $wpdb->prepare(
402
- "
403
- SELECT URL as url, type, object_id as objectid, term_id, custom_id
404
- FROM $gpi_page_stats
405
- WHERE type REGEXP %s
406
- ",
407
- $types
408
- ), ARRAY_A );
 
 
409
 
410
  return $reports;
411
  }
@@ -447,7 +470,7 @@ class GPI_Core
447
  }
448
 
449
  // Get Posts URLs from built in 'post' type
450
- if ( $this->gpi_options['check_posts'] ) {
451
  $types['post'] = 'post';
452
  $x = 0;
453
  $builtin_posts_array = get_posts( array('post_status' => 'publish', 'post_type' => 'post', 'posts_per_page' => -1, 'fields' => 'ids') );
@@ -464,7 +487,7 @@ class GPI_Core
464
  }
465
 
466
  // Get Page URLs
467
- if ( $this->gpi_options['check_pages'] ) {
468
  $types['page'] = 'page';
469
  $x = 0;
470
  $pages_array = get_pages();
@@ -482,7 +505,7 @@ class GPI_Core
482
  }
483
 
484
  // Get Category URLs
485
- if ( $this->gpi_options['check_categories'] ) {
486
  $types['category'] = 'category';
487
  $x = 0;
488
  $categories_array = get_categories();
@@ -499,16 +522,18 @@ class GPI_Core
499
  }
500
 
501
  // Get Custom URLs
502
- if ( $this->gpi_options['check_custom_urls'] ) {
503
 
504
  global $wpdb;
505
 
506
  $gpi_custom_urls = $wpdb->prefix . 'gpi_custom_urls';
507
- $query = "
508
- SELECT ID, URL, type
509
- FROM $gpi_custom_urls
510
- ";
511
- $custom_urls_array = $wpdb->get_results( $query, ARRAY_A );
 
 
512
  $x = 0;
513
  foreach ( $custom_urls_array as $custom_url ) {
514
  if ( ! isset( $types[ $custom_url['type'] ] ) ) {
@@ -516,9 +541,9 @@ class GPI_Core
516
  }
517
  $url = $custom_url['URL'];
518
  if ( ! in_array( $url, $blacklist_urls ) ) {
519
- $flat_urls[] = $url;
520
- $urls_to_check[ $custom_url['type'] ][ $x ]['url'] = $url;
521
- $urls_to_check[ $custom_url['type'] ][ $x ]['objectid'] = $custom_url['ID'];
522
  $urls_to_check[ $custom_url['type'] ][ $x ]['custom'] = 1;
523
  $total_count++;
524
  $x++;
@@ -537,12 +562,12 @@ class GPI_Core
537
  }
538
 
539
  if ( ! empty( $report_info['term_id'] ) ) {
540
- $existing_reports[ $key ]['objectid'] = $report_info['term_id'];
541
  }
542
 
543
  if ( ! empty( $report_info['custom_id'] ) ) {
544
  $existing_reports[ $key ]['custom'] = true;
545
- $existing_reports[ $key ]['objectid'] = $report_info['custom_id'];
546
  }
547
 
548
  unset( $existing_reports[ $key ]['term_id'] );
@@ -571,19 +596,28 @@ class GPI_Core
571
  $score = $result['data']->lighthouseResult->categories->performance->score;
572
 
573
  // Store identifying information
574
- $gpi_page_stats_values['URL'] = $object_url;
575
- $gpi_page_stats_values['type'] = $result['type'];
576
- $gpi_page_stats_values[ $where_column ] = $result[ $where_column ];
577
- $gpi_page_stats_values[ $strategy . '_last_modified' ] = $result['last_modified'];
578
  $gpi_page_stats_values['force_recheck'] = 0;
579
- $gpi_page_stats_values['response_code'] = $result['responseCode'];
580
- $gpi_page_stats_values[ $strategy . '_lab_data' ] = $Pagespeed_API->get_lab_data( $result['data'] );
581
- $gpi_page_stats_values[ $strategy . '_field_data' ] = $Pagespeed_API->get_field_data( $result['data'] );
582
- $gpi_page_stats_values[ $strategy . '_score' ] = $score * 100;
583
 
584
  if ( $update ) {
585
- $wpdb->update( $gpi_page_stats, $gpi_page_stats_values, array( $where_column => $object_id ) );
586
- $last_updated_id = $wpdb->get_var( "SELECT ID FROM $gpi_page_stats WHERE $where_column = $object_id" );
 
 
 
 
 
 
 
 
 
587
  } else {
588
  $wpdb->insert( $gpi_page_stats, $gpi_page_stats_values );
589
  $last_updated_id = $wpdb->insert_id;
@@ -591,8 +625,17 @@ class GPI_Core
591
 
592
  $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
593
  if ( $update ) {
594
- $sql = "DELETE FROM $gpi_page_reports WHERE page_id = '$last_updated_id' AND strategy = '$strategy'";
595
- $wpdb->query( $sql );
 
 
 
 
 
 
 
 
 
596
  }
597
 
598
  $page_reports = $Pagespeed_API->get_page_reports( $result['data'], $last_updated_id, $strategy, $this->gpi_options );
@@ -611,9 +654,11 @@ class GPI_Core
611
 
612
  $row_exist = $wpdb->get_row(
613
  $wpdb->prepare(
614
- "SELECT ID
615
- FROM $gpi_page_blacklist
616
- WHERE URL = %s",
 
 
617
  $object_url
618
  ),
619
  ARRAY_A
@@ -655,6 +700,11 @@ class GPI_Core
655
  $this->update_option( 'api_restriction', true, 'gpagespeedi_options' );
656
  $error_type = 'fatal';
657
 
 
 
 
 
 
658
  } else if ( isset( $errors[0]->reason ) && $errors[0]->reason == 'backendError' ) {
659
 
660
  $this->save_bad_request( $url_group_type, $where_column, $object_id, $object_url, false );
@@ -670,7 +720,7 @@ class GPI_Core
670
 
671
  }
672
 
673
- if ( $this->gpi_options['log_api_errors'] ) {
674
  global $wpdb;
675
 
676
  $gpi_api_error_logs = $wpdb->prefix . 'gpi_api_error_logs';
@@ -695,11 +745,12 @@ class GPI_Core
695
  global $wpdb;
696
 
697
  $gpi_page_blacklist = $wpdb->prefix . 'gpi_page_blacklist';
698
- $query = "
699
- SELECT URL
700
- FROM $gpi_page_blacklist
701
- ";
702
- $blacklist_urls = $wpdb->get_col( $query );
 
703
 
704
  return $blacklist_urls;
705
  }
71
  {
72
  if ( ! isset( $schedules['gpi_scheduled_interval'] ) ) {
73
  $schedules['gpi_scheduled_interval'] = array(
74
+ 'interval' => intval( $this->gpi_options['recheck_interval'] ),
75
+ 'display' => esc_html__( 'Interval set in GPI options', 'gpagespeedi' )
76
  );
77
  }
78
 
99
  {
100
  global $wpdb;
101
 
102
+ $lock = $wpdb->get_var(
103
+ $wpdb->prepare(
104
+ 'SELECT GET_LOCK(%s, %d)',
105
+ 'gpi_lock_' . intval( $this->gpi_options['mutex_id'] ), 0
106
+ )
107
+ );
108
 
109
  return $lock == 1;
110
  }
113
  {
114
  global $wpdb;
115
 
116
+ $wpdb->get_var(
117
+ $wpdb->prepare(
118
+ 'SELECT RELEASE_LOCK(%s)',
119
+ 'gpi_lock_' . intval( $this->gpi_options['mutex_id'] )
120
+ )
121
+ );
122
  }
123
 
124
  public function check_status( $busy )
162
  $busy = true;
163
  } else {
164
  self::$force_recheck_urls = $force_recheck_all_urls;
165
+ $this->worker( $urls_to_check, sanitize_text_field( $this->gpi_options['strategy'] ), $force_recheck_all_urls, $timeout_respawn );
166
  }
167
 
168
  return $busy;
177
  // Add a shutdown function to check if the last scan finished successfully, and relaunch the scan if it did not.
178
  register_shutdown_function( array( 'GPI_Core', 'shutdown_checker' ) );
179
 
180
+ if ( $max_runtime = intval( $this->gpi_options['max_run_time'] ) ) {
181
  $start_runtime = time();
182
  }
183
 
186
  require_once GPI_DIRECTORY . '/classes/class-GPI-Pagespeed-API.php';
187
  }
188
 
189
+ $developer_key = sanitize_text_field( $this->gpi_options['google_developer_key'] );
190
  $Pagespeed_API = new GPI_Pagespeed_API( $developer_key );
191
 
192
+ $recheck_interval = intval( $this->gpi_options['recheck_interval'] );
193
 
194
  // Don't stop the script when the connection is closed
195
  ignore_user_abort( true );
291
 
292
  // If we skipped all URLs because there are no expired reports, alert the user
293
  if ( self::$skipped_all ) {
294
+ update_option( 'gpi_error_message', esc_html__( 'There are no new pages, or pages with expired pagespeed reports to recheck. To force a recheck of all pages, check the "Recheck All" box before starting reporting.', 'gpagespeedi' ) );
295
  }
296
 
297
  // Release our lock on the DB
316
  global $wpdb;
317
 
318
  // Use max_execution_time set in settings.
319
+ @set_time_limit( intval( $this->gpi_options['max_execution_time'] ) );
320
 
321
  $object_url = $item['url'];
322
 
327
  $where_column = $this->get_where_column( $custom_url, $group_type );
328
 
329
  $existing_url_info = $wpdb->get_row(
330
+ $wpdb->prepare(
331
+ "
332
+ SELECT {$strategy}_last_modified, force_recheck
333
+ FROM $gpi_page_stats
334
+ WHERE $where_column = %d
335
+ ",
336
+ $object_id
337
+ )
338
  );
339
 
340
  $property = $strategy . '_last_modified';
351
 
352
  self::$skipped_all = false;
353
 
354
+ $result = $Pagespeed_API->run_pagespeed( $object_url, array( 'locale' => sanitize_text_field( $this->gpi_options['response_language'] ), 'strategy' => $strategy ) );
355
  if ( ! empty( $result ) ) {
356
  if ( isset( $result['responseCode'] ) && $result['responseCode'] >= 200 && $result['responseCode'] < 300 ) {
357
  $result['type'] = $group_type;
367
  }
368
 
369
  // Some web servers seem to have a difficult time responding to the constant requests from the Google API, sleeping inbetween each URL helps
370
+ sleep( intval( $this->gpi_options['sleep_time'] ) );
371
 
372
  return $continue;
373
  }
376
  {
377
  global $wpdb;
378
 
379
+ $abort_scan = $wpdb->get_var(
380
+ "
381
+ SELECT COUNT(*)
382
+ FROM $wpdb->options
383
+ WHERE option_name = 'gpi_abort_scan'
384
+ "
385
+ );
386
 
387
  if ( $abort_scan ) {
388
  delete_option( 'gpi_abort_scan' );
419
  $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
420
  $types = implode( '|', $types );
421
 
422
+ $reports = $wpdb->get_results(
423
+ $wpdb->prepare(
424
+ "
425
+ SELECT URL as url, type, object_id as objectid, term_id, custom_id
426
+ FROM $gpi_page_stats
427
+ WHERE type REGEXP %s
428
+ ",
429
+ $types
430
+ ), ARRAY_A
431
+ );
432
 
433
  return $reports;
434
  }
470
  }
471
 
472
  // Get Posts URLs from built in 'post' type
473
+ if ( (bool) $this->gpi_options['check_posts'] ) {
474
  $types['post'] = 'post';
475
  $x = 0;
476
  $builtin_posts_array = get_posts( array('post_status' => 'publish', 'post_type' => 'post', 'posts_per_page' => -1, 'fields' => 'ids') );
487
  }
488
 
489
  // Get Page URLs
490
+ if ( (bool) $this->gpi_options['check_pages'] ) {
491
  $types['page'] = 'page';
492
  $x = 0;
493
  $pages_array = get_pages();
505
  }
506
 
507
  // Get Category URLs
508
+ if ( (bool) $this->gpi_options['check_categories'] ) {
509
  $types['category'] = 'category';
510
  $x = 0;
511
  $categories_array = get_categories();
522
  }
523
 
524
  // Get Custom URLs
525
+ if ( (bool) $this->gpi_options['check_custom_urls'] ) {
526
 
527
  global $wpdb;
528
 
529
  $gpi_custom_urls = $wpdb->prefix . 'gpi_custom_urls';
530
+ $custom_urls_array = $wpdb->get_results(
531
+ "
532
+ SELECT ID, URL, type
533
+ FROM $gpi_custom_urls
534
+ ",
535
+ ARRAY_A
536
+ );
537
  $x = 0;
538
  foreach ( $custom_urls_array as $custom_url ) {
539
  if ( ! isset( $types[ $custom_url['type'] ] ) ) {
541
  }
542
  $url = $custom_url['URL'];
543
  if ( ! in_array( $url, $blacklist_urls ) ) {
544
+ $flat_urls[] = esc_url_raw( $url );
545
+ $urls_to_check[ $custom_url['type'] ][ $x ]['url'] = esc_url_raw( $url );
546
+ $urls_to_check[ $custom_url['type'] ][ $x ]['objectid'] = intval( $custom_url['ID'] );
547
  $urls_to_check[ $custom_url['type'] ][ $x ]['custom'] = 1;
548
  $total_count++;
549
  $x++;
562
  }
563
 
564
  if ( ! empty( $report_info['term_id'] ) ) {
565
+ $existing_reports[ $key ]['objectid'] = intval( $report_info['term_id'] );
566
  }
567
 
568
  if ( ! empty( $report_info['custom_id'] ) ) {
569
  $existing_reports[ $key ]['custom'] = true;
570
+ $existing_reports[ $key ]['objectid'] = intval( $report_info['custom_id'] );
571
  }
572
 
573
  unset( $existing_reports[ $key ]['term_id'] );
596
  $score = $result['data']->lighthouseResult->categories->performance->score;
597
 
598
  // Store identifying information
599
+ $gpi_page_stats_values['URL'] = esc_url_raw( $object_url );
600
+ $gpi_page_stats_values['type'] = sanitize_title( $result['type'] );
601
+ $gpi_page_stats_values[ sanitize_key( $where_column ) ] = intval( $result[ $where_column ] );
602
+ $gpi_page_stats_values[ sanitize_key( $strategy . '_last_modified' ) ] = intval( $result['last_modified'] );
603
  $gpi_page_stats_values['force_recheck'] = 0;
604
+ $gpi_page_stats_values['response_code'] = intval( $result['responseCode'] );
605
+ $gpi_page_stats_values[ sanitize_key( $strategy . '_lab_data' ) ] = $Pagespeed_API->get_lab_data( $result['data'] );
606
+ $gpi_page_stats_values[ sanitize_key( $strategy . '_field_data' ) ] = $Pagespeed_API->get_field_data( $result['data'] );
607
+ $gpi_page_stats_values[ sanitize_key( $strategy . '_score' ) ] = intval( $score * 100 );
608
 
609
  if ( $update ) {
610
+ $wpdb->update( $gpi_page_stats, $gpi_page_stats_values, array( sanitize_key( $where_column ) => intval( $object_id ) ) );
611
+ $last_updated_id = $wpdb->get_var(
612
+ $wpdb->prepare(
613
+ "
614
+ SELECT ID
615
+ FROM $gpi_page_stats
616
+ WHERE $where_column = %d
617
+ ",
618
+ $object_id
619
+ )
620
+ );
621
  } else {
622
  $wpdb->insert( $gpi_page_stats, $gpi_page_stats_values );
623
  $last_updated_id = $wpdb->insert_id;
625
 
626
  $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
627
  if ( $update ) {
628
+ $wpdb->query(
629
+ $wpdb->prepare(
630
+ "
631
+ DELETE FROM $gpi_page_reports
632
+ WHERE page_id = %d
633
+ AND strategy = %s
634
+ ",
635
+ $last_updated_id,
636
+ $strategy
637
+ )
638
+ );
639
  }
640
 
641
  $page_reports = $Pagespeed_API->get_page_reports( $result['data'], $last_updated_id, $strategy, $this->gpi_options );
654
 
655
  $row_exist = $wpdb->get_row(
656
  $wpdb->prepare(
657
+ "
658
+ SELECT ID
659
+ FROM $gpi_page_blacklist
660
+ WHERE URL = %s
661
+ ",
662
  $object_url
663
  ),
664
  ARRAY_A
700
  $this->update_option( 'api_restriction', true, 'gpagespeedi_options' );
701
  $error_type = 'fatal';
702
 
703
+ } else if ( isset( $errors[0]->reason ) && $errors[0]->reason == 'forbidden' ) {
704
+
705
+ $this->update_option( 'api_restriction', true, 'gpagespeedi_options' );
706
+ $error_type = 'fatal';
707
+
708
  } else if ( isset( $errors[0]->reason ) && $errors[0]->reason == 'backendError' ) {
709
 
710
  $this->save_bad_request( $url_group_type, $where_column, $object_id, $object_url, false );
720
 
721
  }
722
 
723
+ if ( (bool) $this->gpi_options['log_api_errors'] ) {
724
  global $wpdb;
725
 
726
  $gpi_api_error_logs = $wpdb->prefix . 'gpi_api_error_logs';
745
  global $wpdb;
746
 
747
  $gpi_page_blacklist = $wpdb->prefix . 'gpi_page_blacklist';
748
+ $blacklist_urls = $wpdb->get_col(
749
+ "
750
+ SELECT URL
751
+ FROM $gpi_page_blacklist
752
+ "
753
+ );
754
 
755
  return $blacklist_urls;
756
  }
classes/class-GPI-List-Table.php CHANGED
@@ -41,7 +41,7 @@ class GPI_List_Table extends WP_List_Table
41
 
42
  $this->gpi_options = get_option('gpagespeedi_options');
43
  $this->type = $type;
44
- $this->strategy = $this->gpi_options['strategy'];
45
  $this->columns = $this->get_columns();
46
  $this->sortable = $this->get_sortable_columns();
47
  $this->per_page = isset( $_GET['post-per-page']) ? intval( $_GET['post-per-page'] ) : 25;
@@ -65,26 +65,6 @@ class GPI_List_Table extends WP_List_Table
65
  $this->db_columns = array( 'ID', 'URL', 'type' );
66
  break;
67
 
68
- case apply_filters( 'gpi_list_table_custom_case_1_type', 'reserved_for_internal_use' ):
69
- $this->table = apply_filters( 'gpi_list_table_custom_case_1_table', 'reserved_for_internal_use' );
70
- $this->db_columns = apply_filters( 'gpi_list_table_custom_case_1_db_columns', 'reserved_for_internal_use' );
71
- break;
72
-
73
- case apply_filters( 'gpi_list_table_custom_case_2_type', 'reserved_for_internal_use' ):
74
- $this->table = apply_filters( 'gpi_list_table_custom_case_2_table', 'reserved_for_internal_use' );
75
- $this->db_columns = apply_filters( 'gpi_list_table_custom_case_2_db_columns', 'reserved_for_internal_use' );
76
- break;
77
-
78
- case apply_filters( 'gpi_list_table_custom_case_3_type', 'reserved_for_internal_use' ):
79
- $this->table = apply_filters( 'gpi_list_table_custom_case_3_table', 'reserved_for_internal_use' );
80
- $this->db_columns = apply_filters( 'gpi_list_table_custom_case_3_db_columns', 'reserved_for_internal_use' );
81
- break;
82
-
83
- case apply_filters( 'gpi_list_table_custom_case_4_type', 'available_for_custom_integration' ):
84
- $this->table = apply_filters( 'gpi_list_table_custom_case_4_table', 'available_for_custom_integration' );
85
- $this->db_columns = apply_filters( 'gpi_list_table_custom_case_4_db_columns', 'available_for_custom_integration' );
86
- break;
87
-
88
  default:
89
  $this->table = $wpdb->prefix . 'gpi_page_stats';
90
  $this->db_columns = array( 'ID', 'URL', 'desktop_score', 'mobile_score', 'type', 'desktop_last_modified', 'mobile_last_modified' );
@@ -113,10 +93,10 @@ class GPI_List_Table extends WP_List_Table
113
  <?php
114
  }
115
 
116
- public function human_timing( $time )
117
  {
118
  if ( empty( $time ) ) {
119
- return 'N/A';
120
  }
121
  $time = current_time( 'timestamp' ) - $time;
122
 
@@ -147,40 +127,24 @@ class GPI_List_Table extends WP_List_Table
147
  switch( $pagetype )
148
  {
149
  case 'ignored-urls':
150
- _e( 'No Ignored URLs found. A URL can be ignored from the <a href="?page=' . esc_attr( $_REQUEST['page'] ) . '&render=report-list">Report List</a> page if you would like to remove it from report pages', 'gpagespeedi' );
151
  break;
152
 
153
  case 'snapshots':
154
- _e( 'No Snapshots found. Snapshots can be created from the', 'gpagespeedi' ) . ' ' . '<a href="?page=' . esc_attr( $_REQUEST['page'] ) . '&render=summary">' . __( 'Report Summary', 'gpagespeedi' ) . '</a>' . ' ' . __( 'page', 'gpagespeedi' ) . '.';
155
  break;
156
 
157
  case 'custom-urls':
158
- _e( 'No Custom URLs found. Click "Add New URLs" or "Bulk Upload New URLs" above to add custom URLs.', 'gpagespeedi' );
159
- break;
160
-
161
- case apply_filters( 'gpi_list_table_custom_case_1_type', 'reserved_for_internal_use' ):
162
- echo apply_filters( 'gpi_list_table_custom_case_1_no_items', 'reserved_for_internal_use' );
163
- break;
164
-
165
- case apply_filters( 'gpi_list_table_custom_case_2_type', 'reserved_for_internal_use' ):
166
- echo apply_filters( 'gpi_list_table_custom_case_2_no_items', 'reserved_for_internal_use' );
167
- break;
168
-
169
- case apply_filters( 'gpi_list_table_custom_case_3_type', 'reserved_for_internal_use' ):
170
- echo apply_filters( 'gpi_list_table_custom_case_3_no_items', 'reserved_for_internal_use' );
171
- break;
172
-
173
- case apply_filters( 'gpi_list_table_custom_case_4_type', 'available_for_custom_integration' ):
174
- echo apply_filters( 'gpi_list_table_custom_case_4_no_items', 'available_for_custom_integration' );
175
  break;
176
 
177
  default:
178
- _e( 'No Pagespeed Reports Found. Google Pagespeed may still be checking your pages. If problems persist, see the following possible solutions:', 'gpagespeedi' );
179
  ?>
180
  <ol class="no-items">
181
- <li><?php _e( 'Make sure that you have entered your Google API key on the ', 'gpagespeedi' );?><a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=options"><?php _e( 'Options', 'gpagespeedi' ); ?></a> <?php _e( 'page', 'gpagespeedi' ); ?>.</li>
182
- <li><?php _e( 'Make sure that you have enabled "PageSpeed Insights API" from the Services page of the ', 'gpagespeedi' );?><a href="https://code.google.com/apis/console/"> <?php _e( 'Google Console', 'gpagespeedi' ); ?></a>.</li>
183
- <li><?php _e( 'Make sure that your URLs are publicly accessible', 'gpagespeedi' ); ?>.</li>
184
  </ol>
185
  <?php
186
  break;
@@ -197,7 +161,7 @@ class GPI_List_Table extends WP_List_Table
197
  $cleaned_url = str_replace( $search_urls, '', $url );
198
 
199
  if ( '/' == $cleaned_url ) {
200
- $cleaned_url .= ' (' . __( 'homepage', 'gpagespeedi' ) . ')';
201
  }
202
 
203
  return $cleaned_url;
@@ -209,26 +173,26 @@ class GPI_List_Table extends WP_List_Table
209
  {
210
  case 'desktop_last_modified':
211
  $formatted_time = $this->human_timing( $item['desktop_last_modified'] );
212
- return $formatted_time;
213
 
214
  case 'mobile_last_modified':
215
  $formatted_time = $this->human_timing( $item['mobile_last_modified'] );
216
- return $formatted_time;
217
 
218
  case 'type':
219
  return esc_attr( $item[ $column_name ] );
220
 
221
  case 'custom_url':
222
  $actions = array(
223
- 'delete' => sprintf( '?page=%s&render=%s&action=%s&page_id=%s', esc_attr( $_REQUEST['page'] ), 'custom-urls', 'delete', $item['ID'] ),
224
- 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', $item['URL'], __( 'View URL', 'gpagespeedi' ) )
225
  );
226
 
227
  $nonced_url = wp_nonce_url( $actions['delete'], 'bulk-gpi_page_reports' );
228
- $actions['delete'] = '<a href="' . $nonced_url . '">' . __( 'Delete', 'gpagespeedi') . '</a>';
229
 
230
  return sprintf( '%1$s %2$s',
231
- $item['URL'],
232
  $this->row_actions( $actions )
233
  );
234
 
@@ -237,19 +201,19 @@ class GPI_List_Table extends WP_List_Table
237
  $date = date( 'M d, Y - h:i a', $date );
238
 
239
  $actions = array(
240
- 'delete' => sprintf( '?page=%s&render=%s&action=%s&snapshot_id=%s' ,esc_attr( $_REQUEST['page'] ), 'snapshots', 'delete-snapshot', $item['ID'] ),
241
- 'view' => sprintf( '<a href="?page=%s&render=%s&snapshot_id=%s">%s</a>' , esc_attr( $_REQUEST['page'] ), 'view-snapshot', $item['ID'], __( 'View Snapshot', 'gpagespeedi' ) )
242
  );
243
 
244
  $nonced_url = wp_nonce_url( $actions['delete'], 'bulk-gpi_page_reports' );
245
- $actions['delete'] = '<a href="' . $nonced_url . '">' . __('Delete', 'gpagespeedi') . '</a>';
246
 
247
 
248
  return sprintf( '<a href="?page=%1$s&render=%2$s&snapshot_id=%3$s">%4$s</a> %5$s',
249
- esc_attr( $_REQUEST['page'] ),
250
  'view-snapshot',
251
- $item['ID'],
252
- $date,
253
  $this->row_actions( $actions )
254
  );
255
 
@@ -259,13 +223,13 @@ class GPI_List_Table extends WP_List_Table
259
  $filter_replace = array( '', '', __( 'All Custom Post Types', 'gpagespeedi' ), __( 'All Custom URLs', 'gpagespeedi' ), __( 'All Reports', 'gpagespeedi' ), __( 'Pages', 'gpagespeedi' ), __( 'Posts', 'gpagespeedi' ), __( 'Categories', 'gpagespeedi' ) );
260
  $cleaned_filter = str_replace( $filter_search, $filter_replace, $filter );
261
 
262
- return esc_attr( $cleaned_filter );
263
 
264
  case apply_filters( 'gpi_custom_column', false, $column_name ):
265
- return apply_filters( 'gpi_custom_column_config', $column_name, $item );
266
 
267
  default:
268
- return esc_attr( $item[ $column_name ] );
269
  }
270
  }
271
 
@@ -274,21 +238,21 @@ class GPI_List_Table extends WP_List_Table
274
  $cleaned_url = $this->strip_domain( $item['URL'] );
275
 
276
  $actions = array(
277
- 'view_details' => sprintf( '<a href="?page=%s&render=%s&page_id=%s">%s</a>', esc_attr( $_REQUEST['page'] ), 'details', $item['ID'], __( 'Details', 'gpagespeedi' ) ),
278
- 'ignore' => sprintf( '?page=%s&render=%s&action=%s&page_id=%s', esc_attr( $_REQUEST['page'] ), 'report-list', 'ignore', $item['ID'] ),
279
- 'delete_report' => sprintf( '?page=%s&render=%s&action=%s&page_id=%s', esc_attr( $_REQUEST['page'] ), 'report-list', 'delete_report', $item['ID'] ),
280
- 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', $item['URL'], __( 'View URL', 'gpagespeedi' ) )
281
  );
282
 
283
- $actions['ignore'] = '<a href="' . wp_nonce_url( $actions['ignore'], 'bulk-gpi_page_reports' ) . '">'.__( 'Ignore', 'gpagespeedi' ) . '</a>';
284
- $actions['delete_report'] = '<a href="' . wp_nonce_url( $actions['delete_report'], 'bulk-gpi_page_reports' ) . '">'.__( 'Delete', 'gpagespeedi' ) . '</a>';
285
 
286
  return sprintf( '<a href="?page=%3$s&render=%4$s&page_id=%5$s">%1$s</a> %2$s',
287
- $cleaned_url,
288
  $this->row_actions( $actions ),
289
- esc_attr( $_REQUEST['page'] ),
290
  'details',
291
- $item['ID']
292
  );
293
  }
294
 
@@ -297,16 +261,16 @@ class GPI_List_Table extends WP_List_Table
297
  $cleaned_url = $this->strip_domain( $item['URL'] );
298
 
299
  $actions = array(
300
- 'reactivate' => sprintf( '?page=%s&render=%s&action=%s&page_id=%s', esc_attr( $_REQUEST['page'] ), 'ignored-urls', 'reactivate', $item['ID'] ),
301
- 'delete_blacklist' => sprintf( '?page=%s&render=%s&action=%s&page_id=%s', esc_attr( $_REQUEST['page'] ), 'ignored-urls', 'delete_blacklist', $item['ID'] ),
302
- 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', $item['URL'], __( 'View URL', 'gpagespeedi' ) )
303
  );
304
 
305
- $actions['reactivate'] = '<a href="' . wp_nonce_url( $actions['reactivate'], 'bulk-gpi_page_reports' ) . '">' . __( 'Reactivate', 'gpagespeedi' ) . '</a>';
306
- $actions['delete_blacklist'] = '<a href="' . wp_nonce_url( $actions['delete_blacklist'], 'bulk-gpi_page_reports' ) . '">'.__( 'Delete', 'gpagespeedi' ) . '</a>';
307
 
308
  return sprintf( '%1$s %2$s',
309
- $cleaned_url,
310
  $this->row_actions( $actions )
311
  );
312
  }
@@ -314,7 +278,7 @@ class GPI_List_Table extends WP_List_Table
314
  public function column_mobile_score( $item )
315
  {
316
  if ( empty( $item['mobile_score'] ) && '0' != $item['mobile_score'] ) {
317
- return 'N/A';
318
  }
319
 
320
  if ( $item['mobile_score'] < 50 ) {
@@ -326,13 +290,13 @@ class GPI_List_Table extends WP_List_Table
326
  }
327
  $innerdiv_css = 'background-color:' . $barcolor . ';width:' . $item['mobile_score'] . '%';
328
 
329
- return sprintf( '<span class="scorenum">%1$s</span><div class="reportscore_outter_bar"><div class="reportscore_inner_bar" style="%2$s"></div></div>', $item['mobile_score'], $innerdiv_css );
330
  }
331
 
332
  public function column_desktop_score( $item )
333
  {
334
  if ( empty( $item['desktop_score'] ) && '0' != $item['desktop_score'] ) {
335
- return 'N/A';
336
  }
337
 
338
  if ( $item['desktop_score'] < 50 ) {
@@ -344,15 +308,15 @@ class GPI_List_Table extends WP_List_Table
344
  }
345
  $innerdiv_css = 'background-color:' . $barcolor . ';width:' . $item['desktop_score'] . '%';
346
 
347
- return sprintf( '<span class="scorenum">%1$s</span><div class="reportscore_outter_bar"><div class="reportscore_inner_bar" style="%2$s"></div></div>', $item['desktop_score'], $innerdiv_css );
348
  }
349
 
350
  public function column_cb( $item )
351
  {
352
  return sprintf(
353
  '<input type="checkbox" name="%1$s[]" value="%2$s" />',
354
- $this->_args['singular'],
355
- $item['ID']
356
  );
357
  }
358
 
@@ -385,28 +349,12 @@ class GPI_List_Table extends WP_List_Table
385
  );
386
  break;
387
 
388
- case apply_filters( 'gpi_list_table_custom_case_1_type', 'reserved_for_internal_use' ):
389
- $columns = apply_filters( 'gpi_list_table_custom_case_1_columns', 'reserved_for_internal_use' );
390
- break;
391
-
392
- case apply_filters( 'gpi_list_table_custom_case_2_type', 'reserved_for_internal_use' ):
393
- $columns = apply_filters( 'gpi_list_table_custom_case_2_columns', 'reserved_for_internal_use' );
394
- break;
395
-
396
- case apply_filters( 'gpi_list_table_custom_case_3_type', 'reserved_for_internal_use' ):
397
- $columns = apply_filters( 'gpi_list_table_custom_case_3_columns', 'reserved_for_internal_use' );
398
- break;
399
-
400
- case apply_filters( 'gpi_list_table_custom_case_4_type', 'available_for_custom_integration' ):
401
- $columns = apply_filters( 'gpi_list_table_custom_case_4_columns', 'available_for_custom_integration' );
402
- break;
403
-
404
  default:
405
  if ( $this->strategy == 'desktop' ) {
406
  $columns = array(
407
  'cb' => '<input type="checkbox" />',
408
  'url' => __( 'URL', 'gpagespeedi' ),
409
- 'desktop_score' => __( 'Score', 'gpagespeedi' ),
410
  'type' => __( 'Page Type', 'gpagespeedi' ),
411
  'desktop_last_modified' => __( 'Last Checked', 'gpagespeedi' )
412
  );
@@ -414,7 +362,7 @@ class GPI_List_Table extends WP_List_Table
414
  $columns = array(
415
  'cb' => '<input type="checkbox" />',
416
  'url' => __( 'URL', 'gpagespeedi' ),
417
- 'mobile_score' => __( 'Score', 'gpagespeedi' ),
418
  'type' => __( 'Page Type', 'gpagespeedi' ),
419
  'mobile_last_modified' => __( 'Last Checked', 'gpagespeedi' )
420
  );
@@ -422,8 +370,8 @@ class GPI_List_Table extends WP_List_Table
422
  $columns = array(
423
  'cb' => '<input type="checkbox" />',
424
  'url' => __( 'URL', 'gpagespeedi' ),
425
- 'desktop_score' => __( 'Score (Desktop)', 'gpagespeedi' ),
426
- 'mobile_score' => __( 'Score (Mobile)', 'gpagespeedi' ),
427
  'type' => __( 'Page Type', 'gpagespeedi' ),
428
  'desktop_last_modified' => __( 'Last Checked (Desktop)', 'gpagespeedi' ),
429
  'mobile_last_modified' => __( 'Last Checked (Mobile)', 'gpagespeedi' )
@@ -432,7 +380,7 @@ class GPI_List_Table extends WP_List_Table
432
  break;
433
  }
434
 
435
- return $columns;
436
  }
437
 
438
  public function get_sortable_columns()
@@ -460,28 +408,12 @@ class GPI_List_Table extends WP_List_Table
460
  );
461
  break;
462
 
463
- case apply_filters( 'gpi_list_table_custom_case_1_type', 'reserved_for_internal_use' ):
464
- $sortable_columns = apply_filters( 'gpi_list_table_custom_case_1_sortable_columns', 'reserved_for_internal_use' );
465
- break;
466
-
467
- case apply_filters( 'gpi_list_table_custom_case_2_type', 'reserved_for_internal_use' ):
468
- $sortable_columns = apply_filters( 'gpi_list_table_custom_case_2_sortable_columns', 'reserved_for_internal_use' );
469
- break;
470
-
471
- case apply_filters( 'gpi_list_table_custom_case_3_type', 'reserved_for_internal_use' ):
472
- $sortable_columns = apply_filters( 'gpi_list_table_custom_case_3_sortable_columns', 'reserved_for_internal_use' );
473
- break;
474
-
475
- case apply_filters( 'gpi_list_table_custom_case_4_type', 'available_for_custom_integration' ):
476
- $sortable_columns = apply_filters( 'gpi_list_table_custom_case_4_sortable_columns', 'available_for_custom_integration' );
477
- break;
478
-
479
  default:
480
  if ( 'all' == $filter || 'custom_posts' == $filter || 'custom_urls' == $filter ) {
481
  $sortable_columns = array(
482
  'desktop_score' => array( 'desktop_score', false ),
483
  'mobile_score' => array( 'mobile_score', false ),
484
- 'type' => array( 'type', false )
485
  );
486
  } else {
487
  $sortable_columns = array(
@@ -519,22 +451,6 @@ class GPI_List_Table extends WP_List_Table
519
  );
520
  break;
521
 
522
- case apply_filters( 'gpi_list_table_custom_case_1_type', 'reserved_for_internal_use' ):
523
- $actions = apply_filters( 'gpi_list_table_custom_case_1_bulk_actions', 'reserved_for_internal_use' );
524
- break;
525
-
526
- case apply_filters( 'gpi_list_table_custom_case_2_type', 'reserved_for_internal_use' ):
527
- $actions = apply_filters( 'gpi_list_table_custom_case_2_bulk_actions', 'reserved_for_internal_use' );
528
- break;
529
-
530
- case apply_filters( 'gpi_list_table_custom_case_3_type', 'reserved_for_internal_use' ):
531
- $actions = apply_filters( 'gpi_list_table_custom_case_3_bulk_actions', 'reserved_for_internal_use' );
532
- break;
533
-
534
- case apply_filters( 'gpi_list_table_custom_case_4_type', 'available_for_custom_integration' ):
535
- $actions = apply_filters( 'gpi_list_table_custom_case_4_bulk_actions', 'available_for_custom_integration' );
536
- break;
537
-
538
  default:
539
  $actions = array(
540
  'ignore' => __( 'Ignore Reports', 'gpagespeedi' ),
@@ -543,7 +459,7 @@ class GPI_List_Table extends WP_List_Table
543
  break;
544
  }
545
 
546
- return $actions;
547
  }
548
 
549
  public function extra_tablenav( $which )
@@ -566,11 +482,11 @@ class GPI_List_Table extends WP_List_Table
566
 
567
  if ( is_array( $label ) ) :
568
  ?>
569
- <optgroup label="<?php echo $label['optgroup_label']; ?>">
570
  <?php
571
  foreach ( $label['options'] as $sub_value => $sub_label ) :
572
  ?>
573
- <option value="<?php echo $sub_value; ?>" <?php selected( $sub_value, $current_filter ); ?>><?php echo $sub_label; ?></option>
574
  <?php
575
  endforeach;
576
  ?>
@@ -578,7 +494,7 @@ class GPI_List_Table extends WP_List_Table
578
  <?php
579
  else :
580
  ?>
581
- <option value="<?php echo $value; ?>" <?php selected( $value, $current_filter ); ?>><?php echo $label; ?></option>
582
  <?php
583
  endif;
584
  endforeach;
@@ -588,20 +504,20 @@ class GPI_List_Table extends WP_List_Table
588
  <?php endif; ?>
589
  <?php if ( isset( $_GET['render'] ) && 'summary' != $_GET['render'] ) : ?>
590
  <select name="post-per-page" id="post-per-page">
591
- <option value="25" <?php selected( $post_per_page, 25 ); ?>><?php _e( '25 Results/Page', 'gpagespeedi' ); ?></option>
592
- <option value="50" <?php selected( $post_per_page, 50 ); ?>><?php _e( '50 Results/Page', 'gpagespeedi' ); ?></option>
593
- <option value="100" <?php selected( $post_per_page, 100 ); ?>><?php _e( '100 Results/Page', 'gpagespeedi' ); ?></option>
594
- <option value="500" <?php selected( $post_per_page, 500 ); ?>><?php _e( '500 Results/Page', 'gpagespeedi' ); ?></option>
595
- <option value="1000" <?php selected( $post_per_page, 1000 ); ?>><?php _e( '1000 Results/Page', 'gpagespeedi' ); ?></option>
596
  </select>
597
  <?php endif; ?>
598
  <?php
599
- submit_button( __( 'Filter', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
600
  ?>
601
 
602
  <?php if ( 'custom-urls' == $_GET['render'] ) : ?>
603
- <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=add-custom-urls" class="button-secondary"><?php _e( 'Add New URLs', 'gpagespeedi' ); ?></a>
604
- <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=add-custom-urls-bulk" class="button-secondary"><?php _e( 'Bulk Upload New URLs', 'gpagespeedi' ); ?></a>
605
  <?php endif; ?>
606
 
607
  <?php do_action( 'gpi_after_tablenav', sanitize_text_field( $_GET['render'] ) ); ?>
@@ -629,15 +545,17 @@ class GPI_List_Table extends WP_List_Table
629
  $filter = 'gpi_custom_urls' != $filter ? $filter : apply_filters( 'gpi_custom_url_labels', $filter );
630
 
631
  if ( $filter ) {
632
- $data = $wpdb->get_results( $wpdb->prepare(
633
- "
634
- SELECT $db_columns
635
- FROM $this->table
636
- WHERE type REGEXP %s
637
- ORDER BY $orderby $order
638
- ",
639
- $filter
640
- ), ARRAY_A );
 
 
641
  }
642
  } else {
643
  $data = $wpdb->get_results(
@@ -645,8 +563,8 @@ class GPI_List_Table extends WP_List_Table
645
  SELECT $db_columns
646
  FROM $this->table
647
  ORDER BY $orderby $order
648
- "
649
- , ARRAY_A );
650
  }
651
 
652
  $current_page = $this->get_pagenum();
41
 
42
  $this->gpi_options = get_option('gpagespeedi_options');
43
  $this->type = $type;
44
+ $this->strategy = sanitize_text_field( $this->gpi_options['strategy'] );
45
  $this->columns = $this->get_columns();
46
  $this->sortable = $this->get_sortable_columns();
47
  $this->per_page = isset( $_GET['post-per-page']) ? intval( $_GET['post-per-page'] ) : 25;
65
  $this->db_columns = array( 'ID', 'URL', 'type' );
66
  break;
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  default:
69
  $this->table = $wpdb->prefix . 'gpi_page_stats';
70
  $this->db_columns = array( 'ID', 'URL', 'desktop_score', 'mobile_score', 'type', 'desktop_last_modified', 'mobile_last_modified' );
93
  <?php
94
  }
95
 
96
+ private function human_timing( $time )
97
  {
98
  if ( empty( $time ) ) {
99
+ return esc_html__( 'N/A', 'gpagespeedi' );
100
  }
101
  $time = current_time( 'timestamp' ) - $time;
102
 
127
  switch( $pagetype )
128
  {
129
  case 'ignored-urls':
130
+ echo wp_kses_data( __( 'No Ignored URLs found. A URL can be ignored from the <a href="?page=google-pagespeed-insights&render=report-list">Report List</a> page if you would like to remove it from report pages', 'gpagespeedi' ) );
131
  break;
132
 
133
  case 'snapshots':
134
+ echo wp_kses_data( __( 'No Snapshots found. Snapshots can be created from the', 'gpagespeedi' ) . ' ' . '<a href="?page=google-pagespeed-insights&render=summary">' . __( 'Report Summary', 'gpagespeedi' ) . '</a>' . ' ' . __( 'page', 'gpagespeedi' ) . '.' );
135
  break;
136
 
137
  case 'custom-urls':
138
+ esc_html_e( 'No Custom URLs found. Click "Add New URLs" or "Bulk Upload New URLs" above to add custom URLs.', 'gpagespeedi' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  break;
140
 
141
  default:
142
+ esc_html_e( 'No Pagespeed Reports Found. Google Pagespeed may still be checking your pages. If problems persist, see the following possible solutions:', 'gpagespeedi' );
143
  ?>
144
  <ol class="no-items">
145
+ <li><?php esc_html_e( 'Make sure that you have entered your Google API key on the ', 'gpagespeedi' );?><a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a> <?php esc_html_e( 'page', 'gpagespeedi' ); ?>.</li>
146
+ <li><?php esc_html_e( 'Make sure that you have enabled "PageSpeed Insights API" from the Services page of the ', 'gpagespeedi' );?><a href="https://console.developers.google.com/"> <?php esc_html_e( 'Google Console', 'gpagespeedi' ); ?></a>.</li>
147
+ <li><?php esc_html_e( 'Make sure that your URLs are publicly accessible', 'gpagespeedi' ); ?>.</li>
148
  </ol>
149
  <?php
150
  break;
161
  $cleaned_url = str_replace( $search_urls, '', $url );
162
 
163
  if ( '/' == $cleaned_url ) {
164
+ $cleaned_url .= '(' . __( 'homepage', 'gpagespeedi' ) . ')';
165
  }
166
 
167
  return $cleaned_url;
173
  {
174
  case 'desktop_last_modified':
175
  $formatted_time = $this->human_timing( $item['desktop_last_modified'] );
176
+ return esc_html( $formatted_time );
177
 
178
  case 'mobile_last_modified':
179
  $formatted_time = $this->human_timing( $item['mobile_last_modified'] );
180
+ return esc_html( $formatted_time );
181
 
182
  case 'type':
183
  return esc_attr( $item[ $column_name ] );
184
 
185
  case 'custom_url':
186
  $actions = array(
187
+ 'delete' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&page_id=%s', 'custom-urls', 'delete', intval( esc_attr( $item['ID'] ) ) ),
188
+ 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $item['URL'] ), esc_html__( 'View URL', 'gpagespeedi' ) )
189
  );
190
 
191
  $nonced_url = wp_nonce_url( $actions['delete'], 'bulk-gpi_page_reports' );
192
+ $actions['delete'] = '<a href="' . $nonced_url . '">' . esc_html__( 'Delete', 'gpagespeedi') . '</a>';
193
 
194
  return sprintf( '%1$s %2$s',
195
+ esc_url( $item['URL'] ),
196
  $this->row_actions( $actions )
197
  );
198
 
201
  $date = date( 'M d, Y - h:i a', $date );
202
 
203
  $actions = array(
204
+ 'delete' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&snapshot_id=%s', 'snapshots', 'delete-snapshot', intval( esc_attr( $item['ID'] ) ) ),
205
+ 'view' => sprintf( '<a href="?page=google-pagespeed-insights&render=%s&snapshot_id=%s">%s</a>', 'view-snapshot', intval( esc_attr( $item['ID'] ) ), esc_html__( 'View Snapshot', 'gpagespeedi' ) )
206
  );
207
 
208
  $nonced_url = wp_nonce_url( $actions['delete'], 'bulk-gpi_page_reports' );
209
+ $actions['delete'] = '<a href="' . $nonced_url . '">' . esc_html__('Delete', 'gpagespeedi') . '</a>';
210
 
211
 
212
  return sprintf( '<a href="?page=%1$s&render=%2$s&snapshot_id=%3$s">%4$s</a> %5$s',
213
+ 'google-pagespeed-insights',
214
  'view-snapshot',
215
+ intval( esc_attr( $item['ID'] ) ),
216
+ esc_html( $date ),
217
  $this->row_actions( $actions )
218
  );
219
 
223
  $filter_replace = array( '', '', __( 'All Custom Post Types', 'gpagespeedi' ), __( 'All Custom URLs', 'gpagespeedi' ), __( 'All Reports', 'gpagespeedi' ), __( 'Pages', 'gpagespeedi' ), __( 'Posts', 'gpagespeedi' ), __( 'Categories', 'gpagespeedi' ) );
224
  $cleaned_filter = str_replace( $filter_search, $filter_replace, $filter );
225
 
226
+ return esc_html( $cleaned_filter );
227
 
228
  case apply_filters( 'gpi_custom_column', false, $column_name ):
229
+ return esc_html( apply_filters( 'gpi_custom_column_config', $column_name, $item ) );
230
 
231
  default:
232
+ return esc_html( $item[ $column_name ] );
233
  }
234
  }
235
 
238
  $cleaned_url = $this->strip_domain( $item['URL'] );
239
 
240
  $actions = array(
241
+ 'view_details' => sprintf( '<a href="?page=google-pagespeed-insights&render=%s&page_id=%s">%s</a>', 'details', intval( esc_attr( $item['ID'] ) ), esc_html__( 'Details', 'gpagespeedi' ) ),
242
+ 'ignore' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&page_id=%s', 'report-list', 'ignore', intval( esc_attr( $item['ID'] ) ) ),
243
+ 'delete_report' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&page_id=%s', 'report-list', 'delete_report', intval( esc_attr( $item['ID'] ) ) ),
244
+ 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $item['URL'] ), esc_html__( 'View URL', 'gpagespeedi' ) )
245
  );
246
 
247
+ $actions['ignore'] = '<a href="' . wp_nonce_url( $actions['ignore'], 'bulk-gpi_page_reports' ) . '">' . esc_html__( 'Ignore', 'gpagespeedi' ) . '</a>';
248
+ $actions['delete_report'] = '<a href="' . wp_nonce_url( $actions['delete_report'], 'bulk-gpi_page_reports' ) . '">' . esc_html__( 'Delete', 'gpagespeedi' ) . '</a>';
249
 
250
  return sprintf( '<a href="?page=%3$s&render=%4$s&page_id=%5$s">%1$s</a> %2$s',
251
+ esc_url( $cleaned_url ),
252
  $this->row_actions( $actions ),
253
+ 'google-pagespeed-insights',
254
  'details',
255
+ intval( esc_attr( $item['ID'] ) )
256
  );
257
  }
258
 
261
  $cleaned_url = $this->strip_domain( $item['URL'] );
262
 
263
  $actions = array(
264
+ 'reactivate' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&page_id=%s', 'ignored-urls', 'reactivate', intval( esc_attr( $item['ID'] ) ) ),
265
+ 'delete_blacklist' => sprintf( '?page=google-pagespeed-insights&render=%s&action=%s&page_id=%s', 'ignored-urls', 'delete_blacklist', intval( esc_attr( $item['ID'] ) ) ),
266
+ 'visit' => sprintf( '<a href="%s" target="_blank">%s</a>', esc_url( $item['URL'] ), esc_html__( 'View URL', 'gpagespeedi' ) )
267
  );
268
 
269
+ $actions['reactivate'] = '<a href="' . wp_nonce_url( $actions['reactivate'], 'bulk-gpi_page_reports' ) . '">' . esc_html__( 'Reactivate', 'gpagespeedi' ) . '</a>';
270
+ $actions['delete_blacklist'] = '<a href="' . wp_nonce_url( $actions['delete_blacklist'], 'bulk-gpi_page_reports' ) . '">' . esc_html__( 'Delete', 'gpagespeedi' ) . '</a>';
271
 
272
  return sprintf( '%1$s %2$s',
273
+ esc_url( $cleaned_url ),
274
  $this->row_actions( $actions )
275
  );
276
  }
278
  public function column_mobile_score( $item )
279
  {
280
  if ( empty( $item['mobile_score'] ) && '0' != $item['mobile_score'] ) {
281
+ return esc_html__( 'N/A', 'gpagespeedi' );
282
  }
283
 
284
  if ( $item['mobile_score'] < 50 ) {
290
  }
291
  $innerdiv_css = 'background-color:' . $barcolor . ';width:' . $item['mobile_score'] . '%';
292
 
293
+ return sprintf( '<span class="scorenum">%1$s</span><div class="reportscore_outter_bar"><div class="reportscore_inner_bar" style="%2$s"></div></div>', esc_html( $item['mobile_score'] ), esc_attr( $innerdiv_css ) );
294
  }
295
 
296
  public function column_desktop_score( $item )
297
  {
298
  if ( empty( $item['desktop_score'] ) && '0' != $item['desktop_score'] ) {
299
+ return esc_html( 'N/A', 'gpagespeedi' );
300
  }
301
 
302
  if ( $item['desktop_score'] < 50 ) {
308
  }
309
  $innerdiv_css = 'background-color:' . $barcolor . ';width:' . $item['desktop_score'] . '%';
310
 
311
+ return sprintf( '<span class="scorenum">%1$s</span><div class="reportscore_outter_bar"><div class="reportscore_inner_bar" style="%2$s"></div></div>', esc_html( $item['desktop_score'] ), esc_attr( $innerdiv_css ) );
312
  }
313
 
314
  public function column_cb( $item )
315
  {
316
  return sprintf(
317
  '<input type="checkbox" name="%1$s[]" value="%2$s" />',
318
+ esc_attr( $this->_args['singular'] ),
319
+ intval( esc_attr( $item['ID'] ) )
320
  );
321
  }
322
 
349
  );
350
  break;
351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  default:
353
  if ( $this->strategy == 'desktop' ) {
354
  $columns = array(
355
  'cb' => '<input type="checkbox" />',
356
  'url' => __( 'URL', 'gpagespeedi' ),
357
+ 'desktop_score' => __( 'Score', 'gpagespeedi' ),
358
  'type' => __( 'Page Type', 'gpagespeedi' ),
359
  'desktop_last_modified' => __( 'Last Checked', 'gpagespeedi' )
360
  );
362
  $columns = array(
363
  'cb' => '<input type="checkbox" />',
364
  'url' => __( 'URL', 'gpagespeedi' ),
365
+ 'mobile_score' => __( 'Score', 'gpagespeedi' ),
366
  'type' => __( 'Page Type', 'gpagespeedi' ),
367
  'mobile_last_modified' => __( 'Last Checked', 'gpagespeedi' )
368
  );
370
  $columns = array(
371
  'cb' => '<input type="checkbox" />',
372
  'url' => __( 'URL', 'gpagespeedi' ),
373
+ 'desktop_score' => __( 'Score (Desktop)', 'gpagespeedi' ),
374
+ 'mobile_score' => __( 'Score (Mobile)', 'gpagespeedi' ),
375
  'type' => __( 'Page Type', 'gpagespeedi' ),
376
  'desktop_last_modified' => __( 'Last Checked (Desktop)', 'gpagespeedi' ),
377
  'mobile_last_modified' => __( 'Last Checked (Mobile)', 'gpagespeedi' )
380
  break;
381
  }
382
 
383
+ return array_map( 'esc_html', $columns );
384
  }
385
 
386
  public function get_sortable_columns()
408
  );
409
  break;
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  default:
412
  if ( 'all' == $filter || 'custom_posts' == $filter || 'custom_urls' == $filter ) {
413
  $sortable_columns = array(
414
  'desktop_score' => array( 'desktop_score', false ),
415
  'mobile_score' => array( 'mobile_score', false ),
416
+ 'type' => array( 'type', false )
417
  );
418
  } else {
419
  $sortable_columns = array(
451
  );
452
  break;
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  default:
455
  $actions = array(
456
  'ignore' => __( 'Ignore Reports', 'gpagespeedi' ),
459
  break;
460
  }
461
 
462
+ return array_map( 'esc_html', $actions );
463
  }
464
 
465
  public function extra_tablenav( $which )
482
 
483
  if ( is_array( $label ) ) :
484
  ?>
485
+ <optgroup label="<?php echo esc_attr( $label['optgroup_label'] ); ?>">
486
  <?php
487
  foreach ( $label['options'] as $sub_value => $sub_label ) :
488
  ?>
489
+ <option value="<?php echo esc_attr( $sub_value ); ?>" <?php selected( $sub_value, $current_filter ); ?>><?php echo esc_html( $sub_label ); ?></option>
490
  <?php
491
  endforeach;
492
  ?>
494
  <?php
495
  else :
496
  ?>
497
+ <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $current_filter ); ?>><?php echo esc_html( $label ); ?></option>
498
  <?php
499
  endif;
500
  endforeach;
504
  <?php endif; ?>
505
  <?php if ( isset( $_GET['render'] ) && 'summary' != $_GET['render'] ) : ?>
506
  <select name="post-per-page" id="post-per-page">
507
+ <option value="25" <?php selected( $post_per_page, 25 ); ?>><?php esc_html_e( '25 Results/Page', 'gpagespeedi' ); ?></option>
508
+ <option value="50" <?php selected( $post_per_page, 50 ); ?>><?php esc_html_e( '50 Results/Page', 'gpagespeedi' ); ?></option>
509
+ <option value="100" <?php selected( $post_per_page, 100 ); ?>><?php esc_html_e( '100 Results/Page', 'gpagespeedi' ); ?></option>
510
+ <option value="500" <?php selected( $post_per_page, 500 ); ?>><?php esc_html_e( '500 Results/Page', 'gpagespeedi' ); ?></option>
511
+ <option value="1000" <?php selected( $post_per_page, 1000 ); ?>><?php esc_html_e( '1000 Results/Page', 'gpagespeedi' ); ?></option>
512
  </select>
513
  <?php endif; ?>
514
  <?php
515
+ submit_button( esc_html__( 'Filter', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
516
  ?>
517
 
518
  <?php if ( 'custom-urls' == $_GET['render'] ) : ?>
519
+ <a href="?page=google-pagespeed-insights&amp;render=add-custom-urls" class="button-secondary"><?php esc_html_e( 'Add New URLs', 'gpagespeedi' ); ?></a>
520
+ <a href="?page=google-pagespeed-insights&amp;render=add-custom-urls-bulk" class="button-secondary"><?php esc_html_e( 'Bulk Upload New URLs', 'gpagespeedi' ); ?></a>
521
  <?php endif; ?>
522
 
523
  <?php do_action( 'gpi_after_tablenav', sanitize_text_field( $_GET['render'] ) ); ?>
545
  $filter = 'gpi_custom_urls' != $filter ? $filter : apply_filters( 'gpi_custom_url_labels', $filter );
546
 
547
  if ( $filter ) {
548
+ $data = $wpdb->get_results(
549
+ $wpdb->prepare(
550
+ "
551
+ SELECT $db_columns
552
+ FROM $this->table
553
+ WHERE type REGEXP %s
554
+ ORDER BY $orderby $order
555
+ ",
556
+ $filter
557
+ ), ARRAY_A
558
+ );
559
  }
560
  } else {
561
  $data = $wpdb->get_results(
563
  SELECT $db_columns
564
  FROM $this->table
565
  ORDER BY $orderby $order
566
+ ", ARRAY_A
567
+ );
568
  }
569
 
570
  $current_page = $this->get_pagenum();
classes/class-GPI-Pagespeed-API.php CHANGED
@@ -34,17 +34,18 @@ class GPI_Pagespeed_API
34
  $this->audits_to_skip = apply_filters( 'GPI_audits_to_skip', array(
35
  'final-screenshot',
36
  'metrics',
37
- 'network-requests'
 
38
  ) );
39
  }
40
 
41
  public function run_pagespeed( $object_url, $options )
42
  {
43
  $query_args = array(
44
- 'url' => $object_url,
45
- 'key' => $this->developer_key,
46
- 'locale' => isset( $options['locale'] ) ? $options['locale'] : 'en_US',
47
- 'strategy' => isset( $options['strategy'] ) ? $options['strategy'] : 'desktop'
48
  );
49
 
50
  $api_url = add_query_arg( $query_args, $this->api_baseurl );
@@ -70,10 +71,10 @@ class GPI_Pagespeed_API
70
  }
71
 
72
  $lab_data[] = array(
73
- 'title' => $result->lighthouseResult->audits->$index->title,
74
- 'description' => $this->parse_markdown_style_links( $result->lighthouseResult->audits->$index->description ),
75
- 'score' => $result->lighthouseResult->audits->$index->score,
76
- 'displayValue' => $result->lighthouseResult->audits->$index->displayValue
77
  );
78
  }
79
 
@@ -86,7 +87,11 @@ class GPI_Pagespeed_API
86
  return $field_data;
87
  }
88
 
89
- return serialize( $result->loadingExperience->metrics );
 
 
 
 
90
  }
91
 
92
  public function get_page_reports( $result, $page_id, $strategy, $options, $page_reports = array() )
@@ -104,17 +109,17 @@ class GPI_Pagespeed_API
104
  continue;
105
  }
106
 
107
- if ( 'screenshot-thumbnails' == $rulename && ! $options['store_screenshots'] ) {
108
  continue;
109
  }
110
 
111
  $page_reports[] = array(
112
- 'page_id' => $page_id,
113
- 'strategy' => $strategy,
114
- 'rule_key' => $rulename,
115
- 'rule_name' => $results_obj->title,
116
- 'rule_score' => $results_obj->score,
117
- 'rule_type' => isset( $results_obj->details->type ) ? $results_obj->details->type : 'n/a',
118
  'rule_blocks' => $this->get_rule_blocks( $results_obj )
119
  );
120
  }
@@ -126,83 +131,89 @@ class GPI_Pagespeed_API
126
  private function get_rule_blocks( $results_obj, $rule_blocks = array() )
127
  {
128
  if ( isset( $results_obj->description ) ) {
129
- $rule_blocks['description'] = $this->parse_markdown_style_links( $results_obj->description );
130
  }
131
 
132
  if ( isset( $results_obj->scoreDisplayMode ) ) {
133
- $rule_blocks['score_display_mode'] = $results_obj->scoreDisplayMode;
134
  }
135
 
136
  if ( isset( $results_obj->displayValue ) ) {
137
- $rule_blocks['display_value'] = $results_obj->displayValue;
138
  } else {
139
  $rule_blocks['display_value'] = '';
140
  }
141
 
142
- $keys_to_number_format = array(
143
- 'url',
144
- 'wastedMs',
145
- 'scriptParseCompile',
146
- 'total',
147
- 'scripting',
148
- 'duration',
149
- 'totalBytes',
150
- 'wastedBytes',
151
- 'cacheLifetimeMs'
152
- );
153
 
154
- if ( isset( $results_obj->details->items ) ) {
155
- foreach ( $results_obj->details->items as $index => $data ) {
156
- foreach ( $data as $key => $value ) {
157
- if ( ! in_array( $key, $keys_to_number_format ) ) {
158
- continue;
159
- }
160
-
161
- if ( 'url' == $key ) {
162
- $value = $this->link_urls( $value );
163
- } else if ( 'cacheLifetimeMs' == $key ) {
164
- $value = $this->human_readable_timing( $value );
165
- } else {
166
- $value = number_format( $value );
167
- }
168
-
169
- $results_obj->details->items[ $index ]->$key = $value;
170
- }
171
- }
172
- }
173
 
174
- if ( isset( $results_obj->details ) ) {
175
- $rule_blocks['details'] = $results_obj->details;
176
  }
177
 
178
  return serialize( $rule_blocks );
179
  }
180
 
181
- private function human_readable_timing( $value )
182
  {
183
- if ( empty( $value ) ) {
184
- return $value;
185
- }
186
-
187
- $time = $value / 1000;
188
-
189
- $tokens = array (
190
- 31536000 => __( 'year', 'gpagespeedi' ),
191
- 2592000 => __( 'month', 'gpagespeedi' ),
192
- 604800 => __( 'week', 'gpagespeedi' ),
193
- 86400 => __( 'day', 'gpagespeedi' ),
194
- 3600 => __( 'hour', 'gpagespeedi' ),
195
- 60 => __( 'minute', 'gpagespeedi' ),
196
- 1 => __( 'second', 'gpagespeedi' )
197
- );
198
-
199
- foreach ( $tokens as $unit => $text ) {
200
- if ( $time < $unit ) {
201
- continue;
202
  }
203
- $number_of_units = floor( $time / $unit );
 
 
 
 
204
 
205
- return $number_of_units . ' ' . $text . ( ( $number_of_units > 1 ) ? _x( 's', 'make preceeding time unit plural', 'gpagespeedi' ) : '' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
  }
208
 
@@ -217,11 +228,19 @@ class GPI_Pagespeed_API
217
  return '<a href="' . $url . '" target="_blank">' . $value . '</a>';
218
  }
219
 
220
- private function parse_markdown_style_links( $string )
221
  {
222
- $replace = '<a href="${2}" target="_blank">${1}</a>';
 
 
 
 
 
 
 
223
 
224
- return preg_replace('/\[(.*?)\]\((.*?)\)/', $replace, $string );
 
225
  }
226
 
227
  }
34
  $this->audits_to_skip = apply_filters( 'GPI_audits_to_skip', array(
35
  'final-screenshot',
36
  'metrics',
37
+ 'network-requests',
38
+ 'main-thread-tasks'
39
  ) );
40
  }
41
 
42
  public function run_pagespeed( $object_url, $options )
43
  {
44
  $query_args = array(
45
+ 'url' => esc_url_raw ( $object_url ),
46
+ 'key' => sanitize_text_field( $this->developer_key ),
47
+ 'locale' => isset( $options['locale'] ) ? sanitize_text_field( $options['locale'] ) : 'en_US',
48
+ 'strategy' => isset( $options['strategy'] ) ? sanitize_text_field( $options['strategy'] ) : 'desktop'
49
  );
50
 
51
  $api_url = add_query_arg( $query_args, $this->api_baseurl );
71
  }
72
 
73
  $lab_data[] = array(
74
+ 'title' => sanitize_text_field( $result->lighthouseResult->audits->$index->title ),
75
+ 'description' => wp_kses_post( $this->parse_markdown( $result->lighthouseResult->audits->$index->description ) ),
76
+ 'score' => floatval( $result->lighthouseResult->audits->$index->score ),
77
+ 'displayValue' => sanitize_text_field( $result->lighthouseResult->audits->$index->displayValue )
78
  );
79
  }
80
 
87
  return $field_data;
88
  }
89
 
90
+ $result = $this->object_to_array( $result->loadingExperience->metrics );
91
+
92
+ array_walk_recursive( $result, [ $this, 'sanitize_recursive' ], 'fielddata' );
93
+
94
+ return serialize( $result );
95
  }
96
 
97
  public function get_page_reports( $result, $page_id, $strategy, $options, $page_reports = array() )
109
  continue;
110
  }
111
 
112
+ if ( 'screenshot-thumbnails' == $rulename && ! (bool) $options['store_screenshots'] ) {
113
  continue;
114
  }
115
 
116
  $page_reports[] = array(
117
+ 'page_id' => intval( $page_id ),
118
+ 'strategy' => sanitize_text_field( $strategy ),
119
+ 'rule_key' => sanitize_key( $rulename ),
120
+ 'rule_name' => wp_kses_data( $this->parse_markdown( $results_obj->title ) ),
121
+ 'rule_score' => floatval( $results_obj->score ),
122
+ 'rule_type' => isset( $results_obj->details->type ) ? sanitize_key( $results_obj->details->type ) : 'n/a',
123
  'rule_blocks' => $this->get_rule_blocks( $results_obj )
124
  );
125
  }
131
  private function get_rule_blocks( $results_obj, $rule_blocks = array() )
132
  {
133
  if ( isset( $results_obj->description ) ) {
134
+ $rule_blocks['description'] = wp_kses_post( $this->parse_markdown( $results_obj->description ) );
135
  }
136
 
137
  if ( isset( $results_obj->scoreDisplayMode ) ) {
138
+ $rule_blocks['score_display_mode'] = sanitize_text_field( $results_obj->scoreDisplayMode );
139
  }
140
 
141
  if ( isset( $results_obj->displayValue ) ) {
142
+ $rule_blocks['display_value'] = sanitize_text_field( $results_obj->displayValue );
143
  } else {
144
  $rule_blocks['display_value'] = '';
145
  }
146
 
147
+ if ( isset( $results_obj->details ) ) {
148
+ $details = $this->object_to_array( $results_obj->details );
 
 
 
 
 
 
 
 
 
149
 
150
+ array_walk_recursive( $details, [ $this, 'sanitize_recursive' ], 'ruleblocks' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
+ $rule_blocks['details'] = $details;
 
153
  }
154
 
155
  return serialize( $rule_blocks );
156
  }
157
 
158
+ private function object_to_array( $obj )
159
  {
160
+ if ( is_object( $obj ) || is_array( $obj ) ) {
161
+ $ret = (array) $obj;
162
+ foreach ( $ret as &$item ) {
163
+ $item = $this->object_to_array( $item );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
+ return $ret;
166
+ } else {
167
+ return $obj;
168
+ }
169
+ }
170
 
171
+ private function sanitize_recursive( &$value, $key, $type )
172
+ {
173
+ switch ( $key ) {
174
+ case 'url':
175
+ $value = wp_kses_post( $value );
176
+ break;
177
+
178
+ case 'report_url':
179
+ case 'URL':
180
+ $value = esc_url_raw( $value );
181
+ break;
182
+
183
+ case 'groupLabel':
184
+ $value = sanitize_text_field( $value );
185
+ break;
186
+
187
+ case 'min':
188
+ case 'max':
189
+ case 'percentile':
190
+ $value = intval( $value );
191
+ break;
192
+
193
+ case 'proportion':
194
+ case 'average':
195
+ $value = floatval( $value );
196
+ break;
197
+
198
+ case 'blockingTime':
199
+ case 'wastedMs':
200
+ case 'score':
201
+ case 'startTime':
202
+ case 'duration':
203
+ case 'total':
204
+ case 'scripting':
205
+ case 'scriptParseCompile':
206
+ $value = floatval( $value );
207
+ break;
208
+
209
+ case 'wastedBytes':
210
+ case 'totalBytes':
211
+ $value = intval( $value );
212
+ break;
213
+
214
+ case 'transferSize':
215
+ $value = intval( $value );
216
+ break;
217
  }
218
  }
219
 
228
  return '<a href="' . $url . '" target="_blank">' . $value . '</a>';
229
  }
230
 
231
+ private function parse_markdown( $string )
232
  {
233
+ // Inline Code Blocks
234
+ $string = preg_replace_callback( '/`(.*?)`/', [ $this, 'markdown_entities' ], $string );
235
+
236
+ // URLs
237
+ $string = preg_replace( '/\[(.*?)\]\((.*?)\)/', '<a href="${2}" target="_blank">${1}</a>', $string );
238
+
239
+ return $string;
240
+ }
241
 
242
+ private function markdown_entities( $matches ) {
243
+ return '<code>' . htmlentities( str_replace( '`', '', $matches[0] ) ) . '</code>';
244
  }
245
 
246
  }
documentation/index.html CHANGED
@@ -91,7 +91,7 @@
91
 
92
  <p><strong>Google often changes the layout and process involved in enabling their APIs and obtaining an API Key</strong>, but the general process stays the same.</p>
93
  <ol>
94
- <li>Login to <a href="http://code.google.com/apis/console" target="_blank">Google API Console</a></li>
95
  <li>Create a new project</li>
96
  <li>Enable the PageSpeed Insights API</li>
97
  <li>Create an API Key</li>
91
 
92
  <p><strong>Google often changes the layout and process involved in enabling their APIs and obtaining an API Key</strong>, but the general process stays the same.</p>
93
  <ol>
94
+ <li>Login to <a href="https://console.developers.google.com/" target="_blank">Google API Console</a></li>
95
  <li>Create a new project</li>
96
  <li>Enable the PageSpeed Insights API</li>
97
  <li>Create an API Key</li>
google-pagespeed-insights.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Insights from Google PageSpeed
4
  Plugin URI: http://mattkeys.me
5
  Description: Get insights from the Google Pagespeed API right in your WordPress dashboard
6
  Author: Matt Keys
7
- Version: 4.0.4
8
  Author URI: http://mattkeys.me
9
  */
10
 
@@ -45,7 +45,7 @@ if ( ! defined( 'GPI_BASENAME' ) ) {
45
 
46
  // Internal version number
47
  if ( ! defined( 'GPI_VERSION' ) ) {
48
- define( 'GPI_VERSION', '4.0.3' );
49
  }
50
 
51
  if ( is_admin() ) {
@@ -53,7 +53,7 @@ if ( is_admin() ) {
53
  require 'classes/class-GPI-Uninstall.php';
54
  require 'classes/class-GPI-Admin.php';
55
 
56
- $doaction = ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) ? $_REQUEST['action'] : false;
57
 
58
  if ( $doaction && ( isset( $_GET['page'] ) && 'google-pagespeed-insights' == $_GET['page'] ) ) {
59
  require 'classes/class-GPI-Actions.php';
4
  Plugin URI: http://mattkeys.me
5
  Description: Get insights from the Google Pagespeed API right in your WordPress dashboard
6
  Author: Matt Keys
7
+ Version: 4.0.5
8
  Author URI: http://mattkeys.me
9
  */
10
 
45
 
46
  // Internal version number
47
  if ( ! defined( 'GPI_VERSION' ) ) {
48
+ define( 'GPI_VERSION', '4.0.5' );
49
  }
50
 
51
  if ( is_admin() ) {
53
  require 'classes/class-GPI-Uninstall.php';
54
  require 'classes/class-GPI-Admin.php';
55
 
56
+ $doaction = ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) ? true : false;
57
 
58
  if ( $doaction && ( isset( $_GET['page'] ) && 'google-pagespeed-insights' == $_GET['page'] ) ) {
59
  require 'classes/class-GPI-Actions.php';
readme.txt CHANGED
@@ -76,7 +76,7 @@ An extended version of the folliowing instructions as well as other documentatio
76
 
77
  Google Pagespeed Insights requires a Google API Key. Keys are free and can be obtained from Google. In order to get a key, you will need a Google account such as a GMail account. If you do not already have a Google account you can create one here: https://accounts.google.com/SignUp.
78
 
79
- 1. Navigate to https://code.google.com/apis/console
80
  2. Login with your Google Account (Create a Google account if you do not have one)
81
  3. Create a new API Key and enable the Google Pagespeed Insights API* (see note about restrictions)
82
  4. Paste your API Key into the Options page of Insights from Google PageSpeed
@@ -85,7 +85,7 @@ Google Pagespeed Insights requires a Google API Key. Keys are free and can be ob
85
 
86
  = Requirements =
87
 
88
- * Google API Key [https://code.google.com/apis/console/](https://code.google.com/apis/console/)
89
  * WordPress 3.6 or Newer
90
 
91
  == Troubleshooting ==
@@ -136,6 +136,11 @@ Google Pagespeed Insights requires a Google API Key. Keys are free and can be ob
136
 
137
  == Changelog ==
138
 
 
 
 
 
 
139
  = 4.0.4 =
140
  * Bugfix improperly escaped data (xss security issue)
141
  * Rename plugin to "Insights from Google PageSpeed"
@@ -230,6 +235,11 @@ Google Pagespeed Insights requires a Google API Key. Keys are free and can be ob
230
 
231
  == Upgrade Notice ==
232
 
 
 
 
 
 
233
  = 4.0.4 =
234
  * Bugfix improperly escaped data (xss security issue)
235
  * Rename plugin to "Insights from Google PageSpeed"
76
 
77
  Google Pagespeed Insights requires a Google API Key. Keys are free and can be obtained from Google. In order to get a key, you will need a Google account such as a GMail account. If you do not already have a Google account you can create one here: https://accounts.google.com/SignUp.
78
 
79
+ 1. Navigate to https://console.developers.google.com/
80
  2. Login with your Google Account (Create a Google account if you do not have one)
81
  3. Create a new API Key and enable the Google Pagespeed Insights API* (see note about restrictions)
82
  4. Paste your API Key into the Options page of Insights from Google PageSpeed
85
 
86
  = Requirements =
87
 
88
+ * Google API Key [https://console.developers.google.com/](https://code.google.com/apis/console/)
89
  * WordPress 3.6 or Newer
90
 
91
  == Troubleshooting ==
136
 
137
  == Changelog ==
138
 
139
+ = 4.0.5 =
140
+ * Bugfix some validation rule reports not showing properly (some results may need to be rechecked to see the fixes)
141
+ * Better styling for readability in report details
142
+ * Additional validating, sanitizing, and escaping the plugin codebase
143
+
144
  = 4.0.4 =
145
  * Bugfix improperly escaped data (xss security issue)
146
  * Rename plugin to "Insights from Google PageSpeed"
235
 
236
  == Upgrade Notice ==
237
 
238
+ = 4.0.5 =
239
+ * Bugfix some validation rule reports not showing properly (some results may need to be rechecked to see the fixes)
240
+ * Better styling for readability in report details
241
+ * Additional validating, sanitizing, and escaping the plugin codebase
242
+
243
  = 4.0.4 =
244
  * Bugfix improperly escaped data (xss security issue)
245
  * Rename plugin to "Insights from Google PageSpeed"
templates/add-custom-urls-bulk.php CHANGED
@@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  ?>
11
 
12
  <form method="post" action="" enctype="multipart/form-data">
13
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
14
  <input type="hidden" name="render" value="add-custom-urls-bulk" />
15
  <input type="hidden" name="action" value="add-custom-urls-bulk" />
16
 
@@ -18,27 +18,27 @@ if ( ! defined( 'ABSPATH' ) ) {
18
 
19
  <div class="framed boxsizing">
20
  <div class="boxheader large">
21
- <span class="left add"><?php _e( 'Bulk Upload Custom URLs', 'gpagespeedi' ); ?></span>
22
  </div>
23
  <div class="padded">
24
 
25
- <p><?php _e( 'Add any valid URL, even from sites outside of WordPress. Upload a properly formatted XML sitemap below to add pages.', 'gpagespeedi' ); ?></p>
26
- <p><?php _e( 'XML must conform to the <a href="http://www.sitemaps.org/protocol.html" target="_blank">sitemaps.org standards</a>. There are free services that can help you generate a sitemap such as', 'gpagespeedi' ); ?> <a href="http://www.xml-sitemaps.com/" target="_blank">http://www.xml-sitemaps.com/</a>.</p>
27
 
28
  <table class="form-table">
29
  <tbody>
30
  <tr valign="top">
31
  <th scope="row">
32
- <label for="custom_url_label"><?php _e( 'Custom URL Label', 'gpagespeedi' ); ?>:</label>
33
  </th>
34
  <td>
35
- <input type="text" maxlength="20" name="custom_url_label" id="custom_url_label" placeholder="Custom Label" class="regular-text code" />
36
- <p class="description"><?php _e( 'Choose a custom label for your new URLs, this will be used later when sorting your reports.', 'gpagespeedi' ); ?><br /><span style="color:red"><?php _e( 'Max 20 Charactors, Alpha-Numeric Only. Spaces will be replaced with underscores', 'gpagespeedi' ); ?></span></p>
37
  </td>
38
  </tr>
39
  <tr valign="top">
40
  <th scope="row">
41
- <label for="xml_sitemap"><?php _e( 'XML Sitemap File', 'gpagespeedi' ); ?>:</label>
42
  </th>
43
  <td>
44
  <input type="file" name="xml_sitemap" id="xml_sitemap" />
@@ -49,5 +49,5 @@ if ( ! defined( 'ABSPATH' ) ) {
49
  <br />
50
  </div>
51
  </div>
52
- <?php submit_button( __( 'Submit Sitemap', 'gpagespeedi' ) ); ?>
53
  </form>
10
  ?>
11
 
12
  <form method="post" action="" enctype="multipart/form-data">
13
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
14
  <input type="hidden" name="render" value="add-custom-urls-bulk" />
15
  <input type="hidden" name="action" value="add-custom-urls-bulk" />
16
 
18
 
19
  <div class="framed boxsizing">
20
  <div class="boxheader large">
21
+ <span class="left add"><?php esc_html_e( 'Bulk Upload Custom URLs', 'gpagespeedi' ); ?></span>
22
  </div>
23
  <div class="padded">
24
 
25
+ <p><?php esc_html_e( 'Add any valid URL, even from sites outside of WordPress. Upload a properly formatted XML sitemap below to add pages.', 'gpagespeedi' ); ?></p>
26
+ <p><?php echo wp_kses_data( __( 'XML must conform to the <a href="http://www.sitemaps.org/protocol.html" target="_blank">sitemaps.org standards</a>. There are free services that can help you generate a sitemap such as', 'gpagespeedi' ) ); ?> <a href="http://www.xml-sitemaps.com/" target="_blank">http://www.xml-sitemaps.com/</a>.</p>
27
 
28
  <table class="form-table">
29
  <tbody>
30
  <tr valign="top">
31
  <th scope="row">
32
+ <label for="custom_url_label"><?php esc_html_e( 'Custom URL Label', 'gpagespeedi' ); ?>:</label>
33
  </th>
34
  <td>
35
+ <input type="text" maxlength="40" name="custom_url_label" id="custom_url_label" placeholder="Custom Label" class="regular-text code" />
36
+ <p class="description"><?php esc_html_e( 'Choose a custom label for your new URLs, this will be used later when sorting your reports.', 'gpagespeedi' ); ?><br /><span style="color:red"><?php esc_html_e( 'Max 40 Charactors, Lowercase alpha-numeric Only. Spaces will be replaced with hyphens', 'gpagespeedi' ); ?></span></p>
37
  </td>
38
  </tr>
39
  <tr valign="top">
40
  <th scope="row">
41
+ <label for="xml_sitemap"><?php esc_html_e( 'XML Sitemap File', 'gpagespeedi' ); ?>:</label>
42
  </th>
43
  <td>
44
  <input type="file" name="xml_sitemap" id="xml_sitemap" />
49
  <br />
50
  </div>
51
  </div>
52
+ <?php submit_button( esc_html__( 'Submit Sitemap', 'gpagespeedi' ) ); ?>
53
  </form>
templates/add-custom-urls.php CHANGED
@@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
10
  ?>
11
 
12
  <form method="post" action="">
13
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
14
  <input type="hidden" name="render" value="add-custom-urls" />
15
  <input type="hidden" name="action" value="add-custom-urls" />
16
 
@@ -18,26 +18,26 @@ if ( ! defined( 'ABSPATH' ) ) {
18
 
19
  <div class="framed boxsizing">
20
  <div class="boxheader large">
21
- <span class="left add"><?php _e( 'Add Custom URLs', 'gpagespeedi' ); ?></span>
22
  </div>
23
  <div class="padded">
24
 
25
- <p><?php _e( 'Add any valid URL, even from sites outside of WordPress. Enter up to 10 URLs below. If you need to enter a lot of URLs check out the', 'gpagespeedi' ); ?> <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ) ;?>&amp;render=add-custom-urls-bulk"><?php _e( 'Bulk URL uploader', 'gpagespeedi' ); ?></a>.</p>
26
 
27
  <table class="form-table">
28
  <tbody>
29
  <tr valign="top">
30
  <th scope="row">
31
- <label for="custom_url_label"><?php _e( 'Custom URL Label', 'gpagespeedi' ); ?>:</label>
32
  </th>
33
  <td>
34
- <input type="text" maxlength="20" name="custom_url_label" id="custom_url_label" placeholder="Custom Label" class="regular-text code" />
35
- <p class="description"><?php _e( 'Choose a custom label for your new URLs, this will be used later when sorting your reports.', 'gpagespeedi' ); ?><br /><span style="color:red"><?php _e( 'Max 20 Charactors, Alpha-Numeric Only. Spaces will be replaced with underscores', 'gpagespeedi' ); ?></span></p>
36
  </td>
37
  </tr>
38
  <tr valign="top">
39
  <th scope="row">
40
- <label ><?php _e( 'Custom URLs', 'gpagespeedi' ); ?>:</label>
41
  </th>
42
  <td>
43
  <?php
@@ -54,5 +54,5 @@ if ( ! defined( 'ABSPATH' ) ) {
54
  <br />
55
  </div>
56
  </div>
57
- <?php submit_button( __( 'Submit URLs', 'gpagespeedi' ) ); ?>
58
  </form>
10
  ?>
11
 
12
  <form method="post" action="">
13
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
14
  <input type="hidden" name="render" value="add-custom-urls" />
15
  <input type="hidden" name="action" value="add-custom-urls" />
16
 
18
 
19
  <div class="framed boxsizing">
20
  <div class="boxheader large">
21
+ <span class="left add"><?php esc_html_e( 'Add Custom URLs', 'gpagespeedi' ); ?></span>
22
  </div>
23
  <div class="padded">
24
 
25
+ <p><?php esc_html_e( 'Add any valid URL, even from sites outside of WordPress. Enter up to 10 URLs below. If you need to enter a lot of URLs check out the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=add-custom-urls-bulk"><?php esc_html_e( 'Bulk URL uploader', 'gpagespeedi' ); ?></a>.</p>
26
 
27
  <table class="form-table">
28
  <tbody>
29
  <tr valign="top">
30
  <th scope="row">
31
+ <label for="custom_url_label"><?php esc_html_e( 'Custom URL Label', 'gpagespeedi' ); ?>:</label>
32
  </th>
33
  <td>
34
+ <input type="text" maxlength="40" name="custom_url_label" id="custom_url_label" placeholder="Custom Label" class="regular-text code" />
35
+ <p class="description"><?php esc_html_e( 'Choose a custom label for your new URLs, this will be used later when sorting your reports.', 'gpagespeedi' ); ?><br /><span style="color:red"><?php esc_html_e( 'Max 40 Charactors, Lowercase alpha-numeric Only. Spaces will be replaced with hyphens', 'gpagespeedi' ); ?></span></p>
36
  </td>
37
  </tr>
38
  <tr valign="top">
39
  <th scope="row">
40
+ <label ><?php esc_html_e( 'Custom URLs', 'gpagespeedi' ); ?>:</label>
41
  </th>
42
  <td>
43
  <?php
54
  <br />
55
  </div>
56
  </div>
57
+ <?php submit_button( esc_html__( 'Submit URLs', 'gpagespeedi' ) ); ?>
58
  </form>
templates/custom-urls.php CHANGED
@@ -14,7 +14,7 @@ $GPI_List_Table->prepare_items();
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
18
  <input type="hidden" name="render" value="custom-urls" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
18
  <input type="hidden" name="render" value="custom-urls" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
templates/details.php CHANGED
@@ -11,32 +11,32 @@ if ( ! defined( 'ABSPATH' ) ) {
11
 
12
  <h3 id="url" class="subTitle"></h3>
13
  <div class="toolbar">
14
- <a id="view_url" class="button-gpi view" target="_blank"><?php _e( 'View Page', 'gpagespeedi' ); ?></a>
15
- <a id="recheck_url" class="button-gpi recheck"><?php _e( 'Recheck Results', 'gpagespeedi' ); ?></a>
16
  </div>
17
 
18
  <div class="row">
19
  <div class="top-row boxsizing pagespeed_gauge_wrapper" id="pagespeed_gauge_wrapper">
20
  <div class="score_chart_div" id="score_chart_div">
21
- <img class="pagespeed_needle" id="pagespeed_needle" src="<?php echo GPI_PUBLIC_PATH; ?>assets/images/pagespeed_gauge_needle.png" width="204" height="204" alt="" />
22
- <div class="score_text" id="score_text"><span class="score"></span><span class="label"><?php _e( 'score', 'gpagespeedi' ); ?></span></div>
23
  </div>
24
  </div>
25
  <div class="top-row boxsizing framed pagespeed_lab_data_wrapper" id="pagespeed_lab_data_wrapper">
26
  <div class="boxheader">
27
- <span class="left"><?php _e('Lab Data', 'gpagespeedi'); ?></span>
28
- <span class="right"><?php _e( 'Value', 'gpagespeedi' ); ?></span>
29
  </div>
30
  <table class="stats">
31
  <tr class="last_checked">
32
- <td class="leftcol"><?php _e( 'Last Checked', 'gpagespeedi' ); ?></td>
33
  <td class="rightcol"></td>
34
  </tr>
35
  </table>
36
  </div>
37
  <div class="top-row boxsizing framed pagespeed_field_data_wrapper" id="pagespeed_field_data_wrapper">
38
  <div class="boxheader">
39
- <span class="left"><?php _e( 'Field Data', 'gpagespeedi' ); ?></span>
40
  </div>
41
  <div class="chart_data">
42
  <div id="FCP"></div>
@@ -47,28 +47,30 @@ if ( ! defined( 'ABSPATH' ) ) {
47
 
48
  <div class="row boxsizing framed screenshots">
49
  <div class="boxheader">
50
- <span class="left"><?php _e( 'Loading Screenshots', 'gpagespeedi' ); ?></span><span class="light"><?php _e( '(Hover for timestamp)', 'gpagespeedi' ); ?></span>
51
  </div>
52
  <div class="inner screenshots" id="screenshots"></div>
53
  </div>
54
  <div class="row boxsizing framed lighthouse opportunities">
55
  <div class="boxheader">
56
- <span class="left"><?php _e( 'Opportunities for improvement', 'gpagespeedi' ); ?></span><span class="light"><?php _e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
57
- <span class="right"><?php _e( 'Estimated Savings', 'gpagespeedi' ); ?></span>
58
  </div>
59
  <div class="inner opportunities accordion" id="opportunities"></div>
60
  </div>
61
  <div class="row boxsizing framed lighthouse diagnostics">
62
  <div class="boxheader">
63
- <span class="left"><?php _e( 'Diagnostics', 'gpagespeedi' ); ?></span><span class="light"><?php _e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
64
  </div>
65
  <div class="inner diagnostics accordion" id="diagnostics"></div>
66
  </div>
67
  <div class="row boxsizing framed lighthouse passed-audits">
68
  <div class="boxheader">
69
- <span class="left"><?php _e( 'Passed Audits', 'gpagespeedi' ); ?></span><span class="light"><?php _e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
70
- <span class="right"><span id="passed_audits_count"></span> <?php _e( 'audits', 'gpagespeedi' ); ?></span>
71
 
72
  </div>
73
  <div class="inner passed-audits accordion" id="passed_audits"></div>
74
- </div>
 
 
11
 
12
  <h3 id="url" class="subTitle"></h3>
13
  <div class="toolbar">
14
+ <a id="view_url" class="button-gpi view" target="_blank"><?php esc_html_e( 'View Page', 'gpagespeedi' ); ?></a>
15
+ <a id="recheck_url" class="button-gpi recheck"><?php esc_html_e( 'Recheck Results', 'gpagespeedi' ); ?></a>
16
  </div>
17
 
18
  <div class="row">
19
  <div class="top-row boxsizing pagespeed_gauge_wrapper" id="pagespeed_gauge_wrapper">
20
  <div class="score_chart_div" id="score_chart_div">
21
+ <img class="pagespeed_needle" id="pagespeed_needle" src="<?php echo esc_url( GPI_PUBLIC_PATH . 'assets/images/pagespeed_gauge_needle.png' ); ?>" width="204" height="204" alt="" />
22
+ <div class="score_text" id="score_text"><span class="score"></span><span class="label"><?php esc_html_e( 'score', 'gpagespeedi' ); ?></span></div>
23
  </div>
24
  </div>
25
  <div class="top-row boxsizing framed pagespeed_lab_data_wrapper" id="pagespeed_lab_data_wrapper">
26
  <div class="boxheader">
27
+ <span class="left"><?php esc_html_e('Lab Data', 'gpagespeedi'); ?></span>
28
+ <span class="right"><?php esc_html_e( 'Value', 'gpagespeedi' ); ?></span>
29
  </div>
30
  <table class="stats">
31
  <tr class="last_checked">
32
+ <td class="leftcol"><?php esc_html_e( 'Last Checked', 'gpagespeedi' ); ?></td>
33
  <td class="rightcol"></td>
34
  </tr>
35
  </table>
36
  </div>
37
  <div class="top-row boxsizing framed pagespeed_field_data_wrapper" id="pagespeed_field_data_wrapper">
38
  <div class="boxheader">
39
+ <span class="left"><?php esc_html_e( 'Field Data', 'gpagespeedi' ); ?></span>
40
  </div>
41
  <div class="chart_data">
42
  <div id="FCP"></div>
47
 
48
  <div class="row boxsizing framed screenshots">
49
  <div class="boxheader">
50
+ <span class="left"><?php esc_html_e( 'Loading Screenshots', 'gpagespeedi' ); ?></span><span class="light"><?php esc_html_e( '(Hover for timestamp)', 'gpagespeedi' ); ?></span>
51
  </div>
52
  <div class="inner screenshots" id="screenshots"></div>
53
  </div>
54
  <div class="row boxsizing framed lighthouse opportunities">
55
  <div class="boxheader">
56
+ <span class="left"><?php esc_html_e( 'Opportunities for improvement', 'gpagespeedi' ); ?></span><span class="light"><?php esc_html_e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
57
+ <span class="right"><?php esc_html_e( 'Estimated Savings', 'gpagespeedi' ); ?></span>
58
  </div>
59
  <div class="inner opportunities accordion" id="opportunities"></div>
60
  </div>
61
  <div class="row boxsizing framed lighthouse diagnostics">
62
  <div class="boxheader">
63
+ <span class="left"><?php esc_html_e( 'Diagnostics', 'gpagespeedi' ); ?></span><span class="light"><?php esc_html_e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
64
  </div>
65
  <div class="inner diagnostics accordion" id="diagnostics"></div>
66
  </div>
67
  <div class="row boxsizing framed lighthouse passed-audits">
68
  <div class="boxheader">
69
+ <span class="left"><?php esc_html_e( 'Passed Audits', 'gpagespeedi' ); ?></span><span class="light"><?php esc_html_e( '(Click for detailed report)', 'gpagespeedi' ); ?></span>
70
+ <span class="right"><span id="passed_audits_count"></span> <?php esc_html_e( 'audits', 'gpagespeedi' ); ?></span>
71
 
72
  </div>
73
  <div class="inner passed-audits accordion" id="passed_audits"></div>
74
+ </div>
75
+
76
+ <?php include GPI_DIRECTORY . '/templates/parts/nitropack.php'; ?>
templates/ignored-urls.php CHANGED
@@ -14,7 +14,7 @@ $GPI_List_Table->prepare_items();
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
18
  <input type="hidden" name="render" value="ignored-urls" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
18
  <input type="hidden" name="render" value="ignored-urls" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
templates/logs.php CHANGED
@@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
9
 
10
  ?>
11
 
12
- <p><?php _e( 'Error logs are kept for up to 7 days before being erased automatically.', 'gpagespeedi' ); ?></p>
13
 
14
  <?php
15
  $error_logs = apply_filters( 'gpi_error_logs', array() );
@@ -18,12 +18,12 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  <table class="widefat error_logs">
19
  <thead>
20
  <tr>
21
- <td style="width: 200px;"><?php _e( 'URL', 'gpagespeedi' ); ?></td>
22
- <td><?php _e( 'Strategy', 'gpagespeedi' ); ?></td>
23
- <td><?php _e( 'Report Update?', 'gpagespeedi' ); ?></td>
24
- <td><?php _e( 'Type', 'gpagespeedi' ); ?></td>
25
- <td style="width: 100px;"><?php _e( 'Timestamp', 'gpagespeedi' ); ?></td>
26
- <td><?php _e( 'Error(s)', 'gpagespeedi' ); ?></td>
27
  </tr>
28
  </thead>
29
  <tbody>
@@ -34,24 +34,24 @@ if ( ! defined( 'ABSPATH' ) ) {
34
  $errors = maybe_unserialize( $error_log['error'] );
35
  ?>
36
  <tr>
37
- <td><a href="<?php echo $error_log['URL']; ?>"><?php echo $error_log['URL']; ?></a></td>
38
- <td><?php echo $error_log['strategy']; ?></td>
39
  <td><?php echo $update; ?></td>
40
- <td><?php echo $error_log['type']; ?></td>
41
- <td><?php echo date_i18n( 'M d g:ia', $error_log['timestamp'] ); ?></td>
42
  <td>
43
  <?php
44
  if ( isset( $errors[0] ) && is_array( $errors ) ) :
45
  foreach ( $errors[0] as $key => $error ) :
46
  ?>
47
  <p>
48
- <strong><?php echo $key; ?>:</strong>
49
- <?php echo $error; ?>
50
  </p>
51
  <?php
52
  endforeach;
53
  else :
54
- echo $errors;
55
  endif;
56
  ?>
57
  </td>
@@ -60,7 +60,7 @@ if ( ! defined( 'ABSPATH' ) ) {
60
  endforeach;
61
  else :
62
  ?>
63
- <td><?php _e( 'No error logs found.', 'gpagespeedi' ); ?></td>
64
  <?php
65
  endif;
66
  ?>
9
 
10
  ?>
11
 
12
+ <p><?php esc_html_e( 'Error logs are kept for up to 7 days before being erased automatically.', 'gpagespeedi' ); ?></p>
13
 
14
  <?php
15
  $error_logs = apply_filters( 'gpi_error_logs', array() );
18
  <table class="widefat error_logs">
19
  <thead>
20
  <tr>
21
+ <td style="width: 200px;"><?php esc_html_e( 'URL', 'gpagespeedi' ); ?></td>
22
+ <td><?php esc_html_e( 'Strategy', 'gpagespeedi' ); ?></td>
23
+ <td><?php esc_html_e( 'Report Update?', 'gpagespeedi' ); ?></td>
24
+ <td><?php esc_html_e( 'Type', 'gpagespeedi' ); ?></td>
25
+ <td style="width: 100px;"><?php esc_html_e( 'Timestamp', 'gpagespeedi' ); ?></td>
26
+ <td><?php esc_html_e( 'Error(s)', 'gpagespeedi' ); ?></td>
27
  </tr>
28
  </thead>
29
  <tbody>
34
  $errors = maybe_unserialize( $error_log['error'] );
35
  ?>
36
  <tr>
37
+ <td><a target="_blank" href="<?php echo esc_url( $error_log['URL'] ); ?>"><?php echo esc_url( $error_log['URL'] ); ?></a></td>
38
+ <td><?php echo esc_html( $error_log['strategy'] ); ?></td>
39
  <td><?php echo $update; ?></td>
40
+ <td><?php echo esc_html( $error_log['type'] ); ?></td>
41
+ <td><?php echo esc_html( date_i18n( 'M d g:ia', $error_log['timestamp'] ) ); ?></td>
42
  <td>
43
  <?php
44
  if ( isset( $errors[0] ) && is_array( $errors ) ) :
45
  foreach ( $errors[0] as $key => $error ) :
46
  ?>
47
  <p>
48
+ <strong><?php echo esc_html( $key ); ?>:</strong>
49
+ <?php echo esc_html( $error ); ?>
50
  </p>
51
  <?php
52
  endforeach;
53
  else :
54
+ echo esc_html( $errors );
55
  endif;
56
  ?>
57
  </td>
60
  endforeach;
61
  else :
62
  ?>
63
+ <td><?php esc_html_e( 'No error logs found.', 'gpagespeedi' ); ?></td>
64
  <?php
65
  endif;
66
  ?>
templates/options.php CHANGED
@@ -12,15 +12,15 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  <form method="post" action="">
13
  <div class="row framed boxsizing">
14
  <div class="boxheader large toggle">
15
- <span class="left google"><?php _e( 'Google Pagespeed Options', 'gpagespeedi' ); ?></span>
16
  <span class="right open"></span>
17
  </div>
18
  <div class="padded">
19
- <p><?php _e( 'Google API Key:', 'gpagespeedi' ); ?></p>
20
- <input type="text" name="google_developer_key" id="google_developer_key" value="<?php echo $this->gpi_options['google_developer_key']; ?>" class="googleapi code" />
21
- <p class="description"><span style="color:red;"><?php _e( 'This is required', 'gpagespeedi' ); ?></span>: <?php _e( 'if you do not have an API key you can create a new one for free from', 'gpagespeedi' ); ?>: <a href="https://console.developers.google.com" target="_blank">https://console.developers.google.com</a>. <?php _e( 'Read the documentation included with this plugin or <a href="http://mattkeys.me/documentation/google-pagespeed-insights/#required_configuration" target="_blank">online</a> for additional information about creating an API key.', 'gpagespeedi' ); ?></p>
22
 
23
- <p><?php _e( 'Google Response Language:', 'gpagespeedi' ); ?></p>
24
  <select name="response_language" id="response_language">
25
  <option value="ar" <?php selected( $this->gpi_options['response_language'], 'ar' ); ?>>Arabic</option>
26
  <option value="bg" <?php selected( $this->gpi_options['response_language'], 'bg' ); ?>>Bulgarian</option>
@@ -63,79 +63,79 @@ if ( ! defined( 'ABSPATH' ) ) {
63
  <option value="uk" <?php selected( $this->gpi_options['response_language'], 'uk' ); ?>>Ukrainian</option>
64
  <option value="vi" <?php selected( $this->gpi_options['response_language'], 'vi' ); ?>>Vietnamese</option>
65
  </select>
66
- <?php if ( $this->gpi_options['first_run_complete'] ) : ?>
67
- <p class="description"><span style="color:red;"><?php _e( 'Note', 'gpagespeedi' ); ?></span>: <?php _e( 'URLs must be rechecked before language changes take effect. Use the "Delete Data" option under "Advanced Configuration" if you would like to remove old reports.', 'gpagespeedi' ); ?></p>
68
  <?php endif; ?>
69
 
70
- <p><?php _e( 'Report Type(s):', 'gpagespeedi' ); ?></p>
71
  <select name="strategy" id="strategy">
72
- <option value="desktop" <?php selected( $this->gpi_options['strategy'], 'desktop' ); ?>><?php _e( 'Desktop', 'gpagespeedi' ); ?></option>
73
- <option value="mobile" <?php selected( $this->gpi_options['strategy'], 'mobile' ); ?>><?php _e( 'Mobile', 'gpagespeedi' ); ?></option>
74
- <option value="both" <?php selected( $this->gpi_options['strategy'], 'both' ); ?>><?php _e( 'Both', 'gpagespeedi' ); ?></option>
75
  </select>
76
 
77
- <p><?php _e( 'Store Page Load Screenshots:', 'gpagespeedi' ); ?></p>
78
  <select name="store_screenshots" id="store_screenshots">
79
- <option value="0" <?php selected( $this->gpi_options['store_screenshots'], 0 ); ?>><?php _e( 'No', 'gpagespeedi' ); ?></option>
80
- <option value="1" <?php selected( $this->gpi_options['store_screenshots'], 1 ); ?>><?php _e( 'Yes', 'gpagespeedi' ); ?></option>
81
  </select>
82
- <p class="description"><span style="color:red;"><?php _e( 'Note', 'gpagespeedi' ); ?></span>: <?php _e( 'Screenshots stored in the database will usually take up around 50kb ~ 150kb per page report. If you have many pages to report on this may consume an unreasonable amount of space. Changes to this value will take effect on future report scans.', 'gpagespeedi' ); ?></p>
83
  </div>
84
  </div>
85
 
86
  <div class="row framed boxsizing">
87
  <div class="boxheader large toggle">
88
- <span class="left cal"><?php _e( 'Scheduling and URL Configuration', 'gpagespeedi' ); ?></span>
89
  <span class="right"></span>
90
  </div>
91
  <div class="padded hidden">
92
 
93
- <p><h4><?php _e( 'Choose wether or not Google Pagespeed Insights should automatically re-check page scores, and if so, how often.', 'gpagespeedi' ); ?></h4></p>
94
  <p class="checkbx">
95
  <input type="checkbox" name="use_schedule" id="use_schedule" <?php checked( $this->gpi_options['use_schedule'] ); ?>/>
96
- <label for="use_schedule"><?php _e( 'Automatically re-check Pagespeed Insights scores using a schedule', 'gpagespeedi' ); ?></label>
97
  <?php if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) : ?>
98
- <p class="description"><strong><?php _e( 'Notice', 'gpagespeedi' ); ?>:</strong> <?php _e( 'The WP Cron service this plugin uses to check pages is disabled. Hosting providers often disable the WP Cron service and run their own manual Cron service on an interval of their choosing. Contact your hosting provider if scheduled checks fail to run.', 'gpagespeedi' ); ?></p>
99
  <?php endif; ?>
100
  </p>
101
 
102
- <p><label for="recheck_interval"><?php _e( 'Report Expiration / Recheck Interval', 'gpagespeedi' ); ?>:</label></p>
103
  <select name="recheck_interval" id="recheck_interval">
104
- <option value="<?php echo DAY_IN_SECONDS;?>" <?php selected( $this->gpi_options['recheck_interval'], DAY_IN_SECONDS ); ?>><?php _e( '1 Day', 'gpagespeedi' ); ?></option>
105
- <option value="<?php echo WEEK_IN_SECONDS;?>" <?php selected( $this->gpi_options['recheck_interval'], WEEK_IN_SECONDS ); ?>><?php _e( '7 Days', 'gpagespeedi' ); ?></option>
106
- <option value="<?php echo MONTH_IN_SECONDS / 2;?>" <?php selected( $this->gpi_options['recheck_interval'], MONTH_IN_SECONDS / 2 ); ?>><?php _e( '15 Days', 'gpagespeedi' ); ?></option>
107
- <option value="<?php echo MONTH_IN_SECONDS;?>" <?php selected( $this->gpi_options['recheck_interval'], MONTH_IN_SECONDS ); ?>><?php _e( '30 Days', 'gpagespeedi' ); ?></option>
108
  </select>
109
- <p class="description"><?php _e( 'When page reporting is running, pages which are newer than the specified Report Expiration will be skipped.', 'gpagespeedi' ) . '<br />' . __( 'If "Automatically re-check Pagespeed Insights scores" is checked above, this option will control its frequency.', 'gpagespeedi' ); ?></p>
110
 
111
  <?php
112
  $timestamp = wp_next_scheduled( 'googlepagespeedinsightsworker' );
113
  if ( $timestamp ) {
114
  ?>
115
- <p><strong><?php _e( 'Next Scheduled Check', 'gpagespeedi' ); ?></strong>: <?php echo get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $timestamp ), 'F, d @ g:i a' ); ?></p>
116
  <?php
117
  }
118
  ?>
119
 
120
  <hr>
121
- <p><h4><?php _e( 'Configure which types of URLs should be checked when running reports.', 'gpagespeedi' ); ?></h4></p>
122
- <p><span style="color:red;"><?php _e( 'Note', 'gpagespeedi' ); ?></span>: <?php _e( 'Google Pagespeed will load each page to generate a report. The more pages you select, the longer it will take for the scan to complete.', 'gpagespeedi' ); ?></p>
123
  <p class="checkbx">
124
  <input type="checkbox" name="check_pages" id="check_pages" <?php checked( $this->gpi_options['check_pages'] ); ?>/>
125
- <label for="check_pages"><?php _e( 'Check Wordpress Pages', 'gpagespeedi' ); ?> (<?php echo wp_count_posts( 'page' )->publish; ?>)</label>
126
  </p>
127
  <p class="checkbx">
128
  <input type="checkbox" name="check_posts" id="check_posts" <?php checked( $this->gpi_options['check_posts'] ); ?>/>
129
- <label for="check_posts"><?php _e( 'Check Wordpress Posts', 'gpagespeedi' ); ?> (<?php echo wp_count_posts( 'post' )->publish; ?>)</label>
130
  </p>
131
  <p class="checkbx">
132
  <input type="checkbox" name="check_categories" id="check_categories" <?php checked( $this->gpi_options['check_categories'] ); ?>/>
133
- <label for="check_categories"><?php _e( 'Check Category Indexes', 'gpagespeedi' ); ?> (<?php echo count( get_categories() ) ?>)</label>
134
  </p>
135
 
136
  <p class="checkbx">
137
  <input type="checkbox" name="check_custom_urls" id="check_custom_urls" <?php checked( $this->gpi_options['check_custom_urls'] ); ?>/>
138
- <label for="check_custom_urls"><?php _e( 'Check Custom URLs', 'gpagespeedi' ); ?> (<?php echo $custom_urls_count = apply_filters( 'gpi_custom_urls_count', 0 ); ?>)</label>
139
  </p>
140
 
141
  <?php
@@ -143,7 +143,7 @@ if ( ! defined( 'ABSPATH' ) ) {
143
  if ( ! empty( $custom_post_types ) ) :
144
  ?>
145
  <p class="checkbx">
146
- <?php _e( 'Custom Post Types', 'gpagespeedi' ); ?>:
147
  </p>
148
 
149
  <div class="padded" style="padding-top: 0px;">
@@ -151,8 +151,8 @@ if ( ! defined( 'ABSPATH' ) ) {
151
  foreach ( $custom_post_types as $custom_post_type ) :
152
  ?>
153
  <p class="checkbx posttypes">
154
- <input type="checkbox" name="cpt_whitelist[]" id="cpt_<?php echo $custom_post_type['value']; ?>" value="<?php echo $custom_post_type['value']; ?>" <?php if ( $custom_post_type['checked'] ) { echo 'checked="checked"'; } ?> />
155
- <label for="cpt_<?php echo $custom_post_type['value']; ?>"><?php echo $custom_post_type['value']; ?> (<?php echo $custom_post_type['count']; ?>)</label>
156
  </p>
157
  <?php
158
  endforeach;
@@ -166,84 +166,84 @@ if ( ! defined( 'ABSPATH' ) ) {
166
 
167
  <div class="row framed boxsizing">
168
  <div class="boxheader large toggle">
169
- <span class="left gear"><?php _e( 'Advanced Configuration', 'gpagespeedi' ); ?></span>
170
  <span class="right"></span>
171
  </div>
172
  <div class="padded hidden">
173
- <p><?php _e( 'For most users, the following settings can be left at their defaults unless otherwise instructed by support.', 'gpagespeedi' ); ?></p>
174
 
175
- <p><label for="max_execution_time"><?php _e( 'Maximum Execution Time', 'gpagespeedi' ); ?>:</label></p>
176
  <select name="max_execution_time" id="max_execution_time">
177
- <option value="60" <?php selected( $this->gpi_options['max_execution_time'], 60 ); ?>><?php _e( '1 Minute', 'gpagespeedi' ); ?></option>
178
- <option value="300" <?php selected( $this->gpi_options['max_execution_time'], 300 ); ?>><?php _e( '5 Minutes', 'gpagespeedi' ); ?></option>
179
- <option value="600" <?php selected( $this->gpi_options['max_execution_time'], 600 ); ?>><?php _e( '10 Minutes', 'gpagespeedi' ); ?></option>
180
- <option value="900" <?php selected( $this->gpi_options['max_execution_time'], 900 ); ?>><?php _e( '15 Minutes', 'gpagespeedi' ); ?></option>
181
- <option value="1800" <?php selected( $this->gpi_options['max_execution_time'], 1800 ); ?>><?php _e( '30 Minutes', 'gpagespeedi' ); ?></option>
182
  </select>
183
- <p class="description"><?php _e( 'The default value of 5 minutes is fine for most sites.', 'gpagespeedi' ); ?> <?php _e( 'Increasing this value may help if your page reports do not finish completely.', 'gpagespeedi' ); ?></p>
184
  <?php if ( apply_filters( 'gpi_set_time_limit_disabled', false ) ) : ?>
185
- <p class="description"><span style="color:red;"><?php _e( 'Notice', 'gpagespeedi' ); ?>:</span> <?php _e( 'We have detected that your server may not allow the maximum execution time to be overridden by this plugin. If you experience problems with pagespeed report scans failing to complete, contact your hosting provider. Default Maximum Execution Time: ', 'gpagespeedi' ); ?> <strong><?php echo ini_get( 'max_execution_time' ) . ' ' . __( 'seconds', 'gpagespeedi' ); ?></strong></p>
186
  <?php endif; ?>
187
 
188
- <p><label for="max_run_time"><?php _e( 'Maximum Script Run Time', 'gpagespeedi' ); ?>:</label></p>
189
  <select name="max_run_time" id="max_run_time">
190
- <option value="0" <?php selected( $this->gpi_options['max_run_time'], 0 ); ?>><?php _e( 'No Limit', 'gpagespeedi' ); ?></option>
191
- <option value="15" <?php selected( $this->gpi_options['max_run_time'], 15 ); ?>><?php _e( '15 Seconds', 'gpagespeedi' ); ?></option>
192
- <option value="30" <?php selected( $this->gpi_options['max_run_time'], 30 ); ?>><?php _e( '30 Seconds', 'gpagespeedi' ); ?></option>
193
- <option value="45" <?php selected( $this->gpi_options['max_run_time'], 45 ); ?>><?php _e( '45 Seconds', 'gpagespeedi' ); ?></option>
194
- <option value="60" <?php selected( $this->gpi_options['max_run_time'], 60 ); ?>><?php _e( '60 Seconds', 'gpagespeedi' ); ?></option>
195
- <option value="90" <?php selected( $this->gpi_options['max_run_time'], 90 ); ?>><?php _e( '90 Seconds', 'gpagespeedi' ); ?></option>
196
- <option value="120" <?php selected( $this->gpi_options['max_run_time'], 120 ); ?>><?php _e( '120 Seconds', 'gpagespeedi' ); ?></option>
197
- <option value="150" <?php selected( $this->gpi_options['max_run_time'], 150 ); ?>><?php _e( '150 Seconds', 'gpagespeedi' ); ?></option>
198
- <option value="180" <?php selected( $this->gpi_options['max_run_time'], 180 ); ?>><?php _e( '180 Seconds', 'gpagespeedi' ); ?></option>
199
  </select>
200
  <p class="description">
201
- <?php _e( 'Some web hosting providers have limits on script runtime that cannot be overridden. If your scans do not finish completely and changing the Maximum Execution Time does not resolve the problem, this setting may help. Once the specified run time is reached a new scan process will automatically start.', 'gpagespeedi' ); ?>
202
- <?php _e( 'It is best to find the largest value that still allows the script to complete successfully. Test first at 30 seconds, then raise the value to 45 if your test is successful. Continue until you find the maximum runtime your host allows.', 'gpagespeedi' ); ?>
203
  </p>
204
 
205
- <p><label for="sleep_time"><?php _e( 'Report Throttling Delay Time', 'gpagespeedi' ); ?>:</label></p>
206
  <select name="sleep_time" id="sleep_time">
207
- <option value="0" <?php selected( $this->gpi_options['sleep_time'], 0 ); ?>><?php _e( '0 Seconds', 'gpagespeedi' ); ?></option>
208
- <option value="1" <?php selected( $this->gpi_options['sleep_time'], 1 ); ?>><?php _e( '1 Seconds', 'gpagespeedi' ); ?></option>
209
- <option value="2" <?php selected( $this->gpi_options['sleep_time'], 2 ); ?>><?php _e( '2 Seconds', 'gpagespeedi' ); ?></option>
210
- <option value="3" <?php selected( $this->gpi_options['sleep_time'], 3 ); ?>><?php _e( '3 Seconds', 'gpagespeedi' ); ?></option>
211
- <option value="4" <?php selected( $this->gpi_options['sleep_time'], 4 ); ?>><?php _e( '4 Seconds', 'gpagespeedi' ); ?></option>
212
- <option value="5" <?php selected( $this->gpi_options['sleep_time'], 5 ); ?>><?php _e( '5 Seconds', 'gpagespeedi' ); ?></option>
213
- <option value="10" <?php selected( $this->gpi_options['sleep_time'], 10 ); ?>><?php _e( '10 Seconds', 'gpagespeedi' ); ?></option>
214
  </select>
215
  <p class="description">
216
- <?php _e( 'The default value of 0 seconds is fine for most sites.', 'gpagespeedi' ); ?>
217
  <br />
218
- <?php _e( 'Raising this value will slow down page reporting, but may help provide more accurate reports on poorly performing web servers', 'gpagespeedi' ); ?>
219
  </p>
220
 
221
- <p><label for="heartbeat"><?php _e( 'Report Status Indicator Refresh Rate', 'gpagespeedi' ); ?>:</label></p>
222
  <select name="heartbeat" id="heartbeat">
223
- <option value="fast" <?php selected( $this->gpi_options['heartbeat'], 'fast' ); ?>><?php _e( 'Fast', 'gpagespeedi' ); ?></option>
224
- <option value="standard" <?php selected( $this->gpi_options['heartbeat'], 'standard' ); ?>><?php _e( 'Standard' ); ?></option>
225
- <option value="slow" <?php selected( $this->gpi_options['heartbeat'], 'slow' ); ?>><?php _e( 'Slow', 'gpagespeedi' ); ?></option>
226
- <option value="disabled" <?php selected( $this->gpi_options['heartbeat'], 'disabled' ); ?>><?php _e( 'Disabled - manually refresh pages to update status', 'gpagespeedi' ); ?></option>
227
  </select>
228
  <p class="description">
229
- <?php _e( 'The default value of "Fast" is fine for most sites.', 'gpagespeedi' ); ?>
230
  <br />
231
- <?php _e( 'More frequent updates may impact Pagespeed reports on poorly performing servers, reduce the rate if you are experiencing issues.', 'gpagespeedi' ); ?>
232
  </p>
233
 
234
  <p class="checkbx">
235
  <input type="checkbox" name="log_api_errors" id="log_api_errors" <?php checked( $this->gpi_options['log_api_errors'] ); ?>/>
236
- <label for="log_api_errors"><?php _e( 'Log API Exceptions', 'gpagespeedi' ); ?></label>
237
  </p>
238
- <p class="description"><?php _e( 'API error logs will be stored for up to 7 days.', 'gpagespeedi' ); ?> <a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&amp;render=logs"><?php _e( 'View Logs', 'gpagespeedi' ); ?></a></p>
239
 
240
- <p><label for="sleep_time"><?php _e( 'Delete Data', 'gpagespeedi' ); ?>:</label></p>
241
  <select name="purge_all_data" id="purge_all_data">
242
- <option><?php _e( 'Do Nothing', 'gpagespeedi' ); ?></option>
243
- <option value="purge_reports"><?php _e( 'Delete Reports Only', 'gpagespeedi' ); ?></option>
244
- <option value="purge_everything"><?php _e( 'Delete EVERYTHING', 'gpagespeedi' ); ?></option>
245
  </select>
246
- <p class="description"><span style="color:red;"><?php _e( 'Warning', 'gpagespeedi' ); ?>:</span> <?php _e( 'This option can not be reversed.', 'gpagespeedi' ); ?></p>
247
  </div>
248
  </div>
249
 
@@ -252,9 +252,11 @@ if ( ! defined( 'ABSPATH' ) ) {
252
  wp_nonce_field( 'gpi-save-options' );
253
 
254
  if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) :
255
- submit_button( __( 'Save Options', 'gpagespeedi' ), 'secondary', 'submit', false, array( 'disabled' => true ) );
256
  else :
257
- submit_button( __( 'Save Options', 'gpagespeedi' ), 'primary', 'submit', false );
258
  endif;
259
  ?>
 
 
260
  </form>
12
  <form method="post" action="">
13
  <div class="row framed boxsizing">
14
  <div class="boxheader large toggle">
15
+ <span class="left google"><?php esc_html_e( 'Google Pagespeed Options', 'gpagespeedi' ); ?></span>
16
  <span class="right open"></span>
17
  </div>
18
  <div class="padded">
19
+ <p><?php esc_html_e( 'Google API Key:', 'gpagespeedi' ); ?></p>
20
+ <input type="text" name="google_developer_key" id="google_developer_key" value="<?php echo esc_attr( $this->gpi_options['google_developer_key'] ); ?>" class="googleapi code" />
21
+ <p class="description"><span style="color:red;"><?php esc_html_e( 'This is required', 'gpagespeedi' ); ?></span>: <?php esc_html_e( 'if you do not have an API key you can create a new one for free from', 'gpagespeedi' ); ?>: <a href="https://console.developers.google.com" target="_blank">https://console.developers.google.com</a>. <?php echo wp_kses_data( __( 'Read the documentation included with this plugin or <a href="http://mattkeys.me/documentation/google-pagespeed-insights/#required_configuration" target="_blank">online</a> for additional information about creating an API key.', 'gpagespeedi' ) ); ?></p>
22
 
23
+ <p><?php esc_html_e( 'Google Response Language:', 'gpagespeedi' ); ?></p>
24
  <select name="response_language" id="response_language">
25
  <option value="ar" <?php selected( $this->gpi_options['response_language'], 'ar' ); ?>>Arabic</option>
26
  <option value="bg" <?php selected( $this->gpi_options['response_language'], 'bg' ); ?>>Bulgarian</option>
63
  <option value="uk" <?php selected( $this->gpi_options['response_language'], 'uk' ); ?>>Ukrainian</option>
64
  <option value="vi" <?php selected( $this->gpi_options['response_language'], 'vi' ); ?>>Vietnamese</option>
65
  </select>
66
+ <?php if ( (bool) $this->gpi_options['first_run_complete'] ) : ?>
67
+ <p class="description"><span style="color:red;"><?php esc_html_e( 'Note', 'gpagespeedi' ); ?></span>: <?php esc_html_e( 'URLs must be rechecked before language changes take effect. Use the "Delete Data" option under "Advanced Configuration" if you would like to remove old reports.', 'gpagespeedi' ); ?></p>
68
  <?php endif; ?>
69
 
70
+ <p><?php esc_html_e( 'Report Type(s):', 'gpagespeedi' ); ?></p>
71
  <select name="strategy" id="strategy">
72
+ <option value="desktop" <?php selected( $this->gpi_options['strategy'], 'desktop' ); ?>><?php esc_html_e( 'Desktop', 'gpagespeedi' ); ?></option>
73
+ <option value="mobile" <?php selected( $this->gpi_options['strategy'], 'mobile' ); ?>><?php esc_html_e( 'Mobile', 'gpagespeedi' ); ?></option>
74
+ <option value="both" <?php selected( $this->gpi_options['strategy'], 'both' ); ?>><?php esc_html_e( 'Both', 'gpagespeedi' ); ?></option>
75
  </select>
76
 
77
+ <p><?php esc_html_e( 'Store Page Load Screenshots:', 'gpagespeedi' ); ?></p>
78
  <select name="store_screenshots" id="store_screenshots">
79
+ <option value="0" <?php selected( $this->gpi_options['store_screenshots'], 0 ); ?>><?php esc_html_e( 'No', 'gpagespeedi' ); ?></option>
80
+ <option value="1" <?php selected( $this->gpi_options['store_screenshots'], 1 ); ?>><?php esc_html_e( 'Yes', 'gpagespeedi' ); ?></option>
81
  </select>
82
+ <p class="description"><span style="color:red;"><?php esc_html_e( 'Note', 'gpagespeedi' ); ?></span>: <?php esc_html_e( 'Screenshots stored in the database will usually take up around 50kb ~ 150kb per page report. If you have many pages to report on this may consume an unreasonable amount of space. Changes to this value will take effect on future report scans.', 'gpagespeedi' ); ?></p>
83
  </div>
84
  </div>
85
 
86
  <div class="row framed boxsizing">
87
  <div class="boxheader large toggle">
88
+ <span class="left cal"><?php esc_html_e( 'Scheduling and URL Configuration', 'gpagespeedi' ); ?></span>
89
  <span class="right"></span>
90
  </div>
91
  <div class="padded hidden">
92
 
93
+ <p><h4><?php esc_html_e( 'Choose wether or not Google Pagespeed Insights should automatically re-check page scores, and if so, how often.', 'gpagespeedi' ); ?></h4></p>
94
  <p class="checkbx">
95
  <input type="checkbox" name="use_schedule" id="use_schedule" <?php checked( $this->gpi_options['use_schedule'] ); ?>/>
96
+ <label for="use_schedule"><?php esc_html_e( 'Automatically re-check Pagespeed Insights scores using a schedule', 'gpagespeedi' ); ?></label>
97
  <?php if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) : ?>
98
+ <p class="description"><strong><?php esc_html_e( 'Notice', 'gpagespeedi' ); ?>:</strong> <?php esc_html_e( 'The WP Cron service this plugin uses to check pages is disabled. Hosting providers often disable the WP Cron service and run their own manual Cron service on an interval of their choosing. Contact your hosting provider if scheduled checks fail to run.', 'gpagespeedi' ); ?></p>
99
  <?php endif; ?>
100
  </p>
101
 
102
+ <p><label for="recheck_interval"><?php esc_html_e( 'Report Expiration / Recheck Interval', 'gpagespeedi' ); ?>:</label></p>
103
  <select name="recheck_interval" id="recheck_interval">
104
+ <option value="<?php echo esc_attr( DAY_IN_SECONDS );?>" <?php selected( $this->gpi_options['recheck_interval'], DAY_IN_SECONDS ); ?>><?php esc_html_e( '1 Day', 'gpagespeedi' ); ?></option>
105
+ <option value="<?php echo esc_attr( WEEK_IN_SECONDS );?>" <?php selected( $this->gpi_options['recheck_interval'], WEEK_IN_SECONDS ); ?>><?php esc_html_e( '7 Days', 'gpagespeedi' ); ?></option>
106
+ <option value="<?php echo esc_attr( MONTH_IN_SECONDS / 2 );?>" <?php selected( $this->gpi_options['recheck_interval'], MONTH_IN_SECONDS / 2 ); ?>><?php esc_html_e( '15 Days', 'gpagespeedi' ); ?></option>
107
+ <option value="<?php echo esc_attr( MONTH_IN_SECONDS );?>" <?php selected( $this->gpi_options['recheck_interval'], MONTH_IN_SECONDS ); ?>><?php esc_html_e( '30 Days', 'gpagespeedi' ); ?></option>
108
  </select>
109
+ <p class="description"><?php echo esc_html__( 'When page reporting is running, pages which are newer than the specified Report Expiration will be skipped.', 'gpagespeedi' ) . '<br />' . esc_html__( 'If "Automatically re-check Pagespeed Insights scores" is checked above, this option will control its frequency.', 'gpagespeedi' ); ?></p>
110
 
111
  <?php
112
  $timestamp = wp_next_scheduled( 'googlepagespeedinsightsworker' );
113
  if ( $timestamp ) {
114
  ?>
115
+ <p><strong><?php esc_html_e( 'Next Scheduled Check', 'gpagespeedi' ); ?></strong>: <?php echo esc_html( get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $timestamp ), 'F, d @ g:i a' ) ); ?></p>
116
  <?php
117
  }
118
  ?>
119
 
120
  <hr>
121
+ <p><h4><?php esc_html_e( 'Configure which types of URLs should be checked when running reports.', 'gpagespeedi' ); ?></h4></p>
122
+ <p><span style="color:red;"><?php esc_html_e( 'Note', 'gpagespeedi' ); ?></span>: <?php esc_html_e( 'Google Pagespeed will load each page to generate a report. The more pages you select, the longer it will take for the scan to complete.', 'gpagespeedi' ); ?></p>
123
  <p class="checkbx">
124
  <input type="checkbox" name="check_pages" id="check_pages" <?php checked( $this->gpi_options['check_pages'] ); ?>/>
125
+ <label for="check_pages"><?php esc_html_e( 'Check Wordpress Pages', 'gpagespeedi' ); ?> (<?php echo esc_html( wp_count_posts( 'page' )->publish ); ?>)</label>
126
  </p>
127
  <p class="checkbx">
128
  <input type="checkbox" name="check_posts" id="check_posts" <?php checked( $this->gpi_options['check_posts'] ); ?>/>
129
+ <label for="check_posts"><?php esc_html_e( 'Check Wordpress Posts', 'gpagespeedi' ); ?> (<?php echo esc_html( wp_count_posts( 'post' )->publish ); ?>)</label>
130
  </p>
131
  <p class="checkbx">
132
  <input type="checkbox" name="check_categories" id="check_categories" <?php checked( $this->gpi_options['check_categories'] ); ?>/>
133
+ <label for="check_categories"><?php esc_html_e( 'Check Category Indexes', 'gpagespeedi' ); ?> (<?php echo esc_html( count( get_categories() ) ) ?>)</label>
134
  </p>
135
 
136
  <p class="checkbx">
137
  <input type="checkbox" name="check_custom_urls" id="check_custom_urls" <?php checked( $this->gpi_options['check_custom_urls'] ); ?>/>
138
+ <label for="check_custom_urls"><?php esc_html_e( 'Check Custom URLs', 'gpagespeedi' ); ?> (<?php echo esc_html( apply_filters( 'gpi_custom_urls_count', 0 ) ); ?>)</label>
139
  </p>
140
 
141
  <?php
143
  if ( ! empty( $custom_post_types ) ) :
144
  ?>
145
  <p class="checkbx">
146
+ <?php esc_html_e( 'Custom Post Types', 'gpagespeedi' ); ?>:
147
  </p>
148
 
149
  <div class="padded" style="padding-top: 0px;">
151
  foreach ( $custom_post_types as $custom_post_type ) :
152
  ?>
153
  <p class="checkbx posttypes">
154
+ <input type="checkbox" name="cpt_whitelist[]" id="<?php echo esc_attr( 'cpt_' . $custom_post_type['value'] ); ?>" value="<?php echo esc_attr( $custom_post_type['value'] ); ?>" <?php if ( $custom_post_type['checked'] ) { echo esc_html( 'checked="checked"' ); } ?> />
155
+ <label for="<?php echo esc_attr( 'cpt_' . $custom_post_type['value'] ); ?>"><?php echo esc_html( $custom_post_type['value'] ); ?> (<?php echo esc_html( $custom_post_type['count'] ); ?>)</label>
156
  </p>
157
  <?php
158
  endforeach;
166
 
167
  <div class="row framed boxsizing">
168
  <div class="boxheader large toggle">
169
+ <span class="left gear"><?php esc_html_e( 'Advanced Configuration', 'gpagespeedi' ); ?></span>
170
  <span class="right"></span>
171
  </div>
172
  <div class="padded hidden">
173
+ <p><?php esc_html_e( 'For most users, the following settings can be left at their defaults unless otherwise instructed by support.', 'gpagespeedi' ); ?></p>
174
 
175
+ <p><label for="max_execution_time"><?php esc_html_e( 'Maximum Execution Time', 'gpagespeedi' ); ?>:</label></p>
176
  <select name="max_execution_time" id="max_execution_time">
177
+ <option value="60" <?php selected( $this->gpi_options['max_execution_time'], 60 ); ?>><?php esc_html_e( '1 Minute', 'gpagespeedi' ); ?></option>
178
+ <option value="300" <?php selected( $this->gpi_options['max_execution_time'], 300 ); ?>><?php esc_html_e( '5 Minutes', 'gpagespeedi' ); ?></option>
179
+ <option value="600" <?php selected( $this->gpi_options['max_execution_time'], 600 ); ?>><?php esc_html_e( '10 Minutes', 'gpagespeedi' ); ?></option>
180
+ <option value="900" <?php selected( $this->gpi_options['max_execution_time'], 900 ); ?>><?php esc_html_e( '15 Minutes', 'gpagespeedi' ); ?></option>
181
+ <option value="1800" <?php selected( $this->gpi_options['max_execution_time'], 1800 ); ?>><?php esc_html_e( '30 Minutes', 'gpagespeedi' ); ?></option>
182
  </select>
183
+ <p class="description"><?php esc_html_e( 'The default value of 5 minutes is fine for most sites.', 'gpagespeedi' ); ?> <?php esc_html_e( 'Increasing this value may help if your page reports do not finish completely.', 'gpagespeedi' ); ?></p>
184
  <?php if ( apply_filters( 'gpi_set_time_limit_disabled', false ) ) : ?>
185
+ <p class="description"><span style="color:red;"><?php esc_html_e( 'Notice', 'gpagespeedi' ); ?>:</span> <?php esc_html_e( 'We have detected that your server may not allow the maximum execution time to be overridden by this plugin. If you experience problems with pagespeed report scans failing to complete, contact your hosting provider. Default Maximum Execution Time: ', 'gpagespeedi' ); ?> <strong><?php echo esc_html( ini_get( 'max_execution_time' ) ) . ' ' . __( 'seconds', 'gpagespeedi' ); ?></strong></p>
186
  <?php endif; ?>
187
 
188
+ <p><label for="max_run_time"><?php esc_html_e( 'Maximum Script Run Time', 'gpagespeedi' ); ?>:</label></p>
189
  <select name="max_run_time" id="max_run_time">
190
+ <option value="0" <?php selected( $this->gpi_options['max_run_time'], 0 ); ?>><?php esc_html_e( 'No Limit', 'gpagespeedi' ); ?></option>
191
+ <option value="15" <?php selected( $this->gpi_options['max_run_time'], 15 ); ?>><?php esc_html_e( '15 Seconds', 'gpagespeedi' ); ?></option>
192
+ <option value="30" <?php selected( $this->gpi_options['max_run_time'], 30 ); ?>><?php esc_html_e( '30 Seconds', 'gpagespeedi' ); ?></option>
193
+ <option value="45" <?php selected( $this->gpi_options['max_run_time'], 45 ); ?>><?php esc_html_e( '45 Seconds', 'gpagespeedi' ); ?></option>
194
+ <option value="60" <?php selected( $this->gpi_options['max_run_time'], 60 ); ?>><?php esc_html_e( '60 Seconds', 'gpagespeedi' ); ?></option>
195
+ <option value="90" <?php selected( $this->gpi_options['max_run_time'], 90 ); ?>><?php esc_html_e( '90 Seconds', 'gpagespeedi' ); ?></option>
196
+ <option value="120" <?php selected( $this->gpi_options['max_run_time'], 120 ); ?>><?php esc_html_e( '120 Seconds', 'gpagespeedi' ); ?></option>
197
+ <option value="150" <?php selected( $this->gpi_options['max_run_time'], 150 ); ?>><?php esc_html_e( '150 Seconds', 'gpagespeedi' ); ?></option>
198
+ <option value="180" <?php selected( $this->gpi_options['max_run_time'], 180 ); ?>><?php esc_html_e( '180 Seconds', 'gpagespeedi' ); ?></option>
199
  </select>
200
  <p class="description">
201
+ <?php esc_html_e( 'Some web hosting providers have limits on script runtime that cannot be overridden. If your scans do not finish completely and changing the Maximum Execution Time does not resolve the problem, this setting may help. Once the specified run time is reached a new scan process will automatically start.', 'gpagespeedi' ); ?>
202
+ <?php esc_html_e( 'It is best to find the largest value that still allows the script to complete successfully. Test first at 30 seconds, then raise the value to 45 if your test is successful. Continue until you find the maximum runtime your host allows.', 'gpagespeedi' ); ?>
203
  </p>
204
 
205
+ <p><label for="sleep_time"><?php esc_html_e( 'Report Throttling Delay Time', 'gpagespeedi' ); ?>:</label></p>
206
  <select name="sleep_time" id="sleep_time">
207
+ <option value="0" <?php selected( $this->gpi_options['sleep_time'], 0 ); ?>><?php esc_html_e( '0 Seconds', 'gpagespeedi' ); ?></option>
208
+ <option value="1" <?php selected( $this->gpi_options['sleep_time'], 1 ); ?>><?php esc_html_e( '1 Seconds', 'gpagespeedi' ); ?></option>
209
+ <option value="2" <?php selected( $this->gpi_options['sleep_time'], 2 ); ?>><?php esc_html_e( '2 Seconds', 'gpagespeedi' ); ?></option>
210
+ <option value="3" <?php selected( $this->gpi_options['sleep_time'], 3 ); ?>><?php esc_html_e( '3 Seconds', 'gpagespeedi' ); ?></option>
211
+ <option value="4" <?php selected( $this->gpi_options['sleep_time'], 4 ); ?>><?php esc_html_e( '4 Seconds', 'gpagespeedi' ); ?></option>
212
+ <option value="5" <?php selected( $this->gpi_options['sleep_time'], 5 ); ?>><?php esc_html_e( '5 Seconds', 'gpagespeedi' ); ?></option>
213
+ <option value="10" <?php selected( $this->gpi_options['sleep_time'], 10 ); ?>><?php esc_html_e( '10 Seconds', 'gpagespeedi' ); ?></option>
214
  </select>
215
  <p class="description">
216
+ <?php esc_html_e( 'The default value of 0 seconds is fine for most sites.', 'gpagespeedi' ); ?>
217
  <br />
218
+ <?php esc_html_e( 'Raising this value will slow down page reporting, but may help provide more accurate reports on poorly performing web servers', 'gpagespeedi' ); ?>
219
  </p>
220
 
221
+ <p><label for="heartbeat"><?php esc_html_e( 'Report Status Indicator Refresh Rate', 'gpagespeedi' ); ?>:</label></p>
222
  <select name="heartbeat" id="heartbeat">
223
+ <option value="fast" <?php selected( $this->gpi_options['heartbeat'], 'fast' ); ?>><?php esc_html_e( 'Fast', 'gpagespeedi' ); ?></option>
224
+ <option value="standard" <?php selected( $this->gpi_options['heartbeat'], 'standard' ); ?>><?php esc_html_e( 'Standard' ); ?></option>
225
+ <option value="slow" <?php selected( $this->gpi_options['heartbeat'], 'slow' ); ?>><?php esc_html_e( 'Slow', 'gpagespeedi' ); ?></option>
226
+ <option value="disabled" <?php selected( $this->gpi_options['heartbeat'], 'disabled' ); ?>><?php esc_html_e( 'Disabled - manually refresh pages to update status', 'gpagespeedi' ); ?></option>
227
  </select>
228
  <p class="description">
229
+ <?php esc_html_e( 'The default value of "Fast" is fine for most sites.', 'gpagespeedi' ); ?>
230
  <br />
231
+ <?php esc_html_e( 'More frequent updates may impact Pagespeed reports on poorly performing servers, reduce the rate if you are experiencing issues.', 'gpagespeedi' ); ?>
232
  </p>
233
 
234
  <p class="checkbx">
235
  <input type="checkbox" name="log_api_errors" id="log_api_errors" <?php checked( $this->gpi_options['log_api_errors'] ); ?>/>
236
+ <label for="log_api_errors"><?php esc_html_e( 'Log API Exceptions', 'gpagespeedi' ); ?></label>
237
  </p>
238
+ <p class="description"><?php esc_html_e( 'API error logs will be stored for up to 7 days.', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=logs"><?php esc_html_e( 'View Logs', 'gpagespeedi' ); ?></a></p>
239
 
240
+ <p><label for="sleep_time"><?php esc_html_e( 'Delete Data', 'gpagespeedi' ); ?>:</label></p>
241
  <select name="purge_all_data" id="purge_all_data">
242
+ <option><?php esc_html_e( 'Do Nothing', 'gpagespeedi' ); ?></option>
243
+ <option value="purge_reports"><?php esc_html_e( 'Delete Reports Only', 'gpagespeedi' ); ?></option>
244
+ <option value="purge_everything"><?php esc_html_e( 'Delete EVERYTHING', 'gpagespeedi' ); ?></option>
245
  </select>
246
+ <p class="description"><span style="color:red;"><?php esc_html_e( 'Warning', 'gpagespeedi' ); ?>:</span> <?php esc_html_e( 'This option can not be reversed.', 'gpagespeedi' ); ?></p>
247
  </div>
248
  </div>
249
 
252
  wp_nonce_field( 'gpi-save-options' );
253
 
254
  if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) :
255
+ submit_button( esc_html__( 'Save Options', 'gpagespeedi' ), 'secondary', 'submit', false, array( 'disabled' => true ) );
256
  else :
257
+ submit_button( esc_html__( 'Save Options', 'gpagespeedi' ), 'primary', 'submit', false );
258
  endif;
259
  ?>
260
+
261
+ <?php include GPI_DIRECTORY . '/templates/parts/nitropack.php'; ?>
262
  </form>
templates/parts/messages.php CHANGED
@@ -6,110 +6,107 @@
6
  if ( ! defined( 'ABSPATH' ) ) {
7
  exit;
8
  }
9
-
10
- $page = esc_attr( $_REQUEST['page'] );
11
-
12
  ?>
13
 
14
  <?php if ( get_option( 'gpagespeedi_upgrade_recheck_required' ) ) : ?>
15
  <div id="gpi-upgrade-notice">
16
  <div class="inner">
17
  <div class="gpi-icon logo">
18
- <img src="<?php echo GPI_PUBLIC_PATH; ?>assets/images/icon.svg" width="144px" height="100px" alt="Insights from Google PageSpeed" />
19
  </div>
20
  <div class="content">
21
  <h2>
22
- <?php _e( 'Report Updates Required', 'gpagespeedi' ); ?>
23
  </h2>
24
  <p>
25
- <?php _e( 'Thank you for updating to the latest version of Insights from Google PageSpeed!', 'gpagespeedi' ); ?>
26
  </p>
27
  <p>
28
- <?php echo __( 'Version', 'gpagespeedi' ) . ' ' . GPI_VERSION . ' ' . __( 'requires some updates to the way Pagespeed reports are stored to take advantage of the latest plugin updates. You will notice some missing report functionality until all pages have been rechecked.', 'gpagespeedi' ); ?>
29
  </p>
30
  <p>
31
- <a href="<?php echo admin_url( 'tools.php?page=google-pagespeed-insights&amp;render=' . esc_attr( $_GET['render'] ) . '&amp;action=reports_update' ); ?>" class="button button-primary"><?php _e( 'Recheck Pagespeed Reports Now', 'gpagespeedi' ); ?></a>
32
  </p>
33
  </div>
34
  </div>
35
  </div>
36
  <?php endif; ?>
37
- <?php if ( $this->gpi_options['google_developer_key'] == '' && 'options' != $admin_page ) : ?>
38
  <div id="message" class="error">
39
- <p><strong><?php _e( 'You must enter your Google API key to use this plugin! Enter your API key in the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=options"><?php _e( 'Options', 'gpagespeedi' ); ?></a></strong>.</p>
40
  </div>
41
  <?php endif; ?>
42
- <?php if ( $this->gpi_options['bad_api_key'] && 'options' != $admin_page ) : ?>
43
  <div id="message" class="error">
44
- <p><strong><?php _e( 'The Google Pagespeed API Key you entered appears to be invalid. Please update your API key in the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=options"><?php _e( 'Options', 'gpagespeedi' ); ?></a></strong>.</p>
45
  </div>
46
  <?php endif; ?>
47
- <?php if ( $this->gpi_options['pagespeed_disabled'] && 'options' != $admin_page ) : ?>
48
  <div id="message" class="error">
49
- <p><strong><?php _e( 'The "PageSpeed Insights API" service is not enabled. To enable it, please visit the', 'gpagespeedi' ); ?> <a href="https://code.google.com/apis/console/" target="_blank"><?php _e( 'Google API Console', 'gpagespeedi' ); ?></a></strong>.</p>
50
  </div>
51
  <?php endif; ?>
52
- <?php if ( $this->gpi_options['api_restriction'] ) : ?>
53
  <div id="message" class="error">
54
- <p><strong><?php _e( 'This referrer or IP address is restricted from using your API Key. To change your API Key restrictions, please visit the', 'gpagespeedi' ); ?> <a href="https://code.google.com/apis/console/" target="_blank"><?php _e( 'Google API Console', 'gpagespeedi' ); ?></a></strong>.</p>
55
  </div>
56
  <?php endif; ?>
57
  <?php if ( $action_message = $this->gpi_ui_options['action_message'] ) :
58
  if ( ! is_array( $action_message ) ) : ?>
59
  <div id="message" class="updated">
60
- <p><?php echo $action_message; ?></p>
61
  </div>
62
  <?php elseif ( isset( $action_message['type'] ) && isset( $action_message['message'] ) ) : ?>
63
- <div id="message" class="<?php echo $action_message['type']; ?>">
64
- <p><?php echo $action_message['message']; ?></p>
65
  </div>
66
  <?php endif; ?>
67
  <?php endif; ?>
68
  <?php if ( $error_message = get_option('gpi_error_message') ) : ?>
69
  <div id="message" class="error">
70
- <p><?php echo $error_message; ?></p>
71
  </div>
72
  <?php endif; ?>
73
- <?php if ( isset( $_GET['render'] ) && 'logs' == $_GET['render'] && ! $this->gpi_options['log_api_errors'] ) : ?>
74
  <div id="message" class="error">
75
- <p><strong><?php _e( 'API error logging is disabled. Enable "Log API Exceptions" to record new errors.', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=options"><?php _e( 'Options', 'gpagespeedi' ); ?></a></strong></p>
76
  </div>
77
  <?php endif; ?>
78
- <?php if ( $this->gpi_options['new_ignored_items'] ) : ?>
79
  <div id="message" class="notice notice-error is-dismissible">
80
- <p><strong><?php _e( 'One or more URLs could not be reached by Google Pagespeed Insights and have automatically been added to the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=ignored-urls"><?php _e( 'Ignored URLs', 'gpagespeedi' ); ?></a></strong>.</p>
81
  </div>
82
  <?php endif; ?>
83
- <?php if ( $this->gpi_options['backend_error'] ) : ?>
84
  <div id="message" class="error">
85
- <p><strong><?php _e( 'An error has been encountered while checking one or more URLs. Possible causes: <br /><br />Daily API Limit Exceeded <a href="https://code.google.com/apis/console" target="_blank">Check API Usage</a> <br />API Key user limit exceeded <a href="https://code.google.com/apis/console" target="_blank">Check API Usage</a> <br />the URL is not publicly accessible or is bad. <br /><br />The URL(s) have been added to the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=ignored-urls"><?php _e( 'Ignored URLs', 'gpagespeedi' ); ?></a></strong></p>
86
  </div>
87
  <?php endif; ?>
88
  <?php if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) : ?>
89
  <div id="message" class="updated">
90
  <?php if ( 'disabled' != $this->gpi_options['heartbeat'] ) : ?>
91
  <span>
92
- <p id="gpi_status_abort" style="font-size: 13px; display: none;"><?php _e( 'Google Pagespeed has successfully stopped checking pages due to a user requested abort.', 'gpagespeedi' ); ?></p>
93
- <p id="gpi_status_finished" style="font-size: 13px; display: none;"><?php _e( 'Google Pagespeed has finished checking pagespeed scores.', 'gpagespeedi' );?> <a href="?page=<?php echo $page; ?>&amp;render=report-list"><?php _e( 'See new results', 'gpagespeedi' ); ?>.</a></p>
94
- <p id="gpi_status_ajax" class="ellipsis" style="font-size: 13px;"><?php _e( 'Google Pagespeed is running in the background ', 'gpagespeedi' ); ?></p>
95
  </span>
96
  <?php else : ?>
97
- <span><p id="gpi_status_noajax" style="font-size: 13px;"><?php _e( 'Google Pagespeed is running in the background. Progress... ', 'gpagespeedi' ); ?><span id="progress"></span> <?php _e( 'URL(s) checked', 'gpagespeedi' ); ?>. <a href="javascript:location.reload(true);"><?php _e( 'Refresh to update progress or see new results.', 'gpagespeedi' ); ?></a></p></span>
98
  <?php endif; ?>
99
  </div>
100
 
101
  <?php if ( isset( $_GET['render'] ) && 'options' == $_GET['render'] ) : ?>
102
  <div id="message" class="notice notice-warning">
103
- <p><?php _e('Google Pagespeed Options cannot be changed while Pagespeed is running. Please wait until it has finished to make any changes.', 'gpagespeedi' ); ?></p>
104
  </div>
105
  <?php endif; ?>
106
  <?php endif; ?>
107
- <?php if ( ! $worker_status && ! $this->gpi_options['last_run_finished'] ) : ?>
108
  <div id="message" class="error">
109
  <?php if ( apply_filters( 'gpi_set_time_limit_disabled', false ) ) : ?>
110
- <p><strong><?php _e( 'The last pagespeed report scan failed to finish successfully. We have detected that your server may not allow the maximum execution time to be overridden by this plugin. If you continue to experience problems with pagespeed report scans failing to complete, try setting the Maximum Script Run Time in the Advanced Configuration section on the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page;?>&amp;render=options"><?php _e( 'Options Page', 'gpagespeedi' ); ?></a></strong>.</p>
111
  <?php else : ?>
112
- <p><strong><?php _e( 'The last pagespeed report scan failed to finish successfully. If you continue to experience problems with pagespeed report scans failing to complete, try increasing the Maximum Execution Time, or setting the Maximum Script Run Time in the Advanced Configuration section on the', 'gpagespeedi' ); ?> <a href="?page=<?php echo $page; ?>&amp;render=options"><?php _e( 'Options Page', 'gpagespeedi' ); ?></a></strong>.</p>
113
  <?php endif; ?>
114
  </div>
115
  <?php endif; ?>
6
  if ( ! defined( 'ABSPATH' ) ) {
7
  exit;
8
  }
 
 
 
9
  ?>
10
 
11
  <?php if ( get_option( 'gpagespeedi_upgrade_recheck_required' ) ) : ?>
12
  <div id="gpi-upgrade-notice">
13
  <div class="inner">
14
  <div class="gpi-icon logo">
15
+ <img src="<?php echo esc_url( GPI_PUBLIC_PATH . 'assets/images/icon.svg' ); ?>" width="144px" height="100px" alt="Insights from Google PageSpeed" />
16
  </div>
17
  <div class="content">
18
  <h2>
19
+ <?php esc_html_e( 'Report Updates Required', 'gpagespeedi' ); ?>
20
  </h2>
21
  <p>
22
+ <?php esc_html_e( 'Thank you for updating to the latest version of Insights from Google PageSpeed!', 'gpagespeedi' ); ?>
23
  </p>
24
  <p>
25
+ <?php echo esc_html( __( 'Version', 'gpagespeedi' ) . ' ' . GPI_VERSION . ' ' . __( 'requires some updates to the way Pagespeed reports are stored to take advantage of the latest plugin updates. You will notice some missing report functionality until all pages have been rechecked.', 'gpagespeedi' ) ); ?>
26
  </p>
27
  <p>
28
+ <a href="<?php echo esc_url( admin_url( 'tools.php?page=google-pagespeed-insights&amp;render=' . $_GET['render'] . '&amp;action=reports_update' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Recheck Pagespeed Reports Now', 'gpagespeedi' ); ?></a>
29
  </p>
30
  </div>
31
  </div>
32
  </div>
33
  <?php endif; ?>
34
+ <?php if ( '' == $this->gpi_options['google_developer_key'] && 'options' != $admin_page ) : ?>
35
  <div id="message" class="error">
36
+ <p><strong><?php esc_html_e( 'You must enter your Google API key to use this plugin! Enter your API key in the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a></strong>.</p>
37
  </div>
38
  <?php endif; ?>
39
+ <?php if ( (bool) $this->gpi_options['bad_api_key'] && 'options' != $admin_page ) : ?>
40
  <div id="message" class="error">
41
+ <p><strong><?php esc_html_e( 'The Google Pagespeed API Key you entered appears to be invalid. Please update your API key in the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a></strong>.</p>
42
  </div>
43
  <?php endif; ?>
44
+ <?php if ( (bool) $this->gpi_options['pagespeed_disabled'] && 'options' != $admin_page ) : ?>
45
  <div id="message" class="error">
46
+ <p><strong><?php esc_html_e( 'The "PageSpeed Insights API" service is not enabled. To enable it, please visit the', 'gpagespeedi' ); ?> <a href="https://console.developers.google.com/" target="_blank"><?php esc_html_e( 'Google API Console', 'gpagespeedi' ); ?></a></strong>.</p>
47
  </div>
48
  <?php endif; ?>
49
+ <?php if ( (bool) $this->gpi_options['api_restriction'] ) : ?>
50
  <div id="message" class="error">
51
+ <p><strong><?php esc_html_e( 'This referrer or IP address is restricted from using your API Key. To change your API Key restrictions, please visit the', 'gpagespeedi' ); ?> <a href="https://console.developers.google.com/" target="_blank"><?php esc_html_e( 'Google API Console', 'gpagespeedi' ); ?></a></strong>.</p>
52
  </div>
53
  <?php endif; ?>
54
  <?php if ( $action_message = $this->gpi_ui_options['action_message'] ) :
55
  if ( ! is_array( $action_message ) ) : ?>
56
  <div id="message" class="updated">
57
+ <p><?php echo esc_html( $action_message ); ?></p>
58
  </div>
59
  <?php elseif ( isset( $action_message['type'] ) && isset( $action_message['message'] ) ) : ?>
60
+ <div id="message" class="<?php echo esc_attr( $action_message['type'] ); ?>">
61
+ <p><?php echo esc_html( $action_message['message'] ); ?></p>
62
  </div>
63
  <?php endif; ?>
64
  <?php endif; ?>
65
  <?php if ( $error_message = get_option('gpi_error_message') ) : ?>
66
  <div id="message" class="error">
67
+ <p><?php echo esc_html( $error_message ); ?></p>
68
  </div>
69
  <?php endif; ?>
70
+ <?php if ( isset( $_GET['render'] ) && 'logs' == $_GET['render'] && ! (bool) $this->gpi_options['log_api_errors'] ) : ?>
71
  <div id="message" class="error">
72
+ <p><strong><?php esc_html_e( 'API error logging is disabled. Enable "Log API Exceptions" to record new errors.', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a></strong></p>
73
  </div>
74
  <?php endif; ?>
75
+ <?php if ( (bool) $this->gpi_options['new_ignored_items'] ) : ?>
76
  <div id="message" class="notice notice-error is-dismissible">
77
+ <p><strong><?php esc_html_e( 'One or more URLs could not be reached by Google Pagespeed Insights and have automatically been added to the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=ignored-urls"><?php esc_html_e( 'Ignored URLs', 'gpagespeedi' ); ?></a></strong>.</p>
78
  </div>
79
  <?php endif; ?>
80
+ <?php if ( (bool) $this->gpi_options['backend_error'] ) : ?>
81
  <div id="message" class="error">
82
+ <p><strong><?php echo wp_kses_data( __( 'An error has been encountered while checking one or more URLs. Possible causes: <br /><br />Daily API Limit Exceeded <a href="https://console.developers.google.com/" target="_blank">Check API Usage</a> <br />API Key user limit exceeded <a href="https://console.developers.google.com/" target="_blank">Check API Usage</a> <br />the URL is not publicly accessible or is bad. <br /><br />The URL(s) have been added to the', 'gpagespeedi' ) ); ?> <a href="?page=google-pagespeed-insights&amp;render=ignored-urls"><?php esc_html_e( 'Ignored URLs', 'gpagespeedi' ); ?></a></strong></p>
83
  </div>
84
  <?php endif; ?>
85
  <?php if ( $worker_status = apply_filters( 'gpi_check_status', false ) ) : ?>
86
  <div id="message" class="updated">
87
  <?php if ( 'disabled' != $this->gpi_options['heartbeat'] ) : ?>
88
  <span>
89
+ <p id="gpi_status_abort" style="font-size: 13px; display: none;"><?php esc_html_e( 'Google Pagespeed has successfully stopped checking pages due to a user requested abort.', 'gpagespeedi' ); ?></p>
90
+ <p id="gpi_status_finished" style="font-size: 13px; display: none;"><?php esc_html_e( 'Google Pagespeed has finished checking pagespeed scores.', 'gpagespeedi' );?> <a href="?page=google-pagespeed-insights&amp;render=report-list"><?php esc_html_e( 'See new results', 'gpagespeedi' ); ?>.</a></p>
91
+ <p id="gpi_status_ajax" class="ellipsis" style="font-size: 13px;"><?php esc_html_e( 'Google Pagespeed is running in the background ', 'gpagespeedi' ); ?></p>
92
  </span>
93
  <?php else : ?>
94
+ <span><p id="gpi_status_noajax" style="font-size: 13px;"><?php esc_html_e( 'Google Pagespeed is running in the background. Progress... ', 'gpagespeedi' ); ?><span id="progress"></span> <?php esc_html_e( 'URL(s) checked', 'gpagespeedi' ); ?>. <a href="javascript:location.reload(true);"><?php esc_html_e( 'Refresh to update progress or see new results.', 'gpagespeedi' ); ?></a></p></span>
95
  <?php endif; ?>
96
  </div>
97
 
98
  <?php if ( isset( $_GET['render'] ) && 'options' == $_GET['render'] ) : ?>
99
  <div id="message" class="notice notice-warning">
100
+ <p><?php esc_html_e('Google Pagespeed Options cannot be changed while Pagespeed is running. Please wait until it has finished to make any changes.', 'gpagespeedi' ); ?></p>
101
  </div>
102
  <?php endif; ?>
103
  <?php endif; ?>
104
+ <?php if ( ! $worker_status && ! (bool) $this->gpi_options['last_run_finished'] ) : ?>
105
  <div id="message" class="error">
106
  <?php if ( apply_filters( 'gpi_set_time_limit_disabled', false ) ) : ?>
107
+ <p><strong><?php esc_html_e( 'The last pagespeed report scan failed to finish successfully. We have detected that your server may not allow the maximum execution time to be overridden by this plugin. If you continue to experience problems with pagespeed report scans failing to complete, try setting the Maximum Script Run Time in the Advanced Configuration section on the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options Page', 'gpagespeedi' ); ?></a></strong>.</p>
108
  <?php else : ?>
109
+ <p><strong><?php esc_html_e( 'The last pagespeed report scan failed to finish successfully. If you continue to experience problems with pagespeed report scans failing to complete, try increasing the Maximum Execution Time, or setting the Maximum Script Run Time in the Advanced Configuration section on the', 'gpagespeedi' ); ?> <a href="?page=google-pagespeed-insights&amp;render=options"><?php esc_html_e( 'Options Page', 'gpagespeedi' ); ?></a></strong>.</p>
110
  <?php endif; ?>
111
  </div>
112
  <?php endif; ?>
templates/parts/modes.php CHANGED
@@ -11,9 +11,9 @@ if ( ! defined( 'ABSPATH' ) ) {
11
 
12
  <div class="reportmodes">
13
  <?php if ( 'both' == $this->gpi_options['strategy'] || 'desktop' == $this->gpi_options['strategy'] ) : ?>
14
- <a href="<?php echo $_SERVER['REQUEST_URI']; ?>&amp;action=set_view_preference&amp;strategy=desktop" class="button-gpi desktop<?php if ( $this->gpi_ui_options['view_preference'] == 'desktop' ) { echo ' active'; } ?>"><?php _e( 'Desktop Mode', 'gpagespeedi' ); ?></a>
15
  <?php endif; ?>
16
  <?php if ( 'both' == $this->gpi_options['strategy'] || 'mobile' == $this->gpi_options['strategy'] ) : ?>
17
- <a href="<?php echo $_SERVER['REQUEST_URI']; ?>&amp;action=set_view_preference&amp;strategy=mobile" class="button-gpi mobile<?php if ( $this->gpi_ui_options['view_preference'] == 'mobile' ) { echo ' active'; } ?>"><?php _e( 'Mobile Mode', 'gpagespeedi' ); ?></a>
18
  <?php endif; ?>
19
  </div>
11
 
12
  <div class="reportmodes">
13
  <?php if ( 'both' == $this->gpi_options['strategy'] || 'desktop' == $this->gpi_options['strategy'] ) : ?>
14
+ <a href="<?php echo esc_url( $_SERVER['REQUEST_URI'] . '&amp;action=set_view_preference&amp;strategy=desktop' ); ?>" class="button-gpi desktop<?php if ( $this->gpi_ui_options['view_preference'] == 'desktop' ) { echo esc_attr( ' active' ); } ?>"><?php esc_html_e( 'Desktop Mode', 'gpagespeedi' ); ?></a>
15
  <?php endif; ?>
16
  <?php if ( 'both' == $this->gpi_options['strategy'] || 'mobile' == $this->gpi_options['strategy'] ) : ?>
17
+ <a href="<?php echo esc_url( $_SERVER['REQUEST_URI'] . '&amp;action=set_view_preference&amp;strategy=mobile' ); ?>" class="button-gpi mobile<?php if ( $this->gpi_ui_options['view_preference'] == 'mobile' ) { echo esc_attr( ' active' ); } ?>"><?php esc_html_e( 'Mobile Mode', 'gpagespeedi' ); ?></a>
18
  <?php endif; ?>
19
  </div>
templates/parts/navigation.php CHANGED
@@ -7,36 +7,34 @@ if ( ! defined( 'ABSPATH' ) ) {
7
  exit;
8
  }
9
 
10
- $page = esc_attr( $_REQUEST['page'] );
11
-
12
  ?>
13
 
14
  <h3 class="nav-tab-wrapper">
15
- <a href="?page=<?php echo $page; ?>&amp;render=report-list" class="nav-tab <?php if ( $admin_page == '' || $admin_page == 'report-list' || $admin_page == 'ignore' || $admin_page == 'recheck' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Report List', 'gpagespeedi' ); ?></a>
16
  <?php if ( $admin_page == 'details' ) : ?>
17
- <a href="?page=<?php echo $page; ?>&amp;render=details&amp;page_id=<?php echo intval( $_GET['page_id'] ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php _e( 'Report Details', 'gpagespeedi' ); ?></a>
18
  <?php endif; ?>
19
- <a href="?page=<?php echo $page; ?>&amp;render=summary" class="nav-tab <?php if ( $admin_page == 'summary' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Report Summary', 'gpagespeedi' ); ?></a>
20
 
21
- <a href="?page=<?php echo $page; ?>&amp;render=snapshots" class="nav-tab <?php if ( $admin_page == 'snapshots' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Snapshots', 'gpagespeedi' ); ?></a>
22
  <?php if ( $admin_page == 'view-snapshot' && ! isset( $_GET['compare_id'] ) ) : ?>
23
- <a href="?page=<?php echo $page; ?>&amp;render=view-snapshot&amp;snapshot_id=<?php echo intval( $_GET['snapshot_id'] ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php _e( 'View Snapshot', 'gpagespeedi' ); ?></a>
24
  <?php endif; ?>
25
  <?php if ( $admin_page == 'view-snapshot' && isset( $_GET['compare_id'] ) ) : ?>
26
- <a href="?page=<?php echo $page; ?>&amp;render=view-snapshot&amp;snapshot_id=<?php echo intval( $_GET['snapshot_id'] ); ?>&amp;compare_id=<?php echo intval( $_GET['compare_id'] ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php _e('Compare Snapshots', 'gpagespeedi'); ?></a>
27
  <?php endif; ?>
28
- <a href="?page=<?php echo $page; ?>&amp;render=custom-urls" class="nav-tab <?php if ( $admin_page == 'custom-urls' || $admin_page == 'delete' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Custom URLs', 'gpagespeedi' ); ?></a>
29
  <?php if($admin_page == 'add-custom-urls') : ?>
30
- <a href="?page=<?php echo $page; ?>&amp;render=add-custom-urls" class="nav-tab nav-tab-active nav-tab-temp"><?php _e( 'Add New URLs', 'gpagespeedi' ); ?></a>
31
  <?php endif ?>
32
  <?php if ( $admin_page == 'add-custom-urls-bulk' ) : ?>
33
- <a href="?page=<?php echo $page; ?>&amp;render=add-custom-urls-bulk" class="nav-tab nav-tab-active nav-tab-temp"><?php _e( 'Bulk Upload New URLs', 'gpagespeedi' ); ?></a>
34
  <?php endif; ?>
35
 
36
- <a href="?page=<?php echo $page; ?>&amp;render=ignored-urls" class="nav-tab <?php if ( $admin_page == 'ignored-urls' || $admin_page == 'activate' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Ignored URLs', 'gpagespeedi' ); ?></a>
37
- <a href="?page=<?php echo $page; ?>&amp;render=options" class="nav-tab <?php if ( $admin_page == 'options' ) { echo 'nav-tab-active'; } ?>"><?php _e( 'Options', 'gpagespeedi' ); ?></a>
38
  <?php if ( $admin_page == 'logs' ) : ?>
39
- <a href="?page=<?php echo $page; ?>&amp;render=logs" class="nav-tab nav-tab-active nav-tab-temp"><?php _e('Logs', 'gpagespeedi'); ?></a>
40
  <?php endif; ?>
41
 
42
  <?php do_action( 'gpi_navigation', $admin_page ); ?>
7
  exit;
8
  }
9
 
 
 
10
  ?>
11
 
12
  <h3 class="nav-tab-wrapper">
13
+ <a href="?page=google-pagespeed-insights&amp;render=report-list" class="nav-tab <?php if ( $admin_page == '' || $admin_page == 'report-list' || $admin_page == 'ignore' || $admin_page == 'recheck' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Report List', 'gpagespeedi' ); ?></a>
14
  <?php if ( $admin_page == 'details' ) : ?>
15
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=details&amp;page_id=' . intval( $_GET['page_id'] ) ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e( 'Report Details', 'gpagespeedi' ); ?></a>
16
  <?php endif; ?>
17
+ <a href="?page=google-pagespeed-insights&amp;render=summary" class="nav-tab <?php if ( $admin_page == 'summary' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Report Summary', 'gpagespeedi' ); ?></a>
18
 
19
+ <a href="?page=google-pagespeed-insights&amp;render=snapshots" class="nav-tab <?php if ( $admin_page == 'snapshots' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Snapshots', 'gpagespeedi' ); ?></a>
20
  <?php if ( $admin_page == 'view-snapshot' && ! isset( $_GET['compare_id'] ) ) : ?>
21
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=view-snapshot&amp;snapshot_id=' . intval( $_GET['snapshot_id'] ) ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e( 'View Snapshot', 'gpagespeedi' ); ?></a>
22
  <?php endif; ?>
23
  <?php if ( $admin_page == 'view-snapshot' && isset( $_GET['compare_id'] ) ) : ?>
24
+ <a href="<?php echo esc_url( '?page=google-pagespeed-insights&amp;render=view-snapshot&amp;snapshot_id=' . intval( $_GET['snapshot_id'] ) . '&amp;compare_id=' . intval( $_GET['compare_id'] ) ); ?>" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e('Compare Snapshots', 'gpagespeedi'); ?></a>
25
  <?php endif; ?>
26
+ <a href="?page=google-pagespeed-insights&amp;render=custom-urls" class="nav-tab <?php if ( $admin_page == 'custom-urls' || $admin_page == 'delete' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Custom URLs', 'gpagespeedi' ); ?></a>
27
  <?php if($admin_page == 'add-custom-urls') : ?>
28
+ <a href="?page=google-pagespeed-insights&amp;render=add-custom-urls" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e( 'Add New URLs', 'gpagespeedi' ); ?></a>
29
  <?php endif ?>
30
  <?php if ( $admin_page == 'add-custom-urls-bulk' ) : ?>
31
+ <a href="?page=google-pagespeed-insights&amp;render=add-custom-urls-bulk" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e( 'Bulk Upload New URLs', 'gpagespeedi' ); ?></a>
32
  <?php endif; ?>
33
 
34
+ <a href="?page=google-pagespeed-insights&amp;render=ignored-urls" class="nav-tab <?php if ( $admin_page == 'ignored-urls' || $admin_page == 'activate' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Ignored URLs', 'gpagespeedi' ); ?></a>
35
+ <a href="?page=google-pagespeed-insights&amp;render=options" class="nav-tab <?php if ( $admin_page == 'options' ) { echo esc_attr( 'nav-tab-active' ); } ?>"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a>
36
  <?php if ( $admin_page == 'logs' ) : ?>
37
+ <a href="?page=google-pagespeed-insights&amp;render=logs" class="nav-tab nav-tab-active nav-tab-temp"><?php esc_html_e('Logs', 'gpagespeedi'); ?></a>
38
  <?php endif; ?>
39
 
40
  <?php do_action( 'gpi_navigation', $admin_page ); ?>
templates/parts/nitropack.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <a href="<?php echo esc_url( 'https://nitropack.io/platform/wordpress/#VNISUS' ); ?>" target="_blank" class="nitropack-blurb">
2
+ <div class="logo"></div>
3
+ <div class="copy">
4
+ <h1><span><?php esc_html_e( 'Skyrocket your PageSpeed', 'gpagespeedi' ); ?></span> <?php esc_html_e( 'score instantly.', 'gpagespeedi' ); ?></h1>
5
+ <p><?php esc_html_e( "Decrease your website's load time and skyrocket your PageSpeed score with NitroPack. NitroPack users get a 69% PageSpeed score boost on average after installing.", 'gpagespeedi' ); ?></p>
6
+ <p class="small"><?php esc_html_e( 'Insights for Google Pagespeed has partnered as an affiliate with NitroPack. Signing up through this link helps support the development of this plugin!', 'gpagespeedi' ); ?></p>
7
+ </div>
8
+ <div class="link">
9
+ <div class="btn"><?php esc_html_e( 'Start for free', 'gpagespeedi' ); ?></div>
10
+ </div>
11
+ </a>
templates/report-list.php CHANGED
@@ -14,7 +14,7 @@ $GPI_List_Table->prepare_items();
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
18
  <input type="hidden" name="render" value="report-list" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
18
  <input type="hidden" name="render" value="report-list" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
templates/snapshots.php CHANGED
@@ -14,7 +14,7 @@ $GPI_List_Table->prepare_items();
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
18
  <input type="hidden" name="render" value="snapshots" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
14
  ?>
15
 
16
  <form id="reports-filter" action="" method="get">
17
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
18
  <input type="hidden" name="render" value="snapshots" />
19
 
20
  <?php $GPI_List_Table->display(); ?>
templates/summary.php CHANGED
@@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  <div class="tablenav top">
13
  <div class="alignleft actions">
14
  <form method="get" action="" id="filter" name="filter">
15
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
16
  <input type="hidden" name="render" value="summary" />
17
  <select name="filter" id="filter">
18
  <?php
@@ -24,11 +24,11 @@ if ( ! defined( 'ABSPATH' ) ) {
24
 
25
  if ( is_array( $label ) ) :
26
  ?>
27
- <optgroup label="<?php echo $label['optgroup_label']; ?>">
28
  <?php
29
  foreach ( $label['options'] as $sub_value => $sub_label ) :
30
  ?>
31
- <option value="<?php echo $sub_value; ?>" <?php selected( $sub_value, $current_filter ); ?>><?php echo $sub_label; ?></option>
32
  <?php
33
  endforeach;
34
  ?>
@@ -36,7 +36,7 @@ if ( ! defined( 'ABSPATH' ) ) {
36
  <?php
37
  else :
38
  ?>
39
- <option value="<?php echo $value; ?>" <?php selected( $value, $current_filter ); ?>><?php echo $label; ?></option>
40
  <?php
41
  endif;
42
  endforeach;
@@ -44,19 +44,19 @@ if ( ! defined( 'ABSPATH' ) ) {
44
  ?>
45
  </select>
46
  <?php
47
- submit_button( __( 'Filter', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
48
  ?>
49
  </form>
50
  </div>
51
  <div class="alignleft actions">
52
  <form method="post" action="" id="savesnapshot" name="savesnapshot">
53
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
54
  <input type="hidden" name="render" value="summary" />
55
  <input type="hidden" name="action" value="save-snapshot" />
56
- <input type="text" name="comment" placeholder="<?php _e( 'Report Description', 'gpagespeedi' ); ?>" value="" />
57
  <?php
58
  wp_nonce_field( 'gpi_save_snapshot' );
59
- submit_button( __( 'Save Report Snapshot', 'gpagespeedi' ), 'button', 'save-snapshot', false );
60
  ?>
61
  </form>
62
  </div>
@@ -70,15 +70,15 @@ if ( ! defined( 'ABSPATH' ) ) {
70
  <div class="row">
71
  <div class="top-row boxsizing pagespeed_gauge_wrapper" id="pagespeed_gauge_wrapper">
72
  <div class="score_chart_div" id="score_chart_div">
73
- <img class="pagespeed_needle" id="pagespeed_needle" src="<?php echo GPI_PUBLIC_PATH; ?>assets/images/pagespeed_gauge_needle.png" width="204" height="204" alt="" />
74
- <div class="score_text" id="score_text"><span class="score"></span><span class="label"><?php _e( 'score', 'gpagespeedi' ); ?></span></div>
75
  </div>
76
  </div>
77
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper" id="pagespeed_avg_lab_data_wrapper">
78
  <div class="boxheader">
79
  <span class="left">
80
- <?php _e('Average Lab Data Scores', 'gpagespeedi'); ?>
81
- <span class="light">(<?php _e('Click for detailed report', 'gpagespeedi'); ?>)</span>
82
  </span>
83
  </div>
84
  <div id="avg_lab_data"></div>
@@ -86,24 +86,24 @@ if ( ! defined( 'ABSPATH' ) ) {
86
  </div>
87
  <div class="row boxsizing framed largest_improvement" id="largest_improvement">
88
  <div class="boxheader">
89
- <span class="left"><?php _e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
90
- <span class="right"><?php _e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
91
- <span class="right"><?php _e( 'Average Score', 'gpagespeedi' ); ?></span>
92
  </div>
93
  <table class="stats"></table>
94
  </div>
95
  <div class="row scores_div">
96
  <div class="halfwidth boxsizing framed left highest_scores" id="highest_scores">
97
  <div class="boxheader">
98
- <span class="left"><?php _e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
99
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
100
  </div>
101
  <table class="stats"></table>
102
  </div>
103
  <div class="halfwidth boxsizing framed right lowest_scores" id="lowest_scores">
104
  <div class="boxheader">
105
- <span class="left"><?php _e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
106
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
107
  </div>
108
  <table class="stats"></table>
109
  </div>
@@ -112,17 +112,19 @@ if ( ! defined( 'ABSPATH' ) ) {
112
 
113
  <div id="no_results">
114
  <p>
115
- <?php _e( 'No Pagespeed Reports Found. Google Pagespeed may still be checking your pages. If problems persist, see the following possible solutions:', 'gpagespeedi' ); ?>
116
  </p>
117
  <ol class="no-items">
118
  <?php if ( isset( $current_filter ) && $current_filter != 'all' ) : ?>
119
- <li><?php _e( 'There may not be any results for the "' . esc_html( $current_filter ) . '" filter. Try another filter.', 'gpagespeedi' ); ?></li>
120
  <?php endif; ?>
121
- <?php if ( $this->gpi_options['strategy'] == 'both' ) : ?>
122
- <li><?php echo __( 'There may not be any', 'gpagespeedi' ) . ' ' . $this->gpi_ui_options['view_preference'] . ' ' . __( 'reports completed yet.', 'gpagespeedi' ) . ' ' . __( 'Try switching the report mode.', 'gpagespeedi' ); ?></li>
123
  <?php endif; ?>
124
- <li><?php _e( 'Make sure that you have entered your Google API key on the ', 'gpagespeedi' );?><a href="?page=<?php echo esc_attr( $_REQUEST['page'] ); ?>&render=options"><?php _e( 'Options', 'gpagespeedi' ); ?></a> <?php _e( 'page', 'gpagespeedi' ); ?>.</li>
125
- <li><?php _e( 'Make sure that you have enabled "PageSpeed Insights API" from the Services page of the ', 'gpagespeedi' );?><a href="https://code.google.com/apis/console/"><?php _e( 'Google Console', 'gpagespeedi' ); ?></a>.</li>
126
- <li><?php _e( 'Make sure that your URLs are publicly accessible', 'gpagespeedi' ); ?>.</li>
127
  </ol>
128
- </div>
 
 
12
  <div class="tablenav top">
13
  <div class="alignleft actions">
14
  <form method="get" action="" id="filter" name="filter">
15
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
16
  <input type="hidden" name="render" value="summary" />
17
  <select name="filter" id="filter">
18
  <?php
24
 
25
  if ( is_array( $label ) ) :
26
  ?>
27
+ <optgroup label="<?php echo esc_attr( $label['optgroup_label'] ); ?>">
28
  <?php
29
  foreach ( $label['options'] as $sub_value => $sub_label ) :
30
  ?>
31
+ <option value="<?php echo esc_attr( $sub_value ); ?>" <?php selected( $sub_value, $current_filter ); ?>><?php echo esc_html( $sub_label ); ?></option>
32
  <?php
33
  endforeach;
34
  ?>
36
  <?php
37
  else :
38
  ?>
39
+ <option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $current_filter ); ?>><?php echo esc_html( $label ); ?></option>
40
  <?php
41
  endif;
42
  endforeach;
44
  ?>
45
  </select>
46
  <?php
47
+ submit_button( esc_html__( 'Filter', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
48
  ?>
49
  </form>
50
  </div>
51
  <div class="alignleft actions">
52
  <form method="post" action="" id="savesnapshot" name="savesnapshot">
53
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
54
  <input type="hidden" name="render" value="summary" />
55
  <input type="hidden" name="action" value="save-snapshot" />
56
+ <input type="text" name="comment" placeholder="<?php esc_html_e( 'Report Description', 'gpagespeedi' ); ?>" value="" />
57
  <?php
58
  wp_nonce_field( 'gpi_save_snapshot' );
59
+ submit_button( esc_html__( 'Save Report Snapshot', 'gpagespeedi' ), 'button', 'save-snapshot', false );
60
  ?>
61
  </form>
62
  </div>
70
  <div class="row">
71
  <div class="top-row boxsizing pagespeed_gauge_wrapper" id="pagespeed_gauge_wrapper">
72
  <div class="score_chart_div" id="score_chart_div">
73
+ <img class="pagespeed_needle" id="pagespeed_needle" src="<?php echo esc_url( GPI_PUBLIC_PATH . 'assets/images/pagespeed_gauge_needle.png' ); ?>" width="204" height="204" alt="" />
74
+ <div class="score_text" id="score_text"><span class="score"></span><span class="label"><?php esc_html_e( 'score', 'gpagespeedi' ); ?></span></div>
75
  </div>
76
  </div>
77
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper" id="pagespeed_avg_lab_data_wrapper">
78
  <div class="boxheader">
79
  <span class="left">
80
+ <?php esc_html_e('Average Lab Data Scores', 'gpagespeedi'); ?>
81
+ <span class="light">(<?php esc_html_e('Click for detailed report', 'gpagespeedi'); ?>)</span>
82
  </span>
83
  </div>
84
  <div id="avg_lab_data"></div>
86
  </div>
87
  <div class="row boxsizing framed largest_improvement" id="largest_improvement">
88
  <div class="boxheader">
89
+ <span class="left"><?php esc_html_e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
90
+ <span class="right"><?php esc_html_e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
91
+ <span class="right"><?php esc_html_e( 'Average Score', 'gpagespeedi' ); ?></span>
92
  </div>
93
  <table class="stats"></table>
94
  </div>
95
  <div class="row scores_div">
96
  <div class="halfwidth boxsizing framed left highest_scores" id="highest_scores">
97
  <div class="boxheader">
98
+ <span class="left"><?php esc_html_e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
99
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
100
  </div>
101
  <table class="stats"></table>
102
  </div>
103
  <div class="halfwidth boxsizing framed right lowest_scores" id="lowest_scores">
104
  <div class="boxheader">
105
+ <span class="left"><?php esc_html_e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
106
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
107
  </div>
108
  <table class="stats"></table>
109
  </div>
112
 
113
  <div id="no_results">
114
  <p>
115
+ <?php esc_html_e( 'No Pagespeed Reports Found. Google Pagespeed may still be checking your pages. If problems persist, see the following possible solutions:', 'gpagespeedi' ); ?>
116
  </p>
117
  <ol class="no-items">
118
  <?php if ( isset( $current_filter ) && $current_filter != 'all' ) : ?>
119
+ <li><?php esc_html_e( 'There may not be any results for the "' . esc_html( $current_filter ) . '" filter. Try another filter.', 'gpagespeedi' ); ?></li>
120
  <?php endif; ?>
121
+ <?php if ( 'both' == $this->gpi_options['strategy'] ) : ?>
122
+ <li><?php echo esc_html( __( 'There may not be any', 'gpagespeedi' ) . ' ' . $this->gpi_ui_options['view_preference'] . ' ' . __( 'reports completed yet.', 'gpagespeedi' ) . ' ' . __( 'Try switching the report mode.', 'gpagespeedi' ) ); ?></li>
123
  <?php endif; ?>
124
+ <li><?php esc_html_e( 'Make sure that you have entered your Google API key on the ', 'gpagespeedi' );?><a href="?page=google-pagespeed-insights&render=options"><?php esc_html_e( 'Options', 'gpagespeedi' ); ?></a> <?php esc_html_e( 'page', 'gpagespeedi' ); ?>.</li>
125
+ <li><?php esc_html_e( 'Make sure that you have enabled "PageSpeed Insights API" from the Services page of the ', 'gpagespeedi' );?><a href="https://console.developers.google.com/"><?php esc_html_e( 'Google Console', 'gpagespeedi' ); ?></a>.</li>
126
+ <li><?php esc_html_e( 'Make sure that your URLs are publicly accessible', 'gpagespeedi' ); ?>.</li>
127
  </ol>
128
+ </div>
129
+
130
+ <?php include GPI_DIRECTORY . '/templates/parts/nitropack.php'; ?>
templates/view-snapshot.php CHANGED
@@ -12,7 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  <div class="toolbar">
13
  <div class="left">
14
  <form method="get" action="" name="filter">
15
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
16
  <input type="hidden" name="render" value="view-snapshot" />
17
  <div class="tablenav top snapshots">
18
  <select name="snapshot_id">
@@ -21,13 +21,13 @@ if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  foreach( $similar_snapshots as $snapshot ) :
23
  ?>
24
- <option value="<?php echo $snapshot['ID']; ?>" <?php selected( $snapshot['ID'], intval( $_GET['snapshot_id'] ) ); ?>><?php echo date_i18n( 'M d Y g:ia', $snapshot['snaptime'] ); ?></option>
25
  <?php
26
  endforeach;
27
  ?>
28
  </select>
29
  <?php
30
- submit_button( __( 'Apply', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
31
  ?>
32
  <div class="comment" data-selector="snapshot"></div>
33
  </div>
@@ -36,7 +36,7 @@ if ( ! defined( 'ABSPATH' ) ) {
36
  <?php if ( count( $similar_snapshots ) >= 2 ) : ?>
37
  <div class="right">
38
  <form method="get" action="" name="filter">
39
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
40
  <input type="hidden" name="render" value="view-snapshot" />
41
  <input type="hidden" name="snapshot_id" value="<?php echo intval( $_GET['snapshot_id'] ); ?>" />
42
  <div class="tablenav top snapshots">
@@ -48,13 +48,13 @@ if ( ! defined( 'ABSPATH' ) ) {
48
  endif;
49
  $current_compare_id = isset( $_GET['compare_id'] ) ? intval( $_GET['compare_id'] ) : false
50
  ?>
51
- <option value="<?php echo $snapshot['ID']; ?>" <?php selected( $snapshot['ID'], $current_compare_id ); ?>><?php echo date_i18n( 'M d Y g:ia', $snapshot['snaptime'] ); ?></option>
52
  <?php
53
  endforeach;
54
  ?>
55
  </select>
56
  <?php
57
- submit_button( __( 'Compare', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
58
  ?>
59
  <div class="comment" data-selector="compare"></div>
60
  </div>
@@ -63,19 +63,19 @@ if ( ! defined( 'ABSPATH' ) ) {
63
  <?php endif; ?>
64
  </div>
65
 
66
- <div <?php if ( isset( $_GET['compare_id'] ) ) { echo 'class="left half"'; } ?>>
67
  <div class="row">
68
  <div class="top-row boxsizing pagespeed_gauge_wrapper">
69
  <div class="score_chart_div">
70
- <img class="pagespeed_needle" data-selector="snapshot" src="<?php echo GPI_PUBLIC_PATH; ?>assets/images/pagespeed_gauge_needle.png" width="204" height="204" alt="" />
71
- <div class="score_text"><span class="score" data-selector="snapshot"></span><span class="label"><?php _e( 'score', 'gpagespeedi' ); ?></span></div>
72
  </div>
73
  </div>
74
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper">
75
  <div class="boxheader">
76
  <span class="left">
77
- <?php _e('Average Lab Data Scores', 'gpagespeedi'); ?>
78
- <span class="light">(<?php _e('Click for detailed report', 'gpagespeedi'); ?>)</span>
79
  </span>
80
  </div>
81
  <div class="avg_lab_data" data-selector="snapshot"></div>
@@ -83,24 +83,24 @@ if ( ! defined( 'ABSPATH' ) ) {
83
  </div>
84
  <div class="row boxsizing framed largest_improvement">
85
  <div class="boxheader">
86
- <span class="left"><?php _e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
87
- <span class="right"><?php _e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
88
- <span class="right"><?php _e( 'Average Score', 'gpagespeedi' ); ?></span>
89
  </div>
90
  <table class="stats" data-selector="snapshot"></table>
91
  </div>
92
  <div class="row scores_div">
93
  <div class="halfwidth boxsizing framed left highest_scores">
94
  <div class="boxheader">
95
- <span class="left"><?php _e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
96
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
97
  </div>
98
  <table class="stats" data-selector="snapshot"></table>
99
  </div>
100
  <div class="halfwidth boxsizing framed right lowest_scores">
101
  <div class="boxheader">
102
- <span class="left"><?php _e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
103
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
104
  </div>
105
  <table class="stats" data-selector="snapshot"></table>
106
  </div>
@@ -113,15 +113,15 @@ if ( ! defined( 'ABSPATH' ) ) {
113
  <div class="row">
114
  <div class="top-row boxsizing pagespeed_gauge_wrapper">
115
  <div class="score_chart_div">
116
- <img class="pagespeed_needle" data-selector="compare" src="<?php echo GPI_PUBLIC_PATH; ?>assets/images/pagespeed_gauge_needle.png" width="204" height="204" alt="" />
117
- <div class="score_text"><span class="score" data-selector="compare"></span><span class="label"><?php _e( 'score', 'gpagespeedi' ); ?></span></div>
118
  </div>
119
  </div>
120
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper">
121
  <div class="boxheader">
122
  <span class="left">
123
- <?php _e('Average Lab Data Scores', 'gpagespeedi'); ?>
124
- <span class="light">(<?php _e('Click for detailed report', 'gpagespeedi'); ?>)</span>
125
  </span>
126
  </div>
127
  <div class="avg_lab_data" data-selector="compare"></div>
@@ -129,28 +129,30 @@ if ( ! defined( 'ABSPATH' ) ) {
129
  </div>
130
  <div class="row boxsizing framed largest_improvement">
131
  <div class="boxheader">
132
- <span class="left"><?php _e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
133
- <span class="right"><?php _e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
134
- <span class="right"><?php _e( 'Average Score', 'gpagespeedi' ); ?></span>
135
  </div>
136
  <table class="stats" data-selector="compare"></table>
137
  </div>
138
  <div class="row scores_div">
139
  <div class="halfwidth boxsizing framed left highest_scores">
140
  <div class="boxheader">
141
- <span class="left"><?php _e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
142
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
143
  </div>
144
  <table class="stats" data-selector="compare"></table>
145
  </div>
146
  <div class="halfwidth boxsizing framed right lowest_scores">
147
  <div class="boxheader">
148
- <span class="left"><?php _e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
149
- <span class="right"><?php _e( 'Score', 'gpagespeedi' ); ?></span>
150
  </div>
151
  <table class="stats" data-selector="compare"></table>
152
  </div>
153
  </div>
154
  </div>
155
 
156
- <?php endif; ?>
 
 
12
  <div class="toolbar">
13
  <div class="left">
14
  <form method="get" action="" name="filter">
15
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
16
  <input type="hidden" name="render" value="view-snapshot" />
17
  <div class="tablenav top snapshots">
18
  <select name="snapshot_id">
21
 
22
  foreach( $similar_snapshots as $snapshot ) :
23
  ?>
24
+ <option value="<?php echo intval( $snapshot['ID'] ); ?>" <?php selected( $snapshot['ID'], intval( $_GET['snapshot_id'] ) ); ?>><?php echo esc_html( date_i18n( 'M d Y g:ia', $snapshot['snaptime'] ) ); ?></option>
25
  <?php
26
  endforeach;
27
  ?>
28
  </select>
29
  <?php
30
+ submit_button( esc_html__( 'Apply', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
31
  ?>
32
  <div class="comment" data-selector="snapshot"></div>
33
  </div>
36
  <?php if ( count( $similar_snapshots ) >= 2 ) : ?>
37
  <div class="right">
38
  <form method="get" action="" name="filter">
39
+ <input type="hidden" name="page" value="google-pagespeed-insights" />
40
  <input type="hidden" name="render" value="view-snapshot" />
41
  <input type="hidden" name="snapshot_id" value="<?php echo intval( $_GET['snapshot_id'] ); ?>" />
42
  <div class="tablenav top snapshots">
48
  endif;
49
  $current_compare_id = isset( $_GET['compare_id'] ) ? intval( $_GET['compare_id'] ) : false
50
  ?>
51
+ <option value="<?php echo intval( $snapshot['ID'] ); ?>" <?php selected( $snapshot['ID'], $current_compare_id ); ?>><?php echo esc_html( date_i18n( 'M d Y g:ia', $snapshot['snaptime'] ) ); ?></option>
52
  <?php
53
  endforeach;
54
  ?>
55
  </select>
56
  <?php
57
+ submit_button( esc_html__( 'Compare', 'gpagespeedi' ), 'button', false, false, array( 'id' => 'post-query-submit' ) );
58
  ?>
59
  <div class="comment" data-selector="compare"></div>
60
  </div>
63
  <?php endif; ?>
64
  </div>
65
 
66
+ <div class="<?php if ( isset( $_GET['compare_id'] ) ) { echo esc_attr( 'left half' ); } ?>">
67
  <div class="row">
68
  <div class="top-row boxsizing pagespeed_gauge_wrapper">
69
  <div class="score_chart_div">
70
+ <img class="pagespeed_needle" data-selector="snapshot" src="<?php echo esc_url( GPI_PUBLIC_PATH . 'assets/images/pagespeed_gauge_needle.png' ); ?>" width="204" height="204" alt="" />
71
+ <div class="score_text"><span class="score" data-selector="snapshot"></span><span class="label"><?php esc_html_e( 'score', 'gpagespeedi' ); ?></span></div>
72
  </div>
73
  </div>
74
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper">
75
  <div class="boxheader">
76
  <span class="left">
77
+ <?php esc_html_e('Average Lab Data Scores', 'gpagespeedi'); ?>
78
+ <span class="light">(<?php esc_html_e('Click for detailed report', 'gpagespeedi'); ?>)</span>
79
  </span>
80
  </div>
81
  <div class="avg_lab_data" data-selector="snapshot"></div>
83
  </div>
84
  <div class="row boxsizing framed largest_improvement">
85
  <div class="boxheader">
86
+ <span class="left"><?php esc_html_e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
87
+ <span class="right"><?php esc_html_e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
88
+ <span class="right"><?php esc_html_e( 'Average Score', 'gpagespeedi' ); ?></span>
89
  </div>
90
  <table class="stats" data-selector="snapshot"></table>
91
  </div>
92
  <div class="row scores_div">
93
  <div class="halfwidth boxsizing framed left highest_scores">
94
  <div class="boxheader">
95
+ <span class="left"><?php esc_html_e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
96
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
97
  </div>
98
  <table class="stats" data-selector="snapshot"></table>
99
  </div>
100
  <div class="halfwidth boxsizing framed right lowest_scores">
101
  <div class="boxheader">
102
+ <span class="left"><?php esc_html_e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
103
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
104
  </div>
105
  <table class="stats" data-selector="snapshot"></table>
106
  </div>
113
  <div class="row">
114
  <div class="top-row boxsizing pagespeed_gauge_wrapper">
115
  <div class="score_chart_div">
116
+ <img class="pagespeed_needle" data-selector="compare" src="<?php echo esc_url( GPI_PUBLIC_PATH . 'assets/images/pagespeed_gauge_needle.png' ); ?>" width="204" height="204" alt="" />
117
+ <div class="score_text"><span class="score" data-selector="compare"></span><span class="label"><?php esc_html_e( 'score', 'gpagespeedi' ); ?></span></div>
118
  </div>
119
  </div>
120
  <div class="top-row boxsizing framed pagespeed_avg_lab_data_wrapper">
121
  <div class="boxheader">
122
  <span class="left">
123
+ <?php esc_html_e('Average Lab Data Scores', 'gpagespeedi'); ?>
124
+ <span class="light">(<?php esc_html_e('Click for detailed report', 'gpagespeedi'); ?>)</span>
125
  </span>
126
  </div>
127
  <div class="avg_lab_data" data-selector="compare"></div>
129
  </div>
130
  <div class="row boxsizing framed largest_improvement">
131
  <div class="boxheader">
132
+ <span class="left"><?php esc_html_e( 'Largest Areas for Improvement', 'gpagespeedi' ); ?></span>
133
+ <span class="right"><?php esc_html_e( 'Pages Impacted', 'gpagespeedi' ); ?></span>
134
+ <span class="right"><?php esc_html_e( 'Average Score', 'gpagespeedi' ); ?></span>
135
  </div>
136
  <table class="stats" data-selector="compare"></table>
137
  </div>
138
  <div class="row scores_div">
139
  <div class="halfwidth boxsizing framed left highest_scores">
140
  <div class="boxheader">
141
+ <span class="left"><?php esc_html_e( 'Highest Scoring Pages', 'gpagespeedi' ); ?></span>
142
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
143
  </div>
144
  <table class="stats" data-selector="compare"></table>
145
  </div>
146
  <div class="halfwidth boxsizing framed right lowest_scores">
147
  <div class="boxheader">
148
+ <span class="left"><?php esc_html_e( 'Lowest Scoring Pages', 'gpagespeedi' ); ?></span>
149
+ <span class="right"><?php esc_html_e( 'Score', 'gpagespeedi' ); ?></span>
150
  </div>
151
  <table class="stats" data-selector="compare"></table>
152
  </div>
153
  </div>
154
  </div>
155
 
156
+ <?php endif; ?>
157
+
158
+ <?php include GPI_DIRECTORY . '/templates/parts/nitropack.php'; ?>