HEX
Server: LiteSpeed
System: Linux s166.bitcommand.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64
User: h340499 (1922)
PHP: 8.2.16
Disabled: exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Upload Files
File: /home/h340499/public_html/wp-content/plugins/tp-portfolio/assets/js/admin-meta-box.js
/**
 * Meta Box Field Handlers
 * Manages image uploads, video uploads, file uploads, repeater fields, and color picker
 */

'use strict';

jQuery(function ($) {
	// Cache DOM elements and variables
	var $document = $(document);
	var $body = $('body');
	var frame;
	var videoDialogInstance;

	// ========================================
	// 1. PORTFOLIO TYPE TOGGLE
	// ========================================
	function initPortfolioToggle() {
		var $typeBoxes = $('div[class*="portfolio_type_"]').hide();
		var $selectPortfolio = $('#selectPortfolio');

		if ($selectPortfolio.length) {
			$selectPortfolio.on('change', function () {
				$typeBoxes.hide();
				$('.' + $(this).val()).show();
			}).trigger('change');
		}
	}

	// ========================================
	// 2. IMAGE-VIDEO DIALOG INITIALIZATION
	// ========================================
	function initVideoDialog() {
		var $dialogElement = $('#dialog-k');
		if (!$dialogElement.length) {
			return;
		}

		var portfolio_add = false;
		var edit_li;
		var edit_data;

		// Initialize dialog instance
		videoDialogInstance = $dialogElement.dialog({
			autoOpen: false,
			height: 'auto',
			width: 'auto',
			modal: true,
			buttons: {
				'Add': function () {
					handleVideoAdd($(this));
				},
				'Close': function () {
					$(this).dialog('close');
				}
			},
			dialogClass: 'portfolio-dialog'
		});

		function handleVideoAdd($dialog) {
			var ids = $('#thim-video-data-k').val().trim();
			var type = $('#thim-video-type-k').val();
			var $uploadButton = $('.thim-video-advanced-upload-k');
			var $imageList = $uploadButton.siblings('.thim-images-video');

			if (!ids.length) {
				return;
			}

			var xids = type === 'vimeo' ? 'v.' + ids : 'y.' + ids;
			var datav = generateVideoHtml(ids, type);

			if (!portfolio_add) {
				// Edit mode - update existing item
				edit_li.empty().html(
					'<li id="item_' + xids + '">' + datav +
					'<div class="thim-image-bar">' +
					'<a title="Edit" class="thim-edit-file-k" href="#" target="_blank">Edit</a> | ' +
					'<a title="Delete" class="thim-delete-file-k" href="#" data-attachment_id="' + xids + '">×</a>' +
					'</div></li>'
				);
			} else {
				// Add mode - append new item
				$imageList.removeClass('hidden').append(
					'<li id="item_' + xids + '">' + datav +
					'<div class="thim-image-bar">' +
					'<a title="Edit" class="thim-edit-file-k" href="#" target="_blank">Edit</a> | ' +
					'<a title="Delete" class="thim-delete-file-k" href="#" data-attachment_id="' + xids + '">×</a>' +
					'</div></li>'
				);
			}

			$('#thim-video-data-k').val('');
			$dialog.dialog('close');
		}

		function generateVideoHtml(ids, type) {
			if (type === 'vimeo') {
				return '<iframe src="https://player.vimeo.com/video/' + ids + '?title=0&byline=0&portrait=0&color=ffffff" width="150" height="150" frameborder="0"></iframe>';
			}
			return '<iframe title="YouTube video player" class="youtube-player" type="text/html" width="150" height="150" src="https://www.youtube.com/embed/' + ids + '" frameborder="0"></iframe>';
		}

		// Edit video handler
		$body.on('click', '.thim-edit-file-k', function (e) {
			e.preventDefault();
			edit_li = $(this).closest('li');
			var itemId = edit_li.attr('id');
			edit_data = itemId.replace('item_', '');

			var videoId = edit_data.substring(2); // Remove v. or y. prefix
			var videoType = edit_data.substring(0, 2) === 'v.' ? 'vimeo' : 'youtube';

			$('#thim-video-type-k').val(videoType);
			$('#thim-video-data-k').val(videoId);
			$('.portfolio-dialog .ui-button-text:contains(Add)').text('Save');

			portfolio_add = false;
			videoDialogInstance.dialog('open');
		});

		// Add video handler
		$body.on('click', '.thim-video-advanced-upload-k', function (e) {
			e.preventDefault();
			$('.portfolio-dialog .ui-button-text:contains(Save)').text('Add');
			$('#thim-video-type-k').val('youtube');
			$('#thim-video-data-k').val('');

			portfolio_add = true;
			videoDialogInstance.dialog('open');
		});
	}
	// ========================================
	// 3. IMAGE-VIDEO FIELD HANDLERS
	// ========================================
	function initImageVideoField() {
		// Upload images to image-video field
		$body.on('click', '.thim-image-video-advanced-upload', function (e) {
			e.preventDefault();

			var $uploadButton = $(this);
			var $imageList = $uploadButton.siblings('.thim-images-video');
			var maxFileUploads = parseInt($imageList.data('max_file_uploads')) || 0;

			if (!frame) {
				frame = wp.media({
					className: 'media-frame thim-media-frame',
					multiple: true,
					title: 'Select Image',
					library: {
						type: 'image'
					}
				});
			}

			frame.off('select');
			frame.on('select', function () {
				handleImageVideoSelection($uploadButton, $imageList, maxFileUploads);
			});

			frame.open();
		});

		function handleImageVideoSelection($uploadButton, $imageList, maxFileUploads) {
			var selection = frame.state().get('selection').toJSON();
			var uploaded = $imageList.children().length;

			if (maxFileUploads > 0 && (uploaded + selection.length) > maxFileUploads) {
				if (uploaded < maxFileUploads) {
					selection = selection.slice(0, maxFileUploads - uploaded);
				}
				alert('You may only upload maximum ' + maxFileUploads + ' files');
			}

			var ids = _.pluck(selection, 'id');

			if (ids.length > 0) {
				var data = {
					action: 'thim_attach_image_video',
					post_id: $('#post_ID').val(),
					field_id: $imageList.data('field_id'),
					attachment_ids: ids,
					_ajax_nonce: $uploadButton.data('attach_media_nonce')
				};

				$.post(ajaxurl, data, function (r) {
					if (r.success) {
						$imageList.append(r.data);
					}
				}, 'json');
			}
		}

		// Reorder image-video
		$('.thim-images-video').each(function () {
			var $this = $(this);
			var data = {
				action: 'thim_reorder_image_video',
				_ajax_nonce: $this.data('reorder_nonce'),
				post_id: $('#post_ID').val(),
				field_id: $this.data('field_id')
			};

			$this.sortable({
				placeholder: 'ui-state-highlight',
				items: 'li',
				update: function () {
					data.order = $this.sortable('serialize');
					$.post(ajaxurl, data);
				}
			});
		});

		// Delete image-video
		$('.thim-image-video-uploaded').on('click', '.thim-delete-file-k', function () {
			var $this = $(this);
			var $parent = $this.closest('li');
			var $container = $this.closest('.thim-image-video-uploaded');

			var data = {
				action: 'thim_delete_image_video',
				_ajax_nonce: $container.data('delete_nonce'),
				post_id: $('#post_ID').val(),
				field_id: $container.data('field_id'),
				attachment_id: $this.data('attachment_id'),
				force_delete: $container.data('force_delete')
			};

			$.post(ajaxurl, data, function (r) {
				if (!r.success) {
					alert(r.data);
					return;
				}

				$parent.addClass('removed');

				// Handle removal with transition
				if (!('ontransitionend' in window) && ('onwebkittransitionend' in window)) {
					$parent.remove();
					$container.trigger('update.thimFile');
				}

				$('.thim-image-video-uploaded').on('transitionend webkitTransitionEnd otransitionend', 'li.removed', function () {
					$(this).remove();
					$container.trigger('update.thimFile');
				});
			}, 'json');

			return false;
		});
	}

	// ========================================
	// 4. IMAGE FIELD HANDLERS
	// ========================================
	function initImageField() {
		// Upload images
		$body.on('click', '.thim-image-advanced-upload', function (e) {
			e.preventDefault();

			var $uploadButton = $(this);
			var $imageList = $uploadButton.siblings('.thim-images');
			var maxFileUploads = parseInt($imageList.data('max_file_uploads')) || 0;

			if (!frame) {
				frame = wp.media({
					className: 'media-frame thim-media-frame',
					multiple: true,
					title: 'Select Image',
					library: {
						type: 'image'
					}
				});
			}

			frame.off('select');
			frame.on('select', function () {
				handleImageSelection($uploadButton, $imageList, maxFileUploads);
			});

			frame.open();
		});

		function handleImageSelection($uploadButton, $imageList, maxFileUploads) {
			var selection = frame.state().get('selection').toJSON();
			var uploaded = $imageList.children().length;

			if (maxFileUploads > 0 && (uploaded + selection.length) > maxFileUploads) {
				if (uploaded < maxFileUploads) {
					selection = selection.slice(0, maxFileUploads - uploaded);
				}
				alert('You may only upload maximum ' + maxFileUploads + ' files');
			}

			// Filter out duplicates
			selection = _.filter(selection, function (attachment) {
				return $imageList.children('li#item_' + attachment.id).length === 0;
			});

			var ids = _.pluck(selection, 'id');

			if (ids.length > 0) {
				var data = {
					action: 'thim_attach_media',
					post_id: $('#post_ID').val(),
					field_id: $imageList.data('field_id'),
					attachment_ids: ids,
					_ajax_nonce: $uploadButton.data('attach_media_nonce')
				};

				$.post(ajaxurl, data, function (r) {
					if (r.success) {
						$imageList.append(r.data);
					}
				}, 'json');
			}
		}

		// Reorder images
		$('.thim-images').each(function () {
			var $this = $(this);
			var data = {
				action: 'thim_reorder_images',
				_ajax_nonce: $this.data('reorder_nonce'),
				post_id: $('#post_ID').val(),
				field_id: $this.data('field_id')
			};

			$this.sortable({
				placeholder: 'ui-state-highlight',
				items: 'li',
				update: function () {
					data.order = $this.sortable('serialize');
					$.post(ajaxurl, data);
				}
			});
		});

		// Delete image
		$('.thim-images').on('click', '.thim-delete-file', function () {
			var $this = $(this);
			var $parent = $this.closest('li');
			var $container = $this.closest('.thim-images');

			var data = {
				action: 'thim_delete_file',
				_ajax_nonce: $container.data('delete_nonce'),
				post_id: $('#post_ID').val(),
				field_id: $container.data('field_id'),
				attachment_id: $this.data('attachment_id'),
				force_delete: $container.data('force_delete')
			};

			$.post(ajaxurl, data, function (r) {
				if (!r.success) {
					alert(r.data);
					return;
				}

				$parent.addClass('removed');

				// Handle removal with transition
				if (!('ontransitionend' in window) && ('onwebkittransitionend' in window)) {
					$parent.remove();
					$container.trigger('update.rwmbFile');
				}

				$('.thim-uploaded').on('transitionend webkitTransitionEnd otransitionend', 'li.removed', function () {
					$(this).remove();
					$container.trigger('update.rwmbFile');
				});
			}, 'json');

			return false;
		});
	}

	// ========================================
	// 5. FILE UPLOAD HANDLERS
	// ========================================
	function initFileUpload() {
		var file_frame;

		// Open file uploader
		$body.on('click', '[id$="_button"].button', function (e) {
			if (!$(this).hasClass('portfolio_file_upload_button') && !$(this).closest('.file-preview').length) {
				return;
			}

			e.preventDefault();

			var $button = $(this);
			var fieldId = $button.attr('id').replace(/_button$/, '');

			if (file_frame) {
				file_frame.open();
				return;
			}

			file_frame = wp.media.frames.file_frame = wp.media({
				title: 'Select a File',
				button: {
					text: 'Use this file',
				},
				multiple: false
			});

			file_frame.on('select', function () {
				var attachment = file_frame.state().get('selection').first().toJSON();

				if (attachment.mime === 'application/pdf') {
					$('#' + fieldId + '_name').val(attachment.filename);
					$('#' + fieldId + '_url').val(attachment.url);
				} else {
					alert('Please select a PDF file.');
				}
			});

			file_frame.open();
		});

		// Delete uploaded file
		$body.on('click', '.portfolio_file_delete_button', function () {
			var $preview = $(this).closest('.file-preview');
			$preview.find('[id$="_name"]').val('');
			$preview.find('[id$="_url"]').val('');
			$(this).hide();
			$preview.find('a[target="_blank"]').closest('p').hide();
		});
	}

	// ========================================
	// 6. REPEATER FIELD HANDLERS
	// ========================================
	function initRepeater() {
		// Add repeater item
		$document.on('click', '[id^="add-"]', function () {
			var fieldId = $(this).attr('id').replace(/^add-/, '');
			var $wrapper = $('#portfolio-repeater-wrapper, #' + fieldId + '-wrapper').first();

			if (!$wrapper.length) {
				$wrapper = $(this).closest('.thim-field').find('[id$="-wrapper"]').first();
			}

			if (!$wrapper.length) {
				return;
			}

			var index = $wrapper.children('.portfolio-repeater-item').length;
			var newItem = createRepeaterItem(fieldId, index);
			$wrapper.append(newItem);
		});

		function createRepeaterItem(fieldId, index) {
			return '<div class="portfolio-repeater-item">' +
				'<label>Item ' + (index + 1) + ':</label>' +
				'<input type="text" name="' + fieldId + '[' + index + '][title]" placeholder="Title">' +
				'<input type="text" name="' + fieldId + '[' + index + '][description]" placeholder="Description">' +
				'<button type="button" class="remove-repeater-item button">Delete</button>' +
				'</div>';
		}

		// Remove repeater item
		$document.on('click', '.remove-repeater-item', function () {
			$(this).closest('.portfolio-repeater-item').remove();
			reindexRepeaterItems();
		});

		function reindexRepeaterItems() {
			$('.portfolio-repeater-item').each(function (index) {
				var $item = $(this);
				$item.find('label').text('Item ' + (index + 1) + ':');

				$item.find('input').each(function () {
					var $input = $(this);
					var name = $input.attr('name');
					var matches = name.match(/^([^\[]+)\[\d+\]/);

					if (matches) {
						var fieldId = matches[1];
						var type = name.substring(name.lastIndexOf('['));
						$input.attr('name', fieldId + '[' + index + ']' + type);
					}
				});
			});
		}
	}

	// ========================================
	// 7. COLOR PICKER WITH CONDITION CHECK
	// ========================================
	function initColorPicker() {
		// Verify jQuery.fn.wpColorPicker exists before calling
		if (typeof $.fn.wpColorPicker === 'function') {
			$('.thim-color-field').wpColorPicker();
		}
	}

	// ========================================
	// 8. TAB NAVIGATION
	// ========================================
	function initTabNavigation() {
		var $tabNav = $('.thim-tab-nav');
		if (!$tabNav.length) {
			return;
		}

		var $tabs = $tabNav.find('a');
		var $tabContents = $('.thim-tab-content');

		if (!$tabs.length) {
			return;
		}

		$tabs.on('click', function (e) {
			e.preventDefault();

			// Remove active class from all tabs and contents
			$tabs.removeClass('active');
			$tabContents.removeClass('active');

			// Add active class to clicked tab
			$(this).addClass('active');

			// Show corresponding content
			var targetId = $(this).attr('href').substring(1);
			$('#' + targetId).addClass('active');
		});

		// Trigger first tab by default
		$tabs.first().click();
	}

	// ========================================
	// INITIALIZE ALL MODULES
	// ========================================
	initPortfolioToggle();
	initVideoDialog();
	initImageVideoField();
	initImageField();
	initFileUpload();
	initRepeater();
	initColorPicker();
	initTabNavigation();
});