PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / views / media / tmpl / modal.php
vikappointments / admin / views / media / tmpl Last commit date
default.php 2 days ago index.html 2 days ago modal.php 2 days ago
modal.php
542 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 JHtml::fetch('bootstrap.tooltip', '.hasTooltip');
15 JHtml::fetch('vaphtml.assets.fontawesome');
16
17 if ($this->firstConfig)
18 {
19 JHtml::fetch('vaphtml.assets.toast', 'bottom-center', '.vap-media-modal');
20 JText::script('VAPMEDIAFIRSTCONFIG');
21 }
22
23 $files = $this->rows;
24 $selected = $this->selected;
25 $multiple = $this->multiple;
26
27 $vik = VAPApplication::getInstance();
28
29 $model = $this->getModel();
30
31 ?>
32
33 <div class="vap-media-modal">
34
35 <div class="vap-media-grid-box">
36
37 <div class="btn-toolbar" style="height: 32px;">
38
39 <div class="btn-group pull-left input-append hide-with-size-320">
40 <input type="text" id="mediakeysearch" size="32" value="" placeholder="<?php echo JText::translate('JSEARCH_FILTER_SUBMIT'); ?>" autocomplete="off" />
41
42 <button type="button" class="btn" onclick="jQuery('#mediakeysearch').trigger('change');">
43 <i class="fas fa-search"></i>
44 </button>
45 </div>
46
47 <div class="btn-group pull-left hide-with-size-390">
48 <button type="button" class="btn" onclick="jQuery('#mediakeysearch').val('').trigger('change');"><?php echo JText::translate('JSEARCH_FILTER_CLEAR'); ?></button>
49 </div>
50
51 </div>
52
53 <?php
54 $attrs = array();
55 $attrs['id'] = 'no-media-results-alert';
56
57 if ($files)
58 {
59 $attrs['style'] = 'display:none;';
60 }
61
62 echo $vik->alert(JText::translate('JGLOBAL_NO_MATCHING_RESULTS'), 'warning', false, $attrs);
63 ?>
64
65 <div class="vap-media-gallery">
66
67 <?php
68 foreach ($files as $media)
69 {
70 ?>
71 <div class="vap-media-block"
72 data-name="<?php echo $this->escape($media['name']); ?>"
73 data-ext="<?php echo $this->escape($media['file_ext']); ?>"
74 data-size="<?php echo $this->escape($media['size']); ?>"
75 data-date="<?php echo $this->escape($media['creation']); ?>"
76 data-width="<?php echo $this->escape(isset($media['width']) ? $media['width'] : ''); ?>"
77 data-height="<?php echo $this->escape(isset($media['height']) ? $media['height'] : ''); ?>"
78 data-selected="<?php echo in_array($media['name'], $selected) ? 1 : 0; ?>"
79 >
80 <div class="media-preview">
81 <div class="media-thumbnail">
82 <div class="media-centered">
83 <?php
84 // render media by using model
85 echo $model->renderMedia($media);
86 ?>
87 </div>
88 </div>
89 </div>
90 </div>
91 <?php
92 }
93 ?>
94
95 </div>
96 </div>
97
98 <div class="vap-media-sidebar">
99
100 <div class="vap-media-droptarget" id="media-upload-box">
101 <p class="icon">
102 <i class="fas fa-upload" style="font-size: 48px;"></i>
103 </p>
104
105 <div class="lead">
106 <a href="javascript:void(0)" id="media-upload-file"><?php echo JText::translate('VAPMANUALUPLOAD'); ?></a>&nbsp;<?php echo JText::translate('VAPMEDIADRAGDROP'); ?>
107 </div>
108
109 <p class="maxsize">
110 <?php echo JText::sprintf('JGLOBAL_MAXIMUM_UPLOAD_SIZE_LIMIT', JHtml::fetch('vikappointments.maxuploadsize')); ?>
111 </p>
112
113 <input type="file" id="media-legacy-upload" multiple style="display: none;" />
114 </div>
115
116 <div class="vap-media-inspector">
117
118 <div class="inspector-title">
119 <span><?php echo JText::translate('VAPMANAGEMEDIATITLE1'); ?></span>
120 <a href="javascript:void(0)" id="clear-media-selection">
121 <i class="far fa-window-close"></i>
122 </a>
123 </div>
124
125 <div class="selected-media-pool">
126
127 <div class="media-info-box" data-name="">
128 <div class="media-thumbnail media-thumbnail-image">
129 <a href="#" target="_blank">
130 <img src="" />
131 </a>
132 </div>
133
134 <div class="media-details">
135 <div class="filename"></div>
136 <div class="uploaded"></div>
137 <div class="file-size"></div>
138 <div class="dimensions"></div>
139
140 <a href="javascript:void(0)" class="delete-media-image" onclick="vapDeleteMediaFile(this);"><?php echo JText::translate('VAP_DELETE_PERMANENTLY'); ?></a>
141 </div>
142 </div>
143
144 </div>
145
146 </div>
147
148 </div>
149
150 </div>
151
152 <?php
153 JText::script('VAP_DEF_N_SELECTED');
154 JText::script('VAP_DEF_N_SELECTED_1');
155 JText::script('VAP_DEF_N_SELECTED_0');
156 JText::script('VAPSYSTEMCONFIRMATIONMSG');
157 ?>
158
159 <script type="text/javascript">
160
161 if (!window.parent.hasOwnProperty('VAP_TMP_FILES')) {
162 window.parent.VAP_TMP_FILES = [];
163 }
164
165 vapShowMediaInspector();
166
167 jQuery(function() {
168
169 jQuery('.vap-media-block').on('click', vapHandleMediaClick);
170
171 jQuery('#mediakeysearch').on('change', function() {
172
173 var search = jQuery(this).val().toLowerCase();
174
175 var at_least_one = false;
176
177 jQuery('.vap-media-block').each(function() {
178
179 if (!search.length || vapMatchingMediaBox(this, search)) {
180 jQuery(this).show();
181 at_least_one = true;
182 } else {
183 jQuery(this).hide();
184 }
185
186 });
187
188 if (at_least_one) {
189 jQuery('#no-media-results-alert').hide();
190 } else {
191 jQuery('#no-media-results-alert').show();
192 }
193
194 });
195
196 jQuery('#clear-media-selection').on('click', function() {
197 // clear all selected media
198 jQuery('.vap-media-block[data-selected="1"]').trigger('click');
199 });
200
201 });
202
203 function vapHandleMediaClick() {
204 var checked = parseInt(jQuery(this).attr('data-selected')) ? 0 : 1;
205
206 <?php
207 if (!$multiple)
208 {
209 ?>
210 if (checked) {
211 jQuery('.vap-media-block[data-selected="1"]').each(function() {
212 jQuery(this).attr('data-selected', 0);
213 });
214 }
215
216 window.parent.VAP_TMP_FILES = [];
217 <?php
218 }
219 ?>
220
221 jQuery(this).attr('data-selected', checked);
222
223 var file = jQuery(this).data('name');
224 var index = window.parent.VAP_TMP_FILES.indexOf(file);
225
226 if (checked && index === -1) {
227 // add file to list
228 window.parent.VAP_TMP_FILES.push(file);
229 }
230
231 if (!checked && index !== -1) {
232 // remove file from list
233 window.parent.VAP_TMP_FILES.splice(index, 1);
234 }
235
236 if (window.parent.VAP_TMP_FILES.length) {
237 vapShowMediaInspector();
238 } else {
239 vapHideMediaInspector();
240 }
241 }
242
243 function vapMatchingMediaBox(box, search) {
244 // search by media name
245 var media_name = jQuery(box).data('name').trim().toLowerCase();
246
247 if (media_name.indexOf(search) !== -1) {
248 return true;
249 }
250
251 return false;
252 }
253
254 // inspector
255
256 jQuery(function() {
257 /**
258 * Assign the transition animations 32 ms after the page loading.
259 * Hack for Safari, which seems to apply the transition also
260 * for the initial state of the inspector, causing an unwanted
261 * animation when the page loads.
262 */
263 setTimeout(function() {
264 jQuery('.vap-media-inspector').css('transition', '0.4s ease-out all');
265 jQuery('.vap-media-inspector').css('-moz-transition', '0.4s ease-out all');
266 jQuery('.vap-media-inspector').css('-webkit-transition', '0.4s ease-out all');
267 }, 32);
268 });
269
270 function vapShowMediaInspector() {
271 var inspector = jQuery('.vap-media-inspector');
272 if (!inspector.hasClass('slide-in')) {
273 jQuery('.vap-media-inspector').addClass('slide-in');
274 }
275
276 // directly use the list of temporary file
277 var list = window.parent.VAP_TMP_FILES;
278
279 // filter the list and remove all the files that doesn't exist
280 list = list.filter(function(file) {
281 return jQuery('.vap-media-block[data-name="' + file + '"]').length ? true : false
282 });
283
284 // update reference as certain images might have been deleted
285 window.parent.VAP_TMP_FILES = list;
286
287 if (list.length == 0) {
288 // hide media inspector because, even if the selection pool owned some files,
289 // all them didn't exist and were removed to avoid unexpected behaviors
290 vapHideMediaInspector();
291 }
292
293 <?php
294 if ($multiple)
295 {
296 ?>
297 // remove all except for first media box
298 jQuery('.vap-media-inspector .media-info-box:not(:first-child)').remove();
299
300 for (var i = 0; i < list.length; i++) {
301 if (i > 0) {
302 var clone = jQuery('.vap-media-inspector .media-info-box').last().clone();
303 jQuery('.selected-media-pool').append(clone);
304 }
305
306 vapFillInspectorMediaInfo(list[i]);
307 }
308 <?php
309 }
310 else
311 {
312 ?>
313 vapFillInspectorMediaInfo(list[0]);
314 <?php
315 }
316 ?>
317
318 jQuery('.vap-media-inspector .media-info-box').show();
319 }
320
321 function vapFillInspectorMediaInfo(filename) {
322 var media = jQuery('.vap-media-block[data-name="' + filename + '"]');
323
324 var mediaUrl = media.find('*[src],*[data-src]');
325 mediaUrl = mediaUrl.attr('src') || mediaUrl.data('src');
326
327 var box = jQuery('.vap-media-inspector .media-info-box').last();
328
329 box.attr('data-name', media.data('name'))
330 .find('.media-thumbnail-image a')
331 .attr('href', mediaUrl)
332 .html(media.find('.media-centered').html());
333
334 box.find('.media-details .filename').text(media.data('name'));
335 box.find('.media-details .uploaded').text(media.data('date'));
336 box.find('.media-details .file-size').text(media.data('size'));
337
338 if (media.data('width')) {
339 box.find('.media-details .dimensions').text(media.data('width') + 'x' + media.data('height') + ' pixel').show();
340 } else {
341 box.find('.media-details .dimensions').hide();
342 }
343 }
344
345 function vapHideMediaInspector() {
346 jQuery('.vap-media-inspector .media-info-box').hide();
347 jQuery('.vap-media-inspector').removeClass('slide-in');
348 }
349
350 function vapDeleteMediaFile(link) {
351 // double confirm
352 var r = confirm(Joomla.JText._('VAPSYSTEMCONFIRMATIONMSG'));
353
354 if (!r) {
355 return false;
356 }
357
358 // find media name
359 var media = jQuery(link).closest('.media-info-box').attr('data-name');
360
361 // delete media
362 UIAjax.do(
363 'index.php?option=com_vikappointments&task=media.delete&ajax=1',
364 {
365 cid: [media],
366 path: '<?php echo base64_encode($this->path); ?>',
367 }
368 );
369
370 // toggle media selection and then remove it
371 jQuery('.vap-media-block[data-name="' + media + '"]').trigger('click').remove();
372 }
373
374 // files upload
375
376 jQuery(function() {
377
378 var dragCounter = 0;
379
380 // drag&drop actions on target div
381
382 jQuery('#media-upload-box.vap-media-droptarget').on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
383 e.preventDefault();
384 e.stopPropagation();
385 });
386
387 jQuery('#media-upload-box.vap-media-droptarget').on('dragenter', function(e) {
388 // increase the drag counter because we may
389 // enter into a child element
390 dragCounter++;
391
392 jQuery(this).addClass('drag-enter');
393 });
394
395 jQuery('#media-upload-box.vap-media-droptarget').on('dragleave', function(e) {
396 // decrease the drag counter to check if we
397 // left the main container
398 dragCounter--;
399
400 if (dragCounter <= 0) {
401 jQuery(this).removeClass('drag-enter');
402 }
403 });
404
405 jQuery('#media-upload-box.vap-media-droptarget').on('drop', function(e) {
406
407 jQuery(this).removeClass('drag-enter');
408
409 var files = e.originalEvent.dataTransfer.files;
410
411 vapDispatchMediaUploads(files);
412
413 });
414
415 jQuery('#media-upload-box.vap-media-droptarget #media-upload-file').on('click', function() {
416 jQuery('input#media-legacy-upload').val(null).trigger('click');
417 });
418
419 jQuery('input#media-legacy-upload').on('change', function() {
420 vapDispatchMediaUploads(jQuery(this)[0].files);
421 });
422
423 });
424
425 // upload
426
427 function vapDispatchMediaUploads(files) {
428 for (var i = 0; i < files.length; i++) {
429 var status = new UploadingMediaFile();
430 status.setFileName(files[i].name);
431 status.setProgress(0);
432
433 jQuery('.vap-media-gallery').prepend(status.getHtml());
434
435 vapMediaFileUploadThread(status, files[i]);
436 }
437 }
438
439 function UploadingMediaFile() {
440 // create parent
441 this.fileBlock = jQuery('<div class="vap-media-block" data-name="" data-selected="0"></div>');
442
443 // create media thumbnail
444 this.fileThumb = jQuery('<div class="media-preview"><div class="media-thumbnail"><div class="media-centered"><i class="fas fa-file-image"></i></div></div></div>').appendTo(this.fileBlock);
445
446 this.setFileName = function(name) {
447 this.fileBlock.attr('data-name', name);
448 }
449
450 this.setProgress = function(progress) {
451 var opacity = parseFloat(progress / 100);
452
453 this.fileThumb.find('i.fas').css('opacity', opacity);
454 }
455
456 this.complete = function(file) {
457 this.setProgress(100);
458
459 this.fileBlock.attr('data-name', file.name);
460 this.fileBlock.attr('data-ext', file.file_ext);
461 this.fileBlock.attr('data-size', file.size);
462 this.fileBlock.attr('data-date', file.creation);
463 this.fileBlock.attr('data-width', file.width);
464 this.fileBlock.attr('data-height', file.height);
465
466 // append file preview
467 this.fileThumb.find('.media-centered').html(file.html);
468 }
469
470 this.getHtml = function() {
471 return this.fileBlock;
472 }
473 }
474
475 function vapMediaFileUploadThread(status, file) {
476 jQuery.noConflict();
477
478 var formData = new FormData();
479 formData.append('file', file);
480 formData.append('path', '<?php echo base64_encode($this->path); ?>');
481
482 UIAjax.upload(
483 // end-point URL
484 'index.php?option=com_vikappointments&task=media.dropupload',
485 // file post data
486 formData,
487 // success callback
488 function(resp) {
489 // finalize upload
490 status.complete(resp);
491
492 // register click event and trigger it for media auto-selection
493 jQuery(status.fileBlock).on('click', vapHandleMediaClick).trigger('click');
494
495 // refresh search after uploading the image
496 jQuery('#mediakeysearch').trigger('change');
497 },
498 // failure callback
499 function(error) {
500 // raise alert
501 alert(error.responseText);
502
503 // remove file from gallery
504 jQuery('.vap-media-block[data-name="' + file.name + '"]').remove();
505 },
506 // progress callback
507 function(progress) {
508 // update progress
509 status.setProgress(progress);
510 }
511 );
512 }
513
514 <?php
515 /**
516 * Display a toast message to inform the administrator
517 * that it is recommended to set up the media configuration
518 * before uploading the images for the first time.
519 */
520 if ($this->firstConfig)
521 {
522 ?>
523 jQuery(function() {
524 // display toast message with a delay of 256 ms
525 setTimeout(function() {
526 ToastMessage.dispatch({
527 text: Joomla.JText._('VAPMEDIAFIRSTCONFIG'),
528 status: 2,
529 delay: 15000,
530 action: function() {
531 // open new media view in a blank page
532 window.open('index.php?option=com_vikappointments&task=media.add&configure=1', '_blank');
533 },
534 });
535 }, 256);
536 });
537 <?php
538 }
539 ?>
540
541 </script>
542