DiffHelper.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. App::uses('AppHelper', 'View/Helper');
  3. App::uses('DiffLib', 'Tools.Lib');
  4. /**
  5. * DiffHelper class
  6. *
  7. * This class is a wrapper for PEAR Text_Diff with modified renderers from Horde
  8. * You need the stable Text_Diff from PEAR and (if you want to use them) two
  9. * renderers attached with this helper (sidebyside.php and character.php)
  10. *
  11. * To use this helper you either have to use the Vendor files in the Tools Plugin.
  12. * Wraps the DiffLib (which does all the heavy lifting) for the view layer.
  13. *
  14. * @author Marcin Domanski aka kabturek <blog@kabturek.info>
  15. * @license http://opensource.org/licenses/mit-license.php MIT
  16. * @modified Mark Scherer (Make it work with 2.x and clean it up into Lib + Helper)
  17. */
  18. class DiffHelper extends AppHelper {
  19. public $helpers = ['Html'];
  20. /**
  21. * Construct function
  22. * Loads the vendor classes and sets the include path for autoloader to work
  23. *
  24. */
  25. public function __construct($View = null, $config = []) {
  26. parent::__construct($View, $config);
  27. $this->Diff = new DiffLib();
  28. }
  29. /**
  30. * @param string $renderType
  31. * 'unified', 'inline', 'context', 'sidebyside'
  32. * defaults to "inline"
  33. * @return bool Success
  34. */
  35. public function renderType($type = null) {
  36. return $this->Diff->renderType($type);
  37. }
  38. /**
  39. * @param string $engineType
  40. * 'auto', 'native', 'xdiff', 'shell', 'string'
  41. * defaults to "auto"
  42. * @return bool Success
  43. */
  44. public function engineType($type = null) {
  45. return $this->Diff->engineType($type);
  46. }
  47. /**
  48. * Compare function
  49. * Compares two strings/arrays using the specified method and renderer
  50. *
  51. * @param mixed $original
  52. * @param mixed $changed
  53. * @param array $options
  54. * - div: true/false
  55. * - class: defaults to "diff"
  56. * - escape: defaults to true
  57. * @return string output
  58. */
  59. public function compare($original, $changed, $options = []) {
  60. $original = $this->_prep($original);
  61. $changed = $this->_prep($changed);
  62. $string = $this->Diff->compare($original, $changed, $options);
  63. if (isset($options['div']) && $options['div'] === false) {
  64. return $string;
  65. }
  66. $defaults = [
  67. 'class' => 'diff'
  68. ];
  69. $options += $defaults;
  70. $options['escape'] = null;
  71. return $this->Html->tag('div', $string, $options);
  72. }
  73. /**
  74. * @param string $string Either context or unified diff snippet
  75. * @param array $options
  76. * - mode (autodetect, context, unified)
  77. * @return string
  78. */
  79. public function reverse($string, $options = []) {
  80. $string = $this->Diff->reverse($string, $options);
  81. if (isset($options['div']) && $options['div'] === false) {
  82. return $string;
  83. }
  84. $defaults = [
  85. 'class' => 'diff'
  86. ];
  87. $options += $defaults;
  88. $options['escape'] = null;
  89. return $this->Html->tag('div', $string, $options);
  90. }
  91. /**
  92. * Prep for security
  93. * maybe switch to do that after comparison?
  94. *
  95. * @param string $string
  96. * @param array $options
  97. * @return string
  98. */
  99. protected function _prep($string, $options = []) {
  100. if ($this->renderer === 'inline' || isset($options['escape']) && $options['escape'] === false) {
  101. return $string;
  102. }
  103. return h($string);
  104. }
  105. }