1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @package ElkArte Forum |
5
|
|
|
* @copyright ElkArte Forum contributors |
6
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
7
|
|
|
* |
8
|
|
|
* @version 2.0 dev |
9
|
|
|
* |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace ElkArte; |
13
|
|
|
|
14
|
|
|
use BBC\Codes; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class IlaIntegrate |
18
|
|
|
*/ |
19
|
|
|
class IlaIntegrate |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* Register ILA hooks to the system. This is called by the Hooks class, loadIntegrations() |
23
|
|
|
* |
24
|
|
|
* Note for addon authors. All you need to do is extend $modSettings['autoload_integrate'] with |
25
|
|
|
* the "path/filename.php" of your integration (using filenameIntegrate is a nice touch but not required). |
26
|
1 |
|
* register() and settingsRegister() will both be called. You can add and remove the name based on |
27
|
|
|
* if your addon is enabled/disabled and not worry about removing hooks (they do no use permanent) |
28
|
1 |
|
* |
29
|
|
|
* @return array |
30
|
1 |
|
*/ |
31
|
|
|
public static function register() |
32
|
1 |
|
{ |
33
|
|
|
global $modSettings; |
34
|
|
|
|
35
|
|
|
if (empty($modSettings['attachment_inline_enabled'])) |
36
|
|
|
{ |
37
|
|
|
return array(); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
// $hook, $function, $file |
41
|
|
|
return array( |
42
|
|
|
array('integrate_additional_bbc', '\\ElkArte\\IlaIntegrate::integrate_additional_bbc'), |
43
|
|
|
array('integrate_post_bbc_parser', '\\ElkArte\\IlaIntegrate::integrate_post_parser') |
44
|
|
|
); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Register ACP config hooks for setting values |
49
|
|
|
* |
50
|
|
|
* @return array |
51
|
|
|
*/ |
52
|
|
|
public static function settingsRegister() |
53
|
|
|
{ |
54
|
|
|
// $hook, $function, $file |
55
|
|
|
return array( |
56
|
|
|
array('integrate_modify_attachment_settings', '\\ElkArte\\IlaIntegrate::integrate_modify_attachment_settings'), |
57
|
|
|
); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* After parse is done, we need to sub in the message id for proper lightbox navigation |
62
|
|
|
* |
63
|
|
|
* @param string $message |
64
|
|
|
*/ |
65
|
|
|
public static function integrate_post_parser(&$message) |
66
|
|
|
{ |
67
|
|
|
global $context; |
68
|
|
|
|
69
|
|
|
$lighbox_message = 'data-lightboxmessage="' . (!empty($context['id_msg']) ? $context['id_msg'] : '0') . '"'; |
70
|
|
|
$message = str_replace('data-lightboxmessage="0"', $lighbox_message, $message); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* - Adds in new BBC code tags for use with inline images |
75
|
|
|
* |
76
|
|
|
* @param mixed[] $additional_bbc |
77
|
|
|
*/ |
78
|
|
|
public static function integrate_additional_bbc(&$additional_bbc) |
79
|
|
|
{ |
80
|
|
|
global $modSettings; |
81
|
|
|
|
82
|
|
|
// Generally we don't want to render inside of these tags ... |
83
|
|
|
$disallow = array( |
84
|
|
|
'quote' => 1, |
85
|
|
|
'code' => 1, |
86
|
|
|
'nobbc' => 1, |
87
|
|
|
'html' => 1, |
88
|
|
|
'php' => 1, |
89
|
|
|
); |
90
|
|
|
|
91
|
|
|
// Why enable it to disable the tags, oh well |
92
|
|
|
$disabledBBC = empty($modSettings['disabledBBC']) ? array() : explode(',', $modSettings['disabledBBC']); |
93
|
|
|
$disableAttach = in_array('attach', $disabledBBC); |
94
|
|
|
|
95
|
|
|
// Want to see them in quotes eh? |
96
|
|
|
if (!empty($modSettings['attachment_inline_quotes'])) |
97
|
|
|
{ |
98
|
|
|
unset($disallow['quote']); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
// Add ILA codes |
102
|
|
|
$additional_bbc = array_merge($additional_bbc, array( |
103
|
|
|
// Require a width with optional height/align to allow use of full image and/or ;thumb |
104
|
|
|
array( |
105
|
|
|
Codes::ATTR_TAG => 'attach', |
106
|
|
|
Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT, |
107
|
|
|
Codes::ATTR_PARAM => array( |
108
|
|
|
'width' => array( |
109
|
|
|
Codes::PARAM_ATTR_VALIDATE => self::validate_width(), |
110
|
|
|
Codes::PARAM_ATTR_MATCH => '(\d+)', |
111
|
|
|
), |
112
|
|
|
'height' => array( |
113
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
114
|
|
|
Codes::PARAM_ATTR_VALUE => 'max-height:$1px;', |
115
|
|
|
Codes::PARAM_ATTR_MATCH => '(\d+)', |
116
|
|
|
), |
117
|
|
|
'align' => array( |
118
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
119
|
|
|
Codes::PARAM_ATTR_VALUE => 'float$1', |
120
|
|
|
Codes::PARAM_ATTR_MATCH => '(right|left|center)', |
121
|
|
|
), |
122
|
|
|
), |
123
|
|
|
Codes::ATTR_CONTENT => '<a id="link_$1" data-lightboximage="$1" data-lightboxmessage="0" href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1', 'image']) . '"><img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1{width}{height}']) . '" alt="" class="bbc_img {align}" /></a>', |
124
|
|
|
Codes::ATTR_VALIDATE => $disableAttach ? null : self::validate_options(), |
125
|
|
|
Codes::ATTR_DISALLOW_PARENTS => $disallow, |
126
|
|
|
Codes::ATTR_DISABLED_CONTENT => '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . '">(' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . ')</a>', |
127
|
|
|
Codes::ATTR_BLOCK_LEVEL => false, |
128
|
|
|
Codes::ATTR_AUTOLINK => false, |
129
|
|
|
Codes::ATTR_LENGTH => 6, |
130
|
|
|
), |
131
|
|
|
// Require a height with option width/align to allow removal of ;thumb |
132
|
|
|
array( |
133
|
|
|
Codes::ATTR_TAG => 'attach', |
134
|
|
|
Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT, |
135
|
|
|
Codes::ATTR_PARAM => array( |
136
|
|
|
'height' => array( |
137
|
|
|
Codes::PARAM_ATTR_VALIDATE => self::validate_height(), |
138
|
|
|
Codes::PARAM_ATTR_MATCH => '(\d+)', |
139
|
|
|
), |
140
|
|
|
'width' => array( |
141
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
142
|
|
|
Codes::PARAM_ATTR_VALUE => 'width:100%;max-width:$1px;', |
143
|
|
|
Codes::PARAM_ATTR_MATCH => '(\d+)', |
144
|
|
|
), |
145
|
|
|
'align' => array( |
146
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
147
|
|
|
Codes::PARAM_ATTR_VALUE => 'float$1', |
148
|
|
|
Codes::PARAM_ATTR_MATCH => '(right|left|center)', |
149
|
|
|
), |
150
|
|
|
), |
151
|
|
|
Codes::ATTR_CONTENT => '<a id="link_$1" data-lightboximage="$1" data-lightboxmessage="0" href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1', 'image']) . '"><img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1{height}{width}']) . '" alt="" class="bbc_img {align}" /></a>', |
152
|
|
|
Codes::ATTR_VALIDATE => $disableAttach ? null : self::validate_options(), |
153
|
|
|
Codes::ATTR_DISALLOW_PARENTS => $disallow, |
154
|
|
|
Codes::ATTR_DISABLED_CONTENT => '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . '">(' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . ')</a>', |
155
|
|
|
Codes::ATTR_BLOCK_LEVEL => false, |
156
|
|
|
Codes::ATTR_AUTOLINK => false, |
157
|
|
|
Codes::ATTR_LENGTH => 6, |
158
|
|
|
), |
159
|
|
|
// Just a simple attach |
160
|
|
|
array( |
161
|
|
|
Codes::ATTR_TAG => 'attach', |
162
|
|
|
Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT, |
163
|
|
|
Codes::ATTR_CONTENT => '$1', |
164
|
|
|
Codes::ATTR_VALIDATE => $disableAttach ? null : self::validate_plain(), |
165
|
|
|
Codes::ATTR_DISALLOW_PARENTS => $disallow, |
166
|
|
|
Codes::ATTR_DISABLED_CONTENT => '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . '">(' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . ')</a>', |
167
|
|
|
Codes::ATTR_BLOCK_LEVEL => false, |
168
|
|
|
Codes::ATTR_AUTOLINK => false, |
169
|
|
|
Codes::ATTR_LENGTH => 6, |
170
|
|
|
), |
171
|
|
|
// Just an align ? |
172
|
|
|
array( |
173
|
|
|
Codes::ATTR_TAG => 'attach', |
174
|
|
|
Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT, |
175
|
|
|
Codes::ATTR_PARAM => array( |
176
|
|
|
'type' => array( |
177
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
178
|
|
|
Codes::PARAM_ATTR_VALUE => ';$1', |
179
|
|
|
Codes::PARAM_ATTR_MATCH => '(thumb|image)', |
180
|
|
|
), |
181
|
|
|
'align' => array( |
182
|
|
|
Codes::PARAM_ATTR_OPTIONAL => true, |
183
|
|
|
Codes::PARAM_ATTR_VALUE => 'float$1', |
184
|
|
|
Codes::PARAM_ATTR_MATCH => '(right|left|center)', |
185
|
|
|
), |
186
|
|
|
), |
187
|
|
|
Codes::ATTR_CONTENT => '<a id="link_$1" data-lightboximage="$1" data-lightboxmessage="0" href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1', 'image']) . '"><img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1{type}']) . '" alt="X" class="bbc_img {align}" /></a>', |
188
|
|
|
Codes::ATTR_VALIDATE => $disableAttach ? null : self::validate_options(), |
189
|
|
|
Codes::ATTR_DISALLOW_PARENTS => $disallow, |
190
|
|
|
Codes::ATTR_DISABLED_CONTENT => '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . '">(' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . ')</a>', |
191
|
|
|
Codes::ATTR_BLOCK_LEVEL => false, |
192
|
|
|
Codes::ATTR_AUTOLINK => false, |
193
|
|
|
Codes::ATTR_LENGTH => 6, |
194
|
|
|
), |
195
|
|
|
// [attachurl=xx] -- no image but a link with some details |
196
|
|
|
array( |
197
|
|
|
Codes::ATTR_TAG => 'attachurl', |
198
|
|
|
Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT, |
199
|
|
|
Codes::ATTR_CONTENT => '$1', |
200
|
|
|
Codes::ATTR_VALIDATE => self::validate_url(), |
201
|
|
|
Codes::ATTR_DISALLOW_PARENTS => $disallow, |
202
|
|
|
Codes::ATTR_DISABLED_CONTENT => '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . '">(' . getUrl('action', ['action' => 'dlattach', 'attach' => '$1']) . ')</a>', |
203
|
|
|
Codes::ATTR_BLOCK_LEVEL => false, |
204
|
|
|
Codes::ATTR_AUTOLINK => false, |
205
|
|
|
Codes::ATTR_LENGTH => 9, |
206
|
|
|
), |
207
|
|
|
)); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Used when the optional width parameter is set |
212
|
|
|
* |
213
|
|
|
* - Determines the best image, full or thumbnail, based on ILA width desired |
214
|
|
|
* - Used as PARAM_ATTR_VALIDATE function |
215
|
|
|
* |
216
|
|
|
* @return callable function which will return a string |
217
|
|
|
*/ |
218
|
|
|
public static function validate_width() |
219
|
|
|
{ |
220
|
|
|
global $modSettings; |
221
|
|
|
|
222
|
|
|
return function ($data) use ($modSettings) { |
223
|
|
|
// These may look odd, and they are, but its a way to set or not ;thumb to the url |
224
|
|
|
if (!empty($modSettings['attachmentThumbWidth']) && $data <= $modSettings['attachmentThumbWidth']) |
225
|
|
|
{ |
226
|
|
|
return ';thumb" style="width:100%;max-width:' . $data . 'px;'; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
return '" style="width:100%;max-width:' . $data . 'px;'; |
230
|
|
|
}; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* For tags with options (width / height / align) |
235
|
|
|
* |
236
|
|
|
* - Keeps track of attachment usage to prevent displaying below the post |
237
|
|
|
* |
238
|
|
|
* @return callable |
239
|
|
|
*/ |
240
|
|
|
public static function validate_options() |
241
|
|
|
{ |
242
|
|
|
global $context; |
243
|
|
|
|
244
|
|
|
return function (&$data) use (&$context) { |
245
|
|
|
// Not a preview, then sanitize the attach id |
246
|
|
|
if (strpos($data, 'post_tmp_' . User::$info->id . '_') === false) |
247
|
|
|
{ |
248
|
|
|
$data = (int) $data; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
$context['ila_dont_show_attach_below'][] = $data; |
252
|
|
|
$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']); |
253
|
|
|
}; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Used when the optional height parameter is set and no width is set |
258
|
|
|
* |
259
|
|
|
* - Determines the best image, full or thumbnail, based on desired ILA height |
260
|
|
|
* - Used as PARAM_ATTR_VALIDATE function |
261
|
|
|
* |
262
|
|
|
* @return callable which will return a string |
263
|
|
|
*/ |
264
|
|
|
public static function validate_height() |
265
|
|
|
{ |
266
|
|
|
global $modSettings; |
267
|
|
|
|
268
|
|
|
return function ($data) use ($modSettings) { |
269
|
|
|
// These may look odd, and they are, but its a way to set or not ;thumb to the url |
270
|
|
|
if (!empty($modSettings['attachmentThumbHeight']) && $data <= $modSettings['attachmentThumbHeight']) |
271
|
|
|
{ |
272
|
|
|
return ';thumb" style="max-height:' . $data . 'px;'; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
return '" style="max-height:' . $data . 'px;'; |
276
|
|
|
}; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* This provides for some control for "plain" tags |
281
|
|
|
* |
282
|
|
|
* - Determines if the ILA is an image or not |
283
|
|
|
* - Sets the lightbox attributes if an image is identified |
284
|
|
|
* - Keeps track of attachment usage to prevent displaying below the post |
285
|
|
|
* |
286
|
|
|
* @return callable |
287
|
|
|
*/ |
288
|
|
|
public static function validate_plain() |
289
|
|
|
{ |
290
|
|
|
global $context, $modSettings; |
291
|
|
|
|
292
|
|
|
return function (&$data, $disabled) use (&$context, $modSettings) { |
293
|
|
|
if (isset($disabled['attach'])) |
294
|
|
|
{ |
295
|
|
|
return $data; |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
$num = $data; |
299
|
|
|
$is_image = array(); |
300
|
|
|
$preview = strpos($data, 'post_tmp_' . User::$info->id . '_'); |
301
|
|
|
|
302
|
|
|
// Not a preview, then sanitize the attach id and determine the actual type |
303
|
|
|
if ($preview === false) |
304
|
|
|
{ |
305
|
|
|
require_once(SUBSDIR . '/Attachments.subs.php'); |
306
|
|
|
|
307
|
|
|
$num = (int) $data; |
308
|
|
|
$is_image = isAttachmentImage($num); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
// An image will get the light box treatment |
312
|
|
|
if (!empty($is_image['is_image']) || $preview !== false) |
313
|
|
|
{ |
314
|
|
|
$type = !empty($modSettings['attachmentThumbnails']) ? ';thumb' : ''; |
315
|
|
|
$data = '<a id="link_' . $num . '" data-lightboximage="' . $num . '" data-lightboxmessage="0" href="' . getUrl('action', ['action' => 'dlattach', 'attach' => $num, 'image']) . '"><img src="' . getUrl('action', ['action' => 'dlattach', 'attach' => $num . $type]) . '" alt="" class="bbc_img" /></a>'; |
316
|
|
|
} |
317
|
|
|
else |
318
|
|
|
{ |
319
|
|
|
// Not an image, determine a mime or use a default thumbnail |
320
|
|
|
$check = returnMimeThumb(($is_image['fileext'] ?? ''), true); |
321
|
|
|
|
322
|
|
|
if ($is_image === false) |
323
|
|
|
{ |
324
|
|
|
$data = '<img src="' . $check . '" alt="X" class="bbc_img" />'; |
325
|
|
|
} |
326
|
|
|
else |
327
|
|
|
{ |
328
|
|
|
$data = '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => $num]) . '"><img src="' . $check . '" alt="' . $is_image['filename'] . '" class="bbc_img" /></a>'; |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
$context['ila_dont_show_attach_below'][] = $num; |
333
|
|
|
$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']); |
334
|
|
|
}; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** |
338
|
|
|
* This is prevents a little repetition and provides a some control for "plain" tags |
339
|
|
|
* |
340
|
|
|
* - Determines if the ILA is an image or not |
341
|
|
|
* - Keeps track of attachment usage to prevent displaying below the post |
342
|
|
|
* |
343
|
|
|
* @return callable |
344
|
|
|
*/ |
345
|
|
|
public static function validate_url() |
346
|
|
|
{ |
347
|
|
|
global $context; |
348
|
|
|
|
349
|
|
|
return function (&$data, $disabled) use (&$context) { |
350
|
|
|
if (isset($disabled['attach'])) |
351
|
|
|
{ |
352
|
|
|
return $data; |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
$num = $data; |
356
|
|
|
$attachment = false; |
357
|
|
|
|
358
|
|
|
// Not a preview, then sanitize the attach id and determine the details |
359
|
|
|
if (strpos($data, 'post_tmp_' . User::$info->id . '_') === false) |
360
|
|
|
{ |
361
|
|
|
require_once(SUBSDIR . '/Attachments.subs.php'); |
362
|
|
|
|
363
|
|
|
$num = (int) $data; |
364
|
|
|
$attachment = isAttachmentImage($num); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
// If we got the details ... |
368
|
|
|
if ($attachment) |
369
|
|
|
{ |
370
|
|
|
$data = '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => $num]) . '"> |
371
|
|
|
<i class="icon icon-small i-paperclip"></i> ' . $attachment['filename'] . ' |
372
|
|
|
</a> (' . $attachment['size'] . ($attachment['is_image'] ? ' ' . $attachment['width'] . 'x' . $attachment['height'] : '') . ')'; |
373
|
|
|
} |
374
|
|
|
else |
375
|
|
|
{ |
376
|
|
|
$data = '<a href="' . getUrl('action', ['action' => 'dlattach', 'attach' => $num]) . '"> |
377
|
|
|
<i class="icon icon-small i-paperclip"></i> ' . $num . ' |
378
|
|
|
</a>'; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
$context['ila_dont_show_attach_below'][] = $num; |
382
|
|
|
$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']); |
383
|
|
|
}; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Settings hook for the admin panel |
388
|
|
|
* |
389
|
|
|
* What it does: |
390
|
|
|
* |
391
|
|
|
* - Defines our settings array and uses our settings class to manage the data |
392
|
|
|
* |
393
|
|
|
* @param array $config_vars |
394
|
|
|
*/ |
395
|
|
|
public static function integrate_modify_attachment_settings(&$config_vars) |
396
|
|
|
{ |
397
|
|
|
$config_vars[] = array('title', 'attachment_inline_title'); |
398
|
|
|
$config_vars[] = array('check', 'attachment_inline_enabled'); |
399
|
|
|
$config_vars[] = array('check', 'attachment_inline_quotes'); |
400
|
|
|
} |
401
|
|
|
} |
402
|
|
|
|