class DiffFormatter

Same name in this branch
  1. 11.x core/lib/Drupal/Core/Diff/DiffFormatter.php \Drupal\Core\Diff\DiffFormatter
Same name in other branches
  1. 9 core/lib/Drupal/Core/Diff/DiffFormatter.php \Drupal\Core\Diff\DiffFormatter
  2. 9 core/lib/Drupal/Component/Diff/DiffFormatter.php \Drupal\Component\Diff\DiffFormatter
  3. 8.9.x core/lib/Drupal/Core/Diff/DiffFormatter.php \Drupal\Core\Diff\DiffFormatter
  4. 8.9.x core/lib/Drupal/Component/Diff/DiffFormatter.php \Drupal\Component\Diff\DiffFormatter
  5. 10 core/lib/Drupal/Core/Diff/DiffFormatter.php \Drupal\Core\Diff\DiffFormatter
  6. 10 core/lib/Drupal/Component/Diff/DiffFormatter.php \Drupal\Component\Diff\DiffFormatter

A class to format Diffs

This class formats the diff in classic diff format. It is intended that this class be customized via inheritance, to obtain fancier outputs. @todo document @private @subpackage DifferenceEngine

Hierarchy

Expanded class hierarchy of DiffFormatter

2 files declare their use of DiffFormatter
DiffFormatter.php in core/lib/Drupal/Core/Diff/DiffFormatter.php
DiffFormatterTest.php in core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php

File

core/lib/Drupal/Component/Diff/DiffFormatter.php, line 17

Namespace

Drupal\Component\Diff
View source
class DiffFormatter {
    
    /**
     * Should a block header be shown?
     */
    public $show_header = TRUE;
    
    /**
     * Number of leading context "lines" to preserve.
     *
     * This should be left at zero for this class, but subclasses
     * may want to set this to other values.
     */
    public $leading_context_lines = 0;
    
    /**
     * Number of trailing context "lines" to preserve.
     *
     * This should be left at zero for this class, but subclasses
     * may want to set this to other values.
     */
    public $trailing_context_lines = 0;
    
    /**
     * The line stats.
     *
     * @var array
     */
    protected $line_stats = [
        'counter' => [
            'x' => 0,
            'y' => 0,
        ],
        'offset' => [
            'x' => 0,
            'y' => 0,
        ],
    ];
    
    /**
     * Format a diff.
     *
     * @param \Drupal\Component\Diff\Diff $diff
     *   A Diff object.
     *
     * @return string
     *   The formatted output.
     */
    public function format(Diff $diff) {
        $xi = $yi = 1;
        $block = FALSE;
        $context = [];
        $nlead = $this->leading_context_lines;
        $ntrail = $this->trailing_context_lines;
        $this->_start_diff();
        foreach ($diff->getEdits() as $edit) {
            if ($edit->type == 'copy') {
                if (is_array($block)) {
                    if (sizeof($edit->orig) <= $nlead + $ntrail) {
                        $block[] = $edit;
                    }
                    else {
                        if ($ntrail) {
                            $context = array_slice($edit->orig, 0, $ntrail);
                            $block[] = new DiffOpCopy($context);
                        }
                        $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
                        $block = FALSE;
                    }
                }
                $context = $edit->orig;
            }
            else {
                if (!is_array($block)) {
                    $context = array_slice($context, sizeof($context) - $nlead);
                    $x0 = $xi - sizeof($context);
                    $y0 = $yi - sizeof($context);
                    $block = [];
                    if ($context) {
                        $block[] = new DiffOpCopy($context);
                    }
                }
                $block[] = $edit;
            }
            if ($edit->orig) {
                $xi += sizeof($edit->orig);
            }
            if ($edit->closing) {
                $yi += sizeof($edit->closing);
            }
        }
        if (is_array($block)) {
            $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
        }
        $end = $this->_end_diff();
        if (!empty($xi)) {
            $this->line_stats['counter']['x'] += $xi;
        }
        if (!empty($yi)) {
            $this->line_stats['counter']['y'] += $yi;
        }
        return $end;
    }
    protected function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
        $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
        foreach ($edits as $edit) {
            if ($edit->type == 'copy') {
                $this->_context($edit->orig);
            }
            elseif ($edit->type == 'add') {
                $this->_added($edit->closing);
            }
            elseif ($edit->type == 'delete') {
                $this->_deleted($edit->orig);
            }
            elseif ($edit->type == 'change') {
                $this->_changed($edit->orig, $edit->closing);
            }
            else {
                trigger_error('Unknown edit type', E_USER_ERROR);
            }
        }
        $this->_end_block();
    }
    protected function _start_diff() {
        ob_start();
    }
    protected function _end_diff() {
        $val = ob_get_contents();
        ob_end_clean();
        return $val;
    }
    protected function _block_header($xbeg, $xlen, $ybeg, $ylen) {
        if ($xlen > 1) {
            $xbeg .= "," . ($xbeg + $xlen - 1);
        }
        if ($ylen > 1) {
            $ybeg .= "," . ($ybeg + $ylen - 1);
        }
        return $xbeg . ($xlen ? $ylen ? 'c' : 'd' : 'a') . $ybeg;
    }
    protected function _start_block($header) {
        if ($this->show_header) {
            echo $header . "\n";
        }
    }
    protected function _end_block() {
    }
    protected function _lines($lines, $prefix = ' ') {
        foreach ($lines as $line) {
            echo "{$prefix} {$line}\n";
        }
    }
    protected function _context($lines) {
        $this->_lines($lines);
    }
    protected function _added($lines) {
        $this->_lines($lines, '>');
    }
    protected function _deleted($lines) {
        $this->_lines($lines, '<');
    }
    protected function _changed($orig, $closing) {
        $this->_deleted($orig);
        echo "---\n";
        $this->_added($closing);
    }

}

Members

Title Sort descending Modifiers Object type Summary Overrides
DiffFormatter::$leading_context_lines public property Number of leading context &quot;lines&quot; to preserve.
DiffFormatter::$line_stats protected property The line stats.
DiffFormatter::$show_header public property Should a block header be shown?
DiffFormatter::$trailing_context_lines public property Number of trailing context &quot;lines&quot; to preserve.
DiffFormatter::format public function Format a diff.
DiffFormatter::_added protected function 1
DiffFormatter::_block protected function
DiffFormatter::_block_header protected function 1
DiffFormatter::_changed protected function 1
DiffFormatter::_context protected function 1
DiffFormatter::_deleted protected function 1
DiffFormatter::_end_block protected function
DiffFormatter::_end_diff protected function 1
DiffFormatter::_lines protected function 1
DiffFormatter::_start_block protected function 1
DiffFormatter::_start_diff protected function 1

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.