PluginProbe
AL Pack / 1.2.0
AL Pack v1.2.0
1.3.13 trunk 1.0.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.11 1.3.12
alpack / includes / dynamic.php

dynamic.php in AL Pack 1.2.0, at includes/dynamic.php

1,155 lines 38.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5
6 function presslearn_is_plugin_active_for_dynamic() {
7 $dynamic_banner_enabled = get_option('presslearn_dynamic_banner_enabled', 'no');
8 return $dynamic_banner_enabled === 'yes';
9 }
10
11 function presslearn_dynamic_banner_admin_styles() {
12 if (!is_admin()) {
13 return;
14 }
15
16 $screen = get_current_screen();
17 if (!$screen || strpos($screen->id, 'presslearn-dynamic-banner') === false) {
18 return;
19 }
20
21 wp_register_style(
22 'presslearn-dynamic-banner-admin-css',
23 false,
24 array(),
25 PRESSLEARN_PLUGIN_VERSION
26 );
27 wp_enqueue_style('presslearn-dynamic-banner-admin-css');
28
29 $dynamic_banner_css = "
30 .presslearn-modal {
31 position: fixed;
32 z-index: 9999;
33 left: 0;
34 top: 0;
35 width: 100%;
36 height: 100%;
37 background-color: rgba(0, 0, 0, 0.5);
38 display: flex;
39 align-items: center;
40 justify-content: center;
41 }
42
43 .regular-input-form {
44 width: 100% !important;
45 box-sizing: border-box !important;
46 border: 1px solid #eee !important;
47 border-radius: 10px !important;
48 padding: 10px !important;
49 color: #000 !important;
50 }
51
52 .regular-input-form::placeholder {
53 color: #8b95a1 !important;
54 }
55
56 .regular-input-form:focus {
57 border-color: transparent !important;
58 outline: 2px solid #000 !important;
59 }
60
61 input[readonly].regular-input-form {
62 background-color: #f8f8f8;
63 cursor: not-allowed;
64 }
65
66 .presslearn-modal-content {
67 background-color: #fff;
68 width: 90%;
69 max-width: 800px;
70 border-radius: 6px;
71 box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
72 display: flex;
73 flex-direction: column;
74 max-height: 90vh;
75 min-height: 700px;
76 }
77
78 .presslearn-modal-header {
79 padding: 20px;
80 border-bottom: 1px solid #ddd;
81 display: flex;
82 justify-content: space-between;
83 align-items: center;
84 }
85
86 .presslearn-modal-header h3 {
87 margin: 0;
88 font-size: 20px;
89 }
90
91 .presslearn-modal-close {
92 font-size: 28px;
93 font-weight: bold;
94 cursor: pointer;
95 color: #666;
96 }
97
98 .presslearn-modal-close:hover {
99 color: #000;
100 }
101
102 .presslearn-modal-body {
103 padding: 20px;
104 overflow-y: auto;
105 flex: 1;
106 }
107
108 .presslearn-modal-footer {
109 padding: 15px 20px;
110 border-top: 1px solid #ddd;
111 text-align: right;
112 display: flex;
113 gap: 10px;
114 justify-content: flex-end;
115 }
116
117 .campaign-tabs {
118 margin-top: 10px;
119 margin-bottom: 20px;
120 }
121
122 .campaign-tab {
123 display: inline-block;
124 padding: 10px 20px;
125 margin: 0;
126 margin-right: 5px;
127 font-weight: bold;
128 text-decoration: none;
129 background-color: #f8f9fa;
130 border-radius: 100px;
131 color: #000;
132 border: 0;
133 cursor: pointer;
134 }
135
136 .campaign-tab.active {
137 background: #000;
138 color: #fff;
139 }
140
141 .campaign-tab-content {
142 display: none;
143 }
144
145 .campaign-tab-content.active {
146 display: block;
147 }
148
149 .campaign-table {
150 width: 100%;
151 border-collapse: collapse;
152 }
153
154 .campaign-table th,
155 .campaign-table td {
156 padding: 12px;
157 text-align: left;
158 border-bottom: 1px solid #eee;
159 }
160
161 .campaign-table th {
162 background-color: #f8f8f8;
163 font-weight: 600;
164 }
165
166 .campaign-table .no-campaigns {
167 text-align: center;
168 padding: 30px;
169 color: #888;
170 }
171
172 .settings-form-row {
173 margin-bottom: 20px;
174 }
175
176 .settings-form-row label {
177 display: block;
178 margin-bottom: 8px;
179 font-weight: 500;
180 }
181
182 .banner-upload-container {
183 display: flex;
184 gap: 10px;
185 }
186
187 .banner-upload-container input {
188 flex: 1;
189 }
190
191 .banner-preview {
192 margin-top: 10px;
193 max-width: 300px;
194 border: 1px solid #ddd;
195 padding: 5px;
196 border-radius: 4px;
197 }
198
199 .banner-preview img {
200 max-width: 100%;
201 height: auto;
202 }
203
204 .campaign-actions {
205 display: flex;
206 gap: 5px;
207 }
208
209 .campaign-actions button {
210 padding: 2px 8px;
211 background: none;
212 border: 1px solid #ddd;
213 border-radius: 3px;
214 cursor: pointer;
215 }
216
217 .campaign-actions button.edit-campaign {
218 color: #2196F3;
219 }
220
221 .campaign-actions button.delete-campaign {
222 color: #f44336;
223 }
224
225 .form-actions {
226 margin-top: 30px;
227 }
228
229 .campaign-shortcode {
230 padding: 5px 8px;
231 background-color: #f5f5f5;
232 border: 1px solid #ddd;
233 border-radius: 3px;
234 font-family: monospace;
235 display: inline-block;
236 }
237
238 .campaign-status {
239 padding: 3px 8px;
240 border-radius: 20px;
241 font-size: 12px;
242 font-weight: bold;
243 }
244
245 .campaign-status.active {
246 background-color: #e8f5e9;
247 color: #2e7d32;
248 }
249
250 .campaign-status.inactive {
251 background-color: #ffebee;
252 color: #c62828;
253 }
254
255 .shortcode-container {
256 display: flex;
257 align-items: center;
258 gap: 5px;
259 }
260
261 .copy-shortcode {
262 display: inline-flex;
263 align-items: center;
264 justify-content: center;
265 padding: 8px;
266 border-radius: 3px;
267 background-color: #f0f0f0;
268 border: 1px solid #ddd;
269 cursor: pointer;
270 color: #555;
271 transition: all 0.2s ease;
272 }
273
274 .copy-shortcode:hover {
275 background-color: #e0e0e0;
276 color: #333;
277 }
278
279 .copy-success {
280 background-color: #e8f5e9;
281 border: 1px solid #a5d6a7;
282 color: #2e7d32;
283 }
284
285 .banner-type-selector {
286 display: flex;
287 gap: 10px;
288 margin-top: 5px;
289 justify-content: space-between;
290 align-items: center;
291 }
292
293 .banner-type-option {
294 width: 100%;
295 cursor: pointer;
296 transition: all 0.2s ease;
297 position: relative;
298 }
299
300 .banner-type-option input[type=\"radio\"] {
301 position: absolute;
302 opacity: 0;
303 width: 0;
304 height: 0;
305 }
306
307 .banner-type-btn {
308 flex: 1;
309 display: block;
310 padding: 12px 25px;
311 background-color: #f5f5f5;
312 border: 0;
313 border-radius: 10px;
314 font-weight: 500;
315 font-size: 14px;
316 text-align: center;
317 color: #555;
318 transition: all 0.3s ease;
319 min-width: 120px;
320 }
321
322 .banner-type-option:hover .banner-type-btn {
323 background-color: #e9e9e9;
324 border-color: #ccc;
325 }
326
327 .banner-type-option input[type=\"radio\"]:checked + .banner-type-btn {
328 background-color: #2196F3;
329 border-color: #2196F3;
330 color: white;
331 font-weight: 600;
332 }
333
334 .banner-dimensions {
335 display: flex;
336 gap: 20px;
337 }
338
339 .dimension-field {
340 flex: 1;
341 }
342
343 .required {
344 color: #f44336;
345 margin-left: 3px;
346 }
347
348 .code-editor-container {
349 margin-bottom: 10px;
350 border-radius: 8px;
351 overflow: hidden;
352 border: 1px solid #ddd;
353 line-height: 1;
354 }
355
356 .code-editor-header {
357 display: flex;
358 justify-content: space-between;
359 align-items: center;
360 background-color: #f3f3f3;
361 padding: 8px 12px;
362 border-bottom: 1px solid #ddd;
363 font-family: monospace;
364 color: #555;
365 font-size: 12px;
366 }
367
368 .code-copy-btn {
369 display: flex;
370 align-items: center;
371 gap: 5px;
372 background: none;
373 border: none;
374 font-size: 12px;
375 color: #666;
376 cursor: pointer;
377 padding: 4px 8px;
378 border-radius: 4px;
379 }
380
381 .code-copy-btn:hover {
382 background-color: #e0e0e0;
383 }
384
385 .code-editor {
386 width: 100%;
387 border: none;
388 background-color: #fafafa;
389 font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
390 font-size: 13px;
391 color: #333;
392 padding: 15px;
393 resize: vertical;
394 box-sizing: border-box;
395 line-height: 1.5;
396 tab-size: 4;
397 }
398
399 .code-editor:focus {
400 outline: none;
401 background-color: #fff;
402 }
403
404 .form-hint {
405 margin-top: 5px;
406 font-size: 12px;
407 color: #666;
408 }
409
410 .file-upload-progress {
411 margin-top: 8px;
412 height: 4px;
413 background-color: #f1f1f1;
414 border-radius: 2px;
415 overflow: hidden;
416 width: 100%;
417 }
418
419 .progress-bar {
420 height: 100%;
421 width: 0;
422 background-color: #2196F3;
423 transition: width 0.3s ease;
424 }
425
426 .file-upload-info {
427 margin-top: 8px;
428 padding: 8px 12px;
429 background-color: #f8f8f8;
430 border: 1px solid #e0e0e0;
431 border-radius: 6px;
432 font-size: 13px;
433 }
434
435 .file-name {
436 font-weight: 500;
437 word-break: break-all;
438 }
439
440 .edit-modal-overlay {
441 overflow-y: auto;
442 }
443
444 .edit-modal-overlay .presslearn-modal-content {
445 max-width: 700px;
446 margin: 30px auto;
447 }
448
449 #edit_banner_preview {
450 margin-top: 10px;
451 max-width: 100%;
452 text-align: center;
453 }
454
455 #edit_banner_preview img {
456 max-width: 100%;
457 max-height: 300px;
458 border: 1px dashed #ccc;
459 }
460 ";
461
462 wp_add_inline_style('presslearn-dynamic-banner-admin-css', $dynamic_banner_css);
463 }
464
465 function presslearn_dynamic_banner_admin_scripts() {
466 if (!is_admin()) {
467 return;
468 }
469
470 $screen = get_current_screen();
471 if (!$screen || strpos($screen->id, 'presslearn-dynamic-banner') === false) {
472 return;
473 }
474
475 wp_register_script(
476 'presslearn-dynamic-banner-modal-js',
477 false,
478 array('jquery'),
479 PRESSLEARN_PLUGIN_VERSION,
480 true
481 );
482 wp_enqueue_script('presslearn-dynamic-banner-modal-js');
483
484 $modal_js = "
485 jQuery(document).ready(function($) {
486 $('#open-shortcode-modal').on('click', function() {
487 $('#shortcode-modal').show();
488 loadCampaigns();
489 resetCampaignForm();
490 });
491
492 $('.presslearn-modal-close, #close-modal-button').on('click', function() {
493 $('#shortcode-modal').hide();
494 });
495
496 $(window).on('click', function(event) {
497 if ($(event.target).is('.presslearn-modal')) {
498 $('.presslearn-modal').hide();
499 }
500 });
501
502 $('.campaign-tab').on('click', function() {
503 const tab = $(this).data('tab');
504
505 $('.campaign-tab').removeClass('active');
506 $(this).addClass('active');
507
508 $('.campaign-tab-content').removeClass('active');
509 $('#' + tab + '-tab').addClass('active');
510
511 if (tab === 'add-campaign') {
512 resetCampaignForm();
513 }
514 });
515
516 function resetCampaignForm() {
517 $('#add-campaign-form')[0].reset();
518
519 $('input[name=\"banner_type\"][value=\"custom\"]').prop('checked', true).trigger('change');
520
521 $('#banner-preview, #cover-banner-preview, #iframe-cover-banner-preview').hide();
522 $('#banner-preview img, #cover-banner-preview img, #iframe-cover-banner-preview img').attr('src', '');
523
524 $('#campaign_banner_url, #campaign_cover_banner_url, #iframe_campaign_cover_banner_url').val('');
525 $('#campaign_name, #campaign_link, #banner_width, #banner_height').val('');
526 $('#iframe_code, #iframe_link_url, #iframe_width, #iframe_height').val('');
527
528 $('.file-upload-info').hide();
529
530 userModifiedWidth = false;
531 userModifiedHeight = false;
532
533 $('#campaign_id').remove();
534
535 $('#add-campaign-form button[type=\"submit\"]').text('캠페인 추가');
536 }
537
538 window.resetCampaignForm = resetCampaignForm;
539 window.loadCampaigns = loadCampaigns;
540 });
541 ";
542
543 wp_add_inline_script('presslearn-dynamic-banner-modal-js', $modal_js);
544
545 wp_register_script(
546 'presslearn-dynamic-banner-upload-js',
547 false,
548 array('jquery'),
549 PRESSLEARN_PLUGIN_VERSION,
550 true
551 );
552 wp_enqueue_script('presslearn-dynamic-banner-upload-js');
553
554 $upload_js = "
555 jQuery(document).ready(function($) {
556 $('#upload-banner').on('click', function(e) {
557 e.preventDefault();
558 $('#banner_image_file').click();
559 });
560
561 $('#upload-cover-banner').on('click', function(e) {
562 e.preventDefault();
563 $('#cover_banner_image_file').click();
564 });
565
566 $('#iframe-upload-cover-banner').on('click', function(e) {
567 e.preventDefault();
568 $('#iframe_cover_banner_image_file').click();
569 });
570
571 $('#banner_image_file').on('change', function(e) {
572 const file = e.target.files[0];
573 if (!file) return;
574
575 if (!file.type.match('image.*')) {
576 alert('이미지 파일만 �
577 로드 가능합니다.');
578 return;
579 }
580
581 $(this).siblings('.file-upload-info').find('.file-name').text(file.name);
582 $(this).siblings('.file-upload-info').show();
583 $(this).siblings('.file-upload-info').find('.progress-bar').css('width', '0%');
584
585 const formData = new FormData();
586 formData.append('action', 'presslearn_upload_banner');
587 formData.append('banner_image', file);
588 formData.append('nonce', '" . wp_create_nonce("presslearn_upload_banner_nonce") . "');
589
590 const currentUploadContainer = $(this).closest('.settings-form-row');
591
592 $.ajax({
593 url: ajaxurl,
594 type: 'POST',
595 data: formData,
596 processData: false,
597 contentType: false,
598 xhr: function() {
599 const xhr = new window.XMLHttpRequest();
600 xhr.upload.addEventListener('progress', function(evt) {
601 if (evt.lengthComputable) {
602 const percentComplete = (evt.loaded / evt.total) * 100;
603 currentUploadContainer.find('.progress-bar').css('width', percentComplete + '%');
604 }
605 }, false);
606 return xhr;
607 },
608 success: function(response) {
609 if (response.success && response.data.url) {
610 $('#campaign_banner_url').val(response.data.url);
611 $('#banner-preview').show().find('img').attr('src', response.data.url);
612 currentUploadContainer.find('.file-upload-info').hide();
613 } else {
614 alert(response.data.message || '이미지 �
615 로드에 실패했습니다.');
616 currentUploadContainer.find('.file-upload-info').hide();
617 }
618 },
619 error: function() {
620 alert('서버 통신 중 오류가 발생했습니다. 나중에 다시 시도하세요.');
621 currentUploadContainer.find('.file-upload-info').hide();
622 }
623 });
624 });
625
626 $('#cover_banner_image_file').on('change', function(e) {
627 const file = e.target.files[0];
628 if (!file) return;
629
630 if (!file.type.match('image.*')) {
631 alert('이미지 파일만 �
632 로드 가능합니다.');
633 return;
634 }
635
636 $(this).siblings('.file-upload-info').find('.file-name').text(file.name);
637 $(this).siblings('.file-upload-info').show();
638 $(this).siblings('.file-upload-info').find('.progress-bar').css('width', '0%');
639
640 const formData = new FormData();
641 formData.append('action', 'presslearn_upload_banner');
642 formData.append('banner_image', file);
643 formData.append('banner_type', 'cover');
644 formData.append('nonce', '" . wp_create_nonce("presslearn_upload_banner_nonce") . "');
645
646 const currentUploadContainer = $(this).closest('.settings-form-row');
647
648 $.ajax({
649 url: ajaxurl,
650 type: 'POST',
651 data: formData,
652 processData: false,
653 contentType: false,
654 xhr: function() {
655 const xhr = new window.XMLHttpRequest();
656 xhr.upload.addEventListener('progress', function(evt) {
657 if (evt.lengthComputable) {
658 const percentComplete = (evt.loaded / evt.total) * 100;
659 currentUploadContainer.find('.progress-bar').css('width', percentComplete + '%');
660 }
661 }, false);
662 return xhr;
663 },
664 success: function(response) {
665 if (response.success && response.data.url) {
666 $('#campaign_cover_banner_url').val(response.data.url);
667 $('#cover-banner-preview').show().find('img').attr('src', response.data.url);
668 currentUploadContainer.find('.file-upload-info').hide();
669 } else {
670 alert(response.data.message || '커버 배너 이미지 �
671 로드에 실패했습니다.');
672 currentUploadContainer.find('.file-upload-info').hide();
673 }
674 },
675 error: function() {
676 alert('서버 통신 중 오류가 발생했습니다. 나중에 다시 시도하세요.');
677 currentUploadContainer.find('.file-upload-info').hide();
678 }
679 });
680 });
681
682 $('#iframe_cover_banner_image_file').on('change', function(e) {
683 const file = e.target.files[0];
684 if (!file) return;
685
686 if (!file.type.match('image.*')) {
687 alert('이미지 파일만 �
688 로드 가능합니다.');
689 return;
690 }
691
692 $(this).siblings('.file-upload-info').find('.file-name').text(file.name);
693 $(this).siblings('.file-upload-info').show();
694 $(this).siblings('.file-upload-info').find('.progress-bar').css('width', '0%');
695
696 const formData = new FormData();
697 formData.append('action', 'presslearn_upload_banner');
698 formData.append('banner_image', file);
699 formData.append('banner_type', 'cover');
700 formData.append('nonce', '" . wp_create_nonce("presslearn_upload_banner_nonce") . "');
701
702 const currentUploadContainer = $(this).closest('.settings-form-row');
703
704 $.ajax({
705 url: ajaxurl,
706 type: 'POST',
707 data: formData,
708 processData: false,
709 contentType: false,
710 xhr: function() {
711 const xhr = new window.XMLHttpRequest();
712 xhr.upload.addEventListener('progress', function(evt) {
713 if (evt.lengthComputable) {
714 const percentComplete = (evt.loaded / evt.total) * 100;
715 currentUploadContainer.find('.progress-bar').css('width', percentComplete + '%');
716 }
717 }, false);
718 return xhr;
719 },
720 success: function(response) {
721 if (response.success && response.data.url) {
722 $('#iframe_campaign_cover_banner_url').val(response.data.url);
723 $('#iframe-cover-banner-preview').show().find('img').attr('src', response.data.url);
724 currentUploadContainer.find('.file-upload-info').hide();
725 } else {
726 alert(response.data.message || '커버 배너 이미지 �
727 로드에 실패했습니다.');
728 currentUploadContainer.find('.file-upload-info').hide();
729 }
730 },
731 error: function() {
732 alert('서버 통신 중 오류가 발생했습니다. 나중에 다시 시도하세요.');
733 currentUploadContainer.find('.file-upload-info').hide();
734 }
735 });
736 });
737 });
738 ";
739
740 wp_add_inline_script('presslearn-dynamic-banner-upload-js', $upload_js);
741
742 wp_register_script(
743 'presslearn-dynamic-banner-type-js',
744 false,
745 array('jquery'),
746 PRESSLEARN_PLUGIN_VERSION,
747 true
748 );
749 wp_enqueue_script('presslearn-dynamic-banner-type-js');
750
751 $type_js = "
752 jQuery(document).ready(function($) {
753 $('input[name=\"banner_type\"]').on('change', function() {
754 const bannerType = $('input[name=\"banner_type\"]:checked').val();
755
756 if (bannerType === 'custom') {
757 $('#custom-banner-fields').show();
758 $('#iframe-banner-fields').hide();
759
760 $('#banner_width, #banner_height, #campaign_banner_url, #campaign_link').prop('required', true);
761 $('#iframe_width, #iframe_height, #iframe_code').prop('required', false);
762 } else if (bannerType === 'iframe') {
763 $('#custom-banner-fields').hide();
764 $('#iframe-banner-fields').show();
765
766 $('#iframe_width, #iframe_height, #iframe_code').prop('required', true);
767 $('#banner_width, #banner_height, #campaign_banner_url, #campaign_link').prop('required', false);
768 }
769 });
770
771 function extractDimensionsFromIframe(iframeCode) {
772 let width = null;
773 let height = null;
774
775 const widthMatch = iframeCode.match(/width=[\"']?(\\d+)[\"']?/i);
776 if (widthMatch && widthMatch[1]) {
777 width = parseInt(widthMatch[1], 10);
778 }
779
780 const heightMatch = iframeCode.match(/height=[\"']?(\\d+)[\"']?/i);
781 if (heightMatch && heightMatch[1]) {
782 height = parseInt(heightMatch[1], 10);
783 }
784
785 return { width, height };
786 }
787
788 let userModifiedWidth = false;
789 let userModifiedHeight = false;
790
791 $('#iframe_code').on('input', function() {
792 const iframeCode = $(this).val();
793 if (!iframeCode) return;
794
795 const { width, height } = extractDimensionsFromIframe(iframeCode);
796
797 if (!userModifiedWidth && width) {
798 $('#iframe_width').val(width);
799 }
800
801 if (!userModifiedHeight && height) {
802 $('#iframe_height').val(height);
803 }
804 });
805
806 $('#iframe_width').on('input', function() {
807 userModifiedWidth = true;
808 });
809
810 $('#iframe_height').on('input', function() {
811 userModifiedHeight = true;
812 });
813
814 $('#add-campaign-form').on('reset', function() {
815 userModifiedWidth = false;
816 userModifiedHeight = false;
817 });
818
819 window.userModifiedWidth = userModifiedWidth;
820 window.userModifiedHeight = userModifiedHeight;
821 });
822 ";
823
824 wp_add_inline_script('presslearn-dynamic-banner-type-js', $type_js);
825
826 wp_register_script(
827 'presslearn-dynamic-banner-campaign-js',
828 false,
829 array('jquery'),
830 PRESSLEARN_PLUGIN_VERSION,
831 true
832 );
833 wp_enqueue_script('presslearn-dynamic-banner-campaign-js');
834
835 wp_localize_script('presslearn-dynamic-banner-campaign-js', 'pressleanDynamicBanner', array(
836 'ajax_url' => admin_url('admin-ajax.php'),
837 'campaign_nonce' => wp_create_nonce('presslearn_campaign_nonce')
838 ));
839
840 $campaign_js = "
841 jQuery(document).ready(function($) {
842 $(document).on('click', '.edit-campaign', function() {
843 const campaignId = $(this).data('id');
844
845 $.ajax({
846 url: ajaxurl,
847 type: 'POST',
848 data: {
849 action: 'presslearn_get_campaign',
850 nonce: pressleanDynamicBanner.campaign_nonce,
851 id: campaignId
852 },
853 success: function(response) {
854 if (response.success) {
855 const campaign = response.data.campaign;
856
857 $('.campaign-tab[data-tab=\"add-campaign\"]').click();
858
859 $('#campaign_name').val(campaign.name);
860
861 if ($('#campaign_id').length === 0) {
862 $('#add-campaign-form').prepend('<input type=\"hidden\" id=\"campaign_id\" name=\"campaign_id\" value=\"' + campaign.id + '\">');
863 } else {
864 $('#campaign_id').val(campaign.id);
865 }
866
867 $('#add-campaign-form button[type=\"submit\"]').text('캠페인 수정');
868
869 $('input[name=\"banner_type\"][value=\"' + campaign.type + '\"]').prop('checked', true).trigger('change');
870
871 if (campaign.type === 'custom') {
872 $('#campaign_banner_url').val(campaign.banner_url);
873 $('#campaign_link').val(campaign.link);
874 $('#banner_width').val(campaign.width);
875 $('#banner_height').val(campaign.height);
876
877 if (campaign.banner_url) {
878 $('#banner-preview').show().find('img').attr('src', campaign.banner_url);
879 }
880
881 if (campaign.cover_banner_url) {
882 $('#campaign_cover_banner_url').val(campaign.cover_banner_url);
883 $('#cover-banner-preview').show().find('img').attr('src', campaign.cover_banner_url);
884 }
885 } else if (campaign.type === 'iframe') {
886 setTimeout(function() {
887 $('#iframe_code').val(campaign.iframe_code);
888 $('#iframe_link_url').val(campaign.link);
889 $('#iframe_width').val(campaign.width);
890 $('#iframe_height').val(campaign.height);
891
892 if (campaign.cover_banner_url) {
893 $('#iframe_campaign_cover_banner_url').val(campaign.cover_banner_url);
894 $('#iframe-cover-banner-preview').show().find('img').attr('src', campaign.cover_banner_url);
895 }
896 }, 100);
897 }
898 } else {
899 alert(response.data.message || '캠페인 정보를 가져오는 중 오류가 발생했습니다.');
900 }
901 },
902 error: function() {
903 alert('서버 통신 오류가 발생했습니다.');
904 }
905 });
906 });
907
908 $('#add-campaign-form').on('submit', function(e) {
909 e.preventDefault();
910
911 const campaignName = $('#campaign_name').val();
912 const bannerType = $('input[name=\"banner_type\"]:checked').val();
913 const campaignId = $('#campaign_id').val();
914
915 let isValid = true;
916 let formData = {
917 name: campaignName,
918 type: bannerType
919 };
920
921 if (campaignId) {
922 formData.id = campaignId;
923 }
924
925 if (!campaignName) {
926 alert('캠페인 이름을 �
927 력해주세요.');
928 isValid = false;
929 return;
930 }
931
932 if (bannerType === 'custom') {
933 const bannerUrl = $('#campaign_banner_url').val();
934 const campaignLink = $('#campaign_link').val();
935 const bannerWidth = $('#banner_width').val();
936 const bannerHeight = $('#banner_height').val();
937
938 if (!bannerUrl) {
939 alert('배너 이미지 URL을 �
940 력해주세요.');
941 isValid = false;
942 return;
943 }
944
945 if (!campaignLink) {
946 alert('링크 URL을 �
947 력해주세요.');
948 isValid = false;
949 return;
950 }
951
952 if (!bannerWidth || !bannerHeight) {
953 alert('배너 가로/세로 크기를 �
954 력해주세요.');
955 isValid = false;
956 return;
957 }
958
959 formData.banner_url = bannerUrl;
960 formData.link = campaignLink;
961 formData.width = bannerWidth;
962 formData.height = bannerHeight;
963
964 const coverBannerUrl = $('#campaign_cover_banner_url').val();
965 if (coverBannerUrl) {
966 formData.cover_banner_url = coverBannerUrl;
967 }
968 } else if (bannerType === 'iframe') {
969 const iframeCode = $('#iframe_code').val();
970 const iframeLinkUrl = $('#iframe_link_url').val();
971 const iframeWidth = $('#iframe_width').val();
972 const iframeHeight = $('#iframe_height').val();
973
974 if (!iframeCode) {
975 alert('iframe 코드를 �
976 력해주세요.');
977 isValid = false;
978 return;
979 }
980
981 if (!iframeWidth || !iframeHeight) {
982 alert('iframe 가로/세로 크기를 �
983 력해주세요.');
984 isValid = false;
985 return;
986 }
987
988 formData.iframe_code = iframeCode;
989 formData.width = iframeWidth;
990 formData.height = iframeHeight;
991
992 if (iframeLinkUrl) {
993 formData.link = iframeLinkUrl;
994 }
995
996 const coverBannerUrl = $('#iframe_campaign_cover_banner_url').val();
997 if (coverBannerUrl) {
998 formData.cover_banner_url = coverBannerUrl;
999 }
1000 }
1001
1002 if (!isValid) return;
1003
1004 const action = campaignId ? 'presslearn_update_campaign' : 'presslearn_add_campaign';
1005
1006 $.ajax({
1007 url: ajaxurl,
1008 type: 'POST',
1009 data: {
1010 action: action,
1011 nonce: pressleanDynamicBanner.campaign_nonce,
1012 campaign_data: formData
1013 },
1014 beforeSend: function() {
1015 $('#add-campaign-form button[type=\"submit\"]').prop('disabled', true).text('처리 중...');
1016 },
1017 success: function(response) {
1018 if (response.success) {
1019 let message = campaignId ? '캠페인이 수정되었습니다.' : '캠페인이 추가되었습니다.';
1020 alert(message);
1021
1022 loadCampaigns();
1023
1024 resetCampaignForm();
1025
1026 $('.campaign-tab[data-tab=\"campaigns\"]').click();
1027 } else {
1028 alert(response.data.message || '캠페인 저장 중 오류가 발생했습니다.');
1029 }
1030 },
1031 error: function() {
1032 alert('서버 통신 오류가 발생했습니다.');
1033 },
1034 complete: function() {
1035 let buttonText = campaignId ? '캠페인 수정' : '캠페인 추가';
1036 $('#add-campaign-form button[type=\"submit\"]').prop('disabled', false).text(buttonText);
1037 }
1038 });
1039 });
1040
1041 function loadCampaigns() {
1042 $.ajax({
1043 url: ajaxurl,
1044 type: 'POST',
1045 data: {
1046 action: 'presslearn_get_campaigns',
1047 nonce: pressleanDynamicBanner.campaign_nonce
1048 },
1049 beforeSend: function() {
1050 $('#campaign-list').html('<tr><td colspan=\"4\" style=\"text-align:center;padding:20px;\">데이터를 불러오는 중�
1051 니다...</td></tr>');
1052 },
1053 success: function(response) {
1054 if (response.success) {
1055 if (response.data.campaigns && response.data.campaigns.length > 0) {
1056 let campaignsHtml = '';
1057
1058 $.each(response.data.campaigns, function(index, campaign) {
1059 campaignsHtml += `
1060 <tr data-id=\"\${campaign.id}\">
1061 <td>\${campaign.name}</td>
1062 <td>
1063 <div class=\"shortcode-container\">
1064 <span class=\"campaign-shortcode\">\${campaign.shortcode}</span>
1065 <button type=\"button\" class=\"copy-shortcode\" title=\"숏코드 복사\">
1066 <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">
1067 <path d=\"M16 1H4C2.9 1 2 1.9 2 3V17H4V3H16V1ZM19 5H8C6.9 5 6 5.9 6 7V21C6 22.1 6.9 23 8 23H19C20.1 23 21 22.1 21 21V7C21 5.9 20.1 5 19 5ZM19 21H8V7H19V21Z\" fill=\"currentColor\"/>
1068 </svg>
1069 </button>
1070 </div>
1071 </td>
1072 <td>
1073 <div class=\"campaign-actions\">
1074 <button type=\"button\" class=\"edit-campaign\" data-id=\"\${campaign.id}\">수정</button>
1075 <button type=\"button\" class=\"delete-campaign\" data-id=\"\${campaign.id}\">삭제</button>
1076 </div>
1077 </td>
1078 </tr>
1079 `;
1080 });
1081
1082 $('#campaign-list').html(campaignsHtml);
1083 } else {
1084 $('#campaign-list').html('<tr><td colspan=\"4\" class=\"no-campaigns\">등록된 캠페인이 없습니다. 새 캠페인을 추가해주세요.</td></tr>');
1085 }
1086 } else {
1087 alert(response.data.message || '캠페인 목록을 불러오는 중 오류가 발생했습니다.');
1088 $('#campaign-list').html('<tr><td colspan=\"4\" class=\"no-campaigns\">캠페인 목록을 불러올 수 없습니다.</td></tr>');
1089 }
1090 },
1091 error: function() {
1092 alert('서버 통신 오류가 발생했습니다.');
1093 $('#campaign-list').html('<tr><td colspan=\"4\" class=\"no-campaigns\">서버 통신 오류가 발생했습니다.</td></tr>');
1094 }
1095 });
1096 }
1097
1098 $(document).on('click', '.copy-shortcode', function() {
1099 const shortcode = $(this).prev('.campaign-shortcode').text();
1100 const copyButton = $(this);
1101
1102 navigator.clipboard.writeText(shortcode).then(function() {
1103 copyButton.addClass('copy-success');
1104
1105 setTimeout(function() {
1106 copyButton.removeClass('copy-success');
1107 }, 1500);
1108 });
1109 });
1110
1111 $(document).on('click', '.delete-campaign', function() {
1112 const row = $(this).closest('tr');
1113 const name = row.find('td:first').text();
1114 const campaignId = $(this).data('id');
1115
1116 if (confirm('정말로 \"' + name + '\" 캠페인을 삭제하시겠습니까?')) {
1117 $.ajax({
1118 url: ajaxurl,
1119 type: 'POST',
1120 data: {
1121 action: 'presslearn_delete_campaign',
1122 nonce: pressleanDynamicBanner.campaign_nonce,
1123 id: campaignId
1124 },
1125 success: function(response) {
1126 if (response.success) {
1127 row.remove();
1128
1129 if ($('#campaign-list tr').length === 0) {
1130 $('#campaign-list').html('<tr><td colspan=\"5\" class=\"no-campaigns\">등록된 캠페인이 없습니다. 새 캠페인을 추가해주세요.</td></tr>');
1131 }
1132
1133 alert('캠페인이 삭제되었습니다.');
1134 } else {
1135 alert(response.data.message || '캠페인 삭제 중 오류가 발생했습니다.');
1136 }
1137 },
1138 error: function() {
1139 alert('서버 통신 오류가 발생했습니다.');
1140 }
1141 });
1142 }
1143 });
1144
1145 window.loadCampaigns = loadCampaigns;
1146 });
1147 ";
1148
1149 wp_add_inline_script('presslearn-dynamic-banner-campaign-js', $campaign_js);
1150 }
1151
1152 add_action('admin_enqueue_scripts', 'presslearn_dynamic_banner_admin_styles');
1153 add_action('admin_enqueue_scripts', 'presslearn_dynamic_banner_admin_scripts');
1154
1155