PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file Reporter.php

Documentation is available at Reporter.php

  1. <?php
  2. /**
  3.  * Manages reporting of errors and warnings.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  6.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8.  */
  9.  
  10. namespace PHP_CodeSniffer;
  11.  
  12. use PHP_CodeSniffer\Reports\Report;
  13. use PHP_CodeSniffer\Files\File;
  14. use PHP_CodeSniffer\Exceptions\RuntimeException;
  15. use PHP_CodeSniffer\Util\Common;
  16.  
  17. class Reporter
  18. {
  19.  
  20.     /**
  21.      * The config data for the run.
  22.      *
  23.      * @var \PHP_CodeSniffer\Config 
  24.      */
  25.     public $config = null;
  26.  
  27.     /**
  28.      * Total number of files that contain errors or warnings.
  29.      *
  30.      * @var integer 
  31.      */
  32.     public $totalFiles = 0;
  33.  
  34.     /**
  35.      * Total number of errors found during the run.
  36.      *
  37.      * @var integer 
  38.      */
  39.     public $totalErrors = 0;
  40.  
  41.     /**
  42.      * Total number of warnings found during the run.
  43.      *
  44.      * @var integer 
  45.      */
  46.     public $totalWarnings = 0;
  47.  
  48.     /**
  49.      * Total number of errors/warnings that can be fixed.
  50.      *
  51.      * @var integer 
  52.      */
  53.     public $totalFixable = 0;
  54.  
  55.     /**
  56.      * When the PHPCS run started.
  57.      *
  58.      * @var float 
  59.      */
  60.     public static $startTime = 0;
  61.  
  62.     /**
  63.      * A cache of report objects.
  64.      *
  65.      * @var array 
  66.      */
  67.     private $reports = array();
  68.  
  69.     /**
  70.      * A cache of opened temporary files.
  71.      *
  72.      * @var array 
  73.      */
  74.     private $tmpFiles = array();
  75.  
  76.  
  77.     /**
  78.      * Initialise the reporter.
  79.      *
  80.      * All reports specified in the config will be created and their
  81.      * output file (or a temp file if none is specified) initialised by
  82.      * clearing the current contents.
  83.      *
  84.      * @param \PHP_CodeSniffer\Config $config The config data for the run.
  85.      *
  86.      * @return void 
  87.      * @throws RuntimeException If a report is not available.
  88.      */
  89.     public function __construct(Config $config)
  90.     {
  91.         $this->config $config;
  92.  
  93.         foreach ($config->reports as $type => $output{
  94.             $type ucfirst($type);
  95.  
  96.             if ($output === null{
  97.                 $output $config->reportFile;
  98.             }
  99.  
  100.             if (strpos($type'.'!== false{
  101.                 // This is a path to a custom report class.
  102.                 $filename realpath($type);
  103.                 if ($filename === false{
  104.                     echo "ERROR: Custom report \"$type\" not found".PHP_EOL;
  105.                     exit(3);
  106.                 }
  107.  
  108.                 $reportClassName = Autoload::loadFile($filename);
  109.             else {
  110.                 $reportClassName 'PHP_CodeSniffer\Reports\\'.$type;
  111.             }
  112.  
  113.             $reportClass = new $reportClassName();
  114.             if (false === ($reportClass instanceof Report)) {
  115.                 throw new RuntimeException('Class "'.$reportClassName.'" must implement the "PHP_CodeSniffer\Report" interface.');
  116.             }
  117.  
  118.             $this->reports[$type= array(
  119.                                      'output' => $output,
  120.                                      'class'  => $reportClass,
  121.                                     );
  122.  
  123.             if ($output === null{
  124.                 // Using a temp file.
  125.                 $this->tmpFiles[$typetempnam(sys_get_temp_dir()'phpcs');
  126.                 file_put_contents($this->tmpFiles[$type]'');
  127.             else {
  128.                 file_put_contents($output'');
  129.             }
  130.         }//end foreach
  131.  
  132.     }//end __construct()
  133.  
  134.  
  135.     /**
  136.      * Generates and prints final versions of all reports.
  137.      *
  138.      * Returns TRUE if any of the reports output content to the screen
  139.      * or FALSE if all reports were silently printed to a file.
  140.      *
  141.      * @return bool 
  142.      */
  143.     public function printReports()
  144.     {
  145.         $toScreen = false;
  146.         foreach ($this->reports as $type => $report{
  147.             if ($report['output'=== null{
  148.                 $toScreen = true;
  149.             }
  150.  
  151.             $this->printReport($type);
  152.         }
  153.  
  154.         return $toScreen;
  155.  
  156.     }//end printReports()
  157.  
  158.  
  159.     /**
  160.      * Generates and prints a single final report.
  161.      *
  162.      * @param string $report The report type to print.
  163.      *
  164.      * @return void 
  165.      */
  166.     public function printReport($report)
  167.     {
  168.         $report      ucfirst($report);
  169.         $reportClass $this->reports[$report]['class'];
  170.         $reportFile  $this->reports[$report]['output'];
  171.  
  172.         if ($reportFile !== null{
  173.             $filename $reportFile;
  174.             $toScreen = false;
  175.         else {
  176.             if (isset($this->tmpFiles[$report]=== true{
  177.                 $filename $this->tmpFiles[$report];
  178.             else {
  179.                 $filename = null;
  180.             }
  181.  
  182.             $toScreen = true;
  183.         }
  184.  
  185.         $reportCache '';
  186.         if ($filename !== null{
  187.             $reportCache file_get_contents($filename);
  188.         }
  189.  
  190.         ob_start();
  191.         $reportClass->generate(
  192.             $reportCache,
  193.             $this->totalFiles,
  194.             $this->totalErrors,
  195.             $this->totalWarnings,
  196.             $this->totalFixable,
  197.             $this->config->showSources,
  198.             $this->config->reportWidth,
  199.             $this->config->interactive,
  200.             $toScreen
  201.         );
  202.         $generatedReport ob_get_contents();
  203.         ob_end_clean();
  204.  
  205.         if ($this->config->colors !== true || $reportFile !== null{
  206.             $generatedReport preg_replace('`\033\[[0-9;]+m`'''$generatedReport);
  207.         }
  208.  
  209.         if ($reportFile !== null{
  210.             if (PHP_CODESNIFFER_VERBOSITY > 0{
  211.                 echo $generatedReport;
  212.             }
  213.  
  214.             file_put_contents($reportFile$generatedReport.PHP_EOL);
  215.         else {
  216.             echo $generatedReport;
  217.             if ($filename !== null && file_exists($filename=== true{
  218.                 unlink($filename);
  219.             }
  220.         }
  221.  
  222.     }//end printReport()
  223.  
  224.  
  225.     /**
  226.      * Caches the result of a single processed file for all reports.
  227.      *
  228.      * The report content that is generated is appended to the output file
  229.      * assigned to each report. This content may be an intermediate report format
  230.      * and not reflect the final report output.
  231.      *
  232.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file that has been processed.
  233.      *
  234.      * @return void 
  235.      */
  236.     public function cacheFileReport(File $phpcsFile)
  237.     {
  238.         if (isset($this->config->reports=== false{
  239.             // This happens during unit testing, or any time someone just wants
  240.             // the error data and not the printed report.
  241.             return;
  242.         }
  243.  
  244.         $reportData  $this->prepareFileReport($phpcsFile);
  245.         $errorsShown = false;
  246.  
  247.         foreach ($this->reports as $type => $report{
  248.             $reportClass $report['class'];
  249.  
  250.             ob_start();
  251.             $result $reportClass->generateFileReport($reportData$phpcsFile$this->config->showSources$this->config->reportWidth);
  252.             if ($result === true{
  253.                 $errorsShown = true;
  254.             }
  255.  
  256.             $generatedReport ob_get_contents();
  257.             ob_end_clean();
  258.  
  259.             if ($report['output'=== null{
  260.                 // Using a temp file.
  261.                 file_put_contents($this->tmpFiles[$type]$generatedReportFILE_APPEND);
  262.             else {
  263.                 $flags = FILE_APPEND;
  264.                 file_put_contents($report['output']$generatedReportFILE_APPEND);
  265.             }//end if
  266.         }//end foreach
  267.  
  268.         if ($errorsShown === true{
  269.             $this->totalFiles++;
  270.             $this->totalErrors   += $reportData['errors'];
  271.             $this->totalWarnings += $reportData['warnings'];
  272.             $this->totalFixable  += $reportData['fixable'];
  273.         }
  274.  
  275.     }//end cacheFileReport()
  276.  
  277.  
  278.     /**
  279.      * Generate summary information to be used during report generation.
  280.      *
  281.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file that has been processed.
  282.      *
  283.      * @return array 
  284.      */
  285.     public function prepareFileReport(File $phpcsFile)
  286.     {
  287.         $report = array(
  288.                    'filename' => Common::stripBasepath($phpcsFile->getFilename()$this->config->basepath),
  289.                    'errors'   => $phpcsFile->getErrorCount(),
  290.                    'warnings' => $phpcsFile->getWarningCount(),
  291.                    'fixable'  => $phpcsFile->getFixableCount(),
  292.                    'messages' => array(),
  293.                   );
  294.  
  295.         if ($report['errors'=== 0 && $report['warnings'=== 0{
  296.             // Prefect score!
  297.             return $report;
  298.         }
  299.  
  300.         if ($this->config->recordErrors === false{
  301.             $message  'Errors are not being recorded but this report requires error messages. ';
  302.             $message .= 'This report will not show the correct information.';
  303.             $report['messages'][1][1= array(
  304.                                          array(
  305.                                           'message'  => $message,
  306.                                           'source'   => 'Internal.RecordErrors',
  307.                                           'severity' => 5,
  308.                                           'fixable'  => false,
  309.                                           'type'     => 'ERROR',
  310.                                          ),
  311.                                         );
  312.             return $report;
  313.         }
  314.  
  315.         $errors = array();
  316.  
  317.         // Merge errors and warnings.
  318.         foreach ($phpcsFile->getErrors(as $line => $lineErrors{
  319.             foreach ($lineErrors as $column => $colErrors{
  320.                 $newErrors = array();
  321.                 foreach ($colErrors as $data{
  322.                     $newErrors[= array(
  323.                                     'message'  => $data['message'],
  324.                                     'source'   => $data['source'],
  325.                                     'severity' => $data['severity'],
  326.                                     'fixable'  => $data['fixable'],
  327.                                     'type'     => 'ERROR',
  328.                                    );
  329.                 }
  330.  
  331.                 $errors[$line][$column$newErrors;
  332.             }
  333.  
  334.             ksort($errors[$line]);
  335.         }//end foreach
  336.  
  337.         foreach ($phpcsFile->getWarnings(as $line => $lineWarnings{
  338.             foreach ($lineWarnings as $column => $colWarnings{
  339.                 $newWarnings = array();
  340.                 foreach ($colWarnings as $data{
  341.                     $newWarnings[= array(
  342.                                       'message'  => $data['message'],
  343.                                       'source'   => $data['source'],
  344.                                       'severity' => $data['severity'],
  345.                                       'fixable'  => $data['fixable'],
  346.                                       'type'     => 'WARNING',
  347.                                      );
  348.                 }
  349.  
  350.                 if (isset($errors[$line]=== false{
  351.                     $errors[$line= array();
  352.                 }
  353.  
  354.                 if (isset($errors[$line][$column]=== true{
  355.                     $errors[$line][$columnarray_merge(
  356.                         $newWarnings,
  357.                         $errors[$line][$column]
  358.                     );
  359.                 else {
  360.                     $errors[$line][$column$newWarnings;
  361.                 }
  362.             }//end foreach
  363.  
  364.             ksort($errors[$line]);
  365.         }//end foreach
  366.  
  367.         ksort($errors);
  368.         $report['messages'$errors;
  369.         return $report;
  370.  
  371.     }//end prepareFileReport()
  372.  
  373.  
  374. }//end class

Documentation generated on Mon, 11 Mar 2019 14:53:38 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.