Plugin to allow visitor contributions to WordPress posts, wiki style.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

489 lines
9.9KB

  1. <?php
  2. namespace Caxy\HtmlDiff;
  3. /**
  4. * Class HtmlDiffConfig
  5. * @package Caxy\HtmlDiff
  6. */
  7. class HtmlDiffConfig
  8. {
  9. /**
  10. * @var array
  11. */
  12. protected $specialCaseTags = array('strong', 'b', 'i', 'big', 'small', 'u', 'sub', 'sup', 'strike', 's', 'p');
  13. /**
  14. * @var array
  15. */
  16. protected $specialCaseChars = array('.', ',', '(', ')', '\'');
  17. /**
  18. * @var bool
  19. */
  20. protected $groupDiffs = true;
  21. /**
  22. * @var bool
  23. */
  24. protected $insertSpaceInReplace = false;
  25. /**
  26. * @var string
  27. */
  28. protected $encoding = 'UTF-8';
  29. /**
  30. * @var array
  31. */
  32. protected $isolatedDiffTags = array(
  33. 'ol' => '[[REPLACE_ORDERED_LIST]]',
  34. 'ul' => '[[REPLACE_UNORDERED_LIST]]',
  35. 'sub' => '[[REPLACE_SUB_SCRIPT]]',
  36. 'sup' => '[[REPLACE_SUPER_SCRIPT]]',
  37. 'dl' => '[[REPLACE_DEFINITION_LIST]]',
  38. 'table' => '[[REPLACE_TABLE]]',
  39. 'strong' => '[[REPLACE_STRONG]]',
  40. 'b' => '[[REPLACE_B]]',
  41. 'em' => '[[REPLACE_EM]]',
  42. 'i' => '[[REPLACE_I]]',
  43. 'a' => '[[REPLACE_A]]',
  44. );
  45. /**
  46. * @var int
  47. */
  48. protected $matchThreshold = 80;
  49. /**
  50. * @var array
  51. */
  52. protected $specialCaseOpeningTags = array();
  53. /**
  54. * @var array
  55. */
  56. protected $specialCaseClosingTags = array();
  57. /**
  58. * @var bool
  59. */
  60. protected $useTableDiffing = true;
  61. /**
  62. * @var null|\Doctrine\Common\Cache\Cache
  63. */
  64. protected $cacheProvider;
  65. /**
  66. * @var null|string
  67. */
  68. protected $purifierCacheLocation = null;
  69. /**
  70. * @return HtmlDiffConfig
  71. */
  72. public static function create()
  73. {
  74. return new self();
  75. }
  76. /**
  77. * HtmlDiffConfig constructor.
  78. */
  79. public function __construct()
  80. {
  81. $this->setSpecialCaseTags($this->specialCaseTags);
  82. }
  83. /**
  84. * @return int
  85. */
  86. public function getMatchThreshold()
  87. {
  88. return $this->matchThreshold;
  89. }
  90. /**
  91. * @param int $matchThreshold
  92. *
  93. * @return AbstractDiff
  94. */
  95. public function setMatchThreshold($matchThreshold)
  96. {
  97. $this->matchThreshold = $matchThreshold;
  98. return $this;
  99. }
  100. /**
  101. * @param array $chars
  102. */
  103. public function setSpecialCaseChars(array $chars)
  104. {
  105. $this->specialCaseChars = $chars;
  106. }
  107. /**
  108. * @return array|null
  109. */
  110. public function getSpecialCaseChars()
  111. {
  112. return $this->specialCaseChars;
  113. }
  114. /**
  115. * @param string $char
  116. *
  117. * @return $this
  118. */
  119. public function addSpecialCaseChar($char)
  120. {
  121. if (!in_array($char, $this->specialCaseChars)) {
  122. $this->specialCaseChars[] = $char;
  123. }
  124. return $this;
  125. }
  126. /**
  127. * @param string $char
  128. *
  129. * @return $this
  130. */
  131. public function removeSpecialCaseChar($char)
  132. {
  133. $key = array_search($char, $this->specialCaseChars);
  134. if ($key !== false) {
  135. unset($this->specialCaseChars[$key]);
  136. }
  137. return $this;
  138. }
  139. /**
  140. * @param array $tags
  141. *
  142. * @return $this
  143. */
  144. public function setSpecialCaseTags(array $tags = array())
  145. {
  146. $this->specialCaseTags = $tags;
  147. $this->specialCaseOpeningTags = array();
  148. $this->specialCaseClosingTags = array();
  149. foreach ($this->specialCaseTags as $tag) {
  150. $this->addSpecialCaseTag($tag);
  151. }
  152. return $this;
  153. }
  154. /**
  155. * @param string $tag
  156. *
  157. * @return $this
  158. */
  159. public function addSpecialCaseTag($tag)
  160. {
  161. if (!in_array($tag, $this->specialCaseTags)) {
  162. $this->specialCaseTags[] = $tag;
  163. }
  164. $opening = $this->getOpeningTag($tag);
  165. $closing = $this->getClosingTag($tag);
  166. if (!in_array($opening, $this->specialCaseOpeningTags)) {
  167. $this->specialCaseOpeningTags[] = $opening;
  168. }
  169. if (!in_array($closing, $this->specialCaseClosingTags)) {
  170. $this->specialCaseClosingTags[] = $closing;
  171. }
  172. return $this;
  173. }
  174. /**
  175. * @param string $tag
  176. *
  177. * @return $this
  178. */
  179. public function removeSpecialCaseTag($tag)
  180. {
  181. if (($key = array_search($tag, $this->specialCaseTags)) !== false) {
  182. unset($this->specialCaseTags[$key]);
  183. $opening = $this->getOpeningTag($tag);
  184. $closing = $this->getClosingTag($tag);
  185. if (($key = array_search($opening, $this->specialCaseOpeningTags)) !== false) {
  186. unset($this->specialCaseOpeningTags[$key]);
  187. }
  188. if (($key = array_search($closing, $this->specialCaseClosingTags)) !== false) {
  189. unset($this->specialCaseClosingTags[$key]);
  190. }
  191. }
  192. return $this;
  193. }
  194. /**
  195. * @return array|null
  196. */
  197. public function getSpecialCaseTags()
  198. {
  199. return $this->specialCaseTags;
  200. }
  201. /**
  202. * @return boolean
  203. */
  204. public function isGroupDiffs()
  205. {
  206. return $this->groupDiffs;
  207. }
  208. /**
  209. * @param boolean $groupDiffs
  210. *
  211. * @return HtmlDiffConfig
  212. */
  213. public function setGroupDiffs($groupDiffs)
  214. {
  215. $this->groupDiffs = $groupDiffs;
  216. return $this;
  217. }
  218. /**
  219. * @return string
  220. */
  221. public function getEncoding()
  222. {
  223. return $this->encoding;
  224. }
  225. /**
  226. * @param string $encoding
  227. *
  228. * @return HtmlDiffConfig
  229. */
  230. public function setEncoding($encoding)
  231. {
  232. $this->encoding = $encoding;
  233. return $this;
  234. }
  235. /**
  236. * @return boolean
  237. */
  238. public function isInsertSpaceInReplace()
  239. {
  240. return $this->insertSpaceInReplace;
  241. }
  242. /**
  243. * @param boolean $insertSpaceInReplace
  244. *
  245. * @return HtmlDiffConfig
  246. */
  247. public function setInsertSpaceInReplace($insertSpaceInReplace)
  248. {
  249. $this->insertSpaceInReplace = $insertSpaceInReplace;
  250. return $this;
  251. }
  252. /**
  253. * @return array
  254. */
  255. public function getIsolatedDiffTags()
  256. {
  257. return $this->isolatedDiffTags;
  258. }
  259. /**
  260. * @param array $isolatedDiffTags
  261. *
  262. * @return HtmlDiffConfig
  263. */
  264. public function setIsolatedDiffTags($isolatedDiffTags)
  265. {
  266. $this->isolatedDiffTags = $isolatedDiffTags;
  267. return $this;
  268. }
  269. /**
  270. * @param string $tag
  271. * @param null|string $placeholder
  272. *
  273. * @return $this
  274. */
  275. public function addIsolatedDiffTag($tag, $placeholder = null)
  276. {
  277. if (null === $placeholder) {
  278. $placeholder = sprintf('[[REPLACE_%s]]', strtoupper($tag));
  279. }
  280. if ($this->isIsolatedDiffTag($tag) && $this->isolatedDiffTags[$tag] !== $placeholder) {
  281. throw new \InvalidArgumentException(
  282. sprintf('Isolated diff tag "%s" already exists using a different placeholder', $tag)
  283. );
  284. }
  285. $matchingKey = array_search($placeholder, $this->isolatedDiffTags, true);
  286. if (false !== $matchingKey && $matchingKey !== $tag) {
  287. throw new \InvalidArgumentException(
  288. sprintf('Placeholder already being used for a different tag "%s"', $tag)
  289. );
  290. }
  291. if (!array_key_exists($tag, $this->isolatedDiffTags)) {
  292. $this->isolatedDiffTags[$tag] = $placeholder;
  293. }
  294. return $this;
  295. }
  296. /**
  297. * @param string $tag
  298. *
  299. * @return $this
  300. */
  301. public function removeIsolatedDiffTag($tag)
  302. {
  303. if ($this->isIsolatedDiffTag($tag)) {
  304. unset($this->isolatedDiffTags[$tag]);
  305. }
  306. return $this;
  307. }
  308. /**
  309. * @param string $tag
  310. *
  311. * @return bool
  312. */
  313. public function isIsolatedDiffTag($tag)
  314. {
  315. return array_key_exists($tag, $this->isolatedDiffTags);
  316. }
  317. /**
  318. * @param string $text
  319. *
  320. * @return bool
  321. */
  322. public function isIsolatedDiffTagPlaceholder($text)
  323. {
  324. return in_array($text, $this->isolatedDiffTags, true);
  325. }
  326. /**
  327. * @param string $tag
  328. *
  329. * @return null|string
  330. */
  331. public function getIsolatedDiffTagPlaceholder($tag)
  332. {
  333. return $this->isIsolatedDiffTag($tag) ? $this->isolatedDiffTags[$tag] : null;
  334. }
  335. /**
  336. * @return array
  337. */
  338. public function getSpecialCaseOpeningTags()
  339. {
  340. return $this->specialCaseOpeningTags;
  341. }
  342. /**
  343. * @return array
  344. */
  345. public function getSpecialCaseClosingTags()
  346. {
  347. return $this->specialCaseClosingTags;
  348. }
  349. /**
  350. * @return boolean
  351. */
  352. public function isUseTableDiffing()
  353. {
  354. return $this->useTableDiffing;
  355. }
  356. /**
  357. * @param boolean $useTableDiffing
  358. *
  359. * @return HtmlDiffConfig
  360. */
  361. public function setUseTableDiffing($useTableDiffing)
  362. {
  363. $this->useTableDiffing = $useTableDiffing;
  364. return $this;
  365. }
  366. /**
  367. * @param null|\Doctrine\Common\Cache\Cache $cacheProvider
  368. *
  369. * @return $this
  370. */
  371. public function setCacheProvider(\Doctrine\Common\Cache\Cache $cacheProvider = null)
  372. {
  373. $this->cacheProvider = $cacheProvider;
  374. return $this;
  375. }
  376. /**
  377. * @return null|\Doctrine\Common\Cache\Cache
  378. */
  379. public function getCacheProvider()
  380. {
  381. return $this->cacheProvider;
  382. }
  383. /**
  384. * @param null|string
  385. *
  386. * @return $this
  387. */
  388. public function setPurifierCacheLocation($purifierCacheLocation = null)
  389. {
  390. $this->purifierCacheLocation = $purifierCacheLocation;
  391. return $this;
  392. }
  393. /**
  394. * @return null|string
  395. */
  396. public function getPurifierCacheLocation()
  397. {
  398. return $this->purifierCacheLocation;
  399. }
  400. /**
  401. * @param string $tag
  402. *
  403. * @return string
  404. */
  405. protected function getOpeningTag($tag)
  406. {
  407. return "/<".$tag."[^>]*/i";
  408. }
  409. /**
  410. * @param string $tag
  411. *
  412. * @return string
  413. */
  414. protected function getClosingTag($tag)
  415. {
  416. return "</".$tag.">";
  417. }
  418. }