Passed
Push — master ( aea8b9...d57411 )
by Dispositif
03:07
created

DiffAdapter::getDiff()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 7
c 1
b 0
f 1
dl 0
loc 12
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/*
3
 * This file is part of dispositif/wikibot application (@github)
4
 * 2019-2024 © Philippe M./Irønie  <[email protected]>
5
 * For the full copyright and MIT license information, view the license file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Infrastructure;
11
12
use App\Application\InfrastructurePorts\DiffInterface;
13
use Jfcherng\Diff\DiffHelper;
14
use Jfcherng\Diff\Renderer\RendererConstant;
15
16
/**
17
 * Diff lib PHP>=8.1 https://github.com/jfcherng/php-diff
18
 * https://github.com/jfcherng/php-diff/tree/v6/example
19
 */
20
class DiffAdapter implements DiffInterface
21
{
22
    public const STYLE_UNIFIED = 'Unified';
23
    public const STYLE_CONTEXT = 'Context';
24
    protected const DEFAULT_STYLE = self::STYLE_UNIFIED;
25
    protected const DIFF_STYLES = [self::STYLE_UNIFIED, self::STYLE_CONTEXT];
26
    protected array $colorStyles;
27
    protected array $diffOptions;
28
    protected array $rendererOptions;
29
    protected string $diffStyle;
30
31
    public function __construct(string $diffStyle = self::DEFAULT_STYLE)
32
    {
33
        $this->diffStyle = in_array($diffStyle, self::DIFF_STYLES) ? $diffStyle : 'Unified';
34
        $this->initialize();
35
    }
36
37
    private function initialize(): void
38
    {
39
        $this->colorStyles = [
40
            'section' => ['f_black', 'b_cyan'],
41
        ];
42
43
        // options for Diff class
44
        $this->diffOptions = [
45
            // show how many neighbor lines
46
            // Differ::CONTEXT_ALL can be used to show the whole file
47
            'context' => 2,
48
            // ignore case difference
49
            'ignoreCase' => false,
50
            // ignore line ending difference
51
            'ignoreLineEnding' => false,
52
            // ignore whitespace difference
53
            'ignoreWhitespace' => false,
54
            // if the input sequence is too long, it will just gives up (especially for char-level diff)
55
            'lengthLimit' => 2000,
56
        ];
57
58
        // options for renderer class
59
        $this->rendererOptions = [
60
            // how detailed the rendered HTML is? (none, line, word, char)
61
            'detailLevel' => 'word', // line
62
            // renderer language: eng, cht, chs, jpn, ...
63
            // or an array which has the same keys with a language file
64
            // check the "Custom Language" section in the readme for more advanced usage
65
            'language' => 'fra', // eng
66
            // show line numbers in HTML renderers
67
            'lineNumbers' => false,
68
            // show a separator between different diff hunks in HTML renderers
69
            'separateBlock' => true,
70
            // show the (table) header
71
            'showHeader' => true,
72
            // convert spaces/tabs into HTML codes like `<span class="ch sp"> </span>`
73
            // and the frontend is responsible for rendering them with CSS.
74
            // when using this, "spacesToNbsp" should be false and "tabSize" is not respected.
75
            'spaceToHtmlTag' => false,
76
            // the frontend HTML could use CSS "white-space: pre;" to visualize consecutive whitespaces
77
            // but if you want to visualize them in the backend with "&nbsp;", you can set this to true
78
            'spacesToNbsp' => false,
79
            // HTML renderer tab width (negative = do not convert into spaces)
80
            'tabSize' => 4,
81
            // this option is currently only for the Combined renderer.
82
            // it determines whether a replace-type block should be merged or not
83
            // depending on the content changed ratio, which values between 0 and 1.
84
            'mergeThreshold' => 0.8,
85
            // this option is currently only for the Unified and the Context renderers.
86
            // RendererConstant::CLI_COLOR_AUTO = colorize the output if possible (default)
87
            // RendererConstant::CLI_COLOR_ENABLE = force to colorize the output
88
            // RendererConstant::CLI_COLOR_DISABLE = force not to colorize the output
89
            'cliColorization' => RendererConstant::CLI_COLOR_AUTO,
90
            // this option is currently only for the Json renderer.
91
            // internally, ops (tags) are all int type but this is not good for human reading.
92
            // set this to "true" to convert them into string form before outputting.
93
            'outputTagAsString' => false,
94
            // this option is currently only for the Json renderer.
95
            // it controls how the output JSON is formatted.
96
            // see available options on https://www.php.net/manual/en/function.json-encode.php
97
            'jsonEncodeFlags' => \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE,
98
            // this option is currently effective when the "detailLevel" is "word"
99
            // characters listed in this array can be used to make diff segments into a whole
100
            // for example, making "<del>good</del>-<del>looking</del>" into "<del>good-looking</del>"
101
            // this should bring better readability but set this to empty array if you do not want it
102
            'wordGlues' => [' ', '-'],
103
            // change this value to a string as the returned diff if the two input strings are identical
104
            'resultForIdenticals' => null,
105
            // extra HTML classes added to the DOM of the diff container
106
            'wrapperClasses' => ['diff-wrapper'],
107
        ];
108
    }
109
110
    public function getDiff(string $oldText, string $newText): string
111
    {
112
        //echo CliColor::color("$diffStyle Diff\n============", $this->colorStyles['section']) . "\n\n";
113
        $unifiedResult = DiffHelper::calculate(
114
            $oldText,
115
            $newText,
116
            $this->diffStyle,
117
            $this->diffOptions,
118
            $this->rendererOptions,
119
        );
120
121
        return $unifiedResult . "\n\n";
122
    }
123
}