Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
UrlItem.php
1<?php
2
4
11use CIMMessageParamAttach;
12
13class UrlItem implements RestEntity
14{
15 protected string $url = '';
16 protected ?array $metadata = [];
17 protected static array $staticMetadataCache = [];
18 protected ?RichData $richData;
19 protected ?\CIMMessageParamAttach $urlAttach = null;
20
21 public static function getRestEntityName(): string
22 {
23 return 'url';
24 }
25
26 public function __construct(?string $url = null, bool $withFetchMetadata = true)
27 {
28 if (!empty($url))
29 {
30 $this->setUrl($url);
31 if ($this->getUrl())
32 {
33 $metadata = static::$staticMetadataCache[$this->getUrl()] ?? null;
34 if ($metadata === null && $withFetchMetadata)
35 {
36 try
37 {
38 $metadata = UrlPreview::getMetadataByUrl($this->getUrl(), true, false);
39 }
40 catch (\Exception $exception)
41 {
42 $metadata = false;
43 }
44 static::$staticMetadataCache[$this->getUrl()] = $metadata;
45 }
46
47 if ($metadata !== false && $metadata !== null)
48 {
49 $this->setMetadata($metadata);
50 }
51 }
52 }
53 }
54
55 public static function initByMetadata(array $metadata): self
56 {
57 return (new static())->setMetadata($metadata)->setUrl($metadata['URL']);
58 }
59
60 public static function initByPreviewUrlId(int $previewUrlId, bool $withHtml = true): ?self
61 {
62 if ($withHtml)
63 {
64 $metadata = UrlPreview::getMetadataAndHtmlByIds([$previewUrlId]);
65 }
66 else
67 {
68 $metadata = UrlPreview::getMetadataByIds([$previewUrlId]);
69 }
70 if ($metadata === false || !isset($metadata[$previewUrlId]))
71 {
72 return null;
73 }
74
75 return static::initByMetadata($metadata[$previewUrlId]);
76 }
77
82 public static function getUrlsFromText(?string $text): array
83 {
84 if ($text === null)
85 {
86 return [];
87 }
88
89 $textParser = static::getTextParser();
90 $text = $textParser->convertText($text);
91
92 $text = preg_replace('/-{54}.+?-{54}/s'.BX_UTF_PCRE_MODIFIER, "", $text);
93 $text = preg_replace('/\[CODE](.*?)\[\/CODE]/si'.BX_UTF_PCRE_MODIFIER, "", $text);
94
95 preg_replace_callback(
96 '/^(>>(.*)(\n)?)/mi'.BX_UTF_PCRE_MODIFIER,
97 static fn() => " XXX",
98 $text
99 );
100
101 $result = [];
102 preg_replace_callback(
103 '/\[url(=(?P<URL>[^\]]+))?](?P<TEXT>.*?)\[\/url]/i'.BX_UTF_PCRE_MODIFIER,
104 static function (array $matches) use (&$result) {
105 $link = !empty($matches['URL'])? $matches['URL']: $matches['TEXT'];
106 if (!empty($link))
107 {
108 $link = static::normalizeUrl($link);
109 if (static::isUrlValid($link))
110 {
111 $result[] = $link;
112 }
113 }
114 },
115 $text
116 );
117
118 return $result;
119 }
120
121 public static function getFirstUrlFromText(?string $text): ?string
122 {
123 return self::getUrlsFromText($text)[0] ?? null;
124 }
125
126 public static function getByMessage(Message $message): ?self
127 {
128 $firstUrl = self::getFirstUrlFromText($message->getMessage());
129
130 if ($firstUrl === null)
131 {
132 return null;
133 }
134
135 return new self($firstUrl);
136 }
137
138 public function getId(): ?int
139 {
140 if (isset($this->richData))
141 {
142 return $this->getRichData()->getId();
143 }
144
145 $metadata = $this->getMetadata();
146
147 return $metadata['ID'] ?? null;
148 }
149
150 public function toRestFormat(array $option = []): array
151 {
152 return [
153 'source' => $this->getUrl(),
154 'richData' => $this->getRichData()->toRestFormat(),
155 ];
156 }
157
158 protected static function getTextParser(): \CTextParser
159 {
160 $textParser = new \CTextParser();
161
162 $textParser->anchorType = 'bbcode';
163
164 foreach ($textParser->allow as $tag => $value)
165 {
166 $textParser->allow[$tag] = 'N';
167 }
168 $textParser->allow['HTML'] = 'Y';
169 $textParser->allow['ANCHOR'] = 'Y';
170 $textParser->allow['TEXT_ANCHOR'] = 'Y';
171
172 return $textParser;
173 }
174
175 protected static function normalizeUrl(string $url): string
176 {
177 $uri = new Uri($url);
178 if ($uri->getHost() === '')
179 {
180 $uri = new Uri(Common::getPublicDomain().$url);
181 }
182
183 return $uri->getUri();
184 }
185
186 protected static function isUrlValid(string $url): bool
187 {
188 return !(
189 !($parsedUrl = \parse_url($url))
190 || empty($parsedUrl['host'])
191 || strpos($parsedUrl['host'], '.') === false // domain without dots
192 || preg_match("/[\s]+/", $parsedUrl['host']) // spaces in the host
193 || (!empty($parsedUrl['port']) && !is_numeric($parsedUrl['port'])) // non digit port
194 );
195 }
196
197 //region Setters & getters
198
199 public function getUrl(): string
200 {
201 return $this->url;
202 }
203
204 public function setUrl(string $url): self
205 {
206 $url = static::normalizeUrl($url);
207 if (static::isUrlValid($url))
208 {
209 $this->url = $url;
210 }
211 return $this;
212 }
213
214 public function getMetadata(): array
215 {
216 return $this->metadata;
217 }
218
219 public function setMetadata(array $metadata): self
220 {
221 $this->metadata = $metadata;
222 return $this;
223 }
224
225 public function isStaticUrl(): bool
226 {
227 $metadata = $this->getMetadata();
228
229 return !empty($metadata) && ($metadata['TYPE'] == UrlMetadataTable::TYPE_STATIC);
230 }
231
232 public function isDynamicUrl(): bool
233 {
234 $metadata = $this->getMetadata();
235
236 return !empty($metadata) && ($metadata['TYPE'] == UrlMetadataTable::TYPE_DYNAMIC);
237 }
238
239 public function getRichData(): RichData
240 {
241 if (isset($this->richData))
242 {
243 return $this->richData;
244 }
245
246 $this->richData = new RichData();
247
248 $metadata = $this->getMetadata();
249
250 if (empty($metadata))
251 {
252 return $this->richData;
253 }
254
255 if ($metadata['TYPE'] === UrlMetadataTable::TYPE_STATIC)
256 {
258 }
259 elseif ($metadata['TYPE'] === UrlMetadataTable::TYPE_DYNAMIC)
260 {
261 $richData = UrlPreview::getImRich($metadata['URL'], true);
262 if ($richData === false || $richData->getType() === null)
263 {
264 $richData = $this->richData->setType(RichData::DYNAMIC_TYPE);
265 }
266 $this->setRichData($richData);
267 }
268
269 return $this->richData->setId($metadata['ID']);
270 }
271
272 public function setRichData(?RichData $richData): self
273 {
274 $this->richData = $richData;
275 return $this;
276 }
277
278 public function isRich(): bool
279 {
280 return !empty($this->metadata);
281 }
282
283 public function getUrlAttach(): ?\CIMMessageParamAttach
284 {
285 if ($this->urlAttach === null)
286 {
287 if ($this->isRich())
288 {
289 $this->urlAttach = \CIMMessageLink::formatAttach($this->getMetadata()) ?: null;
290 }
291 }
292
293 return $this->urlAttach;
294 }
295
296 public function setUrlAttach(?CIMMessageParamAttach $urlAttach): self
297 {
298 $this->urlAttach = $urlAttach;
299 return $this;
300 }
301
302 //endregion
303}
static getPublicDomain()
Definition common.php:8
static initByAttach(?\CIMMessageParamAttach $attach)
Definition RichData.php:24
setUrlAttach(?CIMMessageParamAttach $urlAttach)
Definition UrlItem.php:296
static normalizeUrl(string $url)
Definition UrlItem.php:175
toRestFormat(array $option=[])
Definition UrlItem.php:150
static initByPreviewUrlId(int $previewUrlId, bool $withHtml=true)
Definition UrlItem.php:60
setMetadata(array $metadata)
Definition UrlItem.php:219
__construct(?string $url=null, bool $withFetchMetadata=true)
Definition UrlItem.php:26
static initByMetadata(array $metadata)
Definition UrlItem.php:55
static array $staticMetadataCache
Definition UrlItem.php:17
setRichData(?RichData $richData)
Definition UrlItem.php:272
static getUrlsFromText(?string $text)
Definition UrlItem.php:82
CIMMessageParamAttach $urlAttach
Definition UrlItem.php:19
static getFirstUrlFromText(?string $text)
Definition UrlItem.php:121
static isUrlValid(string $url)
Definition UrlItem.php:186
static getByMessage(Message $message)
Definition UrlItem.php:126