PluginProbe
AL Pack / trunk
AL Pack vtrunk
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 / buttons.php

buttons.php in AL Pack trunk, at includes/buttons.php

1,075 lines 47.8 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_buttons() {
7 $is_activated = false;
8 if (function_exists('presslearn_plugin')) {
9 $is_activated = presslearn_plugin()->is_plugin_activated();
10 }
11 return $is_activated;
12 }
13
14 function presslearn_register_quick_button_block() {
15 if (!presslearn_is_plugin_active_for_buttons()) {
16 return;
17 }
18
19 $quick_button_enabled = get_option('presslearn_quick_button_enabled', 'no');
20 if ($quick_button_enabled !== 'yes') {
21 return;
22 }
23
24 wp_register_script(
25 'presslearn-quick-button-block',
26 false,
27 array('wp-blocks', 'wp-element', 'wp-editor', 'wp-components'),
28 time(),
29 true
30 );
31
32 $button_transition_enabled = get_option('presslearn_button_transition_enabled', 'no');
33
34 $saved_preset = get_option('presslearn_button_preset', array());
35 $saved_preset_json = !empty($saved_preset) ? wp_json_encode($saved_preset) : 'null';
36
37 wp_add_inline_script('presslearn-quick-button-block', '
38 (function(blocks, element, components, editor) {
39 var el = element.createElement;
40 var RichText = editor.RichText;
41 var ColorPalette = components.ColorPalette;
42 var InspectorControls = editor.InspectorControls;
43 var TextControl = components.TextControl;
44 var SelectControl = components.SelectControl;
45 var PanelBody = components.PanelBody;
46 var PanelRow = components.PanelRow;
47
48 var buttonIcon = el("svg", { width: 24, height: 24, viewBox: "0 0 24 24" },
49 el("path", {
50 d: "M19 6H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 10H5V8h14v8z",
51 fill: "#2196F3"
52 })
53 );
54
55 var infiniteAnimationEnabled = "' . esc_js($button_transition_enabled === 'yes' ? 'yes' : 'no') . '";
56
57 var savedPreset = ' . $saved_preset_json . ';
58 var presslearn_ajax = {
59 ajaxurl: "' . esc_js(admin_url('admin-ajax.php')) . '",
60 nonce: "' . esc_js(wp_create_nonce('presslearn_button_preset')) . '"
61 };
62
63 var defaultValues = {
64 buttonText: "버튼 �
65 �스트",
66 buttonUrl: "#",
67 buttonColor: savedPreset && savedPreset.buttonColor ? savedPreset.buttonColor : "#2196F3",
68 buttonTextColor: savedPreset && savedPreset.buttonTextColor ? savedPreset.buttonTextColor : "#ffffff",
69 buttonHoverColor: savedPreset && savedPreset.buttonHoverColor ? savedPreset.buttonHoverColor : "",
70 buttonPosition: savedPreset && savedPreset.buttonPosition ? savedPreset.buttonPosition : "center",
71 buttonSize: savedPreset && savedPreset.buttonSize ? savedPreset.buttonSize : "medium",
72 buttonWidth: savedPreset && savedPreset.buttonWidth ? savedPreset.buttonWidth : "default",
73 openInNewTab: false,
74 buttonAnimation: savedPreset && savedPreset.buttonAnimation ? savedPreset.buttonAnimation : "none",
75 infiniteAnimation: infiniteAnimationEnabled,
76 borderRadius: savedPreset && savedPreset.borderRadius ? savedPreset.borderRadius : 4
77 };
78
79 blocks.registerBlockType("presslearn/quick-button", {
80 title: "PL 빠른 버튼",
81 icon: buttonIcon,
82 category: "presslearn",
83 keywords: ["버튼", "button", "link", "presslearn"],
84 description: "클릭 가능한 버튼을 추가합니다. �
85 �스트, URL, 색상 및 정렬을 사용자 정의할 수 있습니다.",
86 deprecated: [{
87 attributes: {
88 buttonText: { type: "string", default: "버튼 �
89 �스트" },
90 buttonUrl: { type: "string", default: "#" },
91 buttonColor: { type: "string", default: "#2196F3" },
92 buttonTextColor: { type: "string", default: "#ffffff" },
93 buttonHoverColor: { type: "string", default: "" },
94 buttonPosition: { type: "string", default: "center" },
95 buttonSize: { type: "string", default: "medium" },
96 buttonWidth: { type: "string", default: "default" },
97 openInNewTab: { type: "boolean", default: false },
98 buttonAnimation: { type: "string", default: "none" },
99 infiniteAnimation: { type: "string", default: "yes" },
100 borderRadius: { type: "number", default: 4 }
101 },
102 save: function(props) {
103 var attributes = props.attributes;
104 var buttonPadding = "12px 24px";
105 switch(attributes.buttonSize) {
106 case "small": buttonPadding = "8px 16px"; break;
107 case "large": buttonPadding = "16px 32px"; break;
108 case "xlarge": buttonPadding = "20px 40px"; break;
109 }
110 var fontSize = "15px";
111 switch(attributes.buttonSize) {
112 case "small": fontSize = "13px"; break;
113 case "large": fontSize = "18px"; break;
114 case "xlarge": fontSize = "22px"; break;
115 }
116 var buttonWidth = "auto";
117 var textAlign = "inherit";
118 if (attributes.buttonWidth === "half") {
119 buttonWidth = "50%";
120 textAlign = "center";
121 } else if (attributes.buttonWidth === "full") {
122 buttonWidth = "100%";
123 textAlign = "center";
124 }
125 var containerAlignment = attributes.buttonPosition;
126 if (attributes.buttonWidth === "full") {
127 containerAlignment = "center";
128 }
129 var animationClass = "presslearn-button presslearn-button-animation-" + attributes.buttonAnimation;
130 if (infiniteAnimationEnabled === "yes" && attributes.buttonAnimation !== "none") {
131 animationClass += " presslearn-button-animation-infinite";
132 }
133 return el("div", {
134 className: "presslearn-button-container",
135 style: { textAlign: containerAlignment, margin: "20px 0" }
136 },
137 el("a", {
138 className: animationClass,
139 href: attributes.buttonUrl || "#",
140 ...(attributes.openInNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {}),
141 style: {
142 display: "inline-block",
143 padding: buttonPadding,
144 backgroundColor: attributes.buttonColor,
145 color: attributes.buttonTextColor,
146 textDecoration: "none",
147 borderRadius: attributes.borderRadius + "px",
148 fontWeight: "bold",
149 fontSize: fontSize,
150 width: buttonWidth,
151 textAlign: textAlign,
152 boxSizing: "border-box",
153 transition: "all 0.3s ease-in-out"
154 },
155 "data-hover-color": attributes.buttonHoverColor || attributes.buttonColor
156 }, attributes.buttonText || "버튼 �
157 �스트")
158 );
159 }
160 }],
161 attributes: {
162 buttonText: {
163 type: "string",
164 default: defaultValues.buttonText
165 },
166 buttonUrl: {
167 type: "string",
168 default: defaultValues.buttonUrl
169 },
170 buttonColor: {
171 type: "string",
172 default: defaultValues.buttonColor
173 },
174 buttonTextColor: {
175 type: "string",
176 default: defaultValues.buttonTextColor
177 },
178 buttonHoverColor: {
179 type: "string",
180 default: defaultValues.buttonHoverColor
181 },
182 buttonPosition: {
183 type: "string",
184 default: defaultValues.buttonPosition
185 },
186 buttonSize: {
187 type: "string",
188 default: defaultValues.buttonSize
189 },
190 buttonWidth: {
191 type: "string",
192 default: defaultValues.buttonWidth
193 },
194 openInNewTab: {
195 type: "boolean",
196 default: defaultValues.openInNewTab
197 },
198 buttonAnimation: {
199 type: "string",
200 default: defaultValues.buttonAnimation
201 },
202 infiniteAnimation: {
203 type: "string",
204 default: defaultValues.infiniteAnimation
205 },
206 borderRadius: {
207 type: "number",
208 default: defaultValues.borderRadius
209 }
210 },
211 example: {
212 attributes: {
213 buttonText: "버튼 미리보기",
214 buttonColor: "#2196F3",
215 buttonPosition: "center"
216 }
217 },
218 edit: function(props) {
219 var attributes = props.attributes;
220
221 function onChangeText(newText) {
222 props.setAttributes({ buttonText: newText });
223 }
224
225 function onChangeUrl(newUrl) {
226 props.setAttributes({ buttonUrl: newUrl });
227 }
228
229 function onChangeColor(newColor) {
230 props.setAttributes({ buttonColor: newColor });
231 }
232
233 function onChangeTextColor(newColor) {
234 props.setAttributes({ buttonTextColor: newColor });
235 }
236
237 function onChangeHoverColor(newColor) {
238 props.setAttributes({ buttonHoverColor: newColor });
239 }
240
241 function onChangePosition(newPosition) {
242 props.setAttributes({ buttonPosition: newPosition });
243 }
244
245 function onChangeSize(newSize) {
246 props.setAttributes({ buttonSize: newSize });
247 }
248
249 function onChangeWidth(newWidth) {
250 props.setAttributes({ buttonWidth: newWidth });
251 }
252
253 function onChangeOpenInNewTab(newValue) {
254 props.setAttributes({ openInNewTab: newValue });
255 }
256
257 function onChangeAnimation(newAnimation) {
258 props.setAttributes({ buttonAnimation: newAnimation });
259 }
260
261 function onChangeBorderRadius(newRadius) {
262 props.setAttributes({ borderRadius: newRadius });
263 }
264
265 function savePreset() {
266 var presetData = {
267 buttonColor: attributes.buttonColor,
268 buttonTextColor: attributes.buttonTextColor,
269 buttonHoverColor: attributes.buttonHoverColor,
270 buttonPosition: attributes.buttonPosition,
271 buttonSize: attributes.buttonSize,
272 buttonWidth: attributes.buttonWidth,
273 buttonAnimation: attributes.buttonAnimation,
274 borderRadius: attributes.borderRadius
275 };
276
277 wp.ajax.post(\'presslearn_save_button_preset\', {
278 preset: JSON.stringify(presetData),
279 nonce: presslearn_ajax.nonce
280 }).done(function(response) {
281 savedPreset = presetData;
282 window.presslearnButtonPreset = presetData;
283
284 defaultValues.buttonColor = presetData.buttonColor;
285 defaultValues.buttonTextColor = presetData.buttonTextColor;
286 defaultValues.buttonHoverColor = presetData.buttonHoverColor;
287 defaultValues.buttonPosition = presetData.buttonPosition;
288 defaultValues.buttonSize = presetData.buttonSize;
289 defaultValues.buttonWidth = presetData.buttonWidth;
290 defaultValues.buttonAnimation = presetData.buttonAnimation;
291 defaultValues.borderRadius = presetData.borderRadius;
292
293 var blockType = blocks.getBlockType(\'presslearn/quick-button\');
294 if (blockType && blockType.attributes) {
295 blockType.attributes.buttonColor.default = presetData.buttonColor;
296 blockType.attributes.buttonTextColor.default = presetData.buttonTextColor;
297 blockType.attributes.buttonHoverColor.default = presetData.buttonHoverColor;
298 blockType.attributes.buttonPosition.default = presetData.buttonPosition;
299 blockType.attributes.buttonSize.default = presetData.buttonSize;
300 blockType.attributes.buttonWidth.default = presetData.buttonWidth;
301 blockType.attributes.buttonAnimation.default = presetData.buttonAnimation;
302 blockType.attributes.borderRadius.default = presetData.borderRadius;
303 }
304
305 alert(\'프리�
306 �이 저장되었습니다. 새로운 버튼에 적용됩니다.\');
307 }).fail(function(error) {
308 alert(\'프리�
309 � 저장에 실패했습니다.\');
310 });
311 }
312
313 function deletePreset() {
314 if (confirm(\'저장된 프리�
315 �을 삭제하시겠습니까?\')) {
316 wp.ajax.post(\'presslearn_delete_button_preset\', {
317 nonce: presslearn_ajax.nonce
318 }).done(function(response) {
319 savedPreset = null;
320 window.presslearnButtonPreset = null;
321
322 defaultValues.buttonColor = "#2196F3";
323 defaultValues.buttonTextColor = "#ffffff";
324 defaultValues.buttonHoverColor = "";
325 defaultValues.buttonPosition = "center";
326 defaultValues.buttonSize = "medium";
327 defaultValues.buttonWidth = "default";
328 defaultValues.buttonAnimation = "none";
329 defaultValues.borderRadius = 4;
330
331 var blockType = blocks.getBlockType(\'presslearn/quick-button\');
332 if (blockType && blockType.attributes) {
333 blockType.attributes.buttonColor.default = "#2196F3";
334 blockType.attributes.buttonTextColor.default = "#ffffff";
335 blockType.attributes.buttonHoverColor.default = "";
336 blockType.attributes.buttonPosition.default = "center";
337 blockType.attributes.buttonSize.default = "medium";
338 blockType.attributes.buttonWidth.default = "default";
339 blockType.attributes.buttonAnimation.default = "none";
340 blockType.attributes.borderRadius.default = 4;
341 }
342
343 alert(\'프리�
344 �이 삭제되었습니다. 새로운 버튼은 기본값으로 생성됩니다.\');
345 }).fail(function(error) {
346 alert(\'프리�
347 � 삭제에 실패했습니다.\');
348 });
349 }
350 }
351
352 var buttonPadding;
353 switch(attributes.buttonSize) {
354 case "small":
355 buttonPadding = "8px 16px";
356 break;
357 case "large":
358 buttonPadding = "16px 32px";
359 break;
360 case "xlarge":
361 buttonPadding = "20px 40px";
362 break;
363 default: // medium
364 buttonPadding = "12px 24px";
365 }
366
367 var fontSize;
368 switch(attributes.buttonSize) {
369 case "small":
370 fontSize = "13px";
371 break;
372 case "large":
373 fontSize = "18px";
374 break;
375 case "xlarge":
376 fontSize = "22px";
377 break;
378 default: // medium
379 fontSize = "15px";
380 }
381
382 var buttonWidth = "auto";
383 var textAlign = "inherit";
384 if (attributes.buttonWidth === "half") {
385 buttonWidth = "50%";
386 textAlign = "center";
387 } else if (attributes.buttonWidth === "full") {
388 buttonWidth = "100%";
389 textAlign = "center";
390 }
391
392 var positionControl = null;
393 if (attributes.buttonWidth !== "full") {
394 positionControl = el(PanelRow, {},
395 el(SelectControl, {
396 label: "버튼 위치",
397 value: attributes.buttonPosition,
398 options: [
399 { label: "왼쪽", value: "left" },
400 { label: "가운데", value: "center" },
401 { label: "오른쪽", value: "right" }
402 ],
403 onChange: onChangePosition
404 })
405 );
406 }
407
408 var containerAlignment = attributes.buttonPosition;
409
410 if (attributes.buttonWidth === "full") {
411 containerAlignment = "center";
412 }
413
414 var animationClass = "presslearn-button presslearn-button-animation-" + attributes.buttonAnimation;
415 if (infiniteAnimationEnabled === "yes" && attributes.buttonAnimation !== "none") {
416 animationClass += " presslearn-button-animation-infinite";
417 }
418
419 return [
420 el(InspectorControls, { key: "controls" },
421 el(PanelBody, { title: "버튼 설정", initialOpen: true },
422 el(PanelRow, {},
423 el(TextControl, {
424 label: "버튼 �
425 �스트",
426 value: attributes.buttonText,
427 onChange: onChangeText
428 })
429 ),
430 el(PanelRow, {},
431 el(TextControl, {
432 label: "버튼 URL",
433 value: attributes.buttonUrl,
434 onChange: onChangeUrl
435 })
436 ),
437 el(PanelRow, {},
438 el(components.ToggleControl, {
439 label: "새 탭에서 열기",
440 checked: attributes.openInNewTab,
441 onChange: onChangeOpenInNewTab
442 })
443 ),
444 el(PanelRow, {},
445 el("div", { className: "components-base-control" },
446 el("label", { className: "components-base-control__label" }, "버튼 배경 색상"),
447 el(ColorPalette, {
448 value: attributes.buttonColor,
449 onChange: onChangeColor,
450 clearable: false
451 })
452 )
453 ),
454 el(PanelRow, {},
455 el("div", { className: "components-base-control" },
456 el("label", { className: "components-base-control__label" }, "버튼 글씨 색상"),
457 el(ColorPalette, {
458 value: attributes.buttonTextColor,
459 onChange: onChangeTextColor,
460 clearable: false
461 })
462 )
463 ),
464 el(PanelRow, {},
465 el("div", { className: "components-base-control" },
466 el("label", { className: "components-base-control__label" }, "마우스 오버시 배경 색상"),
467 el(ColorPalette, {
468 value: attributes.buttonHoverColor,
469 onChange: onChangeHoverColor,
470 clearable: true
471 })
472 )
473 ),
474 el(PanelRow, {},
475 el(SelectControl, {
476 label: "버튼 가로 크기",
477 value: attributes.buttonWidth,
478 options: [
479 { label: "기본", value: "default" },
480 { label: "절반", value: "half" },
481 { label: "꽉찬", value: "full" }
482 ],
483 onChange: onChangeWidth
484 })
485 ),
486 positionControl,
487 el(PanelRow, {},
488 el(SelectControl, {
489 label: "버튼 크기",
490 value: attributes.buttonSize,
491 options: [
492 { label: "작게", value: "small" },
493 { label: "중간", value: "medium" },
494 { label: "크게", value: "large" },
495 { label: "매우 크게", value: "xlarge" }
496 ],
497 onChange: onChangeSize
498 })
499 ),
500 el(PanelRow, {},
501 el(SelectControl, {
502 label: "애니메이�
503 � 효과",
504 value: attributes.buttonAnimation,
505 options: [
506 { label: "없음", value: "none" },
507 { label: "펄스", value: "pulse" },
508 { label: "줌", value: "zoom" },
509 { label: "페이드", value: "fade" },
510 { label: "떨림", value: "shake" }
511 ],
512 onChange: onChangeAnimation
513 })
514 ),
515 el(PanelRow, {},
516 el("div", { className: "components-base-control", style: { width: "100%" } },
517 el("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "8px" } },
518 el("label", {
519 className: "components-base-control__label",
520 style: { margin: 0, fontWeight: "regular",fontSize: "11px", flex: "0 0 80%" }
521 }, "모서리 둥글기"),
522 el("span", {
523 style: {
524 flex: "0 0 20%",
525 textAlign: "right",
526 fontWeight: "regular",
527 color: "#8b95a1"
528 }
529 }, attributes.borderRadius + "px")
530 ),
531 el(components.RangeControl, {
532 value: attributes.borderRadius,
533 onChange: onChangeBorderRadius,
534 min: 0,
535 max: 50,
536 step: 1,
537 withInputField: false,
538 style: { marginTop: "4px" }
539 })
540 )
541 )
542 ),
543 el(PanelBody, { title: "프리�
544 �", initialOpen: false },
545 savedPreset ? el(PanelRow, {},
546 el("div", { style: { width: "100%" } },
547 el("p", { style: { marginTop: 0, marginBottom: "10px", color: "#666" } }, "프리�
548 �이 적용된 버튼�
549 니다.")
550 )
551 ) : null,
552 el(PanelRow, {},
553 el(components.ButtonGroup, { style: { display: "flex" , width: "100%" , justifyContent: "space-between" , flexDirection: "column" , gap: "10px" , boxSizing: "border-box" } },
554 el(components.Button, {
555 isPrimary: true,
556 onClick: savePreset,
557 style: { flex: 1 , boxSizing: "border-box" , outline: "none" , boxShadow: "none" }
558 }, "현재 프리�
559 � 저장"),
560 savedPreset ? el(components.Button, {
561 isSecondary: true,
562 onClick: deletePreset,
563 style: { flex: 1 , boxSizing: "border-box" , outline: "none" , boxShadow: "none" , border: "1px solid #e1e4e8"}
564 }, "프리�
565 � 삭제") : null
566 )
567 )
568 )
569 ),
570 el("div", { className: "presslearn-button-block-editor" },
571 el("div", {
572 className: "presslearn-button-container",
573 style: { textAlign: containerAlignment }
574 },
575 el("a", {
576 className: animationClass,
577 href: "#",
578 style: {
579 display: "inline-block",
580 padding: buttonPadding,
581 backgroundColor: attributes.buttonColor,
582 color: attributes.buttonTextColor,
583 textDecoration: "none",
584 borderRadius: attributes.borderRadius + "px",
585 fontWeight: "bold",
586 fontSize: fontSize,
587 width: buttonWidth,
588 textAlign: textAlign,
589 boxSizing: "border-box",
590 transition: "all 0.3s ease-in-out"
591 },
592 "data-hover-color": attributes.buttonHoverColor || attributes.buttonColor
593 }, attributes.buttonText || "버튼 �
594 �스트")
595 )
596 )
597 ];
598 },
599 save: function(props) {
600 var attributes = props.attributes;
601
602 var buttonPadding;
603 switch(attributes.buttonSize) {
604 case "small":
605 buttonPadding = "8px 16px";
606 break;
607 case "large":
608 buttonPadding = "16px 32px";
609 break;
610 case "xlarge":
611 buttonPadding = "20px 40px";
612 break;
613 default: // medium
614 buttonPadding = "12px 24px";
615 }
616
617 var fontSize;
618 switch(attributes.buttonSize) {
619 case "small":
620 fontSize = "13px";
621 break;
622 case "large":
623 fontSize = "18px";
624 break;
625 case "xlarge":
626 fontSize = "22px";
627 break;
628 default: // medium
629 fontSize = "15px";
630 }
631
632 var buttonWidth = "auto";
633 var textAlign = "inherit";
634 if (attributes.buttonWidth === "half") {
635 buttonWidth = "50%";
636 textAlign = "center";
637 } else if (attributes.buttonWidth === "full") {
638 buttonWidth = "100%";
639 textAlign = "center";
640 }
641
642 var containerAlignment = attributes.buttonPosition;
643
644 if (attributes.buttonWidth === "full") {
645 containerAlignment = "center";
646 }
647
648 var animationClass = "presslearn-button presslearn-button-animation-" + attributes.buttonAnimation;
649 if (infiniteAnimationEnabled === "yes" && attributes.buttonAnimation !== "none") {
650 animationClass += " presslearn-button-animation-infinite";
651 }
652
653 return el("div", {
654 className: "presslearn-button-container",
655 style: { textAlign: containerAlignment, margin: "20px 0" }
656 },
657 el("a", {
658 className: animationClass,
659 href: attributes.buttonUrl || "#",
660 ...(attributes.openInNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {}),
661 style: {
662 display: "inline-block",
663 padding: buttonPadding,
664 backgroundColor: attributes.buttonColor,
665 color: attributes.buttonTextColor,
666 textDecoration: "none",
667 borderRadius: attributes.borderRadius + "px",
668 fontWeight: "bold",
669 fontSize: fontSize,
670 width: buttonWidth,
671 textAlign: textAlign,
672 boxSizing: "border-box",
673 transition: "all 0.3s ease-in-out"
674 },
675 "data-hover-color": attributes.buttonHoverColor || attributes.buttonColor
676 }, attributes.buttonText || "버튼 �
677 �스트")
678 );
679 }
680 });
681 })(
682 window.wp.blocks,
683 window.wp.element,
684 window.wp.components,
685 window.wp.blockEditor
686 );
687 ');
688
689 register_block_type('presslearn/quick-button', array(
690 'editor_script' => 'presslearn-quick-button-block',
691 'render_callback' => 'presslearn_render_quick_button',
692 'attributes' => array(
693 'buttonText' => array(
694 'type' => 'string',
695 'default' => '버튼 �
696 �스트'
697 ),
698 'buttonUrl' => array(
699 'type' => 'string',
700 'default' => '#'
701 ),
702 'buttonColor' => array(
703 'type' => 'string',
704 'default' => '#2196F3'
705 ),
706 'buttonTextColor' => array(
707 'type' => 'string',
708 'default' => '#ffffff'
709 ),
710 'buttonHoverColor' => array(
711 'type' => 'string',
712 'default' => ''
713 ),
714 'buttonPosition' => array(
715 'type' => 'string',
716 'default' => 'center'
717 ),
718 'buttonSize' => array(
719 'type' => 'string',
720 'default' => 'medium'
721 ),
722 'buttonWidth' => array(
723 'type' => 'string',
724 'default' => 'default'
725 ),
726 'openInNewTab' => array(
727 'type' => 'boolean',
728 'default' => false
729 ),
730 'buttonAnimation' => array(
731 'type' => 'string',
732 'default' => 'none'
733 ),
734 'infiniteAnimation' => array(
735 'type' => 'string',
736 'default' => 'yes'
737 ),
738 'borderRadius' => array(
739 'type' => 'number',
740 'default' => 4
741 )
742 )
743 ));
744
745 add_filter('block_categories_all', function($categories) {
746 return array_merge(
747 $categories,
748 array(
749 array(
750 'slug' => 'presslearn',
751 'title' => 'PressLearn',
752 'icon' => null,
753 ),
754 )
755 );
756 });
757 }
758 add_action('init', 'presslearn_register_quick_button_block');
759
760 function presslearn_render_quick_button($attributes, $content) {
761 if (!empty($content)) {
762 return $content;
763 }
764
765
766 if (!isset($attributes['borderRadius'])) {
767 $attributes['borderRadius'] = 4;
768 }
769
770 $attributes = wp_parse_args($attributes, array(
771 'buttonText' => '버튼 �
772 �스트',
773 'buttonUrl' => '#',
774 'buttonColor' => '#2196F3',
775 'buttonTextColor' => '#ffffff',
776 'buttonHoverColor' => '',
777 'buttonPosition' => 'center',
778 'buttonSize' => 'medium',
779 'buttonWidth' => 'default',
780 'openInNewTab' => false,
781 'buttonAnimation' => 'none',
782 'infiniteAnimation' => 'yes',
783 'borderRadius' => 4
784 ));
785
786
787 $button_padding = '12px 24px';
788 switch ($attributes['buttonSize']) {
789 case 'small':
790 $button_padding = '8px 16px';
791 break;
792 case 'large':
793 $button_padding = '16px 32px';
794 break;
795 case 'xlarge':
796 $button_padding = '20px 40px';
797 break;
798 }
799
800 $font_size = '15px';
801 switch ($attributes['buttonSize']) {
802 case 'small':
803 $font_size = '13px';
804 break;
805 case 'large':
806 $font_size = '18px';
807 break;
808 case 'xlarge':
809 $font_size = '22px';
810 break;
811 }
812
813 $button_width = 'auto';
814 $text_align = 'inherit';
815 if ($attributes['buttonWidth'] === 'half') {
816 $button_width = '50%';
817 $text_align = 'center';
818 } else if ($attributes['buttonWidth'] === 'full') {
819 $button_width = '100%';
820 $text_align = 'center';
821 }
822
823 $container_alignment = $attributes['buttonPosition'];
824 if ($attributes['buttonWidth'] === 'full') {
825 $container_alignment = 'center';
826 }
827
828 $animation_class = 'presslearn-button presslearn-button-animation-' . $attributes['buttonAnimation'];
829 $button_transition_enabled = get_option('presslearn_button_transition_enabled', 'no');
830 if ($button_transition_enabled === 'yes' && $attributes['buttonAnimation'] !== 'none') {
831 $animation_class .= ' presslearn-button-animation-infinite';
832 }
833
834 $target_attr = $attributes['openInNewTab'] ? ' target="_blank"' : '';
835 $rel_attr = $attributes['openInNewTab'] ? ' rel="noopener noreferrer"' : '';
836
837 $output = '<div class="presslearn-button-container" style="text-align:' . esc_attr($container_alignment) . ';margin:20px 0">';
838 $output .= '<a class="' . esc_attr($animation_class) . '" href="' . esc_url($attributes['buttonUrl']) . '"' . $target_attr . $rel_attr;
839 $output .= ' style="display:inline-block;padding:' . esc_attr($button_padding) . ';background-color:' . esc_attr($attributes['buttonColor']) . ';';
840 $output .= 'color:' . esc_attr($attributes['buttonTextColor']) . ';text-decoration:none;border-radius:' . esc_attr($attributes['borderRadius']) . 'px;font-weight:bold;';
841 $output .= 'font-size:' . esc_attr($font_size) . ';width:' . esc_attr($button_width) . ';text-align:' . esc_attr($text_align) . ';';
842 $output .= 'box-sizing:border-box;transition:all 0.3s ease-in-out" data-hover-color="' . esc_attr($attributes['buttonHoverColor'] ?: $attributes['buttonColor']) . '">';
843 $output .= esc_html($attributes['buttonText'] ?: '버튼 �
844 �스트') . '</a>';
845 $output .= '</div>';
846
847 return $output;
848 }
849
850 function presslearn_quick_button_admin_styles() {
851 if (!presslearn_is_plugin_active_for_buttons()) {
852 return;
853 }
854
855 $quick_button_enabled = get_option('presslearn_quick_button_enabled', 'no');
856 if ($quick_button_enabled !== 'yes') {
857 return;
858 }
859
860 wp_register_style('presslearn-button-admin-styles', false);
861 wp_enqueue_style('presslearn-button-admin-styles');
862
863 $admin_styles = '
864 .presslearn-button-block-editor {
865 padding: 20px;
866 background: #f5f5f5;
867 border-radius: 4px;
868 margin-bottom: 10px;
869 }
870
871 .editor-styles-wrapper .presslearn-button:focus,
872 .editor-styles-wrapper .presslearn-button:hover {
873 color: #fff !important;
874 opacity: 0.9;
875 }
876
877 .block-editor-block-inspector .components-base-control .components-text-control__input,
878 .block-editor-block-inspector .components-base-control .components-select-control__input {
879 width: 100% !important;
880 box-sizing: border-box !important;
881 }
882
883 .components-panel__body .components-base-control {
884 width: 100%;
885 }
886
887 .presslearn-button-animation-pulse {
888 animation: plButtonPulse 2s ease-in-out;
889 }
890 .presslearn-button-animation-zoom {
891 animation: plButtonZoom 2s ease-in-out;
892 }
893 .presslearn-button-animation-fade {
894 animation: plButtonFade 2s ease-in-out;
895 }
896 .presslearn-button-animation-shake {
897 animation: plButtonShake 2s ease-in-out;
898 }
899
900 .presslearn-button-animation-infinite {
901 animation-iteration-count: infinite !important;
902 }
903
904 @keyframes plButtonPulse {
905 0% { transform: scale(1); }
906 50% { transform: scale(1.05); }
907 100% { transform: scale(1); }
908 }
909
910 @keyframes plButtonZoom {
911 0% { transform: scale(1); }
912 50% { transform: scale(1.1); }
913 100% { transform: scale(1); }
914 }
915
916 @keyframes plButtonFade {
917 0% { opacity: 1; }
918 50% { opacity: 0.7; }
919 100% { opacity: 1; }
920 }
921
922 @keyframes plButtonShake {
923 0%, 100% { transform: translateX(0); }
924 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
925 20%, 40%, 60%, 80% { transform: translateX(5px); }
926 }
927 ';
928
929 wp_add_inline_style('presslearn-button-admin-styles', $admin_styles);
930 }
931 add_action('admin_enqueue_scripts', 'presslearn_quick_button_admin_styles');
932
933 function presslearn_quick_button_frontend_styles() {
934 if (!presslearn_is_plugin_active_for_buttons()) {
935 return;
936 }
937
938 $quick_button_enabled = get_option('presslearn_quick_button_enabled', 'no');
939 if ($quick_button_enabled !== 'yes') {
940 return;
941 }
942
943 wp_register_style('presslearn-button-frontend-styles', false);
944 wp_enqueue_style('presslearn-button-frontend-styles');
945
946 $frontend_styles = '
947 .presslearn-button-animation-pulse {
948 animation: plButtonPulse 2s ease-in-out;
949 }
950 .presslearn-button-animation-zoom {
951 animation: plButtonZoom 2s ease-in-out;
952 }
953 .presslearn-button-animation-fade {
954 animation: plButtonFade 2s ease-in-out;
955 }
956 .presslearn-button-animation-shake {
957 animation: plButtonShake 2s ease-in-out;
958 }
959
960 .presslearn-button-animation-infinite {
961 animation-iteration-count: infinite !important;
962 }
963
964 @keyframes plButtonPulse {
965 0% { transform: scale(1); }
966 50% { transform: scale(1.05); }
967 100% { transform: scale(1); }
968 }
969
970 @keyframes plButtonZoom {
971 0% { transform: scale(1); }
972 50% { transform: scale(1.1); }
973 100% { transform: scale(1); }
974 }
975
976 @keyframes plButtonFade {
977 0% { opacity: 1; }
978 50% { opacity: 0.7; }
979 100% { opacity: 1; }
980 }
981
982 @keyframes plButtonShake {
983 0%, 100% { transform: translateX(0); }
984 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
985 20%, 40%, 60%, 80% { transform: translateX(5px); }
986 }
987
988 .presslearn-button:hover {
989 opacity: 0.9;
990 }
991 ';
992
993 wp_add_inline_style('presslearn-button-frontend-styles', $frontend_styles);
994 }
995 add_action('wp_enqueue_scripts', 'presslearn_quick_button_frontend_styles');
996
997 function presslearn_quick_button_frontend_scripts() {
998 if (!presslearn_is_plugin_active_for_buttons()) {
999 return;
1000 }
1001
1002 $quick_button_enabled = get_option('presslearn_quick_button_enabled', 'no');
1003 if ($quick_button_enabled !== 'yes') {
1004 return;
1005 }
1006
1007 wp_register_script('presslearn-button-frontend-script', false, array('jquery'), time(), true);
1008 wp_enqueue_script('presslearn-button-frontend-script');
1009
1010 $script = '
1011 jQuery(document).ready(function($) {
1012 $(document).on("mouseenter", ".presslearn-button", function() {
1013 var $this = $(this);
1014 var hoverColor = $this.attr("data-hover-color");
1015 if (hoverColor) {
1016 $this.data("original-color", $this.css("background-color"));
1017 $this.css("background-color", hoverColor);
1018 }
1019 });
1020
1021 $(document).on("mouseleave", ".presslearn-button", function() {
1022 var $this = $(this);
1023 var originalColor = $this.data("original-color");
1024 if (originalColor) {
1025 $this.css("background-color", originalColor);
1026 }
1027 });
1028 });
1029 ';
1030
1031 wp_add_inline_script('presslearn-button-frontend-script', $script);
1032 }
1033 add_action('wp_enqueue_scripts', 'presslearn_quick_button_frontend_scripts');
1034
1035 function presslearn_save_button_preset() {
1036 check_ajax_referer('presslearn_button_preset', 'nonce');
1037
1038 if (!current_user_can('edit_posts')) {
1039 wp_send_json_error('권한이 없습니다.');
1040 }
1041
1042 $preset_data = isset($_POST['preset']) ? stripslashes($_POST['preset']) : '';
1043
1044 if (empty($preset_data)) {
1045 wp_send_json_error('프리�
1046 � 데이터가 없습니다.');
1047 }
1048
1049 $preset = json_decode($preset_data, true);
1050
1051 if (json_last_error() !== JSON_ERROR_NONE) {
1052 wp_send_json_error('잘못된 프리�
1053 � 데이터�
1054 니다.');
1055 }
1056
1057 update_option('presslearn_button_preset', $preset);
1058 wp_send_json_success('프리�
1059 �이 저장되었습니다.');
1060 }
1061 add_action('wp_ajax_presslearn_save_button_preset', 'presslearn_save_button_preset');
1062
1063 function presslearn_delete_button_preset() {
1064 check_ajax_referer('presslearn_button_preset', 'nonce');
1065
1066 if (!current_user_can('edit_posts')) {
1067 wp_send_json_error('권한이 없습니다.');
1068 }
1069
1070 delete_option('presslearn_button_preset');
1071 wp_send_json_success('프리�
1072 �이 삭제되었습니다.');
1073 }
1074 add_action('wp_ajax_presslearn_delete_button_preset', 'presslearn_delete_button_preset');
1075