vendor/pimcore/pimcore/models/DataObject/ClassDefinition/Data/Wysiwyg.php line 231

Open in your IDE?
  1. <?php
  2. /**
  3. * Pimcore
  4. *
  5. * This source file is available under two different licenses:
  6. * - GNU General Public License version 3 (GPLv3)
  7. * - Pimcore Commercial License (PCL)
  8. * Full copyright and license information is available in
  9. * LICENSE.md which is distributed with this source code.
  10. *
  11. * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12. * @license http://www.pimcore.org/license GPLv3 and PCL
  13. */
  14. namespace Pimcore\Model\DataObject\ClassDefinition\Data;
  15. use Pimcore\Model;
  16. use Pimcore\Model\DataObject;
  17. use Pimcore\Model\DataObject\ClassDefinition\Data;
  18. use Pimcore\Model\Element;
  19. use Pimcore\Normalizer\NormalizerInterface;
  20. use Pimcore\Tool\DomCrawler;
  21. use Pimcore\Tool\Text;
  22. class Wysiwyg extends Data implements ResourcePersistenceAwareInterface, QueryResourcePersistenceAwareInterface, TypeDeclarationSupportInterface, EqualComparisonInterface, VarExporterInterface, NormalizerInterface, IdRewriterInterface, PreGetDataInterface
  23. {
  24. use DataObject\Traits\SimpleComparisonTrait;
  25. use Model\DataObject\ClassDefinition\Data\Extension\Text;
  26. use Extension\ColumnType;
  27. use Extension\QueryColumnType;
  28. use DataObject\Traits\SimpleNormalizerTrait;
  29. /**
  30. * Static type of this element
  31. *
  32. * @internal
  33. *
  34. * @var string
  35. */
  36. public $fieldtype = 'wysiwyg';
  37. /**
  38. * @internal
  39. *
  40. * @var string|int
  41. */
  42. public $width = 0;
  43. /**
  44. * @internal
  45. *
  46. * @var string|int
  47. */
  48. public $height = 0;
  49. /**
  50. * Type for the column to query
  51. *
  52. * @internal
  53. *
  54. * @var string
  55. */
  56. public $queryColumnType = 'longtext';
  57. /**
  58. * Type for the column
  59. *
  60. * @internal
  61. *
  62. * @var string
  63. */
  64. public $columnType = 'longtext';
  65. /**
  66. * @internal
  67. *
  68. * @var string
  69. */
  70. public string $toolbarConfig = '';
  71. /**
  72. * @internal
  73. *
  74. * @var bool
  75. */
  76. public $excludeFromSearchIndex = false;
  77. /**
  78. * @internal
  79. *
  80. * @var string|int
  81. */
  82. public $maxCharacters = 0;
  83. /**
  84. * @return string|int
  85. */
  86. public function getWidth()
  87. {
  88. return $this->width;
  89. }
  90. /**
  91. * @return string|int
  92. */
  93. public function getHeight()
  94. {
  95. return $this->height;
  96. }
  97. /**
  98. * @param string|int $width
  99. *
  100. * @return $this
  101. */
  102. public function setWidth($width)
  103. {
  104. if (is_numeric($width)) {
  105. $width = (int)$width;
  106. }
  107. $this->width = $width;
  108. return $this;
  109. }
  110. /**
  111. * @param string|int $height
  112. *
  113. * @return $this
  114. */
  115. public function setHeight($height)
  116. {
  117. if (is_numeric($height)) {
  118. $height = (int)$height;
  119. }
  120. $this->height = $height;
  121. return $this;
  122. }
  123. /**
  124. * @param string $toolbarConfig
  125. */
  126. public function setToolbarConfig(string $toolbarConfig)
  127. {
  128. $this->toolbarConfig = $toolbarConfig;
  129. }
  130. /**
  131. * @return string
  132. */
  133. public function getToolbarConfig(): string
  134. {
  135. return $this->toolbarConfig;
  136. }
  137. /**
  138. * @return bool
  139. */
  140. public function isExcludeFromSearchIndex(): bool
  141. {
  142. return $this->excludeFromSearchIndex;
  143. }
  144. /**
  145. * @param bool $excludeFromSearchIndex
  146. *
  147. * @return self
  148. */
  149. public function setExcludeFromSearchIndex(bool $excludeFromSearchIndex)
  150. {
  151. $this->excludeFromSearchIndex = $excludeFromSearchIndex;
  152. return $this;
  153. }
  154. /**
  155. * @return string|int
  156. */
  157. public function getMaxCharacters()
  158. {
  159. return $this->maxCharacters;
  160. }
  161. /**
  162. * @param string|int $maxCharacters
  163. */
  164. public function setMaxCharacters($maxCharacters)
  165. {
  166. $this->maxCharacters = $maxCharacters;
  167. }
  168. /**
  169. * @see ResourcePersistenceAwareInterface::getDataForResource
  170. *
  171. * @param string $data
  172. * @param null|DataObject\Concrete $object
  173. * @param mixed $params
  174. *
  175. * @return string
  176. */
  177. public function getDataForResource($data, $object = null, $params = [])
  178. {
  179. return Text::wysiwygText($data);
  180. }
  181. /**
  182. * @see ResourcePersistenceAwareInterface::getDataFromResource
  183. *
  184. * @param string $data
  185. * @param null|DataObject\Concrete $object
  186. * @param mixed $params
  187. *
  188. * @return string
  189. */
  190. public function getDataFromResource($data, $object = null, $params = [])
  191. {
  192. return Text::wysiwygText($data);
  193. }
  194. /**
  195. * @see QueryResourcePersistenceAwareInterface::getDataForQueryResource
  196. *
  197. * @param string $data
  198. * @param null|DataObject\Concrete $object
  199. * @param mixed $params
  200. *
  201. * @return string
  202. */
  203. public function getDataForQueryResource($data, $object = null, $params = [])
  204. {
  205. $data = $this->getDataForResource($data, $object, $params);
  206. $data = strip_tags($data, '<a><img>');
  207. $data = str_replace("\r\n", ' ', $data);
  208. $data = str_replace("\n", ' ', $data);
  209. $data = str_replace("\r", ' ', $data);
  210. $data = str_replace("\t", '', $data);
  211. $data = preg_replace('#[ ]+#', ' ', $data);
  212. return $data;
  213. }
  214. /**
  215. * {@inheritdoc}
  216. */
  217. public function getDataForSearchIndex($object, $params = [])
  218. {
  219. if ($this->isExcludeFromSearchIndex()) {
  220. return '';
  221. } else {
  222. return parent::getDataForSearchIndex($object, $params);
  223. }
  224. }
  225. /**
  226. * @see Data::getDataForEditmode
  227. *
  228. * @param string $data
  229. * @param null|DataObject\Concrete $object
  230. * @param mixed $params
  231. *
  232. * @return string
  233. */
  234. public function getDataForEditmode($data, $object = null, $params = [])
  235. {
  236. return $this->getDataForResource($data, $object, $params);
  237. }
  238. /**
  239. * @see Data::getDataFromEditmode
  240. *
  241. * @param string $data
  242. * @param null|DataObject\Concrete $object
  243. * @param mixed $params
  244. *
  245. * @return string
  246. */
  247. public function getDataFromEditmode($data, $object = null, $params = [])
  248. {
  249. return $data;
  250. }
  251. /**
  252. * @param string|null $data
  253. *
  254. * @return array
  255. */
  256. public function resolveDependencies($data)
  257. {
  258. return Text::getDependenciesOfWysiwygText($data);
  259. }
  260. /**
  261. * {@inheritdoc}
  262. */
  263. public function getCacheTags($data, $tags = [])
  264. {
  265. return Text::getCacheTagsOfWysiwygText($data, $tags);
  266. }
  267. /**
  268. * {@inheritdoc}
  269. */
  270. public function checkValidity($data, $omitMandatoryCheck = false, $params = [])
  271. {
  272. if (!$omitMandatoryCheck && $this->getMandatory() && empty($data)) {
  273. throw new Element\ValidationException('Empty mandatory field [ '.$this->getName().' ]');
  274. }
  275. $dependencies = Text::getDependenciesOfWysiwygText($data);
  276. if (is_array($dependencies)) {
  277. foreach ($dependencies as $key => $value) {
  278. $el = Element\Service::getElementById($value['type'], $value['id']);
  279. if (!$el) {
  280. throw new Element\ValidationException('Invalid dependency in wysiwyg text');
  281. }
  282. }
  283. }
  284. }
  285. /**
  286. * @param DataObject\Concrete|DataObject\Localizedfield|DataObject\Classificationstore|DataObject\Objectbrick\Data\AbstractData|DataObject\Fieldcollection\Data\AbstractData $container
  287. * @param array $params
  288. *
  289. * @return string
  290. */
  291. public function preGetData(/** mixed */ $container, /** array */ $params = []) // : mixed
  292. {
  293. $data = '';
  294. if ($container instanceof DataObject\Concrete) {
  295. $data = $container->getObjectVar($this->getName());
  296. } elseif ($container instanceof DataObject\Localizedfield || $container instanceof DataObject\Classificationstore) {
  297. $data = $params['data'];
  298. } elseif ($container instanceof DataObject\Fieldcollection\Data\AbstractData) {
  299. $data = $container->getObjectVar($this->getName());
  300. } elseif ($container instanceof DataObject\Objectbrick\Data\AbstractData) {
  301. $data = $container->getObjectVar($this->getName());
  302. }
  303. return Text::wysiwygText($data, [
  304. 'object' => $container,
  305. 'context' => $this,
  306. ]);
  307. }
  308. /** Generates a pretty version preview (similar to getVersionPreview) can be either html or
  309. * a image URL. See the https://github.com/pimcore/object-merger bundle documentation for details
  310. *
  311. * @param string|null $data
  312. * @param DataObject\Concrete|null $object
  313. * @param mixed $params
  314. *
  315. * @return array|string
  316. */
  317. public function getDiffVersionPreview($data, $object = null, $params = [])
  318. {
  319. if ($data) {
  320. $value = [];
  321. $value['html'] = $data;
  322. $value['type'] = 'html';
  323. return $value;
  324. } else {
  325. return '';
  326. }
  327. }
  328. /**
  329. * { @inheritdoc }
  330. */
  331. public function rewriteIds(/** mixed */ $container, /** array */ $idMapping, /** array */ $params = []) /** :mixed */
  332. {
  333. $data = $this->getDataFromObjectParam($container, $params);
  334. if ($data) {
  335. $html = new DomCrawler($data);
  336. $es = $html->filter('a[pimcore_id], img[pimcore_id]');
  337. /** @var \DOMElement $el */
  338. foreach ($es as $el) {
  339. if ($el->hasAttribute('href') || $el->hasAttribute('src')) {
  340. $type = $el->getAttribute('pimcore_type');
  341. $id = (int) $el->getAttribute('pimcore_id');
  342. if ($idMapping[$type][$id] ?? false) {
  343. $el->setAttribute('pimcore_id', strtr($el->getAttribute('pimcore_id'), $idMapping[$type]));
  344. }
  345. }
  346. }
  347. $data = $html->html();
  348. $html->clear();
  349. unset($html);
  350. }
  351. return $data;
  352. }
  353. /**
  354. * {@inheritdoc}
  355. */
  356. public function isFilterable(): bool
  357. {
  358. return true;
  359. }
  360. /**
  361. * {@inheritdoc}
  362. */
  363. public function getParameterTypeDeclaration(): ?string
  364. {
  365. return '?string';
  366. }
  367. /**
  368. * {@inheritdoc}
  369. */
  370. public function getReturnTypeDeclaration(): ?string
  371. {
  372. return '?string';
  373. }
  374. /**
  375. * {@inheritdoc}
  376. */
  377. public function getPhpdocInputType(): ?string
  378. {
  379. return 'string|null';
  380. }
  381. /**
  382. * {@inheritdoc}
  383. */
  384. public function getPhpdocReturnType(): ?string
  385. {
  386. return 'string|null';
  387. }
  388. }