DiffHelper.php 3.1 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 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 = array('Html');
  20. /**
  21. * Construct function
  22. * Loads the vendor classes and sets the include path for autoloader to work
  23. *
  24. * @return void
  25. */
  26. public function __construct($View = null, $settings = array()) {
  27. parent::__construct($View, $settings);
  28. $this->Diff = new DiffLib();
  29. }
  30. /**
  31. * @param string $renderType
  32. * 'unified', 'inline', 'context', 'sidebyside'
  33. * defaults to "inline"
  34. * @return boolean Success
  35. */
  36. public function renderType($type = null) {
  37. return $this->Diff->renderType($type);
  38. }
  39. /**
  40. * @param string $engineType
  41. * 'auto', 'native', 'xdiff', 'shell', 'string'
  42. * defaults to "auto"
  43. * @return boolean Success
  44. */
  45. public function engineType($type = null) {
  46. return $this->Diff->engineType($type);
  47. }
  48. /**
  49. * Compare function
  50. * Compares two strings/arrays using the specified method and renderer
  51. *
  52. * @param mixed $original
  53. * @param mixed $changed
  54. * @param array $options
  55. * - div: true/false
  56. * - class: defaults to "diff"
  57. * - escape: defaults to true
  58. * @return string output
  59. */
  60. public function compare($original, $changed, $options = array()) {
  61. $original = $this->_prep($original);
  62. $changed = $this->_prep($changed);
  63. $string = $this->Diff->compare($original, $changed, $options);
  64. if (isset($options['div']) && $options['div'] === false) {
  65. return $string;
  66. }
  67. $defaults = array(
  68. 'class' => 'diff'
  69. );
  70. $options = array_merge($defaults, $options);
  71. $options['escape'] = null;
  72. return $this->Html->tag('div', $string, $options);
  73. }
  74. /**
  75. * @param string $string Either context or unified diff snippet
  76. * @param array $options
  77. * - mode (autodetect, context, unified)
  78. */
  79. public function reverse($string, $options = array()) {
  80. $string = $this->Diff->reverse($string, $options);
  81. if (isset($options['div']) && $options['div'] === false) {
  82. return $string;
  83. }
  84. $defaults = array(
  85. 'class' => 'diff'
  86. );
  87. $options = array_merge($defaults, $options);
  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 = array()) {
  100. if ($this->renderer === 'inline' || isset($options['escape']) && $options['escape'] === false) {
  101. return $string;
  102. }
  103. return h($string);
  104. }
  105. }