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

Documentation generated on Mon, 11 Mar 2019 15:27:42 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.