Passed
Push — main ( 44ea53...137754 )
by TARIQ
15:15 queued 02:39
created
includes/plugin-update-checker-5-1.0/vendor/ParsedownModern.php 3 patches
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1531,8 +1531,8 @@
 block discarded – undo
1531 1531
         'q', 'rt', 'ins', 'font',          'strong',
1532 1532
         's', 'tt', 'sub', 'mark',
1533 1533
         'u', 'xm', 'sup', 'nobr',
1534
-                   'var', 'ruby',
1535
-                   'wbr', 'span',
1536
-                          'time',
1534
+                    'var', 'ruby',
1535
+                    'wbr', 'span',
1536
+                            'time',
1537 1537
     );
1538 1538
 }
1539 1539
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
 
153 153
             while (isset($line[$indent]) and $line[$indent] === ' ')
154 154
             {
155
-                $indent ++;
155
+                $indent++;
156 156
             }
157 157
 
158 158
             $text = $indent > 0 ? substr($line, $indent) : $line;
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
 
166 166
             if (isset($CurrentBlock['continuable']))
167 167
             {
168
-                $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
168
+                $Block = $this->{'block' . $CurrentBlock['type'] . 'Continue'}($Line, $CurrentBlock);
169 169
 
170 170
                 if (isset($Block))
171 171
                 {
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
                 {
178 178
                     if ($this->isBlockCompletable($CurrentBlock['type']))
179 179
                     {
180
-                        $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
180
+                        $CurrentBlock = $this->{'block' . $CurrentBlock['type'] . 'Complete'}($CurrentBlock);
181 181
                     }
182 182
                 }
183 183
             }
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
             {
195 195
                 foreach ($this->BlockTypes[$marker] as $blockType)
196 196
                 {
197
-                    $blockTypes []= $blockType;
197
+                    $blockTypes [] = $blockType;
198 198
                 }
199 199
             }
200 200
 
@@ -203,15 +203,15 @@  discard block
 block discarded – undo
203 203
 
204 204
             foreach ($blockTypes as $blockType)
205 205
             {
206
-                $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
206
+                $Block = $this->{'block' . $blockType}($Line, $CurrentBlock);
207 207
 
208 208
                 if (isset($Block))
209 209
                 {
210 210
                     $Block['type'] = $blockType;
211 211
 
212
-                    if ( ! isset($Block['identified']))
212
+                    if (!isset($Block['identified']))
213 213
                     {
214
-                        $Blocks []= $CurrentBlock;
214
+                        $Blocks [] = $CurrentBlock;
215 215
 
216 216
                         $Block['identified'] = true;
217 217
                     }
@@ -229,13 +229,13 @@  discard block
 block discarded – undo
229 229
 
230 230
             # ~
231 231
 
232
-            if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
232
+            if (isset($CurrentBlock) and !isset($CurrentBlock['type']) and !isset($CurrentBlock['interrupted']))
233 233
             {
234
-                $CurrentBlock['element']['text'] .= "\n".$text;
234
+                $CurrentBlock['element']['text'] .= "\n" . $text;
235 235
             }
236 236
             else
237 237
             {
238
-                $Blocks []= $CurrentBlock;
238
+                $Blocks [] = $CurrentBlock;
239 239
 
240 240
                 $CurrentBlock = $this->paragraph($Line);
241 241
 
@@ -247,12 +247,12 @@  discard block
 block discarded – undo
247 247
 
248 248
         if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
249 249
         {
250
-            $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
250
+            $CurrentBlock = $this->{'block' . $CurrentBlock['type'] . 'Complete'}($CurrentBlock);
251 251
         }
252 252
 
253 253
         # ~
254 254
 
255
-        $Blocks []= $CurrentBlock;
255
+        $Blocks [] = $CurrentBlock;
256 256
 
257 257
         unset($Blocks[0]);
258 258
 
@@ -280,12 +280,12 @@  discard block
 block discarded – undo
280 280
 
281 281
     protected function isBlockContinuable($Type)
282 282
     {
283
-        return method_exists($this, 'block'.$Type.'Continue');
283
+        return method_exists($this, 'block' . $Type . 'Continue');
284 284
     }
285 285
 
286 286
     protected function isBlockCompletable($Type)
287 287
     {
288
-        return method_exists($this, 'block'.$Type.'Complete');
288
+        return method_exists($this, 'block' . $Type . 'Complete');
289 289
     }
290 290
 
291 291
     #
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
 
294 294
     protected function blockCode($Line, $Block = null)
295 295
     {
296
-        if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
296
+        if (isset($Block) and !isset($Block['type']) and !isset($Block['interrupted']))
297 297
         {
298 298
             return;
299 299
         }
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
 
397 397
     protected function blockFencedCode($Line)
398 398
     {
399
-        if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
399
+        if (preg_match('/^[' . $Line['text'][0] . ']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
400 400
         {
401 401
             $Element = array(
402 402
                 'name' => 'code',
@@ -405,7 +405,7 @@  discard block
 block discarded – undo
405 405
 
406 406
             if (isset($matches[1]))
407 407
             {
408
-                $class = 'language-'.$matches[1];
408
+                $class = 'language-' . $matches[1];
409 409
 
410 410
                 $Element['attributes'] = array(
411 411
                     'class' => $class,
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
             unset($Block['interrupted']);
440 440
         }
441 441
 
442
-        if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
442
+        if (preg_match('/^' . $Block['char'] . '{3,}[ ]*$/', $Line['text']))
443 443
         {
444 444
             $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
445 445
 
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
             return $Block;
449 449
         }
450 450
 
451
-        $Block['element']['text']['text'] .= "\n".$Line['body'];;
451
+        $Block['element']['text']['text'] .= "\n" . $Line['body']; ;
452 452
 
453 453
         return $Block;
454 454
     }
@@ -475,7 +475,7 @@  discard block
 block discarded – undo
475 475
 
476 476
             while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
477 477
             {
478
-                $level ++;
478
+                $level++;
479 479
             }
480 480
 
481 481
             if ($level > 6)
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
     {
505 505
         list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
506 506
 
507
-        if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
507
+        if (preg_match('/^(' . $pattern . '[ ]+)(.*)/', $Line['text'], $matches))
508 508
         {
509 509
             $Block = array(
510 510
                 'indent' => $Line['indent'],
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
                 ),
524 524
             );
525 525
 
526
-            $Block['element']['text'] []= & $Block['li'];
526
+            $Block['element']['text'] [] = & $Block['li'];
527 527
 
528 528
             return $Block;
529 529
         }
@@ -531,11 +531,11 @@  discard block
 block discarded – undo
531 531
 
532 532
     protected function blockListContinue($Line, array $Block)
533 533
     {
534
-        if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
534
+        if ($Block['indent'] === $Line['indent'] and preg_match('/^' . $Block['pattern'] . '(?:[ ]+(.*)|$)/', $Line['text'], $matches))
535 535
         {
536 536
             if (isset($Block['interrupted']))
537 537
             {
538
-                $Block['li']['text'] []= '';
538
+                $Block['li']['text'] [] = '';
539 539
 
540 540
                 unset($Block['interrupted']);
541 541
             }
@@ -552,7 +552,7 @@  discard block
 block discarded – undo
552 552
                 ),
553 553
             );
554 554
 
555
-            $Block['element']['text'] []= & $Block['li'];
555
+            $Block['element']['text'] [] = & $Block['li'];
556 556
 
557 557
             return $Block;
558 558
         }
@@ -562,22 +562,22 @@  discard block
 block discarded – undo
562 562
             return $Block;
563 563
         }
564 564
 
565
-        if ( ! isset($Block['interrupted']))
565
+        if (!isset($Block['interrupted']))
566 566
         {
567 567
             $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
568 568
 
569
-            $Block['li']['text'] []= $text;
569
+            $Block['li']['text'] [] = $text;
570 570
 
571 571
             return $Block;
572 572
         }
573 573
 
574 574
         if ($Line['indent'] > 0)
575 575
         {
576
-            $Block['li']['text'] []= '';
576
+            $Block['li']['text'] [] = '';
577 577
 
578 578
             $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
579 579
 
580
-            $Block['li']['text'] []= $text;
580
+            $Block['li']['text'] [] = $text;
581 581
 
582 582
             unset($Block['interrupted']);
583 583
 
@@ -610,19 +610,19 @@  discard block
 block discarded – undo
610 610
         {
611 611
             if (isset($Block['interrupted']))
612 612
             {
613
-                $Block['element']['text'] []= '';
613
+                $Block['element']['text'] [] = '';
614 614
 
615 615
                 unset($Block['interrupted']);
616 616
             }
617 617
 
618
-            $Block['element']['text'] []= $matches[1];
618
+            $Block['element']['text'] [] = $matches[1];
619 619
 
620 620
             return $Block;
621 621
         }
622 622
 
623
-        if ( ! isset($Block['interrupted']))
623
+        if (!isset($Block['interrupted']))
624 624
         {
625
-            $Block['element']['text'] []= $Line['text'];
625
+            $Block['element']['text'] [] = $Line['text'];
626 626
 
627 627
             return $Block;
628 628
         }
@@ -633,7 +633,7 @@  discard block
 block discarded – undo
633 633
 
634 634
     protected function blockRule($Line)
635 635
     {
636
-        if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
636
+        if (preg_match('/^([' . $Line['text'][0] . '])([ ]*\1){2,}[ ]*$/', $Line['text']))
637 637
         {
638 638
             $Block = array(
639 639
                 'element' => array(
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
 
651 651
     protected function blockSetextHeader($Line, array $Block = null)
652 652
     {
653
-        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
653
+        if (!isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
654 654
         {
655 655
             return;
656 656
         }
@@ -673,7 +673,7 @@  discard block
 block discarded – undo
673 673
             return;
674 674
         }
675 675
 
676
-        if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
676
+        if (preg_match('/^<(\w*)(?:[ ]*' . $this->regexHtmlAttribute . ')*[ ]*(\/)?>/', $Line['text'], $matches))
677 677
         {
678 678
             $element = strtolower($matches[1]);
679 679
 
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
                     return;
709 709
                 }
710 710
 
711
-                if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
711
+                if (preg_match('/<\/' . $matches[1] . '>[ ]*$/i', $remainder))
712 712
                 {
713 713
                     $Block['closed'] = true;
714 714
                 }
@@ -725,16 +725,16 @@  discard block
 block discarded – undo
725 725
             return;
726 726
         }
727 727
 
728
-        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
728
+        if (preg_match('/^<' . $Block['name'] . '(?:[ ]*' . $this->regexHtmlAttribute . ')*[ ]*>/i', $Line['text'])) # open
729 729
         {
730
-            $Block['depth'] ++;
730
+            $Block['depth']++;
731 731
         }
732 732
 
733
-        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
733
+        if (preg_match('/(.*?)<\/' . $Block['name'] . '>[ ]*$/i', $Line['text'], $matches)) # close
734 734
         {
735 735
             if ($Block['depth'] > 0)
736 736
             {
737
-                $Block['depth'] --;
737
+                $Block['depth']--;
738 738
             }
739 739
             else
740 740
             {
@@ -749,7 +749,7 @@  discard block
 block discarded – undo
749 749
             unset($Block['interrupted']);
750 750
         }
751 751
 
752
-        $Block['markup'] .= "\n".$Line['body'];
752
+        $Block['markup'] .= "\n" . $Line['body'];
753 753
 
754 754
         return $Block;
755 755
     }
@@ -788,7 +788,7 @@  discard block
 block discarded – undo
788 788
 
789 789
     protected function blockTable($Line, array $Block = null)
790 790
     {
791
-        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
791
+        if (!isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
792 792
         {
793 793
             return;
794 794
         }
@@ -825,7 +825,7 @@  discard block
 block discarded – undo
825 825
                     $alignment = $alignment === 'left' ? 'center' : 'right';
826 826
                 }
827 827
 
828
-                $alignments []= $alignment;
828
+                $alignments [] = $alignment;
829 829
             }
830 830
 
831 831
             # ~
@@ -854,11 +854,11 @@  discard block
 block discarded – undo
854 854
                     $alignment = $alignments[$index];
855 855
 
856 856
                     $HeaderElement['attributes'] = array(
857
-                        'style' => 'text-align: '.$alignment.';',
857
+                        'style' => 'text-align: ' . $alignment . ';',
858 858
                     );
859 859
                 }
860 860
 
861
-                $HeaderElements []= $HeaderElement;
861
+                $HeaderElements [] = $HeaderElement;
862 862
             }
863 863
 
864 864
             # ~
@@ -872,18 +872,18 @@  discard block
 block discarded – undo
872 872
                 ),
873 873
             );
874 874
 
875
-            $Block['element']['text'] []= array(
875
+            $Block['element']['text'] [] = array(
876 876
                 'name' => 'thead',
877 877
                 'handler' => 'elements',
878 878
             );
879 879
 
880
-            $Block['element']['text'] []= array(
880
+            $Block['element']['text'] [] = array(
881 881
                 'name' => 'tbody',
882 882
                 'handler' => 'elements',
883 883
                 'text' => array(),
884 884
             );
885 885
 
886
-            $Block['element']['text'][0]['text'] []= array(
886
+            $Block['element']['text'][0]['text'] [] = array(
887 887
                 'name' => 'tr',
888 888
                 'handler' => 'elements',
889 889
                 'text' => $HeaderElements,
@@ -924,11 +924,11 @@  discard block
 block discarded – undo
924 924
                 if (isset($Block['alignments'][$index]))
925 925
                 {
926 926
                     $Element['attributes'] = array(
927
-                        'style' => 'text-align: '.$Block['alignments'][$index].';',
927
+                        'style' => 'text-align: ' . $Block['alignments'][$index] . ';',
928 928
                     );
929 929
                 }
930 930
 
931
-                $Elements []= $Element;
931
+                $Elements [] = $Element;
932 932
             }
933 933
 
934 934
             $Element = array(
@@ -937,7 +937,7 @@  discard block
 block discarded – undo
937 937
                 'text' => $Elements,
938 938
             );
939 939
 
940
-            $Block['element']['text'][1]['text'] []= $Element;
940
+            $Block['element']['text'][1]['text'] [] = $Element;
941 941
 
942 942
             return $Block;
943 943
         }
@@ -1003,9 +1003,9 @@  discard block
 block discarded – undo
1003 1003
 
1004 1004
             foreach ($this->InlineTypes[$marker] as $inlineType)
1005 1005
             {
1006
-                $Inline = $this->{'inline'.$inlineType}($Excerpt);
1006
+                $Inline = $this->{'inline' . $inlineType}($Excerpt);
1007 1007
 
1008
-                if ( ! isset($Inline))
1008
+                if (!isset($Inline))
1009 1009
                 {
1010 1010
                     continue;
1011 1011
                 }
@@ -1019,7 +1019,7 @@  discard block
 block discarded – undo
1019 1019
 
1020 1020
                 # sets a default inline position
1021 1021
 
1022
-                if ( ! isset($Inline['position']))
1022
+                if (!isset($Inline['position']))
1023 1023
                 {
1024 1024
                     $Inline['position'] = $markerPosition;
1025 1025
                 }
@@ -1061,7 +1061,7 @@  discard block
 block discarded – undo
1061 1061
     {
1062 1062
         $marker = $Excerpt['text'][0];
1063 1063
 
1064
-        if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
1064
+        if (preg_match('/^(' . $marker . '+)[ ]*(.+?)[ ]*(?<!' . $marker . ')\1(?!' . $marker . ')/s', $Excerpt['text'], $matches))
1065 1065
         {
1066 1066
             $text = $matches[2];
1067 1067
             $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
@@ -1083,7 +1083,7 @@  discard block
 block discarded – undo
1083 1083
         {
1084 1084
             $url = $matches[1];
1085 1085
 
1086
-            if ( ! isset($matches[2]))
1086
+            if (!isset($matches[2]))
1087 1087
             {
1088 1088
                 $url = 'mailto:' . $url;
1089 1089
             }
@@ -1103,7 +1103,7 @@  discard block
 block discarded – undo
1103 1103
 
1104 1104
     protected function inlineEmphasis($Excerpt)
1105 1105
     {
1106
-        if ( ! isset($Excerpt['text'][1]))
1106
+        if (!isset($Excerpt['text'][1]))
1107 1107
         {
1108 1108
             return;
1109 1109
         }
@@ -1146,12 +1146,12 @@  discard block
 block discarded – undo
1146 1146
 
1147 1147
     protected function inlineImage($Excerpt)
1148 1148
     {
1149
-        if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
1149
+        if (!isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
1150 1150
         {
1151 1151
             return;
1152 1152
         }
1153 1153
 
1154
-        $Excerpt['text']= substr($Excerpt['text'], 1);
1154
+        $Excerpt['text'] = substr($Excerpt['text'], 1);
1155 1155
 
1156 1156
         $Link = $this->inlineLink($Excerpt);
1157 1157
 
@@ -1232,7 +1232,7 @@  discard block
 block discarded – undo
1232 1232
                 $definition = strtolower($Element['text']);
1233 1233
             }
1234 1234
 
1235
-            if ( ! isset($this->DefinitionData['Reference'][$definition]))
1235
+            if (!isset($this->DefinitionData['Reference'][$definition]))
1236 1236
             {
1237 1237
                 return;
1238 1238
             }
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
             );
1275 1275
         }
1276 1276
 
1277
-        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
1277
+        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*' . $this->regexHtmlAttribute . ')*[ ]*\/?>/s', $Excerpt['text'], $matches))
1278 1278
         {
1279 1279
             return array(
1280 1280
                 'markup' => $matches[0],
@@ -1285,7 +1285,7 @@  discard block
 block discarded – undo
1285 1285
 
1286 1286
     protected function inlineSpecialCharacter($Excerpt)
1287 1287
     {
1288
-        if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
1288
+        if ($Excerpt['text'][0] === '&' and !preg_match('/^&#?\w+;/', $Excerpt['text']))
1289 1289
         {
1290 1290
             return array(
1291 1291
                 'markup' => '&amp;',
@@ -1298,7 +1298,7 @@  discard block
 block discarded – undo
1298 1298
         if (isset($SpecialCharacter[$Excerpt['text'][0]]))
1299 1299
         {
1300 1300
             return array(
1301
-                'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
1301
+                'markup' => '&' . $SpecialCharacter[$Excerpt['text'][0]] . ';',
1302 1302
                 'extent' => 1,
1303 1303
             );
1304 1304
         }
@@ -1306,7 +1306,7 @@  discard block
 block discarded – undo
1306 1306
 
1307 1307
     protected function inlineStrikethrough($Excerpt)
1308 1308
     {
1309
-        if ( ! isset($Excerpt['text'][1]))
1309
+        if (!isset($Excerpt['text'][1]))
1310 1310
         {
1311 1311
             return;
1312 1312
         }
@@ -1326,7 +1326,7 @@  discard block
 block discarded – undo
1326 1326
 
1327 1327
     protected function inlineUrl($Excerpt)
1328 1328
     {
1329
-        if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
1329
+        if ($this->urlsLinked !== true or !isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
1330 1330
         {
1331 1331
             return;
1332 1332
         }
@@ -1391,7 +1391,7 @@  discard block
 block discarded – undo
1391 1391
 
1392 1392
     protected function element(array $Element)
1393 1393
     {
1394
-        $markup = '<'.$Element['name'];
1394
+        $markup = '<' . $Element['name'];
1395 1395
 
1396 1396
         if (isset($Element['attributes']))
1397 1397
         {
@@ -1402,7 +1402,7 @@  discard block
 block discarded – undo
1402 1402
                     continue;
1403 1403
                 }
1404 1404
 
1405
-                $markup .= ' '.$name.'="'.$value.'"';
1405
+                $markup .= ' ' . $name . '="' . $value . '"';
1406 1406
             }
1407 1407
         }
1408 1408
 
@@ -1419,7 +1419,7 @@  discard block
 block discarded – undo
1419 1419
                 $markup .= $Element['text'];
1420 1420
             }
1421 1421
 
1422
-            $markup .= '</'.$Element['name'].'>';
1422
+            $markup .= '</' . $Element['name'] . '>';
1423 1423
         }
1424 1424
         else
1425 1425
         {
@@ -1451,7 +1451,7 @@  discard block
 block discarded – undo
1451 1451
 
1452 1452
         $trimmedMarkup = trim($markup);
1453 1453
 
1454
-        if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
1454
+        if (!in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
1455 1455
         {
1456 1456
             $markup = $trimmedMarkup;
1457 1457
             $markup = substr($markup, 3);
@@ -1527,8 +1527,8 @@  discard block
 block discarded – undo
1527 1527
     protected $textLevelElements = array(
1528 1528
         'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
1529 1529
         'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
1530
-        'i', 'rp', 'del', 'code',          'strike', 'marquee',
1531
-        'q', 'rt', 'ins', 'font',          'strong',
1530
+        'i', 'rp', 'del', 'code', 'strike', 'marquee',
1531
+        'q', 'rt', 'ins', 'font', 'strong',
1532 1532
         's', 'tt', 'sub', 'mark',
1533 1533
         'u', 'xm', 'sup', 'nobr',
1534 1534
                    'var', 'ruby',
Please login to merge, or discard this patch.
Braces   +18 added lines, -26 removed lines patch added patch discarded remove patch
@@ -172,8 +172,7 @@  discard block
 block discarded – undo
172 172
                     $CurrentBlock = $Block;
173 173
 
174 174
                     continue;
175
-                }
176
-                else
175
+                } else
177 176
                 {
178 177
                     if ($this->isBlockCompletable($CurrentBlock['type']))
179 178
                     {
@@ -232,8 +231,7 @@  discard block
 block discarded – undo
232 231
             if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
233 232
             {
234 233
                 $CurrentBlock['element']['text'] .= "\n".$text;
235
-            }
236
-            else
234
+            } else
237 235
             {
238 236
                 $Blocks []= $CurrentBlock;
239 237
 
@@ -700,8 +698,7 @@  discard block
 block discarded – undo
700 698
 
701 699
                     $Block['void'] = true;
702 700
                 }
703
-            }
704
-            else
701
+            } else
705 702
             {
706 703
                 if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
707 704
                 {
@@ -725,18 +722,21 @@  discard block
 block discarded – undo
725 722
             return;
726 723
         }
727 724
 
728
-        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
725
+        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) {
726
+            # open
729 727
         {
730 728
             $Block['depth'] ++;
731 729
         }
730
+        }
732 731
 
733
-        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
732
+        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) {
733
+            # close
734 734
         {
735 735
             if ($Block['depth'] > 0)
736 736
             {
737 737
                 $Block['depth'] --;
738
-            }
739
-            else
738
+        }
739
+            } else
740 740
             {
741 741
                 $Block['closed'] = true;
742 742
             }
@@ -1113,12 +1113,10 @@  discard block
 block discarded – undo
1113 1113
         if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
1114 1114
         {
1115 1115
             $emphasis = 'strong';
1116
-        }
1117
-        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
1116
+        } elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
1118 1117
         {
1119 1118
             $emphasis = 'em';
1120
-        }
1121
-        else
1119
+        } else
1122 1120
         {
1123 1121
             return;
1124 1122
         }
@@ -1201,8 +1199,7 @@  discard block
 block discarded – undo
1201 1199
             $extent += strlen($matches[0]);
1202 1200
 
1203 1201
             $remainder = substr($remainder, $extent);
1204
-        }
1205
-        else
1202
+        } else
1206 1203
         {
1207 1204
             return;
1208 1205
         }
@@ -1217,8 +1214,7 @@  discard block
 block discarded – undo
1217 1214
             }
1218 1215
 
1219 1216
             $extent += strlen($matches[0]);
1220
-        }
1221
-        else
1217
+        } else
1222 1218
         {
1223 1219
             if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
1224 1220
             {
@@ -1226,8 +1222,7 @@  discard block
 block discarded – undo
1226 1222
                 $definition = strtolower($definition);
1227 1223
 
1228 1224
                 $extent += strlen($matches[0]);
1229
-            }
1230
-            else
1225
+            } else
1231 1226
             {
1232 1227
                 $definition = strtolower($Element['text']);
1233 1228
             }
@@ -1375,8 +1370,7 @@  discard block
 block discarded – undo
1375 1370
         if ($this->breaksEnabled)
1376 1371
         {
1377 1372
             $text = preg_replace('/[ ]*\n/', "<br />\n", $text);
1378
-        }
1379
-        else
1373
+        } else
1380 1374
         {
1381 1375
             $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "<br />\n", $text);
1382 1376
             $text = str_replace(" \n", "\n", $text);
@@ -1413,15 +1407,13 @@  discard block
 block discarded – undo
1413 1407
             if (isset($Element['handler']))
1414 1408
             {
1415 1409
                 $markup .= $this->{$Element['handler']}($Element['text']);
1416
-            }
1417
-            else
1410
+            } else
1418 1411
             {
1419 1412
                 $markup .= $Element['text'];
1420 1413
             }
1421 1414
 
1422 1415
             $markup .= '</'.$Element['name'].'>';
1423
-        }
1424
-        else
1416
+        } else
1425 1417
         {
1426 1418
             $markup .= ' />';
1427 1419
         }
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/vendor/PucReadmeParser.php 3 patches
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -9,339 +9,339 @@
 block discarded – undo
9 9
 
10 10
 class PucReadmeParser {
11 11
 
12
-	function __construct() {
13
-		// This space intentionally blank
14
-	}
15
-
16
-	function parse_readme( $file ) {
17
-		$file_contents = @implode('', @file($file));
18
-		return $this->parse_readme_contents( $file_contents );
19
-	}
20
-
21
-	function parse_readme_contents( $file_contents ) {
22
-		$file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23
-		$file_contents = trim($file_contents);
24
-		if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
-			$file_contents = substr( $file_contents, 3 );
26
-
27
-		// Markdown transformations
28
-		$file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n",     $file_contents );
29
-		$file_contents = preg_replace( "|^##([^#]+)#*?\s*?\n|im",  '==$1=='."\n",   $file_contents );
30
-		$file_contents = preg_replace( "|^#([^#]+)#*?\s*?\n|im",   '===$1==='."\n", $file_contents );
31
-
32
-		// === Plugin Name ===
33
-		// Must be the very first thing.
34
-		if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
35
-			return array(); // require a name
36
-		$name = trim($_name[1], '=');
37
-		$name = $this->sanitize_text( $name );
38
-
39
-		$file_contents = $this->chop_string( $file_contents, $_name[0] );
40
-
41
-
42
-		// Requires at least: 1.5
43
-		if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
44
-			$requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45
-		else
46
-			$requires_at_least = NULL;
47
-
48
-
49
-		// Tested up to: 2.1
50
-		if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
-			$tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
52
-		else
53
-			$tested_up_to = NULL;
54
-
55
-		// Requires PHP: 5.2.4
56
-		if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
57
-			$requires_php = $this->sanitize_text( $_requires_php[1] );
58
-		} else {
59
-			$requires_php = null;
60
-		}
61
-
62
-		// Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
-		if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
64
-			$stable_tag = $this->sanitize_text( $_stable_tag[1] );
65
-		else
66
-			$stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
67
-
68
-
69
-		// Tags: some tag, another tag, we like tags
70
-		if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
71
-			$tags = preg_split('|,[\s]*?|', trim($_tags[1]));
72
-			foreach ( array_keys($tags) as $t )
73
-				$tags[$t] = $this->sanitize_text( $tags[$t] );
74
-		} else {
75
-			$tags = array();
76
-		}
77
-
78
-
79
-		// Contributors: markjaquith, mdawaffe, zefrank
80
-		$contributors = array();
81
-		if ( preg_match('|Contributors:(.*)|i', $file_contents, $_contributors) ) {
82
-			$temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
83
-			foreach ( array_keys($temp_contributors) as $c ) {
84
-				$tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
85
-				if ( strlen(trim($tmp_sanitized)) > 0 )
86
-					$contributors[$c] = $tmp_sanitized;
87
-				unset($tmp_sanitized);
88
-			}
89
-		}
90
-
91
-
92
-		// Donate Link: URL
93
-		if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
94
-			$donate_link = esc_url( $_donate_link[1] );
95
-		else
96
-			$donate_link = NULL;
97
-
98
-
99
-		// togs, conts, etc are optional and order shouldn't matter.  So we chop them only after we've grabbed their values.
100
-		foreach ( array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop ) {
101
-			if ( $$chop ) {
102
-				$_chop = '_' . $chop;
103
-				$file_contents = $this->chop_string( $file_contents, ${$_chop}[0] );
104
-			}
105
-		}
106
-
107
-		$file_contents = trim($file_contents);
108
-
109
-
110
-		// short-description fu
111
-		if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
112
-			$_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
113
-		$short_desc_filtered = $this->sanitize_text( $_short_description[2] );
114
-		$short_desc_length = strlen($short_desc_filtered);
115
-		$short_description = substr($short_desc_filtered, 0, 150);
116
-		if ( $short_desc_length > strlen($short_description) )
117
-			$truncated = true;
118
-		else
119
-			$truncated = false;
120
-		if ( $_short_description[1] )
121
-			$file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
122
-
123
-		// == Section ==
124
-		// Break into sections
125
-		// $_sections[0] will be the title of the first section, $_sections[1] will be the content of the first section
126
-		// the array alternates from there:  title2, content2, title3, content3... and so forth
127
-		$_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
128
-
129
-		$sections = array();
130
-		for ( $i=0; $i < count($_sections); $i +=2 ) {
131
-			$title = $this->sanitize_text( $_sections[$i] );
132
-			if ( isset($_sections[$i+1]) ) {
133
-				$content = preg_replace('/(^[\s]*)=[\s]+(.+?)[\s]+=/m', '$1<h4>$2</h4>', $_sections[$i+1]);
134
-				$content = $this->filter_text( $content, true );
135
-			} else {
136
-				$content = '';
137
-			}
138
-			$sections[str_replace(' ', '_', strtolower($title))] = array('title' => $title, 'content' => $content);
139
-		}
140
-
141
-
142
-		// Special sections
143
-		// This is where we nab our special sections, so we can enforce their order and treat them differently, if needed
144
-		// upgrade_notice is not a section, but parse it like it is for now
145
-		$final_sections = array();
146
-		foreach ( array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section ) {
147
-			if ( isset($sections[$special_section]) ) {
148
-				$final_sections[$special_section] = $sections[$special_section]['content'];
149
-				unset($sections[$special_section]);
150
-			}
151
-		}
152
-		if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
153
-			$final_sections['changelog'] = $final_sections['change_log'];
154
-
155
-
156
-		$final_screenshots = array();
157
-		if ( isset($final_sections['screenshots']) ) {
158
-			preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
159
-			if ( $screenshots ) {
160
-				foreach ( (array) $screenshots as $ss )
161
-					$final_screenshots[] = $ss[1];
162
-			}
163
-		}
164
-
165
-		// Parse the upgrade_notice section specially:
166
-		// 1.0 => blah, 1.1 => fnord
167
-		$upgrade_notice = array();
168
-		if ( isset($final_sections['upgrade_notice']) ) {
169
-			$split = preg_split( '#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
170
-			if ( count($split) >= 2 ) {
171
-				for ( $i = 0; $i < count( $split ); $i += 2 ) {
172
-					$upgrade_notice[$this->sanitize_text( $split[$i] )] = substr( $this->sanitize_text( $split[$i + 1] ), 0, 300 );
173
-				}
174
-			}
175
-			unset( $final_sections['upgrade_notice'] );
176
-		}
177
-
178
-		// No description?
179
-		// No problem... we'll just fall back to the old style of description
180
-		// We'll even let you use markup this time!
181
-		$excerpt = false;
182
-		if ( !isset($final_sections['description']) ) {
183
-			$final_sections = array_merge(array('description' => $this->filter_text( $_short_description[2], true )), $final_sections);
184
-			$excerpt = true;
185
-		}
186
-
187
-
188
-		// dump the non-special sections into $remaining_content
189
-		// their order will be determined by their original order in the readme.txt
190
-		$remaining_content = '';
191
-		foreach ( $sections as $s_name => $s_data ) {
192
-			$remaining_content .= "\n<h3>{$s_data['title']}</h3>\n{$s_data['content']}";
193
-		}
194
-		$remaining_content = trim($remaining_content);
195
-
196
-
197
-		// All done!
198
-		// $r['tags'] and $r['contributors'] are simple arrays
199
-		// $r['sections'] is an array with named elements
200
-		$r = array(
201
-			'name' => $name,
202
-			'tags' => $tags,
203
-			'requires_at_least' => $requires_at_least,
204
-			'tested_up_to' => $tested_up_to,
205
-			'requires_php' => $requires_php,
206
-			'stable_tag' => $stable_tag,
207
-			'contributors' => $contributors,
208
-			'donate_link' => $donate_link,
209
-			'short_description' => $short_description,
210
-			'screenshots' => $final_screenshots,
211
-			'is_excerpt' => $excerpt,
212
-			'is_truncated' => $truncated,
213
-			'sections' => $final_sections,
214
-			'remaining_content' => $remaining_content,
215
-			'upgrade_notice' => $upgrade_notice
216
-		);
217
-
218
-		return $r;
219
-	}
220
-
221
-	function chop_string( $string, $chop ) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
222
-		if ( $_string = strstr($string, $chop) ) {
223
-			$_string = substr($_string, strlen($chop));
224
-			return trim($_string);
225
-		} else {
226
-			return trim($string);
227
-		}
228
-	}
229
-
230
-	function user_sanitize( $text, $strict = false ) { // whitelisted chars
231
-		if ( function_exists('user_sanitize') ) // bbPress native
232
-			return user_sanitize( $text, $strict );
233
-
234
-		if ( $strict ) {
235
-			$text = preg_replace('/[^a-z0-9-]/i', '', $text);
236
-			$text = preg_replace('|-+|', '-', $text);
237
-		} else {
238
-			$text = preg_replace('/[^a-z0-9_-]/i', '', $text);
239
-		}
240
-		return $text;
241
-	}
242
-
243
-	function sanitize_text( $text ) { // not fancy
244
-		$text = strip_tags($text);
245
-		$text = esc_html($text);
246
-		$text = trim($text);
247
-		return $text;
248
-	}
249
-
250
-	function filter_text( $text, $markdown = false ) { // fancy, Markdown
251
-		$text = trim($text);
252
-
253
-		$text = call_user_func( array( __CLASS__, 'code_trick' ), $text, $markdown ); // A better parser than Markdown's for: backticks -> CODE
254
-
255
-		if ( $markdown ) { // Parse markdown.
256
-			if ( !class_exists('Parsedown', false) ) {
257
-				/** @noinspection PhpIncludeInspection */
258
-				require_once(dirname(__FILE__) . '/Parsedown' . (version_compare(PHP_VERSION, '5.3.0', '>=') ? '' : 'Legacy') . '.php');
259
-			}
260
-			$instance = Parsedown::instance();
261
-			$text = $instance->text($text);
262
-		}
263
-
264
-		$allowed = array(
265
-			'a' => array(
266
-				'href' => array(),
267
-				'title' => array(),
268
-				'rel' => array()),
269
-			'blockquote' => array('cite' => array()),
270
-			'br' => array(),
271
-			'p' => array(),
272
-			'code' => array(),
273
-			'pre' => array(),
274
-			'em' => array(),
275
-			'strong' => array(),
276
-			'ul' => array(),
277
-			'ol' => array(),
278
-			'li' => array(),
279
-			'h3' => array(),
280
-			'h4' => array()
281
-		);
282
-
283
-		$text = balanceTags($text);
12
+    function __construct() {
13
+        // This space intentionally blank
14
+    }
15
+
16
+    function parse_readme( $file ) {
17
+        $file_contents = @implode('', @file($file));
18
+        return $this->parse_readme_contents( $file_contents );
19
+    }
20
+
21
+    function parse_readme_contents( $file_contents ) {
22
+        $file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23
+        $file_contents = trim($file_contents);
24
+        if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
+            $file_contents = substr( $file_contents, 3 );
26
+
27
+        // Markdown transformations
28
+        $file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n",     $file_contents );
29
+        $file_contents = preg_replace( "|^##([^#]+)#*?\s*?\n|im",  '==$1=='."\n",   $file_contents );
30
+        $file_contents = preg_replace( "|^#([^#]+)#*?\s*?\n|im",   '===$1==='."\n", $file_contents );
31
+
32
+        // === Plugin Name ===
33
+        // Must be the very first thing.
34
+        if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
35
+            return array(); // require a name
36
+        $name = trim($_name[1], '=');
37
+        $name = $this->sanitize_text( $name );
38
+
39
+        $file_contents = $this->chop_string( $file_contents, $_name[0] );
40
+
41
+
42
+        // Requires at least: 1.5
43
+        if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
44
+            $requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45
+        else
46
+            $requires_at_least = NULL;
47
+
48
+
49
+        // Tested up to: 2.1
50
+        if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
+            $tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
52
+        else
53
+            $tested_up_to = NULL;
54
+
55
+        // Requires PHP: 5.2.4
56
+        if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
57
+            $requires_php = $this->sanitize_text( $_requires_php[1] );
58
+        } else {
59
+            $requires_php = null;
60
+        }
61
+
62
+        // Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
+        if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
64
+            $stable_tag = $this->sanitize_text( $_stable_tag[1] );
65
+        else
66
+            $stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
67
+
68
+
69
+        // Tags: some tag, another tag, we like tags
70
+        if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
71
+            $tags = preg_split('|,[\s]*?|', trim($_tags[1]));
72
+            foreach ( array_keys($tags) as $t )
73
+                $tags[$t] = $this->sanitize_text( $tags[$t] );
74
+        } else {
75
+            $tags = array();
76
+        }
77
+
78
+
79
+        // Contributors: markjaquith, mdawaffe, zefrank
80
+        $contributors = array();
81
+        if ( preg_match('|Contributors:(.*)|i', $file_contents, $_contributors) ) {
82
+            $temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
83
+            foreach ( array_keys($temp_contributors) as $c ) {
84
+                $tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
85
+                if ( strlen(trim($tmp_sanitized)) > 0 )
86
+                    $contributors[$c] = $tmp_sanitized;
87
+                unset($tmp_sanitized);
88
+            }
89
+        }
90
+
91
+
92
+        // Donate Link: URL
93
+        if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
94
+            $donate_link = esc_url( $_donate_link[1] );
95
+        else
96
+            $donate_link = NULL;
97
+
98
+
99
+        // togs, conts, etc are optional and order shouldn't matter.  So we chop them only after we've grabbed their values.
100
+        foreach ( array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop ) {
101
+            if ( $$chop ) {
102
+                $_chop = '_' . $chop;
103
+                $file_contents = $this->chop_string( $file_contents, ${$_chop}[0] );
104
+            }
105
+        }
106
+
107
+        $file_contents = trim($file_contents);
108
+
109
+
110
+        // short-description fu
111
+        if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
112
+            $_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
113
+        $short_desc_filtered = $this->sanitize_text( $_short_description[2] );
114
+        $short_desc_length = strlen($short_desc_filtered);
115
+        $short_description = substr($short_desc_filtered, 0, 150);
116
+        if ( $short_desc_length > strlen($short_description) )
117
+            $truncated = true;
118
+        else
119
+            $truncated = false;
120
+        if ( $_short_description[1] )
121
+            $file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
122
+
123
+        // == Section ==
124
+        // Break into sections
125
+        // $_sections[0] will be the title of the first section, $_sections[1] will be the content of the first section
126
+        // the array alternates from there:  title2, content2, title3, content3... and so forth
127
+        $_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
128
+
129
+        $sections = array();
130
+        for ( $i=0; $i < count($_sections); $i +=2 ) {
131
+            $title = $this->sanitize_text( $_sections[$i] );
132
+            if ( isset($_sections[$i+1]) ) {
133
+                $content = preg_replace('/(^[\s]*)=[\s]+(.+?)[\s]+=/m', '$1<h4>$2</h4>', $_sections[$i+1]);
134
+                $content = $this->filter_text( $content, true );
135
+            } else {
136
+                $content = '';
137
+            }
138
+            $sections[str_replace(' ', '_', strtolower($title))] = array('title' => $title, 'content' => $content);
139
+        }
140
+
141
+
142
+        // Special sections
143
+        // This is where we nab our special sections, so we can enforce their order and treat them differently, if needed
144
+        // upgrade_notice is not a section, but parse it like it is for now
145
+        $final_sections = array();
146
+        foreach ( array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section ) {
147
+            if ( isset($sections[$special_section]) ) {
148
+                $final_sections[$special_section] = $sections[$special_section]['content'];
149
+                unset($sections[$special_section]);
150
+            }
151
+        }
152
+        if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
153
+            $final_sections['changelog'] = $final_sections['change_log'];
154
+
155
+
156
+        $final_screenshots = array();
157
+        if ( isset($final_sections['screenshots']) ) {
158
+            preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
159
+            if ( $screenshots ) {
160
+                foreach ( (array) $screenshots as $ss )
161
+                    $final_screenshots[] = $ss[1];
162
+            }
163
+        }
164
+
165
+        // Parse the upgrade_notice section specially:
166
+        // 1.0 => blah, 1.1 => fnord
167
+        $upgrade_notice = array();
168
+        if ( isset($final_sections['upgrade_notice']) ) {
169
+            $split = preg_split( '#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
170
+            if ( count($split) >= 2 ) {
171
+                for ( $i = 0; $i < count( $split ); $i += 2 ) {
172
+                    $upgrade_notice[$this->sanitize_text( $split[$i] )] = substr( $this->sanitize_text( $split[$i + 1] ), 0, 300 );
173
+                }
174
+            }
175
+            unset( $final_sections['upgrade_notice'] );
176
+        }
177
+
178
+        // No description?
179
+        // No problem... we'll just fall back to the old style of description
180
+        // We'll even let you use markup this time!
181
+        $excerpt = false;
182
+        if ( !isset($final_sections['description']) ) {
183
+            $final_sections = array_merge(array('description' => $this->filter_text( $_short_description[2], true )), $final_sections);
184
+            $excerpt = true;
185
+        }
186
+
187
+
188
+        // dump the non-special sections into $remaining_content
189
+        // their order will be determined by their original order in the readme.txt
190
+        $remaining_content = '';
191
+        foreach ( $sections as $s_name => $s_data ) {
192
+            $remaining_content .= "\n<h3>{$s_data['title']}</h3>\n{$s_data['content']}";
193
+        }
194
+        $remaining_content = trim($remaining_content);
195
+
196
+
197
+        // All done!
198
+        // $r['tags'] and $r['contributors'] are simple arrays
199
+        // $r['sections'] is an array with named elements
200
+        $r = array(
201
+            'name' => $name,
202
+            'tags' => $tags,
203
+            'requires_at_least' => $requires_at_least,
204
+            'tested_up_to' => $tested_up_to,
205
+            'requires_php' => $requires_php,
206
+            'stable_tag' => $stable_tag,
207
+            'contributors' => $contributors,
208
+            'donate_link' => $donate_link,
209
+            'short_description' => $short_description,
210
+            'screenshots' => $final_screenshots,
211
+            'is_excerpt' => $excerpt,
212
+            'is_truncated' => $truncated,
213
+            'sections' => $final_sections,
214
+            'remaining_content' => $remaining_content,
215
+            'upgrade_notice' => $upgrade_notice
216
+        );
217
+
218
+        return $r;
219
+    }
220
+
221
+    function chop_string( $string, $chop ) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
222
+        if ( $_string = strstr($string, $chop) ) {
223
+            $_string = substr($_string, strlen($chop));
224
+            return trim($_string);
225
+        } else {
226
+            return trim($string);
227
+        }
228
+    }
229
+
230
+    function user_sanitize( $text, $strict = false ) { // whitelisted chars
231
+        if ( function_exists('user_sanitize') ) // bbPress native
232
+            return user_sanitize( $text, $strict );
233
+
234
+        if ( $strict ) {
235
+            $text = preg_replace('/[^a-z0-9-]/i', '', $text);
236
+            $text = preg_replace('|-+|', '-', $text);
237
+        } else {
238
+            $text = preg_replace('/[^a-z0-9_-]/i', '', $text);
239
+        }
240
+        return $text;
241
+    }
242
+
243
+    function sanitize_text( $text ) { // not fancy
244
+        $text = strip_tags($text);
245
+        $text = esc_html($text);
246
+        $text = trim($text);
247
+        return $text;
248
+    }
249
+
250
+    function filter_text( $text, $markdown = false ) { // fancy, Markdown
251
+        $text = trim($text);
252
+
253
+        $text = call_user_func( array( __CLASS__, 'code_trick' ), $text, $markdown ); // A better parser than Markdown's for: backticks -> CODE
254
+
255
+        if ( $markdown ) { // Parse markdown.
256
+            if ( !class_exists('Parsedown', false) ) {
257
+                /** @noinspection PhpIncludeInspection */
258
+                require_once(dirname(__FILE__) . '/Parsedown' . (version_compare(PHP_VERSION, '5.3.0', '>=') ? '' : 'Legacy') . '.php');
259
+            }
260
+            $instance = Parsedown::instance();
261
+            $text = $instance->text($text);
262
+        }
263
+
264
+        $allowed = array(
265
+            'a' => array(
266
+                'href' => array(),
267
+                'title' => array(),
268
+                'rel' => array()),
269
+            'blockquote' => array('cite' => array()),
270
+            'br' => array(),
271
+            'p' => array(),
272
+            'code' => array(),
273
+            'pre' => array(),
274
+            'em' => array(),
275
+            'strong' => array(),
276
+            'ul' => array(),
277
+            'ol' => array(),
278
+            'li' => array(),
279
+            'h3' => array(),
280
+            'h4' => array()
281
+        );
282
+
283
+        $text = balanceTags($text);
284 284
 		
285
-		$text = wp_kses( $text, $allowed );
286
-		$text = trim($text);
287
-		return $text;
288
-	}
289
-
290
-	function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
291
-		// If doing markdown, first take any user formatted code blocks and turn them into backticks so that
292
-		// markdown will preserve things like underscores in code blocks
293
-		if ( $markdown )
294
-			$text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
295
-
296
-		$text = str_replace(array("\r\n", "\r"), "\n", $text);
297
-		if ( !$markdown ) {
298
-			// This gets the "inline" code blocks, but can't be used with Markdown.
299
-			$text = preg_replace_callback("|(`)(.*?)`|", array( __CLASS__, 'encodeit'), $text);
300
-			// This gets the "block level" code blocks and converts them to PRE CODE
301
-			$text = preg_replace_callback("!(^|\n)`(.*?)`!s", array( __CLASS__, 'encodeit'), $text);
302
-		} else {
303
-			// Markdown can do inline code, we convert bbPress style block level code to Markdown style
304
-			$text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array( __CLASS__, 'indent'), $text);
305
-		}
306
-		return $text;
307
-	}
308
-
309
-	function indent( $matches ) {
310
-		$text = $matches[3];
311
-		$text = preg_replace('|^|m', $matches[2] . '    ', $text);
312
-		return $matches[1] . $text;
313
-	}
314
-
315
-	function encodeit( $matches ) {
316
-		if ( function_exists('encodeit') ) // bbPress native
317
-			return encodeit( $matches );
318
-
319
-		$text = trim($matches[2]);
320
-		$text = htmlspecialchars($text, ENT_QUOTES);
321
-		$text = str_replace(array("\r\n", "\r"), "\n", $text);
322
-		$text = preg_replace("|\n\n\n+|", "\n\n", $text);
323
-		$text = str_replace('&amp;lt;', '&lt;', $text);
324
-		$text = str_replace('&amp;gt;', '&gt;', $text);
325
-		$text = "<code>$text</code>";
326
-		if ( "`" != $matches[1] )
327
-			$text = "<pre>$text</pre>";
328
-		return $text;
329
-	}
330
-
331
-	function decodeit( $matches ) {
332
-		if ( function_exists('decodeit') ) // bbPress native
333
-			return decodeit( $matches );
334
-
335
-		$text = $matches[2];
336
-		$trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
337
-		$text = strtr($text, $trans_table);
338
-		$text = str_replace('<br />', '', $text);
339
-		$text = str_replace('&#38;', '&', $text);
340
-		$text = str_replace('&#39;', "'", $text);
341
-		if ( '<pre><code>' == $matches[1] )
342
-			$text = "\n$text\n";
343
-		return "`$text`";
344
-	}
285
+        $text = wp_kses( $text, $allowed );
286
+        $text = trim($text);
287
+        return $text;
288
+    }
289
+
290
+    function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
291
+        // If doing markdown, first take any user formatted code blocks and turn them into backticks so that
292
+        // markdown will preserve things like underscores in code blocks
293
+        if ( $markdown )
294
+            $text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
295
+
296
+        $text = str_replace(array("\r\n", "\r"), "\n", $text);
297
+        if ( !$markdown ) {
298
+            // This gets the "inline" code blocks, but can't be used with Markdown.
299
+            $text = preg_replace_callback("|(`)(.*?)`|", array( __CLASS__, 'encodeit'), $text);
300
+            // This gets the "block level" code blocks and converts them to PRE CODE
301
+            $text = preg_replace_callback("!(^|\n)`(.*?)`!s", array( __CLASS__, 'encodeit'), $text);
302
+        } else {
303
+            // Markdown can do inline code, we convert bbPress style block level code to Markdown style
304
+            $text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array( __CLASS__, 'indent'), $text);
305
+        }
306
+        return $text;
307
+    }
308
+
309
+    function indent( $matches ) {
310
+        $text = $matches[3];
311
+        $text = preg_replace('|^|m', $matches[2] . '    ', $text);
312
+        return $matches[1] . $text;
313
+    }
314
+
315
+    function encodeit( $matches ) {
316
+        if ( function_exists('encodeit') ) // bbPress native
317
+            return encodeit( $matches );
318
+
319
+        $text = trim($matches[2]);
320
+        $text = htmlspecialchars($text, ENT_QUOTES);
321
+        $text = str_replace(array("\r\n", "\r"), "\n", $text);
322
+        $text = preg_replace("|\n\n\n+|", "\n\n", $text);
323
+        $text = str_replace('&amp;lt;', '&lt;', $text);
324
+        $text = str_replace('&amp;gt;', '&gt;', $text);
325
+        $text = "<code>$text</code>";
326
+        if ( "`" != $matches[1] )
327
+            $text = "<pre>$text</pre>";
328
+        return $text;
329
+    }
330
+
331
+    function decodeit( $matches ) {
332
+        if ( function_exists('decodeit') ) // bbPress native
333
+            return decodeit( $matches );
334
+
335
+        $text = $matches[2];
336
+        $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
337
+        $text = strtr($text, $trans_table);
338
+        $text = str_replace('<br />', '', $text);
339
+        $text = str_replace('&#38;', '&', $text);
340
+        $text = str_replace('&#39;', "'", $text);
341
+        if ( '<pre><code>' == $matches[1] )
342
+            $text = "\n$text\n";
343
+        return "`$text`";
344
+    }
345 345
 
346 346
 } // end class
347 347
 
Please login to merge, or discard this patch.
Spacing   +86 added lines, -86 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if ( !class_exists('PucReadmeParser', false) ):
3
+if (!class_exists('PucReadmeParser', false)):
4 4
 
5 5
 /**
6 6
  * This is a slightly modified version of github.com/markjaquith/WordPress-Plugin-Readme-Parser
@@ -13,64 +13,64 @@  discard block
 block discarded – undo
13 13
 		// This space intentionally blank
14 14
 	}
15 15
 
16
-	function parse_readme( $file ) {
16
+	function parse_readme($file) {
17 17
 		$file_contents = @implode('', @file($file));
18
-		return $this->parse_readme_contents( $file_contents );
18
+		return $this->parse_readme_contents($file_contents);
19 19
 	}
20 20
 
21
-	function parse_readme_contents( $file_contents ) {
21
+	function parse_readme_contents($file_contents) {
22 22
 		$file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23 23
 		$file_contents = trim($file_contents);
24
-		if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
-			$file_contents = substr( $file_contents, 3 );
24
+		if (0 === strpos($file_contents, "\xEF\xBB\xBF"))
25
+			$file_contents = substr($file_contents, 3);
26 26
 
27 27
 		// Markdown transformations
28
-		$file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n",     $file_contents );
29
-		$file_contents = preg_replace( "|^##([^#]+)#*?\s*?\n|im",  '==$1=='."\n",   $file_contents );
30
-		$file_contents = preg_replace( "|^#([^#]+)#*?\s*?\n|im",   '===$1==='."\n", $file_contents );
28
+		$file_contents = preg_replace("|^###([^#]+)#*?\s*?\n|im", '=$1=' . "\n", $file_contents);
29
+		$file_contents = preg_replace("|^##([^#]+)#*?\s*?\n|im", '==$1==' . "\n", $file_contents);
30
+		$file_contents = preg_replace("|^#([^#]+)#*?\s*?\n|im", '===$1===' . "\n", $file_contents);
31 31
 
32 32
 		// === Plugin Name ===
33 33
 		// Must be the very first thing.
34
-		if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
34
+		if (!preg_match('|^===(.*)===|', $file_contents, $_name))
35 35
 			return array(); // require a name
36 36
 		$name = trim($_name[1], '=');
37
-		$name = $this->sanitize_text( $name );
37
+		$name = $this->sanitize_text($name);
38 38
 
39
-		$file_contents = $this->chop_string( $file_contents, $_name[0] );
39
+		$file_contents = $this->chop_string($file_contents, $_name[0]);
40 40
 
41 41
 
42 42
 		// Requires at least: 1.5
43
-		if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
43
+		if (preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least))
44 44
 			$requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45 45
 		else
46 46
 			$requires_at_least = NULL;
47 47
 
48 48
 
49 49
 		// Tested up to: 2.1
50
-		if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
-			$tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
50
+		if (preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to))
51
+			$tested_up_to = $this->sanitize_text($_tested_up_to[1]);
52 52
 		else
53 53
 			$tested_up_to = NULL;
54 54
 
55 55
 		// Requires PHP: 5.2.4
56
-		if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
57
-			$requires_php = $this->sanitize_text( $_requires_php[1] );
56
+		if (preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php)) {
57
+			$requires_php = $this->sanitize_text($_requires_php[1]);
58 58
 		} else {
59 59
 			$requires_php = null;
60 60
 		}
61 61
 
62 62
 		// Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
-		if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
64
-			$stable_tag = $this->sanitize_text( $_stable_tag[1] );
63
+		if (preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag))
64
+			$stable_tag = $this->sanitize_text($_stable_tag[1]);
65 65
 		else
66 66
 			$stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
67 67
 
68 68
 
69 69
 		// Tags: some tag, another tag, we like tags
70
-		if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
70
+		if (preg_match('|Tags:(.*)|i', $file_contents, $_tags)) {
71 71
 			$tags = preg_split('|,[\s]*?|', trim($_tags[1]));
72
-			foreach ( array_keys($tags) as $t )
73
-				$tags[$t] = $this->sanitize_text( $tags[$t] );
72
+			foreach (array_keys($tags) as $t)
73
+				$tags[$t] = $this->sanitize_text($tags[$t]);
74 74
 		} else {
75 75
 			$tags = array();
76 76
 		}
@@ -78,11 +78,11 @@  discard block
 block discarded – undo
78 78
 
79 79
 		// Contributors: markjaquith, mdawaffe, zefrank
80 80
 		$contributors = array();
81
-		if ( preg_match('|Contributors:(.*)|i', $file_contents, $_contributors) ) {
81
+		if (preg_match('|Contributors:(.*)|i', $file_contents, $_contributors)) {
82 82
 			$temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
83
-			foreach ( array_keys($temp_contributors) as $c ) {
84
-				$tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
85
-				if ( strlen(trim($tmp_sanitized)) > 0 )
83
+			foreach (array_keys($temp_contributors) as $c) {
84
+				$tmp_sanitized = $this->user_sanitize($temp_contributors[$c]);
85
+				if (strlen(trim($tmp_sanitized)) > 0)
86 86
 					$contributors[$c] = $tmp_sanitized;
87 87
 				unset($tmp_sanitized);
88 88
 			}
@@ -90,17 +90,17 @@  discard block
 block discarded – undo
90 90
 
91 91
 
92 92
 		// Donate Link: URL
93
-		if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
94
-			$donate_link = esc_url( $_donate_link[1] );
93
+		if (preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link))
94
+			$donate_link = esc_url($_donate_link[1]);
95 95
 		else
96 96
 			$donate_link = NULL;
97 97
 
98 98
 
99 99
 		// togs, conts, etc are optional and order shouldn't matter.  So we chop them only after we've grabbed their values.
100
-		foreach ( array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop ) {
101
-			if ( $$chop ) {
100
+		foreach (array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop) {
101
+			if ($$chop) {
102 102
 				$_chop = '_' . $chop;
103
-				$file_contents = $this->chop_string( $file_contents, ${$_chop}[0] );
103
+				$file_contents = $this->chop_string($file_contents, ${$_chop}[0]);
104 104
 			}
105 105
 		}
106 106
 
@@ -108,30 +108,30 @@  discard block
 block discarded – undo
108 108
 
109 109
 
110 110
 		// short-description fu
111
-		if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
112
-			$_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
113
-		$short_desc_filtered = $this->sanitize_text( $_short_description[2] );
111
+		if (!preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description))
112
+			$_short_description = array(1 => &$file_contents, 2 => &$file_contents);
113
+		$short_desc_filtered = $this->sanitize_text($_short_description[2]);
114 114
 		$short_desc_length = strlen($short_desc_filtered);
115 115
 		$short_description = substr($short_desc_filtered, 0, 150);
116
-		if ( $short_desc_length > strlen($short_description) )
116
+		if ($short_desc_length > strlen($short_description))
117 117
 			$truncated = true;
118 118
 		else
119 119
 			$truncated = false;
120
-		if ( $_short_description[1] )
121
-			$file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
120
+		if ($_short_description[1])
121
+			$file_contents = $this->chop_string($file_contents, $_short_description[1]); // yes, the [1] is intentional
122 122
 
123 123
 		// == Section ==
124 124
 		// Break into sections
125 125
 		// $_sections[0] will be the title of the first section, $_sections[1] will be the content of the first section
126 126
 		// the array alternates from there:  title2, content2, title3, content3... and so forth
127
-		$_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
127
+		$_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
128 128
 
129 129
 		$sections = array();
130
-		for ( $i=0; $i < count($_sections); $i +=2 ) {
131
-			$title = $this->sanitize_text( $_sections[$i] );
132
-			if ( isset($_sections[$i+1]) ) {
133
-				$content = preg_replace('/(^[\s]*)=[\s]+(.+?)[\s]+=/m', '$1<h4>$2</h4>', $_sections[$i+1]);
134
-				$content = $this->filter_text( $content, true );
130
+		for ($i = 0; $i < count($_sections); $i += 2) {
131
+			$title = $this->sanitize_text($_sections[$i]);
132
+			if (isset($_sections[$i + 1])) {
133
+				$content = preg_replace('/(^[\s]*)=[\s]+(.+?)[\s]+=/m', '$1<h4>$2</h4>', $_sections[$i + 1]);
134
+				$content = $this->filter_text($content, true);
135 135
 			} else {
136 136
 				$content = '';
137 137
 			}
@@ -143,21 +143,21 @@  discard block
 block discarded – undo
143 143
 		// This is where we nab our special sections, so we can enforce their order and treat them differently, if needed
144 144
 		// upgrade_notice is not a section, but parse it like it is for now
145 145
 		$final_sections = array();
146
-		foreach ( array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section ) {
147
-			if ( isset($sections[$special_section]) ) {
146
+		foreach (array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section) {
147
+			if (isset($sections[$special_section])) {
148 148
 				$final_sections[$special_section] = $sections[$special_section]['content'];
149 149
 				unset($sections[$special_section]);
150 150
 			}
151 151
 		}
152
-		if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
152
+		if (isset($final_sections['change_log']) && empty($final_sections['changelog']))
153 153
 			$final_sections['changelog'] = $final_sections['change_log'];
154 154
 
155 155
 
156 156
 		$final_screenshots = array();
157
-		if ( isset($final_sections['screenshots']) ) {
157
+		if (isset($final_sections['screenshots'])) {
158 158
 			preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
159
-			if ( $screenshots ) {
160
-				foreach ( (array) $screenshots as $ss )
159
+			if ($screenshots) {
160
+				foreach ((array) $screenshots as $ss)
161 161
 					$final_screenshots[] = $ss[1];
162 162
 			}
163 163
 		}
@@ -165,22 +165,22 @@  discard block
 block discarded – undo
165 165
 		// Parse the upgrade_notice section specially:
166 166
 		// 1.0 => blah, 1.1 => fnord
167 167
 		$upgrade_notice = array();
168
-		if ( isset($final_sections['upgrade_notice']) ) {
169
-			$split = preg_split( '#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
170
-			if ( count($split) >= 2 ) {
171
-				for ( $i = 0; $i < count( $split ); $i += 2 ) {
172
-					$upgrade_notice[$this->sanitize_text( $split[$i] )] = substr( $this->sanitize_text( $split[$i + 1] ), 0, 300 );
168
+		if (isset($final_sections['upgrade_notice'])) {
169
+			$split = preg_split('#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
170
+			if (count($split) >= 2) {
171
+				for ($i = 0; $i < count($split); $i += 2) {
172
+					$upgrade_notice[$this->sanitize_text($split[$i])] = substr($this->sanitize_text($split[$i + 1]), 0, 300);
173 173
 				}
174 174
 			}
175
-			unset( $final_sections['upgrade_notice'] );
175
+			unset($final_sections['upgrade_notice']);
176 176
 		}
177 177
 
178 178
 		// No description?
179 179
 		// No problem... we'll just fall back to the old style of description
180 180
 		// We'll even let you use markup this time!
181 181
 		$excerpt = false;
182
-		if ( !isset($final_sections['description']) ) {
183
-			$final_sections = array_merge(array('description' => $this->filter_text( $_short_description[2], true )), $final_sections);
182
+		if (!isset($final_sections['description'])) {
183
+			$final_sections = array_merge(array('description' => $this->filter_text($_short_description[2], true)), $final_sections);
184 184
 			$excerpt = true;
185 185
 		}
186 186
 
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 		// dump the non-special sections into $remaining_content
189 189
 		// their order will be determined by their original order in the readme.txt
190 190
 		$remaining_content = '';
191
-		foreach ( $sections as $s_name => $s_data ) {
191
+		foreach ($sections as $s_name => $s_data) {
192 192
 			$remaining_content .= "\n<h3>{$s_data['title']}</h3>\n{$s_data['content']}";
193 193
 		}
194 194
 		$remaining_content = trim($remaining_content);
@@ -218,8 +218,8 @@  discard block
 block discarded – undo
218 218
 		return $r;
219 219
 	}
220 220
 
221
-	function chop_string( $string, $chop ) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
222
-		if ( $_string = strstr($string, $chop) ) {
221
+	function chop_string($string, $chop) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
222
+		if ($_string = strstr($string, $chop)) {
223 223
 			$_string = substr($_string, strlen($chop));
224 224
 			return trim($_string);
225 225
 		} else {
@@ -227,11 +227,11 @@  discard block
 block discarded – undo
227 227
 		}
228 228
 	}
229 229
 
230
-	function user_sanitize( $text, $strict = false ) { // whitelisted chars
231
-		if ( function_exists('user_sanitize') ) // bbPress native
232
-			return user_sanitize( $text, $strict );
230
+	function user_sanitize($text, $strict = false) { // whitelisted chars
231
+		if (function_exists('user_sanitize')) // bbPress native
232
+			return user_sanitize($text, $strict);
233 233
 
234
-		if ( $strict ) {
234
+		if ($strict) {
235 235
 			$text = preg_replace('/[^a-z0-9-]/i', '', $text);
236 236
 			$text = preg_replace('|-+|', '-', $text);
237 237
 		} else {
@@ -240,20 +240,20 @@  discard block
 block discarded – undo
240 240
 		return $text;
241 241
 	}
242 242
 
243
-	function sanitize_text( $text ) { // not fancy
243
+	function sanitize_text($text) { // not fancy
244 244
 		$text = strip_tags($text);
245 245
 		$text = esc_html($text);
246 246
 		$text = trim($text);
247 247
 		return $text;
248 248
 	}
249 249
 
250
-	function filter_text( $text, $markdown = false ) { // fancy, Markdown
250
+	function filter_text($text, $markdown = false) { // fancy, Markdown
251 251
 		$text = trim($text);
252 252
 
253
-		$text = call_user_func( array( __CLASS__, 'code_trick' ), $text, $markdown ); // A better parser than Markdown's for: backticks -> CODE
253
+		$text = call_user_func(array(__CLASS__, 'code_trick'), $text, $markdown); // A better parser than Markdown's for: backticks -> CODE
254 254
 
255
-		if ( $markdown ) { // Parse markdown.
256
-			if ( !class_exists('Parsedown', false) ) {
255
+		if ($markdown) { // Parse markdown.
256
+			if (!class_exists('Parsedown', false)) {
257 257
 				/** @noinspection PhpIncludeInspection */
258 258
 				require_once(dirname(__FILE__) . '/Parsedown' . (version_compare(PHP_VERSION, '5.3.0', '>=') ? '' : 'Legacy') . '.php');
259 259
 			}
@@ -282,39 +282,39 @@  discard block
 block discarded – undo
282 282
 
283 283
 		$text = balanceTags($text);
284 284
 		
285
-		$text = wp_kses( $text, $allowed );
285
+		$text = wp_kses($text, $allowed);
286 286
 		$text = trim($text);
287 287
 		return $text;
288 288
 	}
289 289
 
290
-	function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
290
+	function code_trick($text, $markdown) { // Don't use bbPress native function - it's incompatible with Markdown
291 291
 		// If doing markdown, first take any user formatted code blocks and turn them into backticks so that
292 292
 		// markdown will preserve things like underscores in code blocks
293
-		if ( $markdown )
294
-			$text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
293
+		if ($markdown)
294
+			$text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array(__CLASS__, 'decodeit'), $text);
295 295
 
296 296
 		$text = str_replace(array("\r\n", "\r"), "\n", $text);
297
-		if ( !$markdown ) {
297
+		if (!$markdown) {
298 298
 			// This gets the "inline" code blocks, but can't be used with Markdown.
299
-			$text = preg_replace_callback("|(`)(.*?)`|", array( __CLASS__, 'encodeit'), $text);
299
+			$text = preg_replace_callback("|(`)(.*?)`|", array(__CLASS__, 'encodeit'), $text);
300 300
 			// This gets the "block level" code blocks and converts them to PRE CODE
301
-			$text = preg_replace_callback("!(^|\n)`(.*?)`!s", array( __CLASS__, 'encodeit'), $text);
301
+			$text = preg_replace_callback("!(^|\n)`(.*?)`!s", array(__CLASS__, 'encodeit'), $text);
302 302
 		} else {
303 303
 			// Markdown can do inline code, we convert bbPress style block level code to Markdown style
304
-			$text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array( __CLASS__, 'indent'), $text);
304
+			$text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array(__CLASS__, 'indent'), $text);
305 305
 		}
306 306
 		return $text;
307 307
 	}
308 308
 
309
-	function indent( $matches ) {
309
+	function indent($matches) {
310 310
 		$text = $matches[3];
311 311
 		$text = preg_replace('|^|m', $matches[2] . '    ', $text);
312 312
 		return $matches[1] . $text;
313 313
 	}
314 314
 
315
-	function encodeit( $matches ) {
316
-		if ( function_exists('encodeit') ) // bbPress native
317
-			return encodeit( $matches );
315
+	function encodeit($matches) {
316
+		if (function_exists('encodeit')) // bbPress native
317
+			return encodeit($matches);
318 318
 
319 319
 		$text = trim($matches[2]);
320 320
 		$text = htmlspecialchars($text, ENT_QUOTES);
@@ -323,14 +323,14 @@  discard block
 block discarded – undo
323 323
 		$text = str_replace('&amp;lt;', '&lt;', $text);
324 324
 		$text = str_replace('&amp;gt;', '&gt;', $text);
325 325
 		$text = "<code>$text</code>";
326
-		if ( "`" != $matches[1] )
326
+		if ("`" != $matches[1])
327 327
 			$text = "<pre>$text</pre>";
328 328
 		return $text;
329 329
 	}
330 330
 
331
-	function decodeit( $matches ) {
332
-		if ( function_exists('decodeit') ) // bbPress native
333
-			return decodeit( $matches );
331
+	function decodeit($matches) {
332
+		if (function_exists('decodeit')) // bbPress native
333
+			return decodeit($matches);
334 334
 
335 335
 		$text = $matches[2];
336 336
 		$trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
 		$text = str_replace('<br />', '', $text);
339 339
 		$text = str_replace('&#38;', '&', $text);
340 340
 		$text = str_replace('&#39;', "'", $text);
341
-		if ( '<pre><code>' == $matches[1] )
341
+		if ('<pre><code>' == $matches[1])
342 342
 			$text = "\n$text\n";
343 343
 		return "`$text`";
344 344
 	}
Please login to merge, or discard this patch.
Braces   +70 added lines, -45 removed lines patch added patch discarded remove patch
@@ -21,8 +21,9 @@  discard block
 block discarded – undo
21 21
 	function parse_readme_contents( $file_contents ) {
22 22
 		$file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23 23
 		$file_contents = trim($file_contents);
24
-		if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
-			$file_contents = substr( $file_contents, 3 );
24
+		if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) ) {
25
+					$file_contents = substr( $file_contents, 3 );
26
+		}
26 27
 
27 28
 		// Markdown transformations
28 29
 		$file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n",     $file_contents );
@@ -31,8 +32,10 @@  discard block
 block discarded – undo
31 32
 
32 33
 		// === Plugin Name ===
33 34
 		// Must be the very first thing.
34
-		if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
35
-			return array(); // require a name
35
+		if ( !preg_match('|^===(.*)===|', $file_contents, $_name) ) {
36
+					return array();
37
+		}
38
+		// require a name
36 39
 		$name = trim($_name[1], '=');
37 40
 		$name = $this->sanitize_text( $name );
38 41
 
@@ -40,17 +43,19 @@  discard block
 block discarded – undo
40 43
 
41 44
 
42 45
 		// Requires at least: 1.5
43
-		if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
44
-			$requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45
-		else
46
-			$requires_at_least = NULL;
46
+		if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) ) {
47
+					$requires_at_least = $this->sanitize_text($_requires_at_least[1]);
48
+		} else {
49
+					$requires_at_least = NULL;
50
+		}
47 51
 
48 52
 
49 53
 		// Tested up to: 2.1
50
-		if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
-			$tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
52
-		else
53
-			$tested_up_to = NULL;
54
+		if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) ) {
55
+					$tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
56
+		} else {
57
+					$tested_up_to = NULL;
58
+		}
54 59
 
55 60
 		// Requires PHP: 5.2.4
56 61
 		if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
@@ -60,17 +65,20 @@  discard block
 block discarded – undo
60 65
 		}
61 66
 
62 67
 		// Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
-		if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
64
-			$stable_tag = $this->sanitize_text( $_stable_tag[1] );
65
-		else
66
-			$stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
68
+		if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) ) {
69
+					$stable_tag = $this->sanitize_text( $_stable_tag[1] );
70
+		} else {
71
+					$stable_tag = NULL;
72
+		}
73
+		// we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
67 74
 
68 75
 
69 76
 		// Tags: some tag, another tag, we like tags
70 77
 		if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
71 78
 			$tags = preg_split('|,[\s]*?|', trim($_tags[1]));
72
-			foreach ( array_keys($tags) as $t )
73
-				$tags[$t] = $this->sanitize_text( $tags[$t] );
79
+			foreach ( array_keys($tags) as $t ) {
80
+							$tags[$t] = $this->sanitize_text( $tags[$t] );
81
+			}
74 82
 		} else {
75 83
 			$tags = array();
76 84
 		}
@@ -82,18 +90,20 @@  discard block
 block discarded – undo
82 90
 			$temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
83 91
 			foreach ( array_keys($temp_contributors) as $c ) {
84 92
 				$tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
85
-				if ( strlen(trim($tmp_sanitized)) > 0 )
86
-					$contributors[$c] = $tmp_sanitized;
93
+				if ( strlen(trim($tmp_sanitized)) > 0 ) {
94
+									$contributors[$c] = $tmp_sanitized;
95
+				}
87 96
 				unset($tmp_sanitized);
88 97
 			}
89 98
 		}
90 99
 
91 100
 
92 101
 		// Donate Link: URL
93
-		if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
94
-			$donate_link = esc_url( $_donate_link[1] );
95
-		else
96
-			$donate_link = NULL;
102
+		if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) ) {
103
+					$donate_link = esc_url( $_donate_link[1] );
104
+		} else {
105
+					$donate_link = NULL;
106
+		}
97 107
 
98 108
 
99 109
 		// togs, conts, etc are optional and order shouldn't matter.  So we chop them only after we've grabbed their values.
@@ -108,17 +118,21 @@  discard block
 block discarded – undo
108 118
 
109 119
 
110 120
 		// short-description fu
111
-		if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
112
-			$_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
121
+		if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) ) {
122
+					$_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
123
+		}
113 124
 		$short_desc_filtered = $this->sanitize_text( $_short_description[2] );
114 125
 		$short_desc_length = strlen($short_desc_filtered);
115 126
 		$short_description = substr($short_desc_filtered, 0, 150);
116
-		if ( $short_desc_length > strlen($short_description) )
117
-			$truncated = true;
118
-		else
119
-			$truncated = false;
120
-		if ( $_short_description[1] )
121
-			$file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
127
+		if ( $short_desc_length > strlen($short_description) ) {
128
+					$truncated = true;
129
+		} else {
130
+					$truncated = false;
131
+		}
132
+		if ( $_short_description[1] ) {
133
+					$file_contents = $this->chop_string( $file_contents, $_short_description[1] );
134
+		}
135
+		// yes, the [1] is intentional
122 136
 
123 137
 		// == Section ==
124 138
 		// Break into sections
@@ -149,16 +163,18 @@  discard block
 block discarded – undo
149 163
 				unset($sections[$special_section]);
150 164
 			}
151 165
 		}
152
-		if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
153
-			$final_sections['changelog'] = $final_sections['change_log'];
166
+		if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) ) {
167
+					$final_sections['changelog'] = $final_sections['change_log'];
168
+		}
154 169
 
155 170
 
156 171
 		$final_screenshots = array();
157 172
 		if ( isset($final_sections['screenshots']) ) {
158 173
 			preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
159 174
 			if ( $screenshots ) {
160
-				foreach ( (array) $screenshots as $ss )
161
-					$final_screenshots[] = $ss[1];
175
+				foreach ( (array) $screenshots as $ss ) {
176
+									$final_screenshots[] = $ss[1];
177
+				}
162 178
 			}
163 179
 		}
164 180
 
@@ -228,8 +244,10 @@  discard block
 block discarded – undo
228 244
 	}
229 245
 
230 246
 	function user_sanitize( $text, $strict = false ) { // whitelisted chars
231
-		if ( function_exists('user_sanitize') ) // bbPress native
247
+		if ( function_exists('user_sanitize') ) {
248
+		    // bbPress native
232 249
 			return user_sanitize( $text, $strict );
250
+		}
233 251
 
234 252
 		if ( $strict ) {
235 253
 			$text = preg_replace('/[^a-z0-9-]/i', '', $text);
@@ -290,8 +308,9 @@  discard block
 block discarded – undo
290 308
 	function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
291 309
 		// If doing markdown, first take any user formatted code blocks and turn them into backticks so that
292 310
 		// markdown will preserve things like underscores in code blocks
293
-		if ( $markdown )
294
-			$text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
311
+		if ( $markdown ) {
312
+					$text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
313
+		}
295 314
 
296 315
 		$text = str_replace(array("\r\n", "\r"), "\n", $text);
297 316
 		if ( !$markdown ) {
@@ -313,8 +332,10 @@  discard block
 block discarded – undo
313 332
 	}
314 333
 
315 334
 	function encodeit( $matches ) {
316
-		if ( function_exists('encodeit') ) // bbPress native
335
+		if ( function_exists('encodeit') ) {
336
+		    // bbPress native
317 337
 			return encodeit( $matches );
338
+		}
318 339
 
319 340
 		$text = trim($matches[2]);
320 341
 		$text = htmlspecialchars($text, ENT_QUOTES);
@@ -323,14 +344,17 @@  discard block
 block discarded – undo
323 344
 		$text = str_replace('&amp;lt;', '&lt;', $text);
324 345
 		$text = str_replace('&amp;gt;', '&gt;', $text);
325 346
 		$text = "<code>$text</code>";
326
-		if ( "`" != $matches[1] )
327
-			$text = "<pre>$text</pre>";
347
+		if ( "`" != $matches[1] ) {
348
+					$text = "<pre>$text</pre>";
349
+		}
328 350
 		return $text;
329 351
 	}
330 352
 
331 353
 	function decodeit( $matches ) {
332
-		if ( function_exists('decodeit') ) // bbPress native
354
+		if ( function_exists('decodeit') ) {
355
+		    // bbPress native
333 356
 			return decodeit( $matches );
357
+		}
334 358
 
335 359
 		$text = $matches[2];
336 360
 		$trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
@@ -338,8 +362,9 @@  discard block
 block discarded – undo
338 362
 		$text = str_replace('<br />', '', $text);
339 363
 		$text = str_replace('&#38;', '&', $text);
340 364
 		$text = str_replace('&#39;', "'", $text);
341
-		if ( '<pre><code>' == $matches[1] )
342
-			$text = "\n$text\n";
365
+		if ( '<pre><code>' == $matches[1] ) {
366
+					$text = "\n$text\n";
367
+		}
343 368
 		return "`$text`";
344 369
 	}
345 370
 
Please login to merge, or discard this patch.
brighty-core/includes/plugin-update-checker-5-1.0/vendor/Parsedown.php 2 patches
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Parsedown', false) ) {
3
-	require __DIR__ . '/ParsedownModern.php';
3
+    require __DIR__ . '/ParsedownModern.php';
4 4
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@
 block discarded – undo
1 1
 <?php
2
-if ( !class_exists('Parsedown', false) ) {
2
+if (!class_exists('Parsedown', false)) {
3 3
 	require __DIR__ . '/ParsedownModern.php';
4 4
 }
Please login to merge, or discard this patch.
plugins/brighty-core/includes/plugin-update-checker-5-1.0/load-v5p0.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -13,22 +13,22 @@
 block discarded – undo
13 13
 
14 14
 //Register classes defined in this version with the factory.
15 15
 foreach (
16
-	array(
17
-		'Plugin\\UpdateChecker' => Plugin\UpdateChecker::class,
18
-		'Theme\\UpdateChecker'  => Theme\UpdateChecker::class,
19
-
20
-		'Vcs\\PluginUpdateChecker' => Vcs\PluginUpdateChecker::class,
21
-		'Vcs\\ThemeUpdateChecker'  => Vcs\ThemeUpdateChecker::class,
22
-
23
-		'GitHubApi'    => Vcs\GitHubApi::class,
24
-		'BitBucketApi' => Vcs\BitBucketApi::class,
25
-		'GitLabApi'    => Vcs\GitLabApi::class,
26
-	)
27
-	as $pucGeneralClass => $pucVersionedClass
16
+    array(
17
+        'Plugin\\UpdateChecker' => Plugin\UpdateChecker::class,
18
+        'Theme\\UpdateChecker'  => Theme\UpdateChecker::class,
19
+
20
+        'Vcs\\PluginUpdateChecker' => Vcs\PluginUpdateChecker::class,
21
+        'Vcs\\ThemeUpdateChecker'  => Vcs\ThemeUpdateChecker::class,
22
+
23
+        'GitHubApi'    => Vcs\GitHubApi::class,
24
+        'BitBucketApi' => Vcs\BitBucketApi::class,
25
+        'GitLabApi'    => Vcs\GitLabApi::class,
26
+    )
27
+    as $pucGeneralClass => $pucVersionedClass
28 28
 ) {
29
-	MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.0');
30
-	//Also add it to the minor-version factory in case the major-version factory
31
-	//was already defined by another, older version of the update checker.
32
-	MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.0');
29
+    MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.0');
30
+    //Also add it to the minor-version factory in case the major-version factory
31
+    //was already defined by another, older version of the update checker.
32
+    MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.0');
33 33
 }
34 34
 
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/UpdateChecker.php 2 patches
Indentation   +968 added lines, -968 removed lines patch added patch discarded remove patch
@@ -6,998 +6,998 @@
 block discarded – undo
6 6
 
7 7
 if ( !class_exists(UpdateChecker::class, false) ):
8 8
 
9
-	abstract class UpdateChecker {
10
-		protected $filterSuffix = '';
11
-		protected $updateTransient = '';
12
-		protected $translationType = ''; //"plugin" or "theme".
13
-
14
-		/**
15
-		 * Set to TRUE to enable error reporting. Errors are raised using trigger_error()
16
-		 * and should be logged to the standard PHP error log.
17
-		 * @var bool
18
-		 */
19
-		public $debugMode = null;
20
-
21
-		/**
22
-		 * @var string Where to store the update info.
23
-		 */
24
-		public $optionName = '';
25
-
26
-		/**
27
-		 * @var string The URL of the metadata file.
28
-		 */
29
-		public $metadataUrl = '';
30
-
31
-		/**
32
-		 * @var string Plugin or theme directory name.
33
-		 */
34
-		public $directoryName = '';
35
-
36
-		/**
37
-		 * @var string The slug that will be used in update checker hooks and remote API requests.
38
-		 * Usually matches the directory name unless the plugin/theme directory has been renamed.
39
-		 */
40
-		public $slug = '';
41
-
42
-		/**
43
-		 * @var InstalledPackage
44
-		 */
45
-		protected $package;
46
-
47
-		/**
48
-		 * @var Scheduler
49
-		 */
50
-		public $scheduler;
51
-
52
-		/**
53
-		 * @var UpgraderStatus
54
-		 */
55
-		protected $upgraderStatus;
56
-
57
-		/**
58
-		 * @var StateStore
59
-		 */
60
-		protected $updateState;
61
-
62
-		/**
63
-		 * @var array List of API errors triggered during the last checkForUpdates() call.
64
-		 */
65
-		protected $lastRequestApiErrors = array();
66
-
67
-		/**
68
-		 * @var string|mixed The default is 0 because parse_url() can return NULL or FALSE.
69
-		 */
70
-		protected $cachedMetadataHost = 0;
71
-
72
-		/**
73
-		 * @var DebugBar\Extension|null
74
-		 */
75
-		protected $debugBarExtension = null;
76
-
77
-		public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
78
-			$this->debugMode = (bool)(constant('WP_DEBUG'));
79
-			$this->metadataUrl = $metadataUrl;
80
-			$this->directoryName = $directoryName;
81
-			$this->slug = !empty($slug) ? $slug : $this->directoryName;
82
-
83
-			$this->optionName = $optionName;
84
-			if ( empty($this->optionName) ) {
85
-				//BC: Initially the library only supported plugin updates and didn't use type prefixes
86
-				//in the option name. Lets use the same prefix-less name when possible.
87
-				if ( $this->filterSuffix === '' ) {
88
-					$this->optionName = 'external_updates-' . $this->slug;
89
-				} else {
90
-					$this->optionName = $this->getUniqueName('external_updates');
91
-				}
92
-			}
93
-
94
-			$this->package = $this->createInstalledPackage();
95
-			$this->scheduler = $this->createScheduler($checkPeriod);
96
-			$this->upgraderStatus = new UpgraderStatus();
97
-			$this->updateState = new StateStore($this->optionName);
98
-
99
-			if ( did_action('init') ) {
100
-				$this->loadTextDomain();
101
-			} else {
102
-				add_action('init', array($this, 'loadTextDomain'));
103
-			}
104
-
105
-			$this->installHooks();
106
-		}
107
-
108
-		/**
109
-		 * @internal
110
-		 */
111
-		public function loadTextDomain() {
112
-			//We're not using load_plugin_textdomain() or its siblings because figuring out where
113
-			//the library is located (plugin, mu-plugin, theme, custom wp-content paths) is messy.
114
-			$domain = 'plugin-update-checker';
115
-			$locale = apply_filters(
116
-				'plugin_locale',
117
-				(is_admin() && function_exists('get_user_locale')) ? get_user_locale() : get_locale(),
118
-				$domain
119
-			);
120
-
121
-			$moFile = $domain . '-' . $locale . '.mo';
122
-			$path = realpath(dirname(__FILE__) . '/../../languages');
123
-
124
-			if ($path && file_exists($path)) {
125
-				load_textdomain($domain, $path . '/' . $moFile);
126
-			}
127
-		}
128
-
129
-		protected function installHooks() {
130
-			//Insert our update info into the update array maintained by WP.
131
-			add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
132
-
133
-			//Insert translation updates into the update list.
134
-			add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
135
-
136
-			//Clear translation updates when WP clears the update cache.
137
-			//This needs to be done directly because the library doesn't actually remove obsolete plugin updates,
138
-			//it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O.
139
-			add_action(
140
-				'delete_site_transient_' . $this->updateTransient,
141
-				array($this, 'clearCachedTranslationUpdates')
142
-			);
143
-
144
-			//Rename the update directory to be the same as the existing directory.
145
-			if ( $this->directoryName !== '.' ) {
146
-				add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
147
-			}
148
-
149
-			//Allow HTTP requests to the metadata URL even if it's on a local host.
150
-			add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
151
-
152
-			//DebugBar integration.
153
-			if ( did_action('plugins_loaded') ) {
154
-				$this->maybeInitDebugBar();
155
-			} else {
156
-				add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
157
-			}
158
-		}
159
-
160
-		/**
161
-		 * Remove hooks that were added by this update checker instance.
162
-		 */
163
-		public function removeHooks() {
164
-			remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
165
-			remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
166
-			remove_action(
167
-				'delete_site_transient_' . $this->updateTransient,
168
-				array($this, 'clearCachedTranslationUpdates')
169
-			);
170
-
171
-			remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
172
-			remove_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10);
173
-			remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
174
-
175
-			remove_action('init', array($this, 'loadTextDomain'));
176
-
177
-			if ( $this->scheduler ) {
178
-				$this->scheduler->removeHooks();
179
-			}
180
-
181
-			if ( $this->debugBarExtension ) {
182
-				$this->debugBarExtension->removeHooks();
183
-			}
184
-		}
185
-
186
-		/**
187
-		 * Check if the current user has the required permissions to install updates.
188
-		 *
189
-		 * @return bool
190
-		 */
191
-		abstract public function userCanInstallUpdates();
192
-
193
-		/**
194
-		 * Explicitly allow HTTP requests to the metadata URL.
195
-		 *
196
-		 * WordPress has a security feature where the HTTP API will reject all requests that are sent to
197
-		 * another site hosted on the same server as the current site (IP match), a local host, or a local
198
-		 * IP, unless the host exactly matches the current site.
199
-		 *
200
-		 * This feature is opt-in (at least in WP 4.4). Apparently some people enable it.
201
-		 *
202
-		 * That can be a problem when you're developing your plugin and you decide to host the update information
203
-		 * on the same server as your test site. Update requests will mysteriously fail.
204
-		 *
205
-		 * We fix that by adding an exception for the metadata host.
206
-		 *
207
-		 * @param bool $allow
208
-		 * @param string $host
209
-		 * @return bool
210
-		 */
211
-		public function allowMetadataHost($allow, $host) {
212
-			if ( $this->cachedMetadataHost === 0 ) {
213
-				$this->cachedMetadataHost = wp_parse_url($this->metadataUrl, PHP_URL_HOST);
214
-			}
215
-
216
-			if ( is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost)) ) {
217
-				return true;
218
-			}
219
-			return $allow;
220
-		}
221
-
222
-		/**
223
-		 * Create a package instance that represents this plugin or theme.
224
-		 *
225
-		 * @return InstalledPackage
226
-		 */
227
-		abstract protected function createInstalledPackage();
228
-
229
-		/**
230
-		 * @return InstalledPackage
231
-		 */
232
-		public function getInstalledPackage() {
233
-			return $this->package;
234
-		}
235
-
236
-		/**
237
-		 * Create an instance of the scheduler.
238
-		 *
239
-		 * This is implemented as a method to make it possible for plugins to subclass the update checker
240
-		 * and substitute their own scheduler.
241
-		 *
242
-		 * @param int $checkPeriod
243
-		 * @return Scheduler
244
-		 */
245
-		abstract protected function createScheduler($checkPeriod);
246
-
247
-		/**
248
-		 * Check for updates. The results are stored in the DB option specified in $optionName.
249
-		 *
250
-		 * @return Update|null
251
-		 */
252
-		public function checkForUpdates() {
253
-			$installedVersion = $this->getInstalledVersion();
254
-			//Fail silently if we can't find the plugin/theme or read its header.
255
-			if ( $installedVersion === null ) {
256
-				$this->triggerError(
257
-					sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
258
-					E_USER_WARNING
259
-				);
260
-				return null;
261
-			}
262
-
263
-			//Start collecting API errors.
264
-			$this->lastRequestApiErrors = array();
265
-			add_action('puc_api_error', array($this, 'collectApiErrors'), 10, 4);
266
-
267
-			$state = $this->updateState;
268
-			$state->setLastCheckToNow()
269
-				->setCheckedVersion($installedVersion)
270
-				->save(); //Save before checking in case something goes wrong
271
-
272
-			$state->setUpdate($this->requestUpdate());
273
-			$state->save();
274
-
275
-			//Stop collecting API errors.
276
-			remove_action('puc_api_error', array($this, 'collectApiErrors'), 10);
277
-
278
-			return $this->getUpdate();
279
-		}
280
-
281
-		/**
282
-		 * Load the update checker state from the DB.
283
-		 *
284
-		 * @return StateStore
285
-		 */
286
-		public function getUpdateState() {
287
-			return $this->updateState->lazyLoad();
288
-		}
289
-
290
-		/**
291
-		 * Reset update checker state - i.e. last check time, cached update data and so on.
292
-		 *
293
-		 * Call this when your plugin is being uninstalled, or if you want to
294
-		 * clear the update cache.
295
-		 */
296
-		public function resetUpdateState() {
297
-			$this->updateState->delete();
298
-		}
299
-
300
-		/**
301
-		 * Get the details of the currently available update, if any.
302
-		 *
303
-		 * If no updates are available, or if the last known update version is below or equal
304
-		 * to the currently installed version, this method will return NULL.
305
-		 *
306
-		 * Uses cached update data. To retrieve update information straight from
307
-		 * the metadata URL, call requestUpdate() instead.
308
-		 *
309
-		 * @return Update|null
310
-		 */
311
-		public function getUpdate() {
312
-			$update = $this->updateState->getUpdate();
313
-
314
-			//Is there an update available?
315
-			if ( isset($update) ) {
316
-				//Check if the update is actually newer than the currently installed version.
317
-				$installedVersion = $this->getInstalledVersion();
318
-				if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
319
-					return $update;
320
-				}
321
-			}
322
-			return null;
323
-		}
324
-
325
-		/**
326
-		 * Retrieve the latest update (if any) from the configured API endpoint.
327
-		 *
328
-		 * Subclasses should run the update through filterUpdateResult before returning it.
329
-		 *
330
-		 * @return Update An instance of Update, or NULL when no updates are available.
331
-		 */
332
-		abstract public function requestUpdate();
333
-
334
-		/**
335
-		 * Filter the result of a requestUpdate() call.
336
-		 *
337
-		 * @template T of Update
338
-		 * @param T|null $update
339
-		 * @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
340
-		 * @return T
341
-		 */
342
-		protected function filterUpdateResult($update, $httpResult = null) {
343
-			//Let plugins/themes modify the update.
344
-			$update = apply_filters($this->getUniqueName('request_update_result'), $update, $httpResult);
345
-
346
-			$this->fixSupportedWordpressVersion($update);
347
-
348
-			if ( isset($update, $update->translations) ) {
349
-				//Keep only those translation updates that apply to this site.
350
-				$update->translations = $this->filterApplicableTranslations($update->translations);
351
-			}
352
-
353
-			return $update;
354
-		}
355
-
356
-		/**
357
-		 * The "Tested up to" field in the plugin metadata is supposed to be in the form of "major.minor",
358
-		 * while WordPress core's list_plugin_updates() expects the $update->tested field to be an exact
359
-		 * version, e.g. "major.minor.patch", to say it's compatible. In other case it shows
360
-		 * "Compatibility: Unknown".
361
-		 * The function mimics how wordpress.org API crafts the "tested" field out of "Tested up to".
362
-		 *
363
-		 * @param Metadata|null $update
364
-		 */
365
-		protected function fixSupportedWordpressVersion(Metadata $update = null) {
366
-			if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
367
-				return;
368
-			}
369
-
370
-			$actualWpVersions = array();
371
-
372
-			$wpVersion = $GLOBALS['wp_version'];
373
-
374
-			if ( function_exists('get_core_updates') ) {
375
-				$coreUpdates = get_core_updates();
376
-				if ( is_array($coreUpdates) ) {
377
-					foreach ($coreUpdates as $coreUpdate) {
378
-						if ( isset($coreUpdate->current) ) {
379
-							$actualWpVersions[] = $coreUpdate->current;
380
-						}
381
-					}
382
-				}
383
-			}
384
-
385
-			$actualWpVersions[] = $wpVersion;
386
-
387
-			$actualWpPatchNumber = null;
388
-			foreach ($actualWpVersions as $version) {
389
-				if ( preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts) ) {
390
-					if ( $versionParts['majorMinor'] === $update->tested ) {
391
-						$patch = isset($versionParts['patch']) ? intval($versionParts['patch']) : 0;
392
-						if ( $actualWpPatchNumber === null ) {
393
-							$actualWpPatchNumber = $patch;
394
-						} else {
395
-							$actualWpPatchNumber = max($actualWpPatchNumber, $patch);
396
-						}
397
-					}
398
-				}
399
-			}
400
-			if ( $actualWpPatchNumber === null ) {
401
-				$actualWpPatchNumber = 999;
402
-			}
403
-
404
-			if ( $actualWpPatchNumber > 0 ) {
405
-				$update->tested .= '.' . $actualWpPatchNumber;
406
-			}
407
-		}
408
-
409
-		/**
410
-		 * Get the currently installed version of the plugin or theme.
411
-		 *
412
-		 * @return string|null Version number.
413
-		 */
414
-		public function getInstalledVersion() {
415
-			return $this->package->getInstalledVersion();
416
-		}
417
-
418
-		/**
419
-		 * Get the full path of the plugin or theme directory.
420
-		 *
421
-		 * @return string
422
-		 */
423
-		public function getAbsoluteDirectoryPath() {
424
-			return $this->package->getAbsoluteDirectoryPath();
425
-		}
426
-
427
-		/**
428
-		 * Trigger a PHP error, but only when $debugMode is enabled.
429
-		 *
430
-		 * @param string $message
431
-		 * @param int $errorType
432
-		 */
433
-		public function triggerError($message, $errorType) {
434
-			if ( $this->isDebugModeEnabled() ) {
435
-				//phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Only happens in debug mode.
436
-				trigger_error(esc_html($message), $errorType);
437
-			}
438
-		}
439
-
440
-		/**
441
-		 * @return bool
442
-		 */
443
-		protected function isDebugModeEnabled() {
444
-			if ( $this->debugMode === null ) {
445
-				$this->debugMode = (bool)(constant('WP_DEBUG'));
446
-			}
447
-			return $this->debugMode;
448
-		}
449
-
450
-		/**
451
-		 * Get the full name of an update checker filter, action or DB entry.
452
-		 *
453
-		 * This method adds the "puc_" prefix and the "-$slug" suffix to the filter name.
454
-		 * For example, "pre_inject_update" becomes "puc_pre_inject_update-plugin-slug".
455
-		 *
456
-		 * @param string $baseTag
457
-		 * @return string
458
-		 */
459
-		public function getUniqueName($baseTag) {
460
-			$name = 'puc_' . $baseTag;
461
-			if ( $this->filterSuffix !== '' ) {
462
-				$name .= '_' . $this->filterSuffix;
463
-			}
464
-			return $name . '-' . $this->slug;
465
-		}
466
-
467
-		/**
468
-		 * Store API errors that are generated when checking for updates.
469
-		 *
470
-		 * @internal
471
-		 * @param \WP_Error $error
472
-		 * @param array|null $httpResponse
473
-		 * @param string|null $url
474
-		 * @param string|null $slug
475
-		 */
476
-		public function collectApiErrors($error, $httpResponse = null, $url = null, $slug = null) {
477
-			if ( isset($slug) && ($slug !== $this->slug) ) {
478
-				return;
479
-			}
480
-
481
-			$this->lastRequestApiErrors[] = array(
482
-				'error'        => $error,
483
-				'httpResponse' => $httpResponse,
484
-				'url'          => $url,
485
-			);
486
-		}
487
-
488
-		/**
489
-		 * @return array
490
-		 */
491
-		public function getLastRequestApiErrors() {
492
-			return $this->lastRequestApiErrors;
493
-		}
494
-
495
-		/* -------------------------------------------------------------------
9
+    abstract class UpdateChecker {
10
+        protected $filterSuffix = '';
11
+        protected $updateTransient = '';
12
+        protected $translationType = ''; //"plugin" or "theme".
13
+
14
+        /**
15
+         * Set to TRUE to enable error reporting. Errors are raised using trigger_error()
16
+         * and should be logged to the standard PHP error log.
17
+         * @var bool
18
+         */
19
+        public $debugMode = null;
20
+
21
+        /**
22
+         * @var string Where to store the update info.
23
+         */
24
+        public $optionName = '';
25
+
26
+        /**
27
+         * @var string The URL of the metadata file.
28
+         */
29
+        public $metadataUrl = '';
30
+
31
+        /**
32
+         * @var string Plugin or theme directory name.
33
+         */
34
+        public $directoryName = '';
35
+
36
+        /**
37
+         * @var string The slug that will be used in update checker hooks and remote API requests.
38
+         * Usually matches the directory name unless the plugin/theme directory has been renamed.
39
+         */
40
+        public $slug = '';
41
+
42
+        /**
43
+         * @var InstalledPackage
44
+         */
45
+        protected $package;
46
+
47
+        /**
48
+         * @var Scheduler
49
+         */
50
+        public $scheduler;
51
+
52
+        /**
53
+         * @var UpgraderStatus
54
+         */
55
+        protected $upgraderStatus;
56
+
57
+        /**
58
+         * @var StateStore
59
+         */
60
+        protected $updateState;
61
+
62
+        /**
63
+         * @var array List of API errors triggered during the last checkForUpdates() call.
64
+         */
65
+        protected $lastRequestApiErrors = array();
66
+
67
+        /**
68
+         * @var string|mixed The default is 0 because parse_url() can return NULL or FALSE.
69
+         */
70
+        protected $cachedMetadataHost = 0;
71
+
72
+        /**
73
+         * @var DebugBar\Extension|null
74
+         */
75
+        protected $debugBarExtension = null;
76
+
77
+        public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
78
+            $this->debugMode = (bool)(constant('WP_DEBUG'));
79
+            $this->metadataUrl = $metadataUrl;
80
+            $this->directoryName = $directoryName;
81
+            $this->slug = !empty($slug) ? $slug : $this->directoryName;
82
+
83
+            $this->optionName = $optionName;
84
+            if ( empty($this->optionName) ) {
85
+                //BC: Initially the library only supported plugin updates and didn't use type prefixes
86
+                //in the option name. Lets use the same prefix-less name when possible.
87
+                if ( $this->filterSuffix === '' ) {
88
+                    $this->optionName = 'external_updates-' . $this->slug;
89
+                } else {
90
+                    $this->optionName = $this->getUniqueName('external_updates');
91
+                }
92
+            }
93
+
94
+            $this->package = $this->createInstalledPackage();
95
+            $this->scheduler = $this->createScheduler($checkPeriod);
96
+            $this->upgraderStatus = new UpgraderStatus();
97
+            $this->updateState = new StateStore($this->optionName);
98
+
99
+            if ( did_action('init') ) {
100
+                $this->loadTextDomain();
101
+            } else {
102
+                add_action('init', array($this, 'loadTextDomain'));
103
+            }
104
+
105
+            $this->installHooks();
106
+        }
107
+
108
+        /**
109
+         * @internal
110
+         */
111
+        public function loadTextDomain() {
112
+            //We're not using load_plugin_textdomain() or its siblings because figuring out where
113
+            //the library is located (plugin, mu-plugin, theme, custom wp-content paths) is messy.
114
+            $domain = 'plugin-update-checker';
115
+            $locale = apply_filters(
116
+                'plugin_locale',
117
+                (is_admin() && function_exists('get_user_locale')) ? get_user_locale() : get_locale(),
118
+                $domain
119
+            );
120
+
121
+            $moFile = $domain . '-' . $locale . '.mo';
122
+            $path = realpath(dirname(__FILE__) . '/../../languages');
123
+
124
+            if ($path && file_exists($path)) {
125
+                load_textdomain($domain, $path . '/' . $moFile);
126
+            }
127
+        }
128
+
129
+        protected function installHooks() {
130
+            //Insert our update info into the update array maintained by WP.
131
+            add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
132
+
133
+            //Insert translation updates into the update list.
134
+            add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
135
+
136
+            //Clear translation updates when WP clears the update cache.
137
+            //This needs to be done directly because the library doesn't actually remove obsolete plugin updates,
138
+            //it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O.
139
+            add_action(
140
+                'delete_site_transient_' . $this->updateTransient,
141
+                array($this, 'clearCachedTranslationUpdates')
142
+            );
143
+
144
+            //Rename the update directory to be the same as the existing directory.
145
+            if ( $this->directoryName !== '.' ) {
146
+                add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
147
+            }
148
+
149
+            //Allow HTTP requests to the metadata URL even if it's on a local host.
150
+            add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
151
+
152
+            //DebugBar integration.
153
+            if ( did_action('plugins_loaded') ) {
154
+                $this->maybeInitDebugBar();
155
+            } else {
156
+                add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
157
+            }
158
+        }
159
+
160
+        /**
161
+         * Remove hooks that were added by this update checker instance.
162
+         */
163
+        public function removeHooks() {
164
+            remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
165
+            remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
166
+            remove_action(
167
+                'delete_site_transient_' . $this->updateTransient,
168
+                array($this, 'clearCachedTranslationUpdates')
169
+            );
170
+
171
+            remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
172
+            remove_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10);
173
+            remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
174
+
175
+            remove_action('init', array($this, 'loadTextDomain'));
176
+
177
+            if ( $this->scheduler ) {
178
+                $this->scheduler->removeHooks();
179
+            }
180
+
181
+            if ( $this->debugBarExtension ) {
182
+                $this->debugBarExtension->removeHooks();
183
+            }
184
+        }
185
+
186
+        /**
187
+         * Check if the current user has the required permissions to install updates.
188
+         *
189
+         * @return bool
190
+         */
191
+        abstract public function userCanInstallUpdates();
192
+
193
+        /**
194
+         * Explicitly allow HTTP requests to the metadata URL.
195
+         *
196
+         * WordPress has a security feature where the HTTP API will reject all requests that are sent to
197
+         * another site hosted on the same server as the current site (IP match), a local host, or a local
198
+         * IP, unless the host exactly matches the current site.
199
+         *
200
+         * This feature is opt-in (at least in WP 4.4). Apparently some people enable it.
201
+         *
202
+         * That can be a problem when you're developing your plugin and you decide to host the update information
203
+         * on the same server as your test site. Update requests will mysteriously fail.
204
+         *
205
+         * We fix that by adding an exception for the metadata host.
206
+         *
207
+         * @param bool $allow
208
+         * @param string $host
209
+         * @return bool
210
+         */
211
+        public function allowMetadataHost($allow, $host) {
212
+            if ( $this->cachedMetadataHost === 0 ) {
213
+                $this->cachedMetadataHost = wp_parse_url($this->metadataUrl, PHP_URL_HOST);
214
+            }
215
+
216
+            if ( is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost)) ) {
217
+                return true;
218
+            }
219
+            return $allow;
220
+        }
221
+
222
+        /**
223
+         * Create a package instance that represents this plugin or theme.
224
+         *
225
+         * @return InstalledPackage
226
+         */
227
+        abstract protected function createInstalledPackage();
228
+
229
+        /**
230
+         * @return InstalledPackage
231
+         */
232
+        public function getInstalledPackage() {
233
+            return $this->package;
234
+        }
235
+
236
+        /**
237
+         * Create an instance of the scheduler.
238
+         *
239
+         * This is implemented as a method to make it possible for plugins to subclass the update checker
240
+         * and substitute their own scheduler.
241
+         *
242
+         * @param int $checkPeriod
243
+         * @return Scheduler
244
+         */
245
+        abstract protected function createScheduler($checkPeriod);
246
+
247
+        /**
248
+         * Check for updates. The results are stored in the DB option specified in $optionName.
249
+         *
250
+         * @return Update|null
251
+         */
252
+        public function checkForUpdates() {
253
+            $installedVersion = $this->getInstalledVersion();
254
+            //Fail silently if we can't find the plugin/theme or read its header.
255
+            if ( $installedVersion === null ) {
256
+                $this->triggerError(
257
+                    sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
258
+                    E_USER_WARNING
259
+                );
260
+                return null;
261
+            }
262
+
263
+            //Start collecting API errors.
264
+            $this->lastRequestApiErrors = array();
265
+            add_action('puc_api_error', array($this, 'collectApiErrors'), 10, 4);
266
+
267
+            $state = $this->updateState;
268
+            $state->setLastCheckToNow()
269
+                ->setCheckedVersion($installedVersion)
270
+                ->save(); //Save before checking in case something goes wrong
271
+
272
+            $state->setUpdate($this->requestUpdate());
273
+            $state->save();
274
+
275
+            //Stop collecting API errors.
276
+            remove_action('puc_api_error', array($this, 'collectApiErrors'), 10);
277
+
278
+            return $this->getUpdate();
279
+        }
280
+
281
+        /**
282
+         * Load the update checker state from the DB.
283
+         *
284
+         * @return StateStore
285
+         */
286
+        public function getUpdateState() {
287
+            return $this->updateState->lazyLoad();
288
+        }
289
+
290
+        /**
291
+         * Reset update checker state - i.e. last check time, cached update data and so on.
292
+         *
293
+         * Call this when your plugin is being uninstalled, or if you want to
294
+         * clear the update cache.
295
+         */
296
+        public function resetUpdateState() {
297
+            $this->updateState->delete();
298
+        }
299
+
300
+        /**
301
+         * Get the details of the currently available update, if any.
302
+         *
303
+         * If no updates are available, or if the last known update version is below or equal
304
+         * to the currently installed version, this method will return NULL.
305
+         *
306
+         * Uses cached update data. To retrieve update information straight from
307
+         * the metadata URL, call requestUpdate() instead.
308
+         *
309
+         * @return Update|null
310
+         */
311
+        public function getUpdate() {
312
+            $update = $this->updateState->getUpdate();
313
+
314
+            //Is there an update available?
315
+            if ( isset($update) ) {
316
+                //Check if the update is actually newer than the currently installed version.
317
+                $installedVersion = $this->getInstalledVersion();
318
+                if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
319
+                    return $update;
320
+                }
321
+            }
322
+            return null;
323
+        }
324
+
325
+        /**
326
+         * Retrieve the latest update (if any) from the configured API endpoint.
327
+         *
328
+         * Subclasses should run the update through filterUpdateResult before returning it.
329
+         *
330
+         * @return Update An instance of Update, or NULL when no updates are available.
331
+         */
332
+        abstract public function requestUpdate();
333
+
334
+        /**
335
+         * Filter the result of a requestUpdate() call.
336
+         *
337
+         * @template T of Update
338
+         * @param T|null $update
339
+         * @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
340
+         * @return T
341
+         */
342
+        protected function filterUpdateResult($update, $httpResult = null) {
343
+            //Let plugins/themes modify the update.
344
+            $update = apply_filters($this->getUniqueName('request_update_result'), $update, $httpResult);
345
+
346
+            $this->fixSupportedWordpressVersion($update);
347
+
348
+            if ( isset($update, $update->translations) ) {
349
+                //Keep only those translation updates that apply to this site.
350
+                $update->translations = $this->filterApplicableTranslations($update->translations);
351
+            }
352
+
353
+            return $update;
354
+        }
355
+
356
+        /**
357
+         * The "Tested up to" field in the plugin metadata is supposed to be in the form of "major.minor",
358
+         * while WordPress core's list_plugin_updates() expects the $update->tested field to be an exact
359
+         * version, e.g. "major.minor.patch", to say it's compatible. In other case it shows
360
+         * "Compatibility: Unknown".
361
+         * The function mimics how wordpress.org API crafts the "tested" field out of "Tested up to".
362
+         *
363
+         * @param Metadata|null $update
364
+         */
365
+        protected function fixSupportedWordpressVersion(Metadata $update = null) {
366
+            if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
367
+                return;
368
+            }
369
+
370
+            $actualWpVersions = array();
371
+
372
+            $wpVersion = $GLOBALS['wp_version'];
373
+
374
+            if ( function_exists('get_core_updates') ) {
375
+                $coreUpdates = get_core_updates();
376
+                if ( is_array($coreUpdates) ) {
377
+                    foreach ($coreUpdates as $coreUpdate) {
378
+                        if ( isset($coreUpdate->current) ) {
379
+                            $actualWpVersions[] = $coreUpdate->current;
380
+                        }
381
+                    }
382
+                }
383
+            }
384
+
385
+            $actualWpVersions[] = $wpVersion;
386
+
387
+            $actualWpPatchNumber = null;
388
+            foreach ($actualWpVersions as $version) {
389
+                if ( preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts) ) {
390
+                    if ( $versionParts['majorMinor'] === $update->tested ) {
391
+                        $patch = isset($versionParts['patch']) ? intval($versionParts['patch']) : 0;
392
+                        if ( $actualWpPatchNumber === null ) {
393
+                            $actualWpPatchNumber = $patch;
394
+                        } else {
395
+                            $actualWpPatchNumber = max($actualWpPatchNumber, $patch);
396
+                        }
397
+                    }
398
+                }
399
+            }
400
+            if ( $actualWpPatchNumber === null ) {
401
+                $actualWpPatchNumber = 999;
402
+            }
403
+
404
+            if ( $actualWpPatchNumber > 0 ) {
405
+                $update->tested .= '.' . $actualWpPatchNumber;
406
+            }
407
+        }
408
+
409
+        /**
410
+         * Get the currently installed version of the plugin or theme.
411
+         *
412
+         * @return string|null Version number.
413
+         */
414
+        public function getInstalledVersion() {
415
+            return $this->package->getInstalledVersion();
416
+        }
417
+
418
+        /**
419
+         * Get the full path of the plugin or theme directory.
420
+         *
421
+         * @return string
422
+         */
423
+        public function getAbsoluteDirectoryPath() {
424
+            return $this->package->getAbsoluteDirectoryPath();
425
+        }
426
+
427
+        /**
428
+         * Trigger a PHP error, but only when $debugMode is enabled.
429
+         *
430
+         * @param string $message
431
+         * @param int $errorType
432
+         */
433
+        public function triggerError($message, $errorType) {
434
+            if ( $this->isDebugModeEnabled() ) {
435
+                //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Only happens in debug mode.
436
+                trigger_error(esc_html($message), $errorType);
437
+            }
438
+        }
439
+
440
+        /**
441
+         * @return bool
442
+         */
443
+        protected function isDebugModeEnabled() {
444
+            if ( $this->debugMode === null ) {
445
+                $this->debugMode = (bool)(constant('WP_DEBUG'));
446
+            }
447
+            return $this->debugMode;
448
+        }
449
+
450
+        /**
451
+         * Get the full name of an update checker filter, action or DB entry.
452
+         *
453
+         * This method adds the "puc_" prefix and the "-$slug" suffix to the filter name.
454
+         * For example, "pre_inject_update" becomes "puc_pre_inject_update-plugin-slug".
455
+         *
456
+         * @param string $baseTag
457
+         * @return string
458
+         */
459
+        public function getUniqueName($baseTag) {
460
+            $name = 'puc_' . $baseTag;
461
+            if ( $this->filterSuffix !== '' ) {
462
+                $name .= '_' . $this->filterSuffix;
463
+            }
464
+            return $name . '-' . $this->slug;
465
+        }
466
+
467
+        /**
468
+         * Store API errors that are generated when checking for updates.
469
+         *
470
+         * @internal
471
+         * @param \WP_Error $error
472
+         * @param array|null $httpResponse
473
+         * @param string|null $url
474
+         * @param string|null $slug
475
+         */
476
+        public function collectApiErrors($error, $httpResponse = null, $url = null, $slug = null) {
477
+            if ( isset($slug) && ($slug !== $this->slug) ) {
478
+                return;
479
+            }
480
+
481
+            $this->lastRequestApiErrors[] = array(
482
+                'error'        => $error,
483
+                'httpResponse' => $httpResponse,
484
+                'url'          => $url,
485
+            );
486
+        }
487
+
488
+        /**
489
+         * @return array
490
+         */
491
+        public function getLastRequestApiErrors() {
492
+            return $this->lastRequestApiErrors;
493
+        }
494
+
495
+        /* -------------------------------------------------------------------
496 496
 		 * PUC filters and filter utilities
497 497
 		 * -------------------------------------------------------------------
498 498
 		 */
499 499
 
500
-		/**
501
-		 * Register a callback for one of the update checker filters.
502
-		 *
503
-		 * Identical to add_filter(), except it automatically adds the "puc_" prefix
504
-		 * and the "-$slug" suffix to the filter name. For example, "request_info_result"
505
-		 * becomes "puc_request_info_result-your_plugin_slug".
506
-		 *
507
-		 * @param string $tag
508
-		 * @param callable $callback
509
-		 * @param int $priority
510
-		 * @param int $acceptedArgs
511
-		 */
512
-		public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) {
513
-			add_filter($this->getUniqueName($tag), $callback, $priority, $acceptedArgs);
514
-		}
515
-
516
-		/* -------------------------------------------------------------------
500
+        /**
501
+         * Register a callback for one of the update checker filters.
502
+         *
503
+         * Identical to add_filter(), except it automatically adds the "puc_" prefix
504
+         * and the "-$slug" suffix to the filter name. For example, "request_info_result"
505
+         * becomes "puc_request_info_result-your_plugin_slug".
506
+         *
507
+         * @param string $tag
508
+         * @param callable $callback
509
+         * @param int $priority
510
+         * @param int $acceptedArgs
511
+         */
512
+        public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) {
513
+            add_filter($this->getUniqueName($tag), $callback, $priority, $acceptedArgs);
514
+        }
515
+
516
+        /* -------------------------------------------------------------------
517 517
 		 * Inject updates
518 518
 		 * -------------------------------------------------------------------
519 519
 		 */
520 520
 
521
-		/**
522
-		 * Insert the latest update (if any) into the update list maintained by WP.
523
-		 *
524
-		 * @param \stdClass $updates Update list.
525
-		 * @return \stdClass Modified update list.
526
-		 */
527
-		public function injectUpdate($updates) {
528
-			//Is there an update to insert?
529
-			$update = $this->getUpdate();
530
-
531
-			if ( !$this->shouldShowUpdates() ) {
532
-				$update = null;
533
-			}
534
-
535
-			if ( !empty($update) ) {
536
-				//Let plugins filter the update info before it's passed on to WordPress.
537
-				$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
538
-				$updates = $this->addUpdateToList($updates, $update->toWpFormat());
539
-			} else {
540
-				//Clean up any stale update info.
541
-				$updates = $this->removeUpdateFromList($updates);
542
-				//Add a placeholder item to the "no_update" list to enable auto-update support.
543
-				//If we don't do this, the option to enable automatic updates will only show up
544
-				//when an update is available.
545
-				$updates = $this->addNoUpdateItem($updates);
546
-			}
547
-
548
-			return $updates;
549
-		}
550
-
551
-		/**
552
-		 * @param \stdClass|null $updates
553
-		 * @param \stdClass|array $updateToAdd
554
-		 * @return \stdClass
555
-		 */
556
-		protected function addUpdateToList($updates, $updateToAdd) {
557
-			if ( !is_object($updates) ) {
558
-				$updates = new stdClass();
559
-				$updates->response = array();
560
-			}
561
-
562
-			$updates->response[$this->getUpdateListKey()] = $updateToAdd;
563
-			return $updates;
564
-		}
565
-
566
-		/**
567
-		 * @param \stdClass|null $updates
568
-		 * @return \stdClass|null
569
-		 */
570
-		protected function removeUpdateFromList($updates) {
571
-			if ( isset($updates, $updates->response) ) {
572
-				unset($updates->response[$this->getUpdateListKey()]);
573
-			}
574
-			return $updates;
575
-		}
576
-
577
-		/**
578
-		 * See this post for more information:
579
-		 * @link https://make.wordpress.org/core/2020/07/30/recommended-usage-of-the-updates-api-to-support-the-auto-updates-ui-for-plugins-and-themes-in-wordpress-5-5/
580
-		 *
581
-		 * @param \stdClass|null $updates
582
-		 * @return \stdClass
583
-		 */
584
-		protected function addNoUpdateItem($updates) {
585
-			if ( !is_object($updates) ) {
586
-				$updates = new stdClass();
587
-				$updates->response = array();
588
-				$updates->no_update = array();
589
-			} else if ( !isset($updates->no_update) ) {
590
-				$updates->no_update = array();
591
-			}
592
-
593
-			$updates->no_update[$this->getUpdateListKey()] = (object) $this->getNoUpdateItemFields();
594
-
595
-			return $updates;
596
-		}
597
-
598
-		/**
599
-		 * Subclasses should override this method to add fields that are specific to plugins or themes.
600
-		 * @return array
601
-		 */
602
-		protected function getNoUpdateItemFields() {
603
-			return array(
604
-				'new_version'   => $this->getInstalledVersion(),
605
-				'url'           => '',
606
-				'package'       => '',
607
-				'requires_php'  => '',
608
-			);
609
-		}
610
-
611
-		/**
612
-		 * Get the key that will be used when adding updates to the update list that's maintained
613
-		 * by the WordPress core. The list is always an associative array, but the key is different
614
-		 * for plugins and themes.
615
-		 *
616
-		 * @return string
617
-		 */
618
-		abstract protected function getUpdateListKey();
619
-
620
-		/**
621
-		 * Should we show available updates?
622
-		 *
623
-		 * Usually the answer is "yes", but there are exceptions. For example, WordPress doesn't
624
-		 * support automatic updates installation for mu-plugins, so PUC usually won't show update
625
-		 * notifications in that case. See the plugin-specific subclass for details.
626
-		 *
627
-		 * Note: This method only applies to updates that are displayed (or not) in the WordPress
628
-		 * admin. It doesn't affect APIs like requestUpdate and getUpdate.
629
-		 *
630
-		 * @return bool
631
-		 */
632
-		protected function shouldShowUpdates() {
633
-			return true;
634
-		}
635
-
636
-		/* -------------------------------------------------------------------
521
+        /**
522
+         * Insert the latest update (if any) into the update list maintained by WP.
523
+         *
524
+         * @param \stdClass $updates Update list.
525
+         * @return \stdClass Modified update list.
526
+         */
527
+        public function injectUpdate($updates) {
528
+            //Is there an update to insert?
529
+            $update = $this->getUpdate();
530
+
531
+            if ( !$this->shouldShowUpdates() ) {
532
+                $update = null;
533
+            }
534
+
535
+            if ( !empty($update) ) {
536
+                //Let plugins filter the update info before it's passed on to WordPress.
537
+                $update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
538
+                $updates = $this->addUpdateToList($updates, $update->toWpFormat());
539
+            } else {
540
+                //Clean up any stale update info.
541
+                $updates = $this->removeUpdateFromList($updates);
542
+                //Add a placeholder item to the "no_update" list to enable auto-update support.
543
+                //If we don't do this, the option to enable automatic updates will only show up
544
+                //when an update is available.
545
+                $updates = $this->addNoUpdateItem($updates);
546
+            }
547
+
548
+            return $updates;
549
+        }
550
+
551
+        /**
552
+         * @param \stdClass|null $updates
553
+         * @param \stdClass|array $updateToAdd
554
+         * @return \stdClass
555
+         */
556
+        protected function addUpdateToList($updates, $updateToAdd) {
557
+            if ( !is_object($updates) ) {
558
+                $updates = new stdClass();
559
+                $updates->response = array();
560
+            }
561
+
562
+            $updates->response[$this->getUpdateListKey()] = $updateToAdd;
563
+            return $updates;
564
+        }
565
+
566
+        /**
567
+         * @param \stdClass|null $updates
568
+         * @return \stdClass|null
569
+         */
570
+        protected function removeUpdateFromList($updates) {
571
+            if ( isset($updates, $updates->response) ) {
572
+                unset($updates->response[$this->getUpdateListKey()]);
573
+            }
574
+            return $updates;
575
+        }
576
+
577
+        /**
578
+         * See this post for more information:
579
+         * @link https://make.wordpress.org/core/2020/07/30/recommended-usage-of-the-updates-api-to-support-the-auto-updates-ui-for-plugins-and-themes-in-wordpress-5-5/
580
+         *
581
+         * @param \stdClass|null $updates
582
+         * @return \stdClass
583
+         */
584
+        protected function addNoUpdateItem($updates) {
585
+            if ( !is_object($updates) ) {
586
+                $updates = new stdClass();
587
+                $updates->response = array();
588
+                $updates->no_update = array();
589
+            } else if ( !isset($updates->no_update) ) {
590
+                $updates->no_update = array();
591
+            }
592
+
593
+            $updates->no_update[$this->getUpdateListKey()] = (object) $this->getNoUpdateItemFields();
594
+
595
+            return $updates;
596
+        }
597
+
598
+        /**
599
+         * Subclasses should override this method to add fields that are specific to plugins or themes.
600
+         * @return array
601
+         */
602
+        protected function getNoUpdateItemFields() {
603
+            return array(
604
+                'new_version'   => $this->getInstalledVersion(),
605
+                'url'           => '',
606
+                'package'       => '',
607
+                'requires_php'  => '',
608
+            );
609
+        }
610
+
611
+        /**
612
+         * Get the key that will be used when adding updates to the update list that's maintained
613
+         * by the WordPress core. The list is always an associative array, but the key is different
614
+         * for plugins and themes.
615
+         *
616
+         * @return string
617
+         */
618
+        abstract protected function getUpdateListKey();
619
+
620
+        /**
621
+         * Should we show available updates?
622
+         *
623
+         * Usually the answer is "yes", but there are exceptions. For example, WordPress doesn't
624
+         * support automatic updates installation for mu-plugins, so PUC usually won't show update
625
+         * notifications in that case. See the plugin-specific subclass for details.
626
+         *
627
+         * Note: This method only applies to updates that are displayed (or not) in the WordPress
628
+         * admin. It doesn't affect APIs like requestUpdate and getUpdate.
629
+         *
630
+         * @return bool
631
+         */
632
+        protected function shouldShowUpdates() {
633
+            return true;
634
+        }
635
+
636
+        /* -------------------------------------------------------------------
637 637
 		 * JSON-based update API
638 638
 		 * -------------------------------------------------------------------
639 639
 		 */
640 640
 
641
-		/**
642
-		 * Retrieve plugin or theme metadata from the JSON document at $this->metadataUrl.
643
-		 *
644
-		 * @param class-string<Update> $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
645
-		 * @param string $filterRoot
646
-		 * @param array $queryArgs Additional query arguments.
647
-		 * @return array<Metadata|null, array|WP_Error> A metadata instance and the value returned by wp_remote_get().
648
-		 */
649
-		protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
650
-			//Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
651
-			$queryArgs = array_merge(
652
-				array(
653
-					'installed_version' => strval($this->getInstalledVersion()),
654
-					'php' => phpversion(),
655
-					'locale' => get_locale(),
656
-				),
657
-				$queryArgs
658
-			);
659
-			$queryArgs = apply_filters($this->getUniqueName($filterRoot . '_query_args'), $queryArgs);
660
-
661
-			//Various options for the wp_remote_get() call. Plugins can filter these, too.
662
-			$options = array(
663
-				'timeout' => 10, //seconds
664
-				'headers' => array(
665
-					'Accept' => 'application/json',
666
-				),
667
-			);
668
-			$options = apply_filters($this->getUniqueName($filterRoot . '_options'), $options);
669
-
670
-			//The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
671
-			$url = $this->metadataUrl;
672
-			if ( !empty($queryArgs) ){
673
-				$url = add_query_arg($queryArgs, $url);
674
-			}
675
-
676
-			$result = wp_remote_get($url, $options);
677
-
678
-			$result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
641
+        /**
642
+         * Retrieve plugin or theme metadata from the JSON document at $this->metadataUrl.
643
+         *
644
+         * @param class-string<Update> $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
645
+         * @param string $filterRoot
646
+         * @param array $queryArgs Additional query arguments.
647
+         * @return array<Metadata|null, array|WP_Error> A metadata instance and the value returned by wp_remote_get().
648
+         */
649
+        protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
650
+            //Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
651
+            $queryArgs = array_merge(
652
+                array(
653
+                    'installed_version' => strval($this->getInstalledVersion()),
654
+                    'php' => phpversion(),
655
+                    'locale' => get_locale(),
656
+                ),
657
+                $queryArgs
658
+            );
659
+            $queryArgs = apply_filters($this->getUniqueName($filterRoot . '_query_args'), $queryArgs);
660
+
661
+            //Various options for the wp_remote_get() call. Plugins can filter these, too.
662
+            $options = array(
663
+                'timeout' => 10, //seconds
664
+                'headers' => array(
665
+                    'Accept' => 'application/json',
666
+                ),
667
+            );
668
+            $options = apply_filters($this->getUniqueName($filterRoot . '_options'), $options);
669
+
670
+            //The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
671
+            $url = $this->metadataUrl;
672
+            if ( !empty($queryArgs) ){
673
+                $url = add_query_arg($queryArgs, $url);
674
+            }
675
+
676
+            $result = wp_remote_get($url, $options);
677
+
678
+            $result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
679 679
 			
680
-			//Try to parse the response
681
-			$status = $this->validateApiResponse($result);
682
-			$metadata = null;
683
-			if ( !is_wp_error($status) ){
684
-				if ( (strpos($metaClass, '\\') === false) ) {
685
-					$metaClass = __NAMESPACE__ . '\\' . $metaClass;
686
-				}
687
-				$metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
688
-			} else {
689
-				do_action('puc_api_error', $status, $result, $url, $this->slug);
690
-				$this->triggerError(
691
-					sprintf('The URL %s does not point to a valid metadata file. ', $url)
692
-					. $status->get_error_message(),
693
-					E_USER_WARNING
694
-				);
695
-			}
696
-
697
-			return array($metadata, $result);
698
-		}
699
-
700
-		/**
701
-		 * Check if $result is a successful update API response.
702
-		 *
703
-		 * @param array|WP_Error $result
704
-		 * @return true|WP_Error
705
-		 */
706
-		protected function validateApiResponse($result) {
707
-			if ( is_wp_error($result) ) { /** @var WP_Error $result */
708
-				return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
709
-			}
710
-
711
-			if ( !isset($result['response']['code']) ) {
712
-				return new WP_Error(
713
-					'puc_no_response_code',
714
-					'wp_remote_get() returned an unexpected result.'
715
-				);
716
-			}
717
-
718
-			if ( $result['response']['code'] !== 200 ) {
719
-				return new WP_Error(
720
-					'puc_unexpected_response_code',
721
-					'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
722
-				);
723
-			}
724
-
725
-			if ( empty($result['body']) ) {
726
-				return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
727
-			}
728
-
729
-			return true;
730
-		}
731
-
732
-		/* -------------------------------------------------------------------
680
+            //Try to parse the response
681
+            $status = $this->validateApiResponse($result);
682
+            $metadata = null;
683
+            if ( !is_wp_error($status) ){
684
+                if ( (strpos($metaClass, '\\') === false) ) {
685
+                    $metaClass = __NAMESPACE__ . '\\' . $metaClass;
686
+                }
687
+                $metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
688
+            } else {
689
+                do_action('puc_api_error', $status, $result, $url, $this->slug);
690
+                $this->triggerError(
691
+                    sprintf('The URL %s does not point to a valid metadata file. ', $url)
692
+                    . $status->get_error_message(),
693
+                    E_USER_WARNING
694
+                );
695
+            }
696
+
697
+            return array($metadata, $result);
698
+        }
699
+
700
+        /**
701
+         * Check if $result is a successful update API response.
702
+         *
703
+         * @param array|WP_Error $result
704
+         * @return true|WP_Error
705
+         */
706
+        protected function validateApiResponse($result) {
707
+            if ( is_wp_error($result) ) { /** @var WP_Error $result */
708
+                return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
709
+            }
710
+
711
+            if ( !isset($result['response']['code']) ) {
712
+                return new WP_Error(
713
+                    'puc_no_response_code',
714
+                    'wp_remote_get() returned an unexpected result.'
715
+                );
716
+            }
717
+
718
+            if ( $result['response']['code'] !== 200 ) {
719
+                return new WP_Error(
720
+                    'puc_unexpected_response_code',
721
+                    'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
722
+                );
723
+            }
724
+
725
+            if ( empty($result['body']) ) {
726
+                return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
727
+            }
728
+
729
+            return true;
730
+        }
731
+
732
+        /* -------------------------------------------------------------------
733 733
 		 * Language packs / Translation updates
734 734
 		 * -------------------------------------------------------------------
735 735
 		 */
736 736
 
737
-		/**
738
-		 * Filter a list of translation updates and return a new list that contains only updates
739
-		 * that apply to the current site.
740
-		 *
741
-		 * @param array $translations
742
-		 * @return array
743
-		 */
744
-		protected function filterApplicableTranslations($translations) {
745
-			$languages = array_flip(array_values(get_available_languages()));
746
-			$installedTranslations = $this->getInstalledTranslations();
747
-
748
-			$applicableTranslations = array();
749
-			foreach ($translations as $translation) {
750
-				//Does it match one of the available core languages?
751
-				$isApplicable = array_key_exists($translation->language, $languages);
752
-				//Is it more recent than an already-installed translation?
753
-				if ( isset($installedTranslations[$translation->language]) ) {
754
-					$updateTimestamp = strtotime($translation->updated);
755
-					$installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
756
-					$isApplicable = $updateTimestamp > $installedTimestamp;
757
-				}
758
-
759
-				if ( $isApplicable ) {
760
-					$applicableTranslations[] = $translation;
761
-				}
762
-			}
763
-
764
-			return $applicableTranslations;
765
-		}
766
-
767
-		/**
768
-		 * Get a list of installed translations for this plugin or theme.
769
-		 *
770
-		 * @return array
771
-		 */
772
-		protected function getInstalledTranslations() {
773
-			if ( !function_exists('wp_get_installed_translations') ) {
774
-				return array();
775
-			}
776
-			$installedTranslations = wp_get_installed_translations($this->translationType . 's');
777
-			if ( isset($installedTranslations[$this->directoryName]) ) {
778
-				$installedTranslations = $installedTranslations[$this->directoryName];
779
-			} else {
780
-				$installedTranslations = array();
781
-			}
782
-			return $installedTranslations;
783
-		}
784
-
785
-		/**
786
-		 * Insert translation updates into the list maintained by WordPress.
787
-		 *
788
-		 * @param stdClass $updates
789
-		 * @return stdClass
790
-		 */
791
-		public function injectTranslationUpdates($updates) {
792
-			$translationUpdates = $this->getTranslationUpdates();
793
-			if ( empty($translationUpdates) ) {
794
-				return $updates;
795
-			}
796
-
797
-			//Being defensive.
798
-			if ( !is_object($updates) ) {
799
-				$updates = new stdClass();
800
-			}
801
-			if ( !isset($updates->translations) ) {
802
-				$updates->translations = array();
803
-			}
804
-
805
-			//In case there's a name collision with a plugin or theme hosted on wordpress.org,
806
-			//remove any preexisting updates that match our thing.
807
-			$updates->translations = array_values(array_filter(
808
-				$updates->translations,
809
-				array($this, 'isNotMyTranslation')
810
-			));
811
-
812
-			//Add our updates to the list.
813
-			foreach($translationUpdates as $update) {
814
-				$convertedUpdate = array_merge(
815
-					array(
816
-						'type' => $this->translationType,
817
-						'slug' => $this->directoryName,
818
-						'autoupdate' => 0,
819
-						//AFAICT, WordPress doesn't actually use the "version" field for anything.
820
-						//But lets make sure it's there, just in case.
821
-						'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
822
-					),
823
-					(array)$update
824
-				);
825
-
826
-				$updates->translations[] = $convertedUpdate;
827
-			}
828
-
829
-			return $updates;
830
-		}
831
-
832
-		/**
833
-		 * Get a list of available translation updates.
834
-		 *
835
-		 * This method will return an empty array if there are no updates.
836
-		 * Uses cached update data.
837
-		 *
838
-		 * @return array
839
-		 */
840
-		public function getTranslationUpdates() {
841
-			return $this->updateState->getTranslations();
842
-		}
843
-
844
-		/**
845
-		 * Remove all cached translation updates.
846
-		 *
847
-		 * @see wp_clean_update_cache
848
-		 */
849
-		public function clearCachedTranslationUpdates() {
850
-			$this->updateState->setTranslations(array());
851
-		}
852
-
853
-		/**
854
-		 * Filter callback. Keeps only translations that *don't* match this plugin or theme.
855
-		 *
856
-		 * @param array $translation
857
-		 * @return bool
858
-		 */
859
-		protected function isNotMyTranslation($translation) {
860
-			$isMatch = isset($translation['type'], $translation['slug'])
861
-				&& ($translation['type'] === $this->translationType)
862
-				&& ($translation['slug'] === $this->directoryName);
863
-
864
-			return !$isMatch;
865
-		}
866
-
867
-		/* -------------------------------------------------------------------
737
+        /**
738
+         * Filter a list of translation updates and return a new list that contains only updates
739
+         * that apply to the current site.
740
+         *
741
+         * @param array $translations
742
+         * @return array
743
+         */
744
+        protected function filterApplicableTranslations($translations) {
745
+            $languages = array_flip(array_values(get_available_languages()));
746
+            $installedTranslations = $this->getInstalledTranslations();
747
+
748
+            $applicableTranslations = array();
749
+            foreach ($translations as $translation) {
750
+                //Does it match one of the available core languages?
751
+                $isApplicable = array_key_exists($translation->language, $languages);
752
+                //Is it more recent than an already-installed translation?
753
+                if ( isset($installedTranslations[$translation->language]) ) {
754
+                    $updateTimestamp = strtotime($translation->updated);
755
+                    $installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
756
+                    $isApplicable = $updateTimestamp > $installedTimestamp;
757
+                }
758
+
759
+                if ( $isApplicable ) {
760
+                    $applicableTranslations[] = $translation;
761
+                }
762
+            }
763
+
764
+            return $applicableTranslations;
765
+        }
766
+
767
+        /**
768
+         * Get a list of installed translations for this plugin or theme.
769
+         *
770
+         * @return array
771
+         */
772
+        protected function getInstalledTranslations() {
773
+            if ( !function_exists('wp_get_installed_translations') ) {
774
+                return array();
775
+            }
776
+            $installedTranslations = wp_get_installed_translations($this->translationType . 's');
777
+            if ( isset($installedTranslations[$this->directoryName]) ) {
778
+                $installedTranslations = $installedTranslations[$this->directoryName];
779
+            } else {
780
+                $installedTranslations = array();
781
+            }
782
+            return $installedTranslations;
783
+        }
784
+
785
+        /**
786
+         * Insert translation updates into the list maintained by WordPress.
787
+         *
788
+         * @param stdClass $updates
789
+         * @return stdClass
790
+         */
791
+        public function injectTranslationUpdates($updates) {
792
+            $translationUpdates = $this->getTranslationUpdates();
793
+            if ( empty($translationUpdates) ) {
794
+                return $updates;
795
+            }
796
+
797
+            //Being defensive.
798
+            if ( !is_object($updates) ) {
799
+                $updates = new stdClass();
800
+            }
801
+            if ( !isset($updates->translations) ) {
802
+                $updates->translations = array();
803
+            }
804
+
805
+            //In case there's a name collision with a plugin or theme hosted on wordpress.org,
806
+            //remove any preexisting updates that match our thing.
807
+            $updates->translations = array_values(array_filter(
808
+                $updates->translations,
809
+                array($this, 'isNotMyTranslation')
810
+            ));
811
+
812
+            //Add our updates to the list.
813
+            foreach($translationUpdates as $update) {
814
+                $convertedUpdate = array_merge(
815
+                    array(
816
+                        'type' => $this->translationType,
817
+                        'slug' => $this->directoryName,
818
+                        'autoupdate' => 0,
819
+                        //AFAICT, WordPress doesn't actually use the "version" field for anything.
820
+                        //But lets make sure it's there, just in case.
821
+                        'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
822
+                    ),
823
+                    (array)$update
824
+                );
825
+
826
+                $updates->translations[] = $convertedUpdate;
827
+            }
828
+
829
+            return $updates;
830
+        }
831
+
832
+        /**
833
+         * Get a list of available translation updates.
834
+         *
835
+         * This method will return an empty array if there are no updates.
836
+         * Uses cached update data.
837
+         *
838
+         * @return array
839
+         */
840
+        public function getTranslationUpdates() {
841
+            return $this->updateState->getTranslations();
842
+        }
843
+
844
+        /**
845
+         * Remove all cached translation updates.
846
+         *
847
+         * @see wp_clean_update_cache
848
+         */
849
+        public function clearCachedTranslationUpdates() {
850
+            $this->updateState->setTranslations(array());
851
+        }
852
+
853
+        /**
854
+         * Filter callback. Keeps only translations that *don't* match this plugin or theme.
855
+         *
856
+         * @param array $translation
857
+         * @return bool
858
+         */
859
+        protected function isNotMyTranslation($translation) {
860
+            $isMatch = isset($translation['type'], $translation['slug'])
861
+                && ($translation['type'] === $this->translationType)
862
+                && ($translation['slug'] === $this->directoryName);
863
+
864
+            return !$isMatch;
865
+        }
866
+
867
+        /* -------------------------------------------------------------------
868 868
 		 * Fix directory name when installing updates
869 869
 		 * -------------------------------------------------------------------
870 870
 		 */
871 871
 
872
-		/**
873
-		 * Rename the update directory to match the existing plugin/theme directory.
874
-		 *
875
-		 * When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain
876
-		 * exactly one directory, and that the directory name will be the same as the directory where
877
-		 * the plugin or theme is currently installed.
878
-		 *
879
-		 * GitHub and other repositories provide ZIP downloads, but they often use directory names like
880
-		 * "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder.
881
-		 *
882
-		 * This is a hook callback. Don't call it from a plugin.
883
-		 *
884
-		 * @access protected
885
-		 *
886
-		 * @param string $source The directory to copy to /wp-content/plugins or /wp-content/themes. Usually a subdirectory of $remoteSource.
887
-		 * @param string $remoteSource WordPress has extracted the update to this directory.
888
-		 * @param \WP_Upgrader $upgrader
889
-		 * @return string|WP_Error
890
-		 */
891
-		public function fixDirectoryName($source, $remoteSource, $upgrader) {
892
-			global $wp_filesystem;
893
-			/** @var \WP_Filesystem_Base $wp_filesystem */
894
-
895
-			//Basic sanity checks.
896
-			if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
897
-				return $source;
898
-			}
899
-
900
-			//If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
901
-			if ( !$this->isBeingUpgraded($upgrader) ) {
902
-				return $source;
903
-			}
904
-
905
-			//Rename the source to match the existing directory.
906
-			$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
907
-			if ( $source !== $correctedSource ) {
908
-				//The update archive should contain a single directory that contains the rest of plugin/theme files.
909
-				//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
910
-				//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
911
-				//after update.
912
-				if ( $this->isBadDirectoryStructure($remoteSource) ) {
913
-					return new WP_Error(
914
-						'puc-incorrect-directory-structure',
915
-						sprintf(
916
-							'The directory structure of the update is incorrect. All files should be inside ' .
917
-							'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
918
-							htmlentities($this->slug)
919
-						)
920
-					);
921
-				}
922
-
923
-				/** @var \WP_Upgrader_Skin $upgrader ->skin */
924
-				$upgrader->skin->feedback(sprintf(
925
-					'Renaming %s to %s&#8230;',
926
-					'<span class="code">' . basename($source) . '</span>',
927
-					'<span class="code">' . $this->directoryName . '</span>'
928
-				));
929
-
930
-				if ( $wp_filesystem->move($source, $correctedSource, true) ) {
931
-					$upgrader->skin->feedback('Directory successfully renamed.');
932
-					return $correctedSource;
933
-				} else {
934
-					return new WP_Error(
935
-						'puc-rename-failed',
936
-						'Unable to rename the update to match the existing directory.'
937
-					);
938
-				}
939
-			}
940
-
941
-			return $source;
942
-		}
943
-
944
-		/**
945
-		 * Is there an update being installed right now, for this plugin or theme?
946
-		 *
947
-		 * @param \WP_Upgrader|null $upgrader The upgrader that's performing the current update.
948
-		 * @return bool
949
-		 */
950
-		abstract public function isBeingUpgraded($upgrader = null);
951
-
952
-		/**
953
-		 * Check for incorrect update directory structure. An update must contain a single directory,
954
-		 * all other files should be inside that directory.
955
-		 *
956
-		 * @param string $remoteSource Directory path.
957
-		 * @return bool
958
-		 */
959
-		protected function isBadDirectoryStructure($remoteSource) {
960
-			global $wp_filesystem;
961
-			/** @var \WP_Filesystem_Base $wp_filesystem */
962
-
963
-			$sourceFiles = $wp_filesystem->dirlist($remoteSource);
964
-			if ( is_array($sourceFiles) ) {
965
-				$sourceFiles = array_keys($sourceFiles);
966
-				$firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
967
-				return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
968
-			}
969
-
970
-			//Assume it's fine.
971
-			return false;
972
-		}
973
-
974
-		/* -------------------------------------------------------------------
872
+        /**
873
+         * Rename the update directory to match the existing plugin/theme directory.
874
+         *
875
+         * When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain
876
+         * exactly one directory, and that the directory name will be the same as the directory where
877
+         * the plugin or theme is currently installed.
878
+         *
879
+         * GitHub and other repositories provide ZIP downloads, but they often use directory names like
880
+         * "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder.
881
+         *
882
+         * This is a hook callback. Don't call it from a plugin.
883
+         *
884
+         * @access protected
885
+         *
886
+         * @param string $source The directory to copy to /wp-content/plugins or /wp-content/themes. Usually a subdirectory of $remoteSource.
887
+         * @param string $remoteSource WordPress has extracted the update to this directory.
888
+         * @param \WP_Upgrader $upgrader
889
+         * @return string|WP_Error
890
+         */
891
+        public function fixDirectoryName($source, $remoteSource, $upgrader) {
892
+            global $wp_filesystem;
893
+            /** @var \WP_Filesystem_Base $wp_filesystem */
894
+
895
+            //Basic sanity checks.
896
+            if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
897
+                return $source;
898
+            }
899
+
900
+            //If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
901
+            if ( !$this->isBeingUpgraded($upgrader) ) {
902
+                return $source;
903
+            }
904
+
905
+            //Rename the source to match the existing directory.
906
+            $correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
907
+            if ( $source !== $correctedSource ) {
908
+                //The update archive should contain a single directory that contains the rest of plugin/theme files.
909
+                //Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
910
+                //We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
911
+                //after update.
912
+                if ( $this->isBadDirectoryStructure($remoteSource) ) {
913
+                    return new WP_Error(
914
+                        'puc-incorrect-directory-structure',
915
+                        sprintf(
916
+                            'The directory structure of the update is incorrect. All files should be inside ' .
917
+                            'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
918
+                            htmlentities($this->slug)
919
+                        )
920
+                    );
921
+                }
922
+
923
+                /** @var \WP_Upgrader_Skin $upgrader ->skin */
924
+                $upgrader->skin->feedback(sprintf(
925
+                    'Renaming %s to %s&#8230;',
926
+                    '<span class="code">' . basename($source) . '</span>',
927
+                    '<span class="code">' . $this->directoryName . '</span>'
928
+                ));
929
+
930
+                if ( $wp_filesystem->move($source, $correctedSource, true) ) {
931
+                    $upgrader->skin->feedback('Directory successfully renamed.');
932
+                    return $correctedSource;
933
+                } else {
934
+                    return new WP_Error(
935
+                        'puc-rename-failed',
936
+                        'Unable to rename the update to match the existing directory.'
937
+                    );
938
+                }
939
+            }
940
+
941
+            return $source;
942
+        }
943
+
944
+        /**
945
+         * Is there an update being installed right now, for this plugin or theme?
946
+         *
947
+         * @param \WP_Upgrader|null $upgrader The upgrader that's performing the current update.
948
+         * @return bool
949
+         */
950
+        abstract public function isBeingUpgraded($upgrader = null);
951
+
952
+        /**
953
+         * Check for incorrect update directory structure. An update must contain a single directory,
954
+         * all other files should be inside that directory.
955
+         *
956
+         * @param string $remoteSource Directory path.
957
+         * @return bool
958
+         */
959
+        protected function isBadDirectoryStructure($remoteSource) {
960
+            global $wp_filesystem;
961
+            /** @var \WP_Filesystem_Base $wp_filesystem */
962
+
963
+            $sourceFiles = $wp_filesystem->dirlist($remoteSource);
964
+            if ( is_array($sourceFiles) ) {
965
+                $sourceFiles = array_keys($sourceFiles);
966
+                $firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
967
+                return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
968
+            }
969
+
970
+            //Assume it's fine.
971
+            return false;
972
+        }
973
+
974
+        /* -------------------------------------------------------------------
975 975
 		 * DebugBar integration
976 976
 		 * -------------------------------------------------------------------
977 977
 		 */
978 978
 
979
-		/**
980
-		 * Initialize the update checker Debug Bar plugin/add-on thingy.
981
-		 */
982
-		public function maybeInitDebugBar() {
983
-			if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__) . '/DebugBar') ) {
984
-				$this->debugBarExtension = $this->createDebugBarExtension();
985
-			}
986
-		}
987
-
988
-		protected function createDebugBarExtension() {
989
-			return new DebugBar\Extension($this);
990
-		}
991
-
992
-		/**
993
-		 * Display additional configuration details in the Debug Bar panel.
994
-		 *
995
-		 * @param DebugBar\Panel $panel
996
-		 */
997
-		public function onDisplayConfiguration($panel) {
998
-			//Do nothing. Subclasses can use this to add additional info to the panel.
999
-		}
1000
-
1001
-	}
979
+        /**
980
+         * Initialize the update checker Debug Bar plugin/add-on thingy.
981
+         */
982
+        public function maybeInitDebugBar() {
983
+            if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__) . '/DebugBar') ) {
984
+                $this->debugBarExtension = $this->createDebugBarExtension();
985
+            }
986
+        }
987
+
988
+        protected function createDebugBarExtension() {
989
+            return new DebugBar\Extension($this);
990
+        }
991
+
992
+        /**
993
+         * Display additional configuration details in the Debug Bar panel.
994
+         *
995
+         * @param DebugBar\Panel $panel
996
+         */
997
+        public function onDisplayConfiguration($panel) {
998
+            //Do nothing. Subclasses can use this to add additional info to the panel.
999
+        }
1000
+
1001
+    }
1002 1002
 
1003 1003
 endif;
Please login to merge, or discard this patch.
Spacing   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use stdClass;
5 5
 use WP_Error;
6 6
 
7
-if ( !class_exists(UpdateChecker::class, false) ):
7
+if (!class_exists(UpdateChecker::class, false)):
8 8
 
9 9
 	abstract class UpdateChecker {
10 10
 		protected $filterSuffix = '';
@@ -75,16 +75,16 @@  discard block
 block discarded – undo
75 75
 		protected $debugBarExtension = null;
76 76
 
77 77
 		public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
78
-			$this->debugMode = (bool)(constant('WP_DEBUG'));
78
+			$this->debugMode = (bool) (constant('WP_DEBUG'));
79 79
 			$this->metadataUrl = $metadataUrl;
80 80
 			$this->directoryName = $directoryName;
81 81
 			$this->slug = !empty($slug) ? $slug : $this->directoryName;
82 82
 
83 83
 			$this->optionName = $optionName;
84
-			if ( empty($this->optionName) ) {
84
+			if (empty($this->optionName)) {
85 85
 				//BC: Initially the library only supported plugin updates and didn't use type prefixes
86 86
 				//in the option name. Lets use the same prefix-less name when possible.
87
-				if ( $this->filterSuffix === '' ) {
87
+				if ($this->filterSuffix === '') {
88 88
 					$this->optionName = 'external_updates-' . $this->slug;
89 89
 				} else {
90 90
 					$this->optionName = $this->getUniqueName('external_updates');
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 			$this->upgraderStatus = new UpgraderStatus();
97 97
 			$this->updateState = new StateStore($this->optionName);
98 98
 
99
-			if ( did_action('init') ) {
99
+			if (did_action('init')) {
100 100
 				$this->loadTextDomain();
101 101
 			} else {
102 102
 				add_action('init', array($this, 'loadTextDomain'));
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
 
129 129
 		protected function installHooks() {
130 130
 			//Insert our update info into the update array maintained by WP.
131
-			add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
131
+			add_filter('site_transient_' . $this->updateTransient, array($this, 'injectUpdate'));
132 132
 
133 133
 			//Insert translation updates into the update list.
134 134
 			add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 			);
143 143
 
144 144
 			//Rename the update directory to be the same as the existing directory.
145
-			if ( $this->directoryName !== '.' ) {
145
+			if ($this->directoryName !== '.') {
146 146
 				add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
147 147
 			}
148 148
 
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
 			add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
151 151
 
152 152
 			//DebugBar integration.
153
-			if ( did_action('plugins_loaded') ) {
153
+			if (did_action('plugins_loaded')) {
154 154
 				$this->maybeInitDebugBar();
155 155
 			} else {
156 156
 				add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
 		 * Remove hooks that were added by this update checker instance.
162 162
 		 */
163 163
 		public function removeHooks() {
164
-			remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
164
+			remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectUpdate'));
165 165
 			remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
166 166
 			remove_action(
167 167
 				'delete_site_transient_' . $this->updateTransient,
@@ -174,11 +174,11 @@  discard block
 block discarded – undo
174 174
 
175 175
 			remove_action('init', array($this, 'loadTextDomain'));
176 176
 
177
-			if ( $this->scheduler ) {
177
+			if ($this->scheduler) {
178 178
 				$this->scheduler->removeHooks();
179 179
 			}
180 180
 
181
-			if ( $this->debugBarExtension ) {
181
+			if ($this->debugBarExtension) {
182 182
 				$this->debugBarExtension->removeHooks();
183 183
 			}
184 184
 		}
@@ -209,11 +209,11 @@  discard block
 block discarded – undo
209 209
 		 * @return bool
210 210
 		 */
211 211
 		public function allowMetadataHost($allow, $host) {
212
-			if ( $this->cachedMetadataHost === 0 ) {
212
+			if ($this->cachedMetadataHost === 0) {
213 213
 				$this->cachedMetadataHost = wp_parse_url($this->metadataUrl, PHP_URL_HOST);
214 214
 			}
215 215
 
216
-			if ( is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost)) ) {
216
+			if (is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost))) {
217 217
 				return true;
218 218
 			}
219 219
 			return $allow;
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
 		public function checkForUpdates() {
253 253
 			$installedVersion = $this->getInstalledVersion();
254 254
 			//Fail silently if we can't find the plugin/theme or read its header.
255
-			if ( $installedVersion === null ) {
255
+			if ($installedVersion === null) {
256 256
 				$this->triggerError(
257 257
 					sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
258 258
 					E_USER_WARNING
@@ -312,10 +312,10 @@  discard block
 block discarded – undo
312 312
 			$update = $this->updateState->getUpdate();
313 313
 
314 314
 			//Is there an update available?
315
-			if ( isset($update) ) {
315
+			if (isset($update)) {
316 316
 				//Check if the update is actually newer than the currently installed version.
317 317
 				$installedVersion = $this->getInstalledVersion();
318
-				if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
318
+				if (($installedVersion !== null) && version_compare($update->version, $installedVersion, '>')) {
319 319
 					return $update;
320 320
 				}
321 321
 			}
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 
346 346
 			$this->fixSupportedWordpressVersion($update);
347 347
 
348
-			if ( isset($update, $update->translations) ) {
348
+			if (isset($update, $update->translations)) {
349 349
 				//Keep only those translation updates that apply to this site.
350 350
 				$update->translations = $this->filterApplicableTranslations($update->translations);
351 351
 			}
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
 		 * @param Metadata|null $update
364 364
 		 */
365 365
 		protected function fixSupportedWordpressVersion(Metadata $update = null) {
366
-			if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
366
+			if (!isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested)) {
367 367
 				return;
368 368
 			}
369 369
 
@@ -371,11 +371,11 @@  discard block
 block discarded – undo
371 371
 
372 372
 			$wpVersion = $GLOBALS['wp_version'];
373 373
 
374
-			if ( function_exists('get_core_updates') ) {
374
+			if (function_exists('get_core_updates')) {
375 375
 				$coreUpdates = get_core_updates();
376
-				if ( is_array($coreUpdates) ) {
376
+				if (is_array($coreUpdates)) {
377 377
 					foreach ($coreUpdates as $coreUpdate) {
378
-						if ( isset($coreUpdate->current) ) {
378
+						if (isset($coreUpdate->current)) {
379 379
 							$actualWpVersions[] = $coreUpdate->current;
380 380
 						}
381 381
 					}
@@ -386,10 +386,10 @@  discard block
 block discarded – undo
386 386
 
387 387
 			$actualWpPatchNumber = null;
388 388
 			foreach ($actualWpVersions as $version) {
389
-				if ( preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts) ) {
390
-					if ( $versionParts['majorMinor'] === $update->tested ) {
389
+				if (preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts)) {
390
+					if ($versionParts['majorMinor'] === $update->tested) {
391 391
 						$patch = isset($versionParts['patch']) ? intval($versionParts['patch']) : 0;
392
-						if ( $actualWpPatchNumber === null ) {
392
+						if ($actualWpPatchNumber === null) {
393 393
 							$actualWpPatchNumber = $patch;
394 394
 						} else {
395 395
 							$actualWpPatchNumber = max($actualWpPatchNumber, $patch);
@@ -397,11 +397,11 @@  discard block
 block discarded – undo
397 397
 					}
398 398
 				}
399 399
 			}
400
-			if ( $actualWpPatchNumber === null ) {
400
+			if ($actualWpPatchNumber === null) {
401 401
 				$actualWpPatchNumber = 999;
402 402
 			}
403 403
 
404
-			if ( $actualWpPatchNumber > 0 ) {
404
+			if ($actualWpPatchNumber > 0) {
405 405
 				$update->tested .= '.' . $actualWpPatchNumber;
406 406
 			}
407 407
 		}
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 		 * @param int $errorType
432 432
 		 */
433 433
 		public function triggerError($message, $errorType) {
434
-			if ( $this->isDebugModeEnabled() ) {
434
+			if ($this->isDebugModeEnabled()) {
435 435
 				//phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error -- Only happens in debug mode.
436 436
 				trigger_error(esc_html($message), $errorType);
437 437
 			}
@@ -441,8 +441,8 @@  discard block
 block discarded – undo
441 441
 		 * @return bool
442 442
 		 */
443 443
 		protected function isDebugModeEnabled() {
444
-			if ( $this->debugMode === null ) {
445
-				$this->debugMode = (bool)(constant('WP_DEBUG'));
444
+			if ($this->debugMode === null) {
445
+				$this->debugMode = (bool) (constant('WP_DEBUG'));
446 446
 			}
447 447
 			return $this->debugMode;
448 448
 		}
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
 		 */
459 459
 		public function getUniqueName($baseTag) {
460 460
 			$name = 'puc_' . $baseTag;
461
-			if ( $this->filterSuffix !== '' ) {
461
+			if ($this->filterSuffix !== '') {
462 462
 				$name .= '_' . $this->filterSuffix;
463 463
 			}
464 464
 			return $name . '-' . $this->slug;
@@ -474,7 +474,7 @@  discard block
 block discarded – undo
474 474
 		 * @param string|null $slug
475 475
 		 */
476 476
 		public function collectApiErrors($error, $httpResponse = null, $url = null, $slug = null) {
477
-			if ( isset($slug) && ($slug !== $this->slug) ) {
477
+			if (isset($slug) && ($slug !== $this->slug)) {
478 478
 				return;
479 479
 			}
480 480
 
@@ -528,11 +528,11 @@  discard block
 block discarded – undo
528 528
 			//Is there an update to insert?
529 529
 			$update = $this->getUpdate();
530 530
 
531
-			if ( !$this->shouldShowUpdates() ) {
531
+			if (!$this->shouldShowUpdates()) {
532 532
 				$update = null;
533 533
 			}
534 534
 
535
-			if ( !empty($update) ) {
535
+			if (!empty($update)) {
536 536
 				//Let plugins filter the update info before it's passed on to WordPress.
537 537
 				$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
538 538
 				$updates = $this->addUpdateToList($updates, $update->toWpFormat());
@@ -554,7 +554,7 @@  discard block
 block discarded – undo
554 554
 		 * @return \stdClass
555 555
 		 */
556 556
 		protected function addUpdateToList($updates, $updateToAdd) {
557
-			if ( !is_object($updates) ) {
557
+			if (!is_object($updates)) {
558 558
 				$updates = new stdClass();
559 559
 				$updates->response = array();
560 560
 			}
@@ -568,7 +568,7 @@  discard block
 block discarded – undo
568 568
 		 * @return \stdClass|null
569 569
 		 */
570 570
 		protected function removeUpdateFromList($updates) {
571
-			if ( isset($updates, $updates->response) ) {
571
+			if (isset($updates, $updates->response)) {
572 572
 				unset($updates->response[$this->getUpdateListKey()]);
573 573
 			}
574 574
 			return $updates;
@@ -582,11 +582,11 @@  discard block
 block discarded – undo
582 582
 		 * @return \stdClass
583 583
 		 */
584 584
 		protected function addNoUpdateItem($updates) {
585
-			if ( !is_object($updates) ) {
585
+			if (!is_object($updates)) {
586 586
 				$updates = new stdClass();
587 587
 				$updates->response = array();
588 588
 				$updates->no_update = array();
589
-			} else if ( !isset($updates->no_update) ) {
589
+			} else if (!isset($updates->no_update)) {
590 590
 				$updates->no_update = array();
591 591
 			}
592 592
 
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
 
670 670
 			//The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
671 671
 			$url = $this->metadataUrl;
672
-			if ( !empty($queryArgs) ){
672
+			if (!empty($queryArgs)) {
673 673
 				$url = add_query_arg($queryArgs, $url);
674 674
 			}
675 675
 
@@ -680,8 +680,8 @@  discard block
 block discarded – undo
680 680
 			//Try to parse the response
681 681
 			$status = $this->validateApiResponse($result);
682 682
 			$metadata = null;
683
-			if ( !is_wp_error($status) ){
684
-				if ( (strpos($metaClass, '\\') === false) ) {
683
+			if (!is_wp_error($status)) {
684
+				if ((strpos($metaClass, '\\') === false)) {
685 685
 					$metaClass = __NAMESPACE__ . '\\' . $metaClass;
686 686
 				}
687 687
 				$metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
@@ -704,25 +704,25 @@  discard block
 block discarded – undo
704 704
 		 * @return true|WP_Error
705 705
 		 */
706 706
 		protected function validateApiResponse($result) {
707
-			if ( is_wp_error($result) ) { /** @var WP_Error $result */
707
+			if (is_wp_error($result)) { /** @var WP_Error $result */
708 708
 				return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
709 709
 			}
710 710
 
711
-			if ( !isset($result['response']['code']) ) {
711
+			if (!isset($result['response']['code'])) {
712 712
 				return new WP_Error(
713 713
 					'puc_no_response_code',
714 714
 					'wp_remote_get() returned an unexpected result.'
715 715
 				);
716 716
 			}
717 717
 
718
-			if ( $result['response']['code'] !== 200 ) {
718
+			if ($result['response']['code'] !== 200) {
719 719
 				return new WP_Error(
720 720
 					'puc_unexpected_response_code',
721 721
 					'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
722 722
 				);
723 723
 			}
724 724
 
725
-			if ( empty($result['body']) ) {
725
+			if (empty($result['body'])) {
726 726
 				return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
727 727
 			}
728 728
 
@@ -750,13 +750,13 @@  discard block
 block discarded – undo
750 750
 				//Does it match one of the available core languages?
751 751
 				$isApplicable = array_key_exists($translation->language, $languages);
752 752
 				//Is it more recent than an already-installed translation?
753
-				if ( isset($installedTranslations[$translation->language]) ) {
753
+				if (isset($installedTranslations[$translation->language])) {
754 754
 					$updateTimestamp = strtotime($translation->updated);
755 755
 					$installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
756 756
 					$isApplicable = $updateTimestamp > $installedTimestamp;
757 757
 				}
758 758
 
759
-				if ( $isApplicable ) {
759
+				if ($isApplicable) {
760 760
 					$applicableTranslations[] = $translation;
761 761
 				}
762 762
 			}
@@ -770,11 +770,11 @@  discard block
 block discarded – undo
770 770
 		 * @return array
771 771
 		 */
772 772
 		protected function getInstalledTranslations() {
773
-			if ( !function_exists('wp_get_installed_translations') ) {
773
+			if (!function_exists('wp_get_installed_translations')) {
774 774
 				return array();
775 775
 			}
776 776
 			$installedTranslations = wp_get_installed_translations($this->translationType . 's');
777
-			if ( isset($installedTranslations[$this->directoryName]) ) {
777
+			if (isset($installedTranslations[$this->directoryName])) {
778 778
 				$installedTranslations = $installedTranslations[$this->directoryName];
779 779
 			} else {
780 780
 				$installedTranslations = array();
@@ -790,15 +790,15 @@  discard block
 block discarded – undo
790 790
 		 */
791 791
 		public function injectTranslationUpdates($updates) {
792 792
 			$translationUpdates = $this->getTranslationUpdates();
793
-			if ( empty($translationUpdates) ) {
793
+			if (empty($translationUpdates)) {
794 794
 				return $updates;
795 795
 			}
796 796
 
797 797
 			//Being defensive.
798
-			if ( !is_object($updates) ) {
798
+			if (!is_object($updates)) {
799 799
 				$updates = new stdClass();
800 800
 			}
801
-			if ( !isset($updates->translations) ) {
801
+			if (!isset($updates->translations)) {
802 802
 				$updates->translations = array();
803 803
 			}
804 804
 
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
 			));
811 811
 
812 812
 			//Add our updates to the list.
813
-			foreach($translationUpdates as $update) {
813
+			foreach ($translationUpdates as $update) {
814 814
 				$convertedUpdate = array_merge(
815 815
 					array(
816 816
 						'type' => $this->translationType,
@@ -820,7 +820,7 @@  discard block
 block discarded – undo
820 820
 						//But lets make sure it's there, just in case.
821 821
 						'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
822 822
 					),
823
-					(array)$update
823
+					(array) $update
824 824
 				);
825 825
 
826 826
 				$updates->translations[] = $convertedUpdate;
@@ -893,23 +893,23 @@  discard block
 block discarded – undo
893 893
 			/** @var \WP_Filesystem_Base $wp_filesystem */
894 894
 
895 895
 			//Basic sanity checks.
896
-			if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
896
+			if (!isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem)) {
897 897
 				return $source;
898 898
 			}
899 899
 
900 900
 			//If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
901
-			if ( !$this->isBeingUpgraded($upgrader) ) {
901
+			if (!$this->isBeingUpgraded($upgrader)) {
902 902
 				return $source;
903 903
 			}
904 904
 
905 905
 			//Rename the source to match the existing directory.
906 906
 			$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
907
-			if ( $source !== $correctedSource ) {
907
+			if ($source !== $correctedSource) {
908 908
 				//The update archive should contain a single directory that contains the rest of plugin/theme files.
909 909
 				//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
910 910
 				//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
911 911
 				//after update.
912
-				if ( $this->isBadDirectoryStructure($remoteSource) ) {
912
+				if ($this->isBadDirectoryStructure($remoteSource)) {
913 913
 					return new WP_Error(
914 914
 						'puc-incorrect-directory-structure',
915 915
 						sprintf(
@@ -927,7 +927,7 @@  discard block
 block discarded – undo
927 927
 					'<span class="code">' . $this->directoryName . '</span>'
928 928
 				));
929 929
 
930
-				if ( $wp_filesystem->move($source, $correctedSource, true) ) {
930
+				if ($wp_filesystem->move($source, $correctedSource, true)) {
931 931
 					$upgrader->skin->feedback('Directory successfully renamed.');
932 932
 					return $correctedSource;
933 933
 				} else {
@@ -961,7 +961,7 @@  discard block
 block discarded – undo
961 961
 			/** @var \WP_Filesystem_Base $wp_filesystem */
962 962
 
963 963
 			$sourceFiles = $wp_filesystem->dirlist($remoteSource);
964
-			if ( is_array($sourceFiles) ) {
964
+			if (is_array($sourceFiles)) {
965 965
 				$sourceFiles = array_keys($sourceFiles);
966 966
 				$firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
967 967
 				return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
@@ -980,7 +980,7 @@  discard block
 block discarded – undo
980 980
 		 * Initialize the update checker Debug Bar plugin/add-on thingy.
981 981
 		 */
982 982
 		public function maybeInitDebugBar() {
983
-			if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__) . '/DebugBar') ) {
983
+			if (class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__) . '/DebugBar')) {
984 984
 				$this->debugBarExtension = $this->createDebugBarExtension();
985 985
 			}
986 986
 		}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Plugin/UpdateChecker.php 2 patches
Indentation   +413 added lines, -413 removed lines patch added patch discarded remove patch
@@ -8,418 +8,418 @@
 block discarded – undo
8 8
 
9 9
 if ( !class_exists(UpdateChecker::class, false) ):
10 10
 
11
-	/**
12
-	 * A custom plugin update checker.
13
-	 *
14
-	 * @author Janis Elsts
15
-	 * @copyright 2018
16
-	 * @access public
17
-	 */
18
-	class UpdateChecker extends BaseUpdateChecker {
19
-		protected $updateTransient = 'update_plugins';
20
-		protected $translationType = 'plugin';
21
-
22
-		public $pluginAbsolutePath = ''; //Full path of the main plugin file.
23
-		public $pluginFile = '';  //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
24
-		public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
25
-
26
-		/**
27
-		 * @var Package
28
-		 */
29
-		protected $package;
30
-
31
-		private $extraUi = null;
32
-
33
-		/**
34
-		 * Class constructor.
35
-		 *
36
-		 * @param string $metadataUrl The URL of the plugin's metadata file.
37
-		 * @param string $pluginFile Fully qualified path to the main plugin file.
38
-		 * @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug.
39
-		 * @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
40
-		 * @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
41
-		 * @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
42
-		 */
43
-		public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
44
-			$this->pluginAbsolutePath = $pluginFile;
45
-			$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
46
-			$this->muPluginFile = $muPluginFile;
47
-
48
-			//If no slug is specified, use the name of the main plugin file as the slug.
49
-			//For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
50
-			if ( empty($slug) ){
51
-				$slug = basename($this->pluginFile, '.php');
52
-			}
53
-
54
-			//Plugin slugs must be unique.
55
-			$slugCheckFilter = 'puc_is_slug_in_use-' . $slug;
56
-			$slugUsedBy = apply_filters($slugCheckFilter, false);
57
-			if ( $slugUsedBy ) {
58
-				$this->triggerError(sprintf(
59
-					'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
60
-					$slug,
61
-					$slugUsedBy
62
-				), E_USER_ERROR);
63
-			}
64
-			add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
65
-
66
-			parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
67
-
68
-			//Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
69
-			//it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
70
-			if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
71
-				$this->muPluginFile = $this->pluginFile;
72
-			}
73
-
74
-			//To prevent a crash during plugin uninstallation, remove updater hooks when the user removes the plugin.
75
-			//Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
76
-			add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
77
-
78
-			$this->extraUi = new Ui($this);
79
-		}
80
-
81
-		/**
82
-		 * Create an instance of the scheduler.
83
-		 *
84
-		 * @param int $checkPeriod
85
-		 * @return Scheduler
86
-		 */
87
-		protected function createScheduler($checkPeriod) {
88
-			$scheduler = new Scheduler($this, $checkPeriod, array('load-plugins.php'));
89
-			register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
90
-			return $scheduler;
91
-		}
92
-
93
-		/**
94
-		 * Install the hooks required to run periodic update checks and inject update info
95
-		 * into WP data structures.
96
-		 *
97
-		 * @return void
98
-		 */
99
-		protected function installHooks(){
100
-			//Override requests for plugin information
101
-			add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
102
-
103
-			parent::installHooks();
104
-		}
105
-
106
-		/**
107
-		 * Remove update checker hooks.
108
-		 *
109
-		 * The intent is to prevent a fatal error that can happen if the plugin has an uninstall
110
-		 * hook. During uninstallation, WP includes the main plugin file (which creates a PUC instance),
111
-		 * the uninstall hook runs, WP deletes the plugin files and then updates some transients.
112
-		 * If PUC hooks are still around at this time, they could throw an error while trying to
113
-		 * autoload classes from files that no longer exist.
114
-		 *
115
-		 * The "site_transient_{$transient}" filter is the main problem here, but let's also remove
116
-		 * most other PUC hooks to be safe.
117
-		 *
118
-		 * @internal
119
-		 */
120
-		public function removeHooks() {
121
-			parent::removeHooks();
122
-			$this->extraUi->removeHooks();
123
-			$this->package->removeHooks();
124
-
125
-			remove_filter('plugins_api', array($this, 'injectInfo'), 20);
126
-		}
127
-
128
-		/**
129
-		 * Retrieve plugin info from the configured API endpoint.
130
-		 *
131
-		 * @uses wp_remote_get()
132
-		 *
133
-		 * @param array $queryArgs Additional query arguments to append to the request. Optional.
134
-		 * @return PluginInfo
135
-		 */
136
-		public function requestInfo($queryArgs = array()) {
137
-			list($pluginInfo, $result) = $this->requestMetadata(
138
-				PluginInfo::class,
139
-				'request_info',
140
-				$queryArgs
141
-			);
142
-
143
-			if ( $pluginInfo !== null ) {
144
-				/** @var PluginInfo $pluginInfo */
145
-				$pluginInfo->filename = $this->pluginFile;
146
-				$pluginInfo->slug = $this->slug;
147
-			}
148
-
149
-			$pluginInfo = apply_filters($this->getUniqueName('request_info_result'), $pluginInfo, $result);
150
-			return $pluginInfo;
151
-		}
152
-
153
-		/**
154
-		 * Retrieve the latest update (if any) from the configured API endpoint.
155
-		 *
156
-		 * @uses UpdateChecker::requestInfo()
157
-		 *
158
-		 * @return Update|null An instance of Plugin Update, or NULL when no updates are available.
159
-		 */
160
-		public function requestUpdate() {
161
-			//For the sake of simplicity, this function just calls requestInfo()
162
-			//and transforms the result accordingly.
163
-			$pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
164
-			if ( $pluginInfo === null ){
165
-				return null;
166
-			}
167
-			$update = Update::fromPluginInfo($pluginInfo);
168
-
169
-			$update = $this->filterUpdateResult($update);
170
-
171
-			return $update;
172
-		}
173
-
174
-		/**
175
-		 * Intercept plugins_api() calls that request information about our plugin and
176
-		 * use the configured API endpoint to satisfy them.
177
-		 *
178
-		 * @see plugins_api()
179
-		 *
180
-		 * @param mixed $result
181
-		 * @param string $action
182
-		 * @param array|object $args
183
-		 * @return mixed
184
-		 */
185
-		public function injectInfo($result, $action = null, $args = null){
186
-			$relevant = ($action == 'plugin_information') && isset($args->slug) && (
187
-					($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
188
-				);
189
-			if ( !$relevant ) {
190
-				return $result;
191
-			}
192
-
193
-			$pluginInfo = $this->requestInfo();
194
-			$this->fixSupportedWordpressVersion($pluginInfo);
195
-
196
-			$pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
197
-			if ( $pluginInfo ) {
198
-				return $pluginInfo->toWpFormat();
199
-			}
200
-
201
-			return $result;
202
-		}
203
-
204
-		protected function shouldShowUpdates() {
205
-			//No update notifications for mu-plugins unless explicitly enabled. The MU plugin file
206
-			//is usually different from the main plugin file so the update wouldn't show up properly anyway.
207
-			return !$this->isUnknownMuPlugin();
208
-		}
209
-
210
-		/**
211
-		 * @param \stdClass|null $updates
212
-		 * @param \stdClass $updateToAdd
213
-		 * @return \stdClass
214
-		 */
215
-		protected function addUpdateToList($updates, $updateToAdd) {
216
-			if ( $this->package->isMuPlugin() ) {
217
-				//WP does not support automatic update installation for mu-plugins, but we can
218
-				//still display a notice.
219
-				$updateToAdd->package = null;
220
-			}
221
-			return parent::addUpdateToList($updates, $updateToAdd);
222
-		}
223
-
224
-		/**
225
-		 * @param \stdClass|null $updates
226
-		 * @return \stdClass|null
227
-		 */
228
-		protected function removeUpdateFromList($updates) {
229
-			$updates = parent::removeUpdateFromList($updates);
230
-			if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
231
-				unset($updates->response[$this->muPluginFile]);
232
-			}
233
-			return $updates;
234
-		}
235
-
236
-		/**
237
-		 * For plugins, the update array is indexed by the plugin filename relative to the "plugins"
238
-		 * directory. Example: "plugin-name/plugin.php".
239
-		 *
240
-		 * @return string
241
-		 */
242
-		protected function getUpdateListKey() {
243
-			if ( $this->package->isMuPlugin() ) {
244
-				return $this->muPluginFile;
245
-			}
246
-			return $this->pluginFile;
247
-		}
248
-
249
-		protected function getNoUpdateItemFields() {
250
-			return array_merge(
251
-				parent::getNoUpdateItemFields(),
252
-				array(
253
-					'id'            => $this->pluginFile,
254
-					'slug'          => $this->slug,
255
-					'plugin'        => $this->pluginFile,
256
-					'icons'         => array(),
257
-					'banners'       => array(),
258
-					'banners_rtl'   => array(),
259
-					'tested'        => '',
260
-					'compatibility' => new \stdClass(),
261
-				)
262
-			);
263
-		}
264
-
265
-		/**
266
-		 * Alias for isBeingUpgraded().
267
-		 *
268
-		 * @deprecated
269
-		 * @param \WP_Upgrader|null $upgrader The upgrader that's performing the current update.
270
-		 * @return bool
271
-		 */
272
-		public function isPluginBeingUpgraded($upgrader = null) {
273
-			return $this->isBeingUpgraded($upgrader);
274
-		}
275
-
276
-		/**
277
-		 * Is there an update being installed for this plugin, right now?
278
-		 *
279
-		 * @param \WP_Upgrader|null $upgrader
280
-		 * @return bool
281
-		 */
282
-		public function isBeingUpgraded($upgrader = null) {
283
-			return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader);
284
-		}
285
-
286
-		/**
287
-		 * Get the details of the currently available update, if any.
288
-		 *
289
-		 * If no updates are available, or if the last known update version is below or equal
290
-		 * to the currently installed version, this method will return NULL.
291
-		 *
292
-		 * Uses cached update data. To retrieve update information straight from
293
-		 * the metadata URL, call requestUpdate() instead.
294
-		 *
295
-		 * @return Update|null
296
-		 */
297
-		public function getUpdate() {
298
-			$update = parent::getUpdate();
299
-			if ( isset($update) ) {
300
-				/** @var Update $update */
301
-				$update->filename = $this->pluginFile;
302
-			}
303
-			return $update;
304
-		}
305
-
306
-		/**
307
-		 * Get the translated plugin title.
308
-		 *
309
-		 * @deprecated
310
-		 * @return string
311
-		 */
312
-		public function getPluginTitle() {
313
-			return $this->package->getPluginTitle();
314
-		}
315
-
316
-		/**
317
-		 * Check if the current user has the required permissions to install updates.
318
-		 *
319
-		 * @return bool
320
-		 */
321
-		public function userCanInstallUpdates() {
322
-			return current_user_can('update_plugins');
323
-		}
324
-
325
-		/**
326
-		 * Check if the plugin file is inside the mu-plugins directory.
327
-		 *
328
-		 * @deprecated
329
-		 * @return bool
330
-		 */
331
-		protected function isMuPlugin() {
332
-			return $this->package->isMuPlugin();
333
-		}
334
-
335
-		/**
336
-		 * MU plugins are partially supported, but only when we know which file in mu-plugins
337
-		 * corresponds to this plugin.
338
-		 *
339
-		 * @return bool
340
-		 */
341
-		protected function isUnknownMuPlugin() {
342
-			return empty($this->muPluginFile) && $this->package->isMuPlugin();
343
-		}
344
-
345
-		/**
346
-		 * Get absolute path to the main plugin file.
347
-		 *
348
-		 * @return string
349
-		 */
350
-		public function getAbsolutePath() {
351
-			return $this->pluginAbsolutePath;
352
-		}
353
-
354
-		/**
355
-		 * Register a callback for filtering query arguments.
356
-		 *
357
-		 * The callback function should take one argument - an associative array of query arguments.
358
-		 * It should return a modified array of query arguments.
359
-		 *
360
-		 * @uses add_filter() This method is a convenience wrapper for add_filter().
361
-		 *
362
-		 * @param callable $callback
363
-		 * @return void
364
-		 */
365
-		public function addQueryArgFilter($callback){
366
-			$this->addFilter('request_info_query_args', $callback);
367
-		}
368
-
369
-		/**
370
-		 * Register a callback for filtering arguments passed to wp_remote_get().
371
-		 *
372
-		 * The callback function should take one argument - an associative array of arguments -
373
-		 * and return a modified array or arguments. See the WP documentation on wp_remote_get()
374
-		 * for details on what arguments are available and how they work.
375
-		 *
376
-		 * @uses add_filter() This method is a convenience wrapper for add_filter().
377
-		 *
378
-		 * @param callable $callback
379
-		 * @return void
380
-		 */
381
-		public function addHttpRequestArgFilter($callback) {
382
-			$this->addFilter('request_info_options', $callback);
383
-		}
384
-
385
-		/**
386
-		 * Register a callback for filtering the plugin info retrieved from the external API.
387
-		 *
388
-		 * The callback function should take two arguments. If the plugin info was retrieved
389
-		 * successfully, the first argument passed will be an instance of  PluginInfo. Otherwise,
390
-		 * it will be NULL. The second argument will be the corresponding return value of
391
-		 * wp_remote_get (see WP docs for details).
392
-		 *
393
-		 * The callback function should return a new or modified instance of PluginInfo or NULL.
394
-		 *
395
-		 * @uses add_filter() This method is a convenience wrapper for add_filter().
396
-		 *
397
-		 * @param callable $callback
398
-		 * @return void
399
-		 */
400
-		public function addResultFilter($callback) {
401
-			$this->addFilter('request_info_result', $callback, 10, 2);
402
-		}
403
-
404
-		protected function createDebugBarExtension() {
405
-			return new DebugBar\PluginExtension($this);
406
-		}
407
-
408
-		/**
409
-		 * Create a package instance that represents this plugin or theme.
410
-		 *
411
-		 * @return InstalledPackage
412
-		 */
413
-		protected function createInstalledPackage() {
414
-			return new Package($this->pluginAbsolutePath, $this);
415
-		}
416
-
417
-		/**
418
-		 * @return Package
419
-		 */
420
-		public function getInstalledPackage() {
421
-			return $this->package;
422
-		}
423
-	}
11
+    /**
12
+     * A custom plugin update checker.
13
+     *
14
+     * @author Janis Elsts
15
+     * @copyright 2018
16
+     * @access public
17
+     */
18
+    class UpdateChecker extends BaseUpdateChecker {
19
+        protected $updateTransient = 'update_plugins';
20
+        protected $translationType = 'plugin';
21
+
22
+        public $pluginAbsolutePath = ''; //Full path of the main plugin file.
23
+        public $pluginFile = '';  //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
24
+        public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
25
+
26
+        /**
27
+         * @var Package
28
+         */
29
+        protected $package;
30
+
31
+        private $extraUi = null;
32
+
33
+        /**
34
+         * Class constructor.
35
+         *
36
+         * @param string $metadataUrl The URL of the plugin's metadata file.
37
+         * @param string $pluginFile Fully qualified path to the main plugin file.
38
+         * @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug.
39
+         * @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
40
+         * @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
41
+         * @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
42
+         */
43
+        public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
44
+            $this->pluginAbsolutePath = $pluginFile;
45
+            $this->pluginFile = plugin_basename($this->pluginAbsolutePath);
46
+            $this->muPluginFile = $muPluginFile;
47
+
48
+            //If no slug is specified, use the name of the main plugin file as the slug.
49
+            //For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
50
+            if ( empty($slug) ){
51
+                $slug = basename($this->pluginFile, '.php');
52
+            }
53
+
54
+            //Plugin slugs must be unique.
55
+            $slugCheckFilter = 'puc_is_slug_in_use-' . $slug;
56
+            $slugUsedBy = apply_filters($slugCheckFilter, false);
57
+            if ( $slugUsedBy ) {
58
+                $this->triggerError(sprintf(
59
+                    'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
60
+                    $slug,
61
+                    $slugUsedBy
62
+                ), E_USER_ERROR);
63
+            }
64
+            add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
65
+
66
+            parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
67
+
68
+            //Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
69
+            //it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
70
+            if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
71
+                $this->muPluginFile = $this->pluginFile;
72
+            }
73
+
74
+            //To prevent a crash during plugin uninstallation, remove updater hooks when the user removes the plugin.
75
+            //Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
76
+            add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
77
+
78
+            $this->extraUi = new Ui($this);
79
+        }
80
+
81
+        /**
82
+         * Create an instance of the scheduler.
83
+         *
84
+         * @param int $checkPeriod
85
+         * @return Scheduler
86
+         */
87
+        protected function createScheduler($checkPeriod) {
88
+            $scheduler = new Scheduler($this, $checkPeriod, array('load-plugins.php'));
89
+            register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
90
+            return $scheduler;
91
+        }
92
+
93
+        /**
94
+         * Install the hooks required to run periodic update checks and inject update info
95
+         * into WP data structures.
96
+         *
97
+         * @return void
98
+         */
99
+        protected function installHooks(){
100
+            //Override requests for plugin information
101
+            add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
102
+
103
+            parent::installHooks();
104
+        }
105
+
106
+        /**
107
+         * Remove update checker hooks.
108
+         *
109
+         * The intent is to prevent a fatal error that can happen if the plugin has an uninstall
110
+         * hook. During uninstallation, WP includes the main plugin file (which creates a PUC instance),
111
+         * the uninstall hook runs, WP deletes the plugin files and then updates some transients.
112
+         * If PUC hooks are still around at this time, they could throw an error while trying to
113
+         * autoload classes from files that no longer exist.
114
+         *
115
+         * The "site_transient_{$transient}" filter is the main problem here, but let's also remove
116
+         * most other PUC hooks to be safe.
117
+         *
118
+         * @internal
119
+         */
120
+        public function removeHooks() {
121
+            parent::removeHooks();
122
+            $this->extraUi->removeHooks();
123
+            $this->package->removeHooks();
124
+
125
+            remove_filter('plugins_api', array($this, 'injectInfo'), 20);
126
+        }
127
+
128
+        /**
129
+         * Retrieve plugin info from the configured API endpoint.
130
+         *
131
+         * @uses wp_remote_get()
132
+         *
133
+         * @param array $queryArgs Additional query arguments to append to the request. Optional.
134
+         * @return PluginInfo
135
+         */
136
+        public function requestInfo($queryArgs = array()) {
137
+            list($pluginInfo, $result) = $this->requestMetadata(
138
+                PluginInfo::class,
139
+                'request_info',
140
+                $queryArgs
141
+            );
142
+
143
+            if ( $pluginInfo !== null ) {
144
+                /** @var PluginInfo $pluginInfo */
145
+                $pluginInfo->filename = $this->pluginFile;
146
+                $pluginInfo->slug = $this->slug;
147
+            }
148
+
149
+            $pluginInfo = apply_filters($this->getUniqueName('request_info_result'), $pluginInfo, $result);
150
+            return $pluginInfo;
151
+        }
152
+
153
+        /**
154
+         * Retrieve the latest update (if any) from the configured API endpoint.
155
+         *
156
+         * @uses UpdateChecker::requestInfo()
157
+         *
158
+         * @return Update|null An instance of Plugin Update, or NULL when no updates are available.
159
+         */
160
+        public function requestUpdate() {
161
+            //For the sake of simplicity, this function just calls requestInfo()
162
+            //and transforms the result accordingly.
163
+            $pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
164
+            if ( $pluginInfo === null ){
165
+                return null;
166
+            }
167
+            $update = Update::fromPluginInfo($pluginInfo);
168
+
169
+            $update = $this->filterUpdateResult($update);
170
+
171
+            return $update;
172
+        }
173
+
174
+        /**
175
+         * Intercept plugins_api() calls that request information about our plugin and
176
+         * use the configured API endpoint to satisfy them.
177
+         *
178
+         * @see plugins_api()
179
+         *
180
+         * @param mixed $result
181
+         * @param string $action
182
+         * @param array|object $args
183
+         * @return mixed
184
+         */
185
+        public function injectInfo($result, $action = null, $args = null){
186
+            $relevant = ($action == 'plugin_information') && isset($args->slug) && (
187
+                    ($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
188
+                );
189
+            if ( !$relevant ) {
190
+                return $result;
191
+            }
192
+
193
+            $pluginInfo = $this->requestInfo();
194
+            $this->fixSupportedWordpressVersion($pluginInfo);
195
+
196
+            $pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
197
+            if ( $pluginInfo ) {
198
+                return $pluginInfo->toWpFormat();
199
+            }
200
+
201
+            return $result;
202
+        }
203
+
204
+        protected function shouldShowUpdates() {
205
+            //No update notifications for mu-plugins unless explicitly enabled. The MU plugin file
206
+            //is usually different from the main plugin file so the update wouldn't show up properly anyway.
207
+            return !$this->isUnknownMuPlugin();
208
+        }
209
+
210
+        /**
211
+         * @param \stdClass|null $updates
212
+         * @param \stdClass $updateToAdd
213
+         * @return \stdClass
214
+         */
215
+        protected function addUpdateToList($updates, $updateToAdd) {
216
+            if ( $this->package->isMuPlugin() ) {
217
+                //WP does not support automatic update installation for mu-plugins, but we can
218
+                //still display a notice.
219
+                $updateToAdd->package = null;
220
+            }
221
+            return parent::addUpdateToList($updates, $updateToAdd);
222
+        }
223
+
224
+        /**
225
+         * @param \stdClass|null $updates
226
+         * @return \stdClass|null
227
+         */
228
+        protected function removeUpdateFromList($updates) {
229
+            $updates = parent::removeUpdateFromList($updates);
230
+            if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
231
+                unset($updates->response[$this->muPluginFile]);
232
+            }
233
+            return $updates;
234
+        }
235
+
236
+        /**
237
+         * For plugins, the update array is indexed by the plugin filename relative to the "plugins"
238
+         * directory. Example: "plugin-name/plugin.php".
239
+         *
240
+         * @return string
241
+         */
242
+        protected function getUpdateListKey() {
243
+            if ( $this->package->isMuPlugin() ) {
244
+                return $this->muPluginFile;
245
+            }
246
+            return $this->pluginFile;
247
+        }
248
+
249
+        protected function getNoUpdateItemFields() {
250
+            return array_merge(
251
+                parent::getNoUpdateItemFields(),
252
+                array(
253
+                    'id'            => $this->pluginFile,
254
+                    'slug'          => $this->slug,
255
+                    'plugin'        => $this->pluginFile,
256
+                    'icons'         => array(),
257
+                    'banners'       => array(),
258
+                    'banners_rtl'   => array(),
259
+                    'tested'        => '',
260
+                    'compatibility' => new \stdClass(),
261
+                )
262
+            );
263
+        }
264
+
265
+        /**
266
+         * Alias for isBeingUpgraded().
267
+         *
268
+         * @deprecated
269
+         * @param \WP_Upgrader|null $upgrader The upgrader that's performing the current update.
270
+         * @return bool
271
+         */
272
+        public function isPluginBeingUpgraded($upgrader = null) {
273
+            return $this->isBeingUpgraded($upgrader);
274
+        }
275
+
276
+        /**
277
+         * Is there an update being installed for this plugin, right now?
278
+         *
279
+         * @param \WP_Upgrader|null $upgrader
280
+         * @return bool
281
+         */
282
+        public function isBeingUpgraded($upgrader = null) {
283
+            return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader);
284
+        }
285
+
286
+        /**
287
+         * Get the details of the currently available update, if any.
288
+         *
289
+         * If no updates are available, or if the last known update version is below or equal
290
+         * to the currently installed version, this method will return NULL.
291
+         *
292
+         * Uses cached update data. To retrieve update information straight from
293
+         * the metadata URL, call requestUpdate() instead.
294
+         *
295
+         * @return Update|null
296
+         */
297
+        public function getUpdate() {
298
+            $update = parent::getUpdate();
299
+            if ( isset($update) ) {
300
+                /** @var Update $update */
301
+                $update->filename = $this->pluginFile;
302
+            }
303
+            return $update;
304
+        }
305
+
306
+        /**
307
+         * Get the translated plugin title.
308
+         *
309
+         * @deprecated
310
+         * @return string
311
+         */
312
+        public function getPluginTitle() {
313
+            return $this->package->getPluginTitle();
314
+        }
315
+
316
+        /**
317
+         * Check if the current user has the required permissions to install updates.
318
+         *
319
+         * @return bool
320
+         */
321
+        public function userCanInstallUpdates() {
322
+            return current_user_can('update_plugins');
323
+        }
324
+
325
+        /**
326
+         * Check if the plugin file is inside the mu-plugins directory.
327
+         *
328
+         * @deprecated
329
+         * @return bool
330
+         */
331
+        protected function isMuPlugin() {
332
+            return $this->package->isMuPlugin();
333
+        }
334
+
335
+        /**
336
+         * MU plugins are partially supported, but only when we know which file in mu-plugins
337
+         * corresponds to this plugin.
338
+         *
339
+         * @return bool
340
+         */
341
+        protected function isUnknownMuPlugin() {
342
+            return empty($this->muPluginFile) && $this->package->isMuPlugin();
343
+        }
344
+
345
+        /**
346
+         * Get absolute path to the main plugin file.
347
+         *
348
+         * @return string
349
+         */
350
+        public function getAbsolutePath() {
351
+            return $this->pluginAbsolutePath;
352
+        }
353
+
354
+        /**
355
+         * Register a callback for filtering query arguments.
356
+         *
357
+         * The callback function should take one argument - an associative array of query arguments.
358
+         * It should return a modified array of query arguments.
359
+         *
360
+         * @uses add_filter() This method is a convenience wrapper for add_filter().
361
+         *
362
+         * @param callable $callback
363
+         * @return void
364
+         */
365
+        public function addQueryArgFilter($callback){
366
+            $this->addFilter('request_info_query_args', $callback);
367
+        }
368
+
369
+        /**
370
+         * Register a callback for filtering arguments passed to wp_remote_get().
371
+         *
372
+         * The callback function should take one argument - an associative array of arguments -
373
+         * and return a modified array or arguments. See the WP documentation on wp_remote_get()
374
+         * for details on what arguments are available and how they work.
375
+         *
376
+         * @uses add_filter() This method is a convenience wrapper for add_filter().
377
+         *
378
+         * @param callable $callback
379
+         * @return void
380
+         */
381
+        public function addHttpRequestArgFilter($callback) {
382
+            $this->addFilter('request_info_options', $callback);
383
+        }
384
+
385
+        /**
386
+         * Register a callback for filtering the plugin info retrieved from the external API.
387
+         *
388
+         * The callback function should take two arguments. If the plugin info was retrieved
389
+         * successfully, the first argument passed will be an instance of  PluginInfo. Otherwise,
390
+         * it will be NULL. The second argument will be the corresponding return value of
391
+         * wp_remote_get (see WP docs for details).
392
+         *
393
+         * The callback function should return a new or modified instance of PluginInfo or NULL.
394
+         *
395
+         * @uses add_filter() This method is a convenience wrapper for add_filter().
396
+         *
397
+         * @param callable $callback
398
+         * @return void
399
+         */
400
+        public function addResultFilter($callback) {
401
+            $this->addFilter('request_info_result', $callback, 10, 2);
402
+        }
403
+
404
+        protected function createDebugBarExtension() {
405
+            return new DebugBar\PluginExtension($this);
406
+        }
407
+
408
+        /**
409
+         * Create a package instance that represents this plugin or theme.
410
+         *
411
+         * @return InstalledPackage
412
+         */
413
+        protected function createInstalledPackage() {
414
+            return new Package($this->pluginAbsolutePath, $this);
415
+        }
416
+
417
+        /**
418
+         * @return Package
419
+         */
420
+        public function getInstalledPackage() {
421
+            return $this->package;
422
+        }
423
+    }
424 424
 
425 425
 endif;
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
 use YahnisElsts\PluginUpdateChecker\v5p0\Scheduler;
7 7
 use YahnisElsts\PluginUpdateChecker\v5p0\DebugBar;
8 8
 
9
-if ( !class_exists(UpdateChecker::class, false) ):
9
+if (!class_exists(UpdateChecker::class, false)):
10 10
 
11 11
 	/**
12 12
 	 * A custom plugin update checker.
@@ -20,7 +20,7 @@  discard block
 block discarded – undo
20 20
 		protected $translationType = 'plugin';
21 21
 
22 22
 		public $pluginAbsolutePath = ''; //Full path of the main plugin file.
23
-		public $pluginFile = '';  //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
23
+		public $pluginFile = ''; //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
24 24
 		public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
25 25
 
26 26
 		/**
@@ -40,21 +40,21 @@  discard block
 block discarded – undo
40 40
 		 * @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
41 41
 		 * @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
42 42
 		 */
43
-		public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
43
+		public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
44 44
 			$this->pluginAbsolutePath = $pluginFile;
45 45
 			$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
46 46
 			$this->muPluginFile = $muPluginFile;
47 47
 
48 48
 			//If no slug is specified, use the name of the main plugin file as the slug.
49 49
 			//For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
50
-			if ( empty($slug) ){
50
+			if (empty($slug)) {
51 51
 				$slug = basename($this->pluginFile, '.php');
52 52
 			}
53 53
 
54 54
 			//Plugin slugs must be unique.
55 55
 			$slugCheckFilter = 'puc_is_slug_in_use-' . $slug;
56 56
 			$slugUsedBy = apply_filters($slugCheckFilter, false);
57
-			if ( $slugUsedBy ) {
57
+			if ($slugUsedBy) {
58 58
 				$this->triggerError(sprintf(
59 59
 					'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
60 60
 					$slug,
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
 
68 68
 			//Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
69 69
 			//it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
70
-			if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
70
+			if ((strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin()) {
71 71
 				$this->muPluginFile = $this->pluginFile;
72 72
 			}
73 73
 
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 		 *
97 97
 		 * @return void
98 98
 		 */
99
-		protected function installHooks(){
99
+		protected function installHooks() {
100 100
 			//Override requests for plugin information
101 101
 			add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
102 102
 
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
 				$queryArgs
141 141
 			);
142 142
 
143
-			if ( $pluginInfo !== null ) {
143
+			if ($pluginInfo !== null) {
144 144
 				/** @var PluginInfo $pluginInfo */
145 145
 				$pluginInfo->filename = $this->pluginFile;
146 146
 				$pluginInfo->slug = $this->slug;
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
 			//For the sake of simplicity, this function just calls requestInfo()
162 162
 			//and transforms the result accordingly.
163 163
 			$pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
164
-			if ( $pluginInfo === null ){
164
+			if ($pluginInfo === null) {
165 165
 				return null;
166 166
 			}
167 167
 			$update = Update::fromPluginInfo($pluginInfo);
@@ -182,11 +182,11 @@  discard block
 block discarded – undo
182 182
 		 * @param array|object $args
183 183
 		 * @return mixed
184 184
 		 */
185
-		public function injectInfo($result, $action = null, $args = null){
185
+		public function injectInfo($result, $action = null, $args = null) {
186 186
 			$relevant = ($action == 'plugin_information') && isset($args->slug) && (
187 187
 					($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
188 188
 				);
189
-			if ( !$relevant ) {
189
+			if (!$relevant) {
190 190
 				return $result;
191 191
 			}
192 192
 
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
 			$this->fixSupportedWordpressVersion($pluginInfo);
195 195
 
196 196
 			$pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
197
-			if ( $pluginInfo ) {
197
+			if ($pluginInfo) {
198 198
 				return $pluginInfo->toWpFormat();
199 199
 			}
200 200
 
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
 		 * @return \stdClass
214 214
 		 */
215 215
 		protected function addUpdateToList($updates, $updateToAdd) {
216
-			if ( $this->package->isMuPlugin() ) {
216
+			if ($this->package->isMuPlugin()) {
217 217
 				//WP does not support automatic update installation for mu-plugins, but we can
218 218
 				//still display a notice.
219 219
 				$updateToAdd->package = null;
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 		 */
228 228
 		protected function removeUpdateFromList($updates) {
229 229
 			$updates = parent::removeUpdateFromList($updates);
230
-			if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
230
+			if (!empty($this->muPluginFile) && isset($updates, $updates->response)) {
231 231
 				unset($updates->response[$this->muPluginFile]);
232 232
 			}
233 233
 			return $updates;
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
 		 * @return string
241 241
 		 */
242 242
 		protected function getUpdateListKey() {
243
-			if ( $this->package->isMuPlugin() ) {
243
+			if ($this->package->isMuPlugin()) {
244 244
 				return $this->muPluginFile;
245 245
 			}
246 246
 			return $this->pluginFile;
@@ -296,7 +296,7 @@  discard block
 block discarded – undo
296 296
 		 */
297 297
 		public function getUpdate() {
298 298
 			$update = parent::getUpdate();
299
-			if ( isset($update) ) {
299
+			if (isset($update)) {
300 300
 				/** @var Update $update */
301 301
 				$update->filename = $this->pluginFile;
302 302
 			}
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
 		 * @param callable $callback
363 363
 		 * @return void
364 364
 		 */
365
-		public function addQueryArgFilter($callback){
365
+		public function addQueryArgFilter($callback) {
366 366
 			$this->addFilter('request_info_query_args', $callback);
367 367
 		}
368 368
 
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Plugin/Update.php 2 patches
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -5,112 +5,112 @@
 block discarded – undo
5 5
 
6 6
 if ( !class_exists(Update::class, false) ):
7 7
 
8
-	/**
9
-	 * A simple container class for holding information about an available update.
10
-	 *
11
-	 * @author Janis Elsts
12
-	 * @copyright 2016
13
-	 * @access public
14
-	 */
15
-	class Update extends BaseUpdate {
16
-		public $id = 0;
17
-		public $homepage;
18
-		public $upgrade_notice;
19
-		public $tested;
20
-		public $requires_php = false;
21
-		public $icons = array();
22
-		public $filename; //Plugin filename relative to the plugins directory.
8
+    /**
9
+     * A simple container class for holding information about an available update.
10
+     *
11
+     * @author Janis Elsts
12
+     * @copyright 2016
13
+     * @access public
14
+     */
15
+    class Update extends BaseUpdate {
16
+        public $id = 0;
17
+        public $homepage;
18
+        public $upgrade_notice;
19
+        public $tested;
20
+        public $requires_php = false;
21
+        public $icons = array();
22
+        public $filename; //Plugin filename relative to the plugins directory.
23 23
 
24
-		protected static $extraFields = array(
25
-			'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename',
26
-		);
24
+        protected static $extraFields = array(
25
+            'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename',
26
+        );
27 27
 
28
-		/**
29
-		 * Create a new instance of PluginUpdate from its JSON-encoded representation.
30
-		 *
31
-		 * @param string $json
32
-		 * @return self|null
33
-		 */
34
-		public static function fromJson($json){
35
-			//Since update-related information is simply a subset of the full plugin info,
36
-			//we can parse the update JSON as if it was a plugin info string, then copy over
37
-			//the parts that we care about.
38
-			$pluginInfo = PluginInfo::fromJson($json);
39
-			if ( $pluginInfo !== null ) {
40
-				return self::fromPluginInfo($pluginInfo);
41
-			} else {
42
-				return null;
43
-			}
44
-		}
28
+        /**
29
+         * Create a new instance of PluginUpdate from its JSON-encoded representation.
30
+         *
31
+         * @param string $json
32
+         * @return self|null
33
+         */
34
+        public static function fromJson($json){
35
+            //Since update-related information is simply a subset of the full plugin info,
36
+            //we can parse the update JSON as if it was a plugin info string, then copy over
37
+            //the parts that we care about.
38
+            $pluginInfo = PluginInfo::fromJson($json);
39
+            if ( $pluginInfo !== null ) {
40
+                return self::fromPluginInfo($pluginInfo);
41
+            } else {
42
+                return null;
43
+            }
44
+        }
45 45
 
46
-		/**
47
-		 * Create a new instance of PluginUpdate based on an instance of PluginInfo.
48
-		 * Basically, this just copies a subset of fields from one object to another.
49
-		 *
50
-		 * @param PluginInfo $info
51
-		 * @return static
52
-		 */
53
-		public static function fromPluginInfo($info){
54
-			return static::fromObject($info);
55
-		}
46
+        /**
47
+         * Create a new instance of PluginUpdate based on an instance of PluginInfo.
48
+         * Basically, this just copies a subset of fields from one object to another.
49
+         *
50
+         * @param PluginInfo $info
51
+         * @return static
52
+         */
53
+        public static function fromPluginInfo($info){
54
+            return static::fromObject($info);
55
+        }
56 56
 
57
-		/**
58
-		 * Create a new instance by copying the necessary fields from another object.
59
-		 *
60
-		 * @param \StdClass|PluginInfo|self $object The source object.
61
-		 * @return self The new copy.
62
-		 */
63
-		public static function fromObject($object) {
64
-			$update = new self();
65
-			$update->copyFields($object, $update);
66
-			return $update;
67
-		}
57
+        /**
58
+         * Create a new instance by copying the necessary fields from another object.
59
+         *
60
+         * @param \StdClass|PluginInfo|self $object The source object.
61
+         * @return self The new copy.
62
+         */
63
+        public static function fromObject($object) {
64
+            $update = new self();
65
+            $update->copyFields($object, $update);
66
+            return $update;
67
+        }
68 68
 
69
-		/**
70
-		 * @return string[]
71
-		 */
72
-		protected function getFieldNames() {
73
-			return array_merge(parent::getFieldNames(), self::$extraFields);
74
-		}
69
+        /**
70
+         * @return string[]
71
+         */
72
+        protected function getFieldNames() {
73
+            return array_merge(parent::getFieldNames(), self::$extraFields);
74
+        }
75 75
 
76
-		/**
77
-		 * Transform the update into the format used by WordPress native plugin API.
78
-		 *
79
-		 * @return object
80
-		 */
81
-		public function toWpFormat() {
82
-			$update = parent::toWpFormat();
76
+        /**
77
+         * Transform the update into the format used by WordPress native plugin API.
78
+         *
79
+         * @return object
80
+         */
81
+        public function toWpFormat() {
82
+            $update = parent::toWpFormat();
83 83
 
84
-			$update->id = $this->id;
85
-			$update->url = $this->homepage;
86
-			$update->tested = $this->tested;
87
-			$update->requires_php = $this->requires_php;
88
-			$update->plugin = $this->filename;
84
+            $update->id = $this->id;
85
+            $update->url = $this->homepage;
86
+            $update->tested = $this->tested;
87
+            $update->requires_php = $this->requires_php;
88
+            $update->plugin = $this->filename;
89 89
 
90
-			if ( !empty($this->upgrade_notice) ) {
91
-				$update->upgrade_notice = $this->upgrade_notice;
92
-			}
90
+            if ( !empty($this->upgrade_notice) ) {
91
+                $update->upgrade_notice = $this->upgrade_notice;
92
+            }
93 93
 
94
-			if ( !empty($this->icons) && is_array($this->icons) ) {
95
-				//This should be an array with up to 4 keys: 'svg', '1x', '2x' and 'default'.
96
-				//Docs: https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
97
-				$icons = array_intersect_key(
98
-					$this->icons,
99
-					array('svg' => true, '1x' => true, '2x' => true, 'default' => true)
100
-				);
101
-				if ( !empty($icons) ) {
102
-					$update->icons = $icons;
94
+            if ( !empty($this->icons) && is_array($this->icons) ) {
95
+                //This should be an array with up to 4 keys: 'svg', '1x', '2x' and 'default'.
96
+                //Docs: https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
97
+                $icons = array_intersect_key(
98
+                    $this->icons,
99
+                    array('svg' => true, '1x' => true, '2x' => true, 'default' => true)
100
+                );
101
+                if ( !empty($icons) ) {
102
+                    $update->icons = $icons;
103 103
 
104
-					//It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
105
-					//but lets set it just in case a future release needs it.
106
-					if ( !isset($update->icons['default']) ) {
107
-						$update->icons['default'] = current($update->icons);
108
-					}
109
-				}
110
-			}
104
+                    //It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
105
+                    //but lets set it just in case a future release needs it.
106
+                    if ( !isset($update->icons['default']) ) {
107
+                        $update->icons['default'] = current($update->icons);
108
+                    }
109
+                }
110
+            }
111 111
 
112
-			return $update;
113
-		}
114
-	}
112
+            return $update;
113
+        }
114
+    }
115 115
 
116 116
 endif;
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 
4 4
 use YahnisElsts\PluginUpdateChecker\v5p0\Update as BaseUpdate;
5 5
 
6
-if ( !class_exists(Update::class, false) ):
6
+if (!class_exists(Update::class, false)):
7 7
 
8 8
 	/**
9 9
 	 * A simple container class for holding information about an available update.
@@ -31,12 +31,12 @@  discard block
 block discarded – undo
31 31
 		 * @param string $json
32 32
 		 * @return self|null
33 33
 		 */
34
-		public static function fromJson($json){
34
+		public static function fromJson($json) {
35 35
 			//Since update-related information is simply a subset of the full plugin info,
36 36
 			//we can parse the update JSON as if it was a plugin info string, then copy over
37 37
 			//the parts that we care about.
38 38
 			$pluginInfo = PluginInfo::fromJson($json);
39
-			if ( $pluginInfo !== null ) {
39
+			if ($pluginInfo !== null) {
40 40
 				return self::fromPluginInfo($pluginInfo);
41 41
 			} else {
42 42
 				return null;
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
 		 * @param PluginInfo $info
51 51
 		 * @return static
52 52
 		 */
53
-		public static function fromPluginInfo($info){
53
+		public static function fromPluginInfo($info) {
54 54
 			return static::fromObject($info);
55 55
 		}
56 56
 
@@ -87,23 +87,23 @@  discard block
 block discarded – undo
87 87
 			$update->requires_php = $this->requires_php;
88 88
 			$update->plugin = $this->filename;
89 89
 
90
-			if ( !empty($this->upgrade_notice) ) {
90
+			if (!empty($this->upgrade_notice)) {
91 91
 				$update->upgrade_notice = $this->upgrade_notice;
92 92
 			}
93 93
 
94
-			if ( !empty($this->icons) && is_array($this->icons) ) {
94
+			if (!empty($this->icons) && is_array($this->icons)) {
95 95
 				//This should be an array with up to 4 keys: 'svg', '1x', '2x' and 'default'.
96 96
 				//Docs: https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
97 97
 				$icons = array_intersect_key(
98 98
 					$this->icons,
99 99
 					array('svg' => true, '1x' => true, '2x' => true, 'default' => true)
100 100
 				);
101
-				if ( !empty($icons) ) {
101
+				if (!empty($icons)) {
102 102
 					$update->icons = $icons;
103 103
 
104 104
 					//It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
105 105
 					//but lets set it just in case a future release needs it.
106
-					if ( !isset($update->icons['default']) ) {
106
+					if (!isset($update->icons['default'])) {
107 107
 						$update->icons['default'] = current($update->icons);
108 108
 					}
109 109
 				}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Plugin/Package.php 2 patches
Indentation   +178 added lines, -178 removed lines patch added patch discarded remove patch
@@ -6,183 +6,183 @@
 block discarded – undo
6 6
 
7 7
 if ( !class_exists(Package::class, false) ):
8 8
 
9
-	class Package extends InstalledPackage {
10
-		/**
11
-		 * @var UpdateChecker
12
-		 */
13
-		protected $updateChecker;
14
-
15
-		/**
16
-		 * @var string Full path of the main plugin file.
17
-		 */
18
-		protected $pluginAbsolutePath = '';
19
-
20
-		/**
21
-		 * @var string Plugin basename.
22
-		 */
23
-		private $pluginFile;
24
-
25
-		/**
26
-		 * @var string|null
27
-		 */
28
-		private $cachedInstalledVersion = null;
29
-
30
-		public function __construct($pluginAbsolutePath, $updateChecker) {
31
-			$this->pluginAbsolutePath = $pluginAbsolutePath;
32
-			$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
33
-
34
-			parent::__construct($updateChecker);
35
-
36
-			//Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
37
-			add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
38
-			add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
39
-		}
40
-
41
-		public function getInstalledVersion() {
42
-			if ( isset($this->cachedInstalledVersion) ) {
43
-				return $this->cachedInstalledVersion;
44
-			}
45
-
46
-			$pluginHeader = $this->getPluginHeader();
47
-			if ( isset($pluginHeader['Version']) ) {
48
-				$this->cachedInstalledVersion = $pluginHeader['Version'];
49
-				return $pluginHeader['Version'];
50
-			} else {
51
-				//This can happen if the filename points to something that is not a plugin.
52
-				$this->updateChecker->triggerError(
53
-					sprintf(
54
-						"Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.",
55
-						$this->updateChecker->pluginFile
56
-					),
57
-					E_USER_WARNING
58
-				);
59
-				return null;
60
-			}
61
-		}
62
-
63
-		/**
64
-		 * Clear the cached plugin version. This method can be set up as a filter (hook) and will
65
-		 * return the filter argument unmodified.
66
-		 *
67
-		 * @param mixed $filterArgument
68
-		 * @return mixed
69
-		 */
70
-		public function clearCachedVersion($filterArgument = null) {
71
-			$this->cachedInstalledVersion = null;
72
-			return $filterArgument;
73
-		}
74
-
75
-		public function getAbsoluteDirectoryPath() {
76
-			return dirname($this->pluginAbsolutePath);
77
-		}
78
-
79
-		/**
80
-		 * Get the value of a specific plugin or theme header.
81
-		 *
82
-		 * @param string $headerName
83
-		 * @param string $defaultValue
84
-		 * @return string Either the value of the header, or $defaultValue if the header doesn't exist or is empty.
85
-		 */
86
-		public function getHeaderValue($headerName, $defaultValue = '') {
87
-			$headers = $this->getPluginHeader();
88
-			if ( isset($headers[$headerName]) && ($headers[$headerName] !== '') ) {
89
-				return $headers[$headerName];
90
-			}
91
-			return $defaultValue;
92
-		}
93
-
94
-		protected function getHeaderNames() {
95
-			return array(
96
-				'Name'              => 'Plugin Name',
97
-				'PluginURI'         => 'Plugin URI',
98
-				'Version'           => 'Version',
99
-				'Description'       => 'Description',
100
-				'Author'            => 'Author',
101
-				'AuthorURI'         => 'Author URI',
102
-				'TextDomain'        => 'Text Domain',
103
-				'DomainPath'        => 'Domain Path',
104
-				'Network'           => 'Network',
105
-
106
-				//The newest WordPress version that this plugin requires or has been tested with.
107
-				//We support several different formats for compatibility with other libraries.
108
-				'Tested WP'         => 'Tested WP',
109
-				'Requires WP'       => 'Requires WP',
110
-				'Tested up to'      => 'Tested up to',
111
-				'Requires at least' => 'Requires at least',
112
-			);
113
-		}
114
-
115
-		/**
116
-		 * Get the translated plugin title.
117
-		 *
118
-		 * @return string
119
-		 */
120
-		public function getPluginTitle() {
121
-			$title = '';
122
-			$header = $this->getPluginHeader();
123
-			if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
124
-				$title = translate($header['Name'], $header['TextDomain']);
125
-			}
126
-			return $title;
127
-		}
128
-
129
-		/**
130
-		 * Get plugin's metadata from its file header.
131
-		 *
132
-		 * @return array
133
-		 */
134
-		public function getPluginHeader() {
135
-			if ( !is_file($this->pluginAbsolutePath) ) {
136
-				//This can happen if the plugin filename is wrong.
137
-				$this->updateChecker->triggerError(
138
-					sprintf(
139
-						"Can't to read the plugin header for '%s'. The file does not exist.",
140
-						$this->updateChecker->pluginFile
141
-					),
142
-					E_USER_WARNING
143
-				);
144
-				return array();
145
-			}
146
-
147
-			if ( !function_exists('get_plugin_data') ) {
148
-				require_once(ABSPATH . '/wp-admin/includes/plugin.php');
149
-			}
150
-			return get_plugin_data($this->pluginAbsolutePath, false, false);
151
-		}
152
-
153
-		public function removeHooks() {
154
-			remove_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
155
-			remove_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
156
-		}
157
-
158
-		/**
159
-		 * Check if the plugin file is inside the mu-plugins directory.
160
-		 *
161
-		 * @return bool
162
-		 */
163
-		public function isMuPlugin() {
164
-			static $cachedResult = null;
165
-
166
-			if ( $cachedResult === null ) {
167
-				if ( !defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR) ) {
168
-					$cachedResult = false;
169
-					return $cachedResult;
170
-				}
171
-
172
-				//Convert both paths to the canonical form before comparison.
173
-				$muPluginDir = realpath(WPMU_PLUGIN_DIR);
174
-				$pluginPath  = realpath($this->pluginAbsolutePath);
175
-				//If realpath() fails, just normalize the syntax instead.
176
-				if (($muPluginDir === false) || ($pluginPath === false)) {
177
-					$muPluginDir = PucFactory::normalizePath(WPMU_PLUGIN_DIR);
178
-					$pluginPath  = PucFactory::normalizePath($this->pluginAbsolutePath);
179
-				}
180
-
181
-				$cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
182
-			}
183
-
184
-			return $cachedResult;
185
-		}
186
-	}
9
+    class Package extends InstalledPackage {
10
+        /**
11
+         * @var UpdateChecker
12
+         */
13
+        protected $updateChecker;
14
+
15
+        /**
16
+         * @var string Full path of the main plugin file.
17
+         */
18
+        protected $pluginAbsolutePath = '';
19
+
20
+        /**
21
+         * @var string Plugin basename.
22
+         */
23
+        private $pluginFile;
24
+
25
+        /**
26
+         * @var string|null
27
+         */
28
+        private $cachedInstalledVersion = null;
29
+
30
+        public function __construct($pluginAbsolutePath, $updateChecker) {
31
+            $this->pluginAbsolutePath = $pluginAbsolutePath;
32
+            $this->pluginFile = plugin_basename($this->pluginAbsolutePath);
33
+
34
+            parent::__construct($updateChecker);
35
+
36
+            //Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
37
+            add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
38
+            add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
39
+        }
40
+
41
+        public function getInstalledVersion() {
42
+            if ( isset($this->cachedInstalledVersion) ) {
43
+                return $this->cachedInstalledVersion;
44
+            }
45
+
46
+            $pluginHeader = $this->getPluginHeader();
47
+            if ( isset($pluginHeader['Version']) ) {
48
+                $this->cachedInstalledVersion = $pluginHeader['Version'];
49
+                return $pluginHeader['Version'];
50
+            } else {
51
+                //This can happen if the filename points to something that is not a plugin.
52
+                $this->updateChecker->triggerError(
53
+                    sprintf(
54
+                        "Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.",
55
+                        $this->updateChecker->pluginFile
56
+                    ),
57
+                    E_USER_WARNING
58
+                );
59
+                return null;
60
+            }
61
+        }
62
+
63
+        /**
64
+         * Clear the cached plugin version. This method can be set up as a filter (hook) and will
65
+         * return the filter argument unmodified.
66
+         *
67
+         * @param mixed $filterArgument
68
+         * @return mixed
69
+         */
70
+        public function clearCachedVersion($filterArgument = null) {
71
+            $this->cachedInstalledVersion = null;
72
+            return $filterArgument;
73
+        }
74
+
75
+        public function getAbsoluteDirectoryPath() {
76
+            return dirname($this->pluginAbsolutePath);
77
+        }
78
+
79
+        /**
80
+         * Get the value of a specific plugin or theme header.
81
+         *
82
+         * @param string $headerName
83
+         * @param string $defaultValue
84
+         * @return string Either the value of the header, or $defaultValue if the header doesn't exist or is empty.
85
+         */
86
+        public function getHeaderValue($headerName, $defaultValue = '') {
87
+            $headers = $this->getPluginHeader();
88
+            if ( isset($headers[$headerName]) && ($headers[$headerName] !== '') ) {
89
+                return $headers[$headerName];
90
+            }
91
+            return $defaultValue;
92
+        }
93
+
94
+        protected function getHeaderNames() {
95
+            return array(
96
+                'Name'              => 'Plugin Name',
97
+                'PluginURI'         => 'Plugin URI',
98
+                'Version'           => 'Version',
99
+                'Description'       => 'Description',
100
+                'Author'            => 'Author',
101
+                'AuthorURI'         => 'Author URI',
102
+                'TextDomain'        => 'Text Domain',
103
+                'DomainPath'        => 'Domain Path',
104
+                'Network'           => 'Network',
105
+
106
+                //The newest WordPress version that this plugin requires or has been tested with.
107
+                //We support several different formats for compatibility with other libraries.
108
+                'Tested WP'         => 'Tested WP',
109
+                'Requires WP'       => 'Requires WP',
110
+                'Tested up to'      => 'Tested up to',
111
+                'Requires at least' => 'Requires at least',
112
+            );
113
+        }
114
+
115
+        /**
116
+         * Get the translated plugin title.
117
+         *
118
+         * @return string
119
+         */
120
+        public function getPluginTitle() {
121
+            $title = '';
122
+            $header = $this->getPluginHeader();
123
+            if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
124
+                $title = translate($header['Name'], $header['TextDomain']);
125
+            }
126
+            return $title;
127
+        }
128
+
129
+        /**
130
+         * Get plugin's metadata from its file header.
131
+         *
132
+         * @return array
133
+         */
134
+        public function getPluginHeader() {
135
+            if ( !is_file($this->pluginAbsolutePath) ) {
136
+                //This can happen if the plugin filename is wrong.
137
+                $this->updateChecker->triggerError(
138
+                    sprintf(
139
+                        "Can't to read the plugin header for '%s'. The file does not exist.",
140
+                        $this->updateChecker->pluginFile
141
+                    ),
142
+                    E_USER_WARNING
143
+                );
144
+                return array();
145
+            }
146
+
147
+            if ( !function_exists('get_plugin_data') ) {
148
+                require_once(ABSPATH . '/wp-admin/includes/plugin.php');
149
+            }
150
+            return get_plugin_data($this->pluginAbsolutePath, false, false);
151
+        }
152
+
153
+        public function removeHooks() {
154
+            remove_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
155
+            remove_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
156
+        }
157
+
158
+        /**
159
+         * Check if the plugin file is inside the mu-plugins directory.
160
+         *
161
+         * @return bool
162
+         */
163
+        public function isMuPlugin() {
164
+            static $cachedResult = null;
165
+
166
+            if ( $cachedResult === null ) {
167
+                if ( !defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR) ) {
168
+                    $cachedResult = false;
169
+                    return $cachedResult;
170
+                }
171
+
172
+                //Convert both paths to the canonical form before comparison.
173
+                $muPluginDir = realpath(WPMU_PLUGIN_DIR);
174
+                $pluginPath  = realpath($this->pluginAbsolutePath);
175
+                //If realpath() fails, just normalize the syntax instead.
176
+                if (($muPluginDir === false) || ($pluginPath === false)) {
177
+                    $muPluginDir = PucFactory::normalizePath(WPMU_PLUGIN_DIR);
178
+                    $pluginPath  = PucFactory::normalizePath($this->pluginAbsolutePath);
179
+                }
180
+
181
+                $cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
182
+            }
183
+
184
+            return $cachedResult;
185
+        }
186
+    }
187 187
 
188 188
 endif;
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use YahnisElsts\PluginUpdateChecker\v5p0\InstalledPackage;
5 5
 use YahnisElsts\PluginUpdateChecker\v5p0\PucFactory;
6 6
 
7
-if ( !class_exists(Package::class, false) ):
7
+if (!class_exists(Package::class, false)):
8 8
 
9 9
 	class Package extends InstalledPackage {
10 10
 		/**
@@ -39,12 +39,12 @@  discard block
 block discarded – undo
39 39
 		}
40 40
 
41 41
 		public function getInstalledVersion() {
42
-			if ( isset($this->cachedInstalledVersion) ) {
42
+			if (isset($this->cachedInstalledVersion)) {
43 43
 				return $this->cachedInstalledVersion;
44 44
 			}
45 45
 
46 46
 			$pluginHeader = $this->getPluginHeader();
47
-			if ( isset($pluginHeader['Version']) ) {
47
+			if (isset($pluginHeader['Version'])) {
48 48
 				$this->cachedInstalledVersion = $pluginHeader['Version'];
49 49
 				return $pluginHeader['Version'];
50 50
 			} else {
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
 		 */
86 86
 		public function getHeaderValue($headerName, $defaultValue = '') {
87 87
 			$headers = $this->getPluginHeader();
88
-			if ( isset($headers[$headerName]) && ($headers[$headerName] !== '') ) {
88
+			if (isset($headers[$headerName]) && ($headers[$headerName] !== '')) {
89 89
 				return $headers[$headerName];
90 90
 			}
91 91
 			return $defaultValue;
@@ -120,7 +120,7 @@  discard block
 block discarded – undo
120 120
 		public function getPluginTitle() {
121 121
 			$title = '';
122 122
 			$header = $this->getPluginHeader();
123
-			if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
123
+			if ($header && !empty($header['Name']) && isset($header['TextDomain'])) {
124 124
 				$title = translate($header['Name'], $header['TextDomain']);
125 125
 			}
126 126
 			return $title;
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
 		 * @return array
133 133
 		 */
134 134
 		public function getPluginHeader() {
135
-			if ( !is_file($this->pluginAbsolutePath) ) {
135
+			if (!is_file($this->pluginAbsolutePath)) {
136 136
 				//This can happen if the plugin filename is wrong.
137 137
 				$this->updateChecker->triggerError(
138 138
 					sprintf(
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 				return array();
145 145
 			}
146 146
 
147
-			if ( !function_exists('get_plugin_data') ) {
147
+			if (!function_exists('get_plugin_data')) {
148 148
 				require_once(ABSPATH . '/wp-admin/includes/plugin.php');
149 149
 			}
150 150
 			return get_plugin_data($this->pluginAbsolutePath, false, false);
@@ -163,8 +163,8 @@  discard block
 block discarded – undo
163 163
 		public function isMuPlugin() {
164 164
 			static $cachedResult = null;
165 165
 
166
-			if ( $cachedResult === null ) {
167
-				if ( !defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR) ) {
166
+			if ($cachedResult === null) {
167
+				if (!defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR)) {
168 168
 					$cachedResult = false;
169 169
 					return $cachedResult;
170 170
 				}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Plugin/PluginInfo.php 2 patches
Indentation   +127 added lines, -127 removed lines patch added patch discarded remove patch
@@ -5,132 +5,132 @@
 block discarded – undo
5 5
 
6 6
 if ( !class_exists(PluginInfo::class, false) ):
7 7
 
8
-	/**
9
-	 * A container class for holding and transforming various plugin metadata.
10
-	 *
11
-	 * @author Janis Elsts
12
-	 * @copyright 2016
13
-	 * @access public
14
-	 */
15
-	class PluginInfo extends Metadata {
16
-		//Most fields map directly to the contents of the plugin's info.json file.
17
-		//See the relevant docs for a description of their meaning.
18
-		public $name;
19
-		public $slug;
20
-		public $version;
21
-		public $homepage;
22
-		public $sections = array();
23
-		public $download_url;
24
-
25
-		public $banners;
26
-		public $icons = array();
27
-		public $translations = array();
28
-
29
-		public $author;
30
-		public $author_homepage;
31
-
32
-		public $requires;
33
-		public $tested;
34
-		public $requires_php;
35
-		public $upgrade_notice;
36
-
37
-		public $rating;
38
-		public $num_ratings;
39
-		public $downloaded;
40
-		public $active_installs;
41
-		public $last_updated;
42
-
43
-		public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
44
-
45
-		public $filename; //Plugin filename relative to the plugins directory.
46
-
47
-		/**
48
-		 * Create a new instance of Plugin Info from JSON-encoded plugin info
49
-		 * returned by an external update API.
50
-		 *
51
-		 * @param string $json Valid JSON string representing plugin info.
52
-		 * @return self|null New instance of Plugin Info, or NULL on error.
53
-		 */
54
-		public static function fromJson($json){
55
-			$instance = new self();
56
-
57
-			if ( !parent::createFromJson($json, $instance) ) {
58
-				return null;
59
-			}
60
-
61
-			//json_decode decodes assoc. arrays as objects. We want them as arrays.
62
-			$instance->sections = (array)$instance->sections;
63
-			$instance->icons = (array)$instance->icons;
64
-
65
-			return $instance;
66
-		}
67
-
68
-		/**
69
-		 * Very, very basic validation.
70
-		 *
71
-		 * @param \StdClass $apiResponse
72
-		 * @return bool|\WP_Error
73
-		 */
74
-		protected function validateMetadata($apiResponse) {
75
-			if (
76
-				!isset($apiResponse->name, $apiResponse->version)
77
-				|| empty($apiResponse->name)
78
-				|| empty($apiResponse->version)
79
-			) {
80
-				return new \WP_Error(
81
-					'puc-invalid-metadata',
82
-					"The plugin metadata file does not contain the required 'name' and/or 'version' keys."
83
-				);
84
-			}
85
-			return true;
86
-		}
87
-
88
-
89
-		/**
90
-		 * Transform plugin info into the format used by the native WordPress.org API
91
-		 *
92
-		 * @return object
93
-		 */
94
-		public function toWpFormat(){
95
-			$info = new \stdClass;
96
-
97
-			//The custom update API is built so that many fields have the same name and format
98
-			//as those returned by the native WordPress.org API. These can be assigned directly.
99
-			$sameFormat = array(
100
-				'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
101
-				'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
102
-				'requires_php',
103
-			);
104
-			foreach($sameFormat as $field){
105
-				if ( isset($this->$field) ) {
106
-					$info->$field = $this->$field;
107
-				} else {
108
-					$info->$field = null;
109
-				}
110
-			}
111
-
112
-			//Other fields need to be renamed and/or transformed.
113
-			$info->download_link = $this->download_url;
114
-			$info->author = $this->getFormattedAuthor();
115
-			$info->sections = array_merge(array('description' => ''), $this->sections);
116
-
117
-			if ( !empty($this->banners) ) {
118
-				//WP expects an array with two keys: "high" and "low". Both are optional.
119
-				//Docs: https://wordpress.org/plugins/about/faq/#banners
120
-				$info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
121
-				$info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true));
122
-			}
123
-
124
-			return $info;
125
-		}
126
-
127
-		protected function getFormattedAuthor() {
128
-			if ( !empty($this->author_homepage) ){
129
-				/** @noinspection HtmlUnknownTarget */
130
-				return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
131
-			}
132
-			return $this->author;
133
-		}
134
-	}
8
+    /**
9
+     * A container class for holding and transforming various plugin metadata.
10
+     *
11
+     * @author Janis Elsts
12
+     * @copyright 2016
13
+     * @access public
14
+     */
15
+    class PluginInfo extends Metadata {
16
+        //Most fields map directly to the contents of the plugin's info.json file.
17
+        //See the relevant docs for a description of their meaning.
18
+        public $name;
19
+        public $slug;
20
+        public $version;
21
+        public $homepage;
22
+        public $sections = array();
23
+        public $download_url;
24
+
25
+        public $banners;
26
+        public $icons = array();
27
+        public $translations = array();
28
+
29
+        public $author;
30
+        public $author_homepage;
31
+
32
+        public $requires;
33
+        public $tested;
34
+        public $requires_php;
35
+        public $upgrade_notice;
36
+
37
+        public $rating;
38
+        public $num_ratings;
39
+        public $downloaded;
40
+        public $active_installs;
41
+        public $last_updated;
42
+
43
+        public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
44
+
45
+        public $filename; //Plugin filename relative to the plugins directory.
46
+
47
+        /**
48
+         * Create a new instance of Plugin Info from JSON-encoded plugin info
49
+         * returned by an external update API.
50
+         *
51
+         * @param string $json Valid JSON string representing plugin info.
52
+         * @return self|null New instance of Plugin Info, or NULL on error.
53
+         */
54
+        public static function fromJson($json){
55
+            $instance = new self();
56
+
57
+            if ( !parent::createFromJson($json, $instance) ) {
58
+                return null;
59
+            }
60
+
61
+            //json_decode decodes assoc. arrays as objects. We want them as arrays.
62
+            $instance->sections = (array)$instance->sections;
63
+            $instance->icons = (array)$instance->icons;
64
+
65
+            return $instance;
66
+        }
67
+
68
+        /**
69
+         * Very, very basic validation.
70
+         *
71
+         * @param \StdClass $apiResponse
72
+         * @return bool|\WP_Error
73
+         */
74
+        protected function validateMetadata($apiResponse) {
75
+            if (
76
+                !isset($apiResponse->name, $apiResponse->version)
77
+                || empty($apiResponse->name)
78
+                || empty($apiResponse->version)
79
+            ) {
80
+                return new \WP_Error(
81
+                    'puc-invalid-metadata',
82
+                    "The plugin metadata file does not contain the required 'name' and/or 'version' keys."
83
+                );
84
+            }
85
+            return true;
86
+        }
87
+
88
+
89
+        /**
90
+         * Transform plugin info into the format used by the native WordPress.org API
91
+         *
92
+         * @return object
93
+         */
94
+        public function toWpFormat(){
95
+            $info = new \stdClass;
96
+
97
+            //The custom update API is built so that many fields have the same name and format
98
+            //as those returned by the native WordPress.org API. These can be assigned directly.
99
+            $sameFormat = array(
100
+                'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
101
+                'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
102
+                'requires_php',
103
+            );
104
+            foreach($sameFormat as $field){
105
+                if ( isset($this->$field) ) {
106
+                    $info->$field = $this->$field;
107
+                } else {
108
+                    $info->$field = null;
109
+                }
110
+            }
111
+
112
+            //Other fields need to be renamed and/or transformed.
113
+            $info->download_link = $this->download_url;
114
+            $info->author = $this->getFormattedAuthor();
115
+            $info->sections = array_merge(array('description' => ''), $this->sections);
116
+
117
+            if ( !empty($this->banners) ) {
118
+                //WP expects an array with two keys: "high" and "low". Both are optional.
119
+                //Docs: https://wordpress.org/plugins/about/faq/#banners
120
+                $info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
121
+                $info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true));
122
+            }
123
+
124
+            return $info;
125
+        }
126
+
127
+        protected function getFormattedAuthor() {
128
+            if ( !empty($this->author_homepage) ){
129
+                /** @noinspection HtmlUnknownTarget */
130
+                return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
131
+            }
132
+            return $this->author;
133
+        }
134
+    }
135 135
 
136 136
 endif;
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 
4 4
 use YahnisElsts\PluginUpdateChecker\v5p0\Metadata;
5 5
 
6
-if ( !class_exists(PluginInfo::class, false) ):
6
+if (!class_exists(PluginInfo::class, false)):
7 7
 
8 8
 	/**
9 9
 	 * A container class for holding and transforming various plugin metadata.
@@ -51,16 +51,16 @@  discard block
 block discarded – undo
51 51
 		 * @param string $json Valid JSON string representing plugin info.
52 52
 		 * @return self|null New instance of Plugin Info, or NULL on error.
53 53
 		 */
54
-		public static function fromJson($json){
54
+		public static function fromJson($json) {
55 55
 			$instance = new self();
56 56
 
57
-			if ( !parent::createFromJson($json, $instance) ) {
57
+			if (!parent::createFromJson($json, $instance)) {
58 58
 				return null;
59 59
 			}
60 60
 
61 61
 			//json_decode decodes assoc. arrays as objects. We want them as arrays.
62
-			$instance->sections = (array)$instance->sections;
63
-			$instance->icons = (array)$instance->icons;
62
+			$instance->sections = (array) $instance->sections;
63
+			$instance->icons = (array) $instance->icons;
64 64
 
65 65
 			return $instance;
66 66
 		}
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 		 *
92 92
 		 * @return object
93 93
 		 */
94
-		public function toWpFormat(){
94
+		public function toWpFormat() {
95 95
 			$info = new \stdClass;
96 96
 
97 97
 			//The custom update API is built so that many fields have the same name and format
@@ -101,8 +101,8 @@  discard block
 block discarded – undo
101 101
 				'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
102 102
 				'requires_php',
103 103
 			);
104
-			foreach($sameFormat as $field){
105
-				if ( isset($this->$field) ) {
104
+			foreach ($sameFormat as $field) {
105
+				if (isset($this->$field)) {
106 106
 					$info->$field = $this->$field;
107 107
 				} else {
108 108
 					$info->$field = null;
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 			$info->author = $this->getFormattedAuthor();
115 115
 			$info->sections = array_merge(array('description' => ''), $this->sections);
116 116
 
117
-			if ( !empty($this->banners) ) {
117
+			if (!empty($this->banners)) {
118 118
 				//WP expects an array with two keys: "high" and "low". Both are optional.
119 119
 				//Docs: https://wordpress.org/plugins/about/faq/#banners
120 120
 				$info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 		}
126 126
 
127 127
 		protected function getFormattedAuthor() {
128
-			if ( !empty($this->author_homepage) ){
128
+			if (!empty($this->author_homepage)) {
129 129
 				/** @noinspection HtmlUnknownTarget */
130 130
 				return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
131 131
 			}
Please login to merge, or discard this patch.