first commit
BIN
admin/.DS_Store
vendored
Normal file
3
admin/assets/css/admin-customers.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.table-toolbar {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
267
admin/assets/css/admin-editor.css
Normal file
@@ -0,0 +1,267 @@
|
||||
input.formipay-post-shortcode-input {
|
||||
padding: 0.5em;
|
||||
background-color: #efefef;
|
||||
color: #2c3338;
|
||||
border: 1px solid #2c3338;
|
||||
border-radius: .5em;
|
||||
}
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
#titlediv #title-prompt-text {
|
||||
padding: 3px 10px;
|
||||
}
|
||||
.editor-styles-wrapper h1 {
|
||||
font-size: 24px!important;
|
||||
margin: unset!important;
|
||||
width: 100%;
|
||||
max-width: 100%!important;
|
||||
border: 1px solid #ccc;
|
||||
padding: .25rem 1rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
#sidebar_panel {
|
||||
background-color: #2c3e50;
|
||||
flex: 0 0 273px;
|
||||
}
|
||||
#fields_panel {
|
||||
background-color: #f0f3f5;
|
||||
flex: 1 1 calc(100% - 273px);
|
||||
}
|
||||
#preview-wrapper {
|
||||
border: 3px dashed #ccc;
|
||||
padding: 1.8rem 1rem;
|
||||
max-width: 500px;
|
||||
margin: auto;
|
||||
border-radius: 1rem
|
||||
}
|
||||
#add_field_form {
|
||||
position: sticky;
|
||||
top: 140px;
|
||||
}
|
||||
#add_field_form input[type=text],
|
||||
#add_field_form select,
|
||||
div#preview-wrapper input:not([type=checkbox],[type=radio]),
|
||||
div#preview-wrapper select {
|
||||
border-radius: 5px;
|
||||
border: 1px solid #bec5cb;
|
||||
background-color: #ffffff;
|
||||
height: 40px;
|
||||
padding: 6px 16px;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
.label-divider, .label-page_break {
|
||||
font-size: larger;
|
||||
font-weight: bold;
|
||||
}
|
||||
span.divider-line {
|
||||
border-top: 1px dashed #ccc;
|
||||
display: block;
|
||||
}
|
||||
.preview-field{
|
||||
position: relative;
|
||||
}
|
||||
[data-field-type="page_break"] {
|
||||
border-top: 2px dashed #a3a3a3;
|
||||
padding-top: .5em;
|
||||
}
|
||||
span.grab {
|
||||
cursor: grab;
|
||||
}
|
||||
.the_buttons > button {
|
||||
padding: .15rem!important;
|
||||
}
|
||||
.the_buttons svg {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
#preview-wrapper .the_buttons svg path {
|
||||
fill: #ccc!important;
|
||||
stroke: #ccc!important;
|
||||
}
|
||||
.the_buttons > button svg {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
#preview-wrapper .the_buttons > button:hover svg path {
|
||||
fill: #666!important;
|
||||
stroke: #666!important;
|
||||
}
|
||||
span.scissors {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: -10px;
|
||||
}
|
||||
.field-icons.the_buttons button {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 50%;
|
||||
color: #ccc!important;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
.field-icons.the_buttons button:hover {
|
||||
border: 1px solid #666;
|
||||
border-radius: 50%;
|
||||
color: #666!important;
|
||||
margin-bottom: .5em;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.field-icons i {
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
}
|
||||
.field-icons i:hover {
|
||||
color: #555;
|
||||
}
|
||||
.form-check.form-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.form-switch .form-check-input {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.wp-core-ui.wp-editor-wrap {
|
||||
margin-top: -2.5em;
|
||||
}
|
||||
.form-check.formipay-radio-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .5em;
|
||||
}
|
||||
.form-check.formipay-radio-group > input::before {
|
||||
background-color: white;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance {
|
||||
padding-right: 0!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance .row {
|
||||
margin-left: 0!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance .column {
|
||||
padding: 1.8rem!important;
|
||||
}
|
||||
.wpcfto-tab.active {
|
||||
padding-right: 0!important;
|
||||
}
|
||||
.wpcfto-tab.active > .container > .row {
|
||||
margin: 0!important;
|
||||
}
|
||||
.wpcfto-repeater-single:not(:first-child) {
|
||||
border-top: 1px solid #ccc!important;
|
||||
}
|
||||
.wpcfto_settings_head+.stm_metaboxes_grid .stm_metaboxes_grid__inner .row .column {
|
||||
padding-right: 1.8rem!important;
|
||||
}
|
||||
.wpcfto_group_started .wpcfto_generic_field_editor {
|
||||
padding: 0!important;
|
||||
}
|
||||
#formipay .inside, #formipay_canvas .inside {
|
||||
padding: 0!important;
|
||||
margin: 0!important;
|
||||
}
|
||||
#payments .wpcfto-field-content .wpcfto_multi_checkbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#payments .wpcfto-field-content .wpcfto_multi_checkbox > label {
|
||||
width: 100%;
|
||||
}
|
||||
.formipay-checkbox-wrapper {
|
||||
display: grid;
|
||||
}
|
||||
.trumbowyg-textarea {
|
||||
min-height: 14em !important;
|
||||
height: unset!important;
|
||||
}
|
||||
.wpcfto-editor span.ql-formats:nth-last-child(3) {
|
||||
display: none!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner, .wpcfto_settings_head {
|
||||
max-width: unset!important;
|
||||
}
|
||||
.wpcfto-box-child.repeater {
|
||||
padding-top: 0;
|
||||
padding-right: calc(var(--bs-gutter-x) * .5);
|
||||
padding-left: calc(var(--bs-gutter-x) * .5);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
#inactive.wpcfto_sorter_single > h6 {
|
||||
background-color: #999999;
|
||||
}
|
||||
.dropzone {
|
||||
border: 2px dashed #0073aa;
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
transition: background-color 0.3s;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dropzone-area {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropzone-area:hover {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
#thumbnailPreview {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#previewImage {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#uploadStatus {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
.child-field-title {
|
||||
border-radius: 10px;
|
||||
}
|
||||
.child-field-title.option-detail-opened {
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
.child-field-wrapper {
|
||||
border-top: unset;
|
||||
background-color: #666;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
.table>:not(caption)>*>* {
|
||||
background-color: unset!important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.table.child-field-input-table tr:last-child th,
|
||||
.table.child-field-input-table tr:last-child td {
|
||||
border-bottom: unset!important;
|
||||
}
|
||||
.child-field-image-wrapper {
|
||||
border: 4px dashed #cccccc;
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: .5em;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.the_buttons button {
|
||||
font-size: 10px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.child-fields-wrapper table th {
|
||||
vertical-align: top;
|
||||
}
|
||||
.trumbowyg-modal.trumbowyg-fixed-top {
|
||||
display: none;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
.sortable {
|
||||
touch-action: none;
|
||||
}
|
||||
52
admin/assets/css/admin-global.css
Normal file
@@ -0,0 +1,52 @@
|
||||
li#toplevel_page_formipay .wp-menu-image img {
|
||||
width: 18px;
|
||||
}
|
||||
li#toplevel_page_formipay a[href^="admin.php?page=formipay-orders"]:before,
|
||||
li#toplevel_page_formipay a[href^="admin.php?page=formipay-settings"]:before{
|
||||
border-bottom: 1px solid hsla(0, 0%, 100%, .2);
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 8px -15px 13px;
|
||||
content: "";
|
||||
width: calc(100% + 26px);
|
||||
}
|
||||
/** CHOICES */
|
||||
.category > .choices {
|
||||
min-width: 200px;
|
||||
}
|
||||
.choices__inner {
|
||||
max-width: 100%;
|
||||
width: unset;
|
||||
display: block;
|
||||
min-height: unset!important;
|
||||
padding: 2px!important;
|
||||
border: 1px solid #b7b7b7!important;
|
||||
border-radius: .5em!important;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.choices__list {
|
||||
display: block;
|
||||
}
|
||||
.choices__list:not(.choices__list--dropdown) {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
.choices__list.choices__list--dropdown {
|
||||
margin-top: .5em;
|
||||
border-radius: .5em;
|
||||
}
|
||||
.choices__list.choices__list--dropdown > .choices__list {
|
||||
padding: 0;
|
||||
}
|
||||
.choices__item.choices__item--choice.is-selected.choices__item--selectable.is-highlighted {
|
||||
background-color: #277aff25!important;
|
||||
}
|
||||
/** END CHOICES */
|
||||
|
||||
.wp-submenu-wrap li:has(a[href="edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product"]) {
|
||||
display: none;
|
||||
}
|
||||
.wp-submenu-wrap li:has(a[href="admin.php?page=formipay-products"]).current ~ li:has(a[href="edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product"]),
|
||||
.wp-submenu-wrap li:has(a[href="admin.php?page=formipay-products"]):hover ~ li:has(a[href="edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product"]),
|
||||
.wp-submenu-wrap li:has(a[href="edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product"]).current {
|
||||
display: block;
|
||||
}
|
||||
93
admin/assets/css/admin-order-details.css
Normal file
@@ -0,0 +1,93 @@
|
||||
table#order-items-table th {
|
||||
width: 60%;
|
||||
}
|
||||
table#order-items-table td {
|
||||
width: 40%;
|
||||
text-align: right
|
||||
}
|
||||
table#order-items-table #order-total {
|
||||
color: #277aff!important;
|
||||
font-size: larger;
|
||||
font-weight: bold
|
||||
}
|
||||
.card {
|
||||
max-width: unset!important;
|
||||
}
|
||||
.card-header {
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
b.field-name {
|
||||
text-transform: capitalize;
|
||||
font-size: smaller;
|
||||
}
|
||||
.media, .recipient-type, .notification-status {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
/** Timeline Trx Tracking **/
|
||||
.rb-container {
|
||||
width: 50%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rb-container ul.rb {
|
||||
margin: 2.5em 0 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rb-container ul.rb li {
|
||||
list-style: none;
|
||||
margin: auto;
|
||||
min-height: 50px;
|
||||
border-left: 1px dashed #000;
|
||||
padding: 0 0 50px 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rb-container ul.rb li:last-child {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.rb-container ul.rb li::before {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: 0;
|
||||
content: " ";
|
||||
border: 10px solid rgba(0, 0, 0, 1);
|
||||
border-radius: 500%;
|
||||
background: #277aff;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
transition: all 500ms ease-in-out;
|
||||
}
|
||||
|
||||
.rb-container ul.rb li:hover::before {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
ul.rb li .timestamp {
|
||||
color: #277aff;
|
||||
position: relative;
|
||||
font-size: smaller;
|
||||
}
|
||||
input, select, .form-control, .form-select {
|
||||
height: 40px;
|
||||
}
|
||||
#order_status {
|
||||
width: 200px;
|
||||
}
|
||||
.access-link-wrapper {
|
||||
display: flex!important;
|
||||
}
|
||||
.access-link-wrapper > input {
|
||||
flex: 0 0 calc(100% - 100px)!important;
|
||||
}
|
||||
.access-link-wrapper > button {
|
||||
flex: 0 0 100px!important;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
43
admin/assets/css/admin-orders.css
Normal file
@@ -0,0 +1,43 @@
|
||||
#formipay-orders table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
th.gridjs-th[data-column-id=id],
|
||||
th.gridjs-th[data-column-id=date],
|
||||
th.gridjs-th[data-column-id=total],
|
||||
th.gridjs-th[data-column-id=paymentGateway],
|
||||
th.gridjs-th[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
td.gridjs-td[data-column-id=id],
|
||||
td.gridjs-td[data-column-id=paymentGateway],
|
||||
td.gridjs-td[data-column-id=date],
|
||||
td.gridjs-td[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
span.grand_total {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
span.grand_total img {
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
span:has(.status-label) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
span.status-label {
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
text-transform: capitalize;
|
||||
background-color: #999999;
|
||||
color: white;
|
||||
}
|
||||
span.status-label.Completed {
|
||||
background-color: #277aff;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
217
admin/assets/css/admin-pages.css
Normal file
@@ -0,0 +1,217 @@
|
||||
body {
|
||||
background-color: #f0f0f1!important;
|
||||
}
|
||||
#screen-meta-links:not(:has(button.screen-meta-active)), #screen-meta {
|
||||
margin-top: -2em;
|
||||
}
|
||||
/** Header **/
|
||||
div#wpbody-content {
|
||||
position: relative;
|
||||
}
|
||||
.formipay-screen-menu {
|
||||
margin-left: -20px;
|
||||
margin-bottom: 2em;
|
||||
padding: 10px 20px 10px 50px;
|
||||
background-color: white;
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: center;
|
||||
position: sticky;
|
||||
top: 32px;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
box-shadow: 0 10px 20px #d2d2d2
|
||||
}
|
||||
.formipay-screen-menu h1 {
|
||||
font-size: 24px!important;
|
||||
color: #1d2327;
|
||||
margin: .67em 0;
|
||||
}
|
||||
.screen-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
}
|
||||
.formipay-screen-menu > img {
|
||||
width: 56px;
|
||||
}
|
||||
/** END Header **/
|
||||
|
||||
/** Metabox */
|
||||
.stm_metaboxes_grid__inner .wpcfto-tab {
|
||||
padding: 0!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance {
|
||||
padding-right: 0!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance .row {
|
||||
margin-left: 0!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner #appearance .column {
|
||||
padding: 1.8rem!important;
|
||||
}
|
||||
.wpcfto-tab.active {
|
||||
padding-right: 0!important;
|
||||
}
|
||||
.wpcfto-tab.active > .container > .row {
|
||||
margin: 0!important;
|
||||
}
|
||||
.wpcfto-repeater-single:not(:first-child) {
|
||||
border-top: 1px solid #ccc!important;
|
||||
}
|
||||
.wpcfto_settings_head+.stm_metaboxes_grid .stm_metaboxes_grid__inner .row .column {
|
||||
padding-right: 1.8rem!important;
|
||||
}
|
||||
.wpcfto_group_started .wpcfto_generic_field_editor {
|
||||
padding: 0!important;
|
||||
}
|
||||
.trumbowyg-textarea {
|
||||
min-height: 14em !important;
|
||||
height: unset!important;
|
||||
}
|
||||
.wpcfto-editor span.ql-formats:nth-last-child(3) {
|
||||
display: none!important;
|
||||
}
|
||||
.stm_metaboxes_grid__inner, .wpcfto_settings_head {
|
||||
max-width: unset!important;
|
||||
}
|
||||
.wpcfto-box-child.repeater {
|
||||
padding-top: 0;
|
||||
padding-right: calc(var(--bs-gutter-x) * .5);
|
||||
padding-left: calc(var(--bs-gutter-x) * .5);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
#inactive.wpcfto_sorter_single > h6 {
|
||||
background-color: #999999;
|
||||
}
|
||||
.wpcfto_sorter .list-group-item.disable {
|
||||
color: #8c99a5;
|
||||
background-color: #efefef;
|
||||
}
|
||||
.wpcfto_sorter .list-group-item.disable:hover {
|
||||
color: #f72657;
|
||||
}
|
||||
.wpcfto_sorter .list-group-item i {
|
||||
float: right;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.choices {
|
||||
overflow: visible!important;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
/** Table **/
|
||||
.post-action a {
|
||||
text-decoration: none;
|
||||
}
|
||||
button#formipay-delete-selected {
|
||||
min-height: 44px;
|
||||
margin-bottom: 0!important;
|
||||
border-radius: .5rem;
|
||||
color: #58151c;
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-radius: .5em;
|
||||
border: 1px solid #58151c;
|
||||
background-color: #f1aeb5;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.post-status-wrapper {
|
||||
display: flex;
|
||||
gap: .5rem;
|
||||
align-items: center;
|
||||
}
|
||||
.post-status-wrapper a {
|
||||
color: #999999;
|
||||
cursor: pointer;
|
||||
}
|
||||
.post-status-wrapper a[data-active=true] {
|
||||
color: #277aff;
|
||||
font-weight: bold;
|
||||
}
|
||||
table.gridjs-table th, button.gridjs-currentPage {
|
||||
background: #277aff!important;
|
||||
color: #ffffff;
|
||||
}
|
||||
table.gridjs-table tr *:is(th, td):first-child {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.gridjs-pagination button:hover {
|
||||
background-color: #277aff!important;
|
||||
color: white!important;
|
||||
}
|
||||
.gridjs-head {
|
||||
display: none;
|
||||
}
|
||||
#reset-filter {
|
||||
color: #277aff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
gap: .5em;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.filter-bar select, .filter-bar input{
|
||||
padding: .5em 1em;
|
||||
border-radius: .5em;
|
||||
color: #666666 !important;
|
||||
border: 1px solid #b7b7b7 !important;
|
||||
min-height: 44px !important;
|
||||
}
|
||||
.filter-bar select {
|
||||
padding-right: 1.75em;
|
||||
}
|
||||
.gridjs-pages > * {
|
||||
padding: 1em 1.5em!important;
|
||||
}
|
||||
/** END Table **/
|
||||
|
||||
/** SweetAlert2 **/
|
||||
button.swal2-confirm.swal2-styled {
|
||||
background-color: rgb(39, 122, 255)!important;
|
||||
}
|
||||
div:where(.swal2-container) button:where(.swal2-styled).swal2-confirm:focus {
|
||||
box-shadow: 0 0 0 3px rgba(39, 122, 255, .5)!important;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
/** END SweetAlert2 **/
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.formipay-screen-menu {
|
||||
top: 0;
|
||||
align-items: start;
|
||||
}
|
||||
.screen-title h1 {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
.screen-title {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.filter-bar {
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
}
|
||||
.filter-bar,
|
||||
.filter-bar > *:not(:first-child),
|
||||
.filter-bar > *:not(:first-child) > * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
140
admin/assets/css/admin-product-editor.css
Normal file
@@ -0,0 +1,140 @@
|
||||
#product-variables-table {
|
||||
padding: 0;
|
||||
}
|
||||
#product-variables-table > .wpcfto-field-content {
|
||||
width: 100%;
|
||||
}
|
||||
#product-variables-table > .wpcfto-field-content > table.wpcfto-table {
|
||||
width:100%;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
#product-variables-table > .wpcfto-field-content > table.wpcfto-table th {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
th[data-cell="name"] {
|
||||
text-align: left!important;
|
||||
}
|
||||
th[data-cell="price"], td[data-cell="price"],
|
||||
th[data-cell="sale"], td[data-cell="sale"] {
|
||||
max-width: 150px;
|
||||
}
|
||||
th[data-cell="stock"], td[data-cell="stock"],
|
||||
th[data-cell="weight"], td[data-cell="weight"] {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
/* Toggle Switch Styles */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 36px;
|
||||
height: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.switch input { display:none; }
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background-color: #ccc;
|
||||
border-radius: 20px;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
transition: .4s;
|
||||
}
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 16px; width: 16px;
|
||||
left: 2px; bottom: 2px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: .4s;
|
||||
}
|
||||
input:checked + .slider {
|
||||
background-color: #2985f7;
|
||||
}
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(16px);
|
||||
}
|
||||
|
||||
/* Gray out inactive rows */
|
||||
.variation-inactive {
|
||||
background: #eee !important;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.price-input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price-input-wrapper span {
|
||||
background: #eee;
|
||||
padding: 0 8px;
|
||||
border-right: 1px solid #ccc;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.price-input-wrapper input {
|
||||
border: none!important;
|
||||
outline: none;
|
||||
padding: 6px 8px!important;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-link.child-row-toggle {
|
||||
transition: all .5s ease-out;
|
||||
}
|
||||
.button-link.child-row-toggle:active,
|
||||
.button-link.child-row-toggle:focus {
|
||||
box-shadow: unset!important;
|
||||
}
|
||||
.button-link.child-row-toggle.active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
td.manual-price-hint {
|
||||
color: #8c99a5;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.variation-details-content {
|
||||
padding: 1rem;
|
||||
border: 1px dashed #bec5cb;
|
||||
border-radius: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.price-input-wrapper > .price-currency {
|
||||
min-width: 40px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
table.wpcfto-table.inner-table {
|
||||
width: 100%;
|
||||
border-collapse:collapse
|
||||
}
|
||||
|
||||
table.wpcfto-table.inner-table tr > th {
|
||||
text-transform: uppercase;
|
||||
background-color: #bec5cb;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
table.wpcfto-table.inner-table tr td {
|
||||
padding: 5px 0 5px 5px;
|
||||
}
|
||||
table.wpcfto-table.inner-table tbody tr:hover td {
|
||||
background-color: #dfe7ee;
|
||||
}
|
||||
table.wpcfto-table.inner-table tr > *:is(th, td):first-child {
|
||||
width: 50%;
|
||||
text-align: left;
|
||||
}
|
||||
16
admin/assets/css/admin-setting.css
Normal file
@@ -0,0 +1,16 @@
|
||||
.nav-link.active:hover {
|
||||
color: white;
|
||||
}
|
||||
.form-check.form-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.form-switch .form-check-input {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.formipay-editor-tab-content .card {
|
||||
max-width: unset;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
155
admin/assets/css/classic-editor.css
Normal file
@@ -0,0 +1,155 @@
|
||||
.wp-header-end {
|
||||
margin: 30px 0 0;
|
||||
}
|
||||
/* === Title Input Box === */
|
||||
#title {
|
||||
font-size: 1.5rem!important;
|
||||
padding: 16px!important;
|
||||
border-radius: 8px;
|
||||
border: unset;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
margin-bottom: 15px!important;
|
||||
height: unset!important;
|
||||
}
|
||||
|
||||
/* === Meta Boxes General Styling === */
|
||||
.postbox {
|
||||
background-color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.postbox h2.hndle {
|
||||
font-size: 1.1rem!important;
|
||||
padding: 10px 15px 10px 0!important;
|
||||
border-radius: 6px 6px 0 0;
|
||||
cursor: pointer!important;
|
||||
}
|
||||
|
||||
/* === Publish Box (Right Side) === */
|
||||
#submitdiv {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
#submitdiv h3 {
|
||||
background-color: #f1f1f1;
|
||||
padding: 10px 15px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#submitdiv .inside {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#publishing-action {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#publishing-action input[type="submit"] {
|
||||
font-size: 1rem;
|
||||
padding: 10px 25px;
|
||||
border-radius: 6px;
|
||||
border: none;
|
||||
background-color: #0073aa;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
#major-publishing-actions {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0;
|
||||
flex-direction: column-reverse;
|
||||
gap: 1rem;
|
||||
}
|
||||
#major-publishing-actions > *,
|
||||
#major-publishing-actions > * > * {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
#major-publishing-actions .spinner {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
background: unset;
|
||||
margin: unset;
|
||||
display: unset;
|
||||
}
|
||||
a#post-preview {
|
||||
width: 100%;
|
||||
padding: 5px 15px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#minor-publishing-actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* === Categories / Tags Boxes === */
|
||||
#categorydiv,
|
||||
#tagsdiv-post_tag {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.1);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#categorydiv h3,
|
||||
#tagsdiv-post_tag h3 {
|
||||
background-color: #f5f5f5;
|
||||
padding: 10px 15px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#categorychecklist li label,
|
||||
#tagchecklist span a {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
#tag-input {
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.inside:has(.categorydiv) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.category-tabs li.tabs, input#formipay-product-category-add-submit {
|
||||
border: 1px solid #0073aa;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
ul.category-tabs li.tabs a{
|
||||
color: #0073aa!important;
|
||||
outline: unset;
|
||||
border: unset;
|
||||
box-shadow: unset;
|
||||
}
|
||||
ul.category-tabs li.tabs a:focus,
|
||||
ul.category-tabs li.tabs a:active {
|
||||
outline: unset;
|
||||
border: unset;
|
||||
box-shadow: unset;
|
||||
}
|
||||
.categorydiv .tabs-panel {
|
||||
border: unset!important;
|
||||
}
|
||||
|
||||
/* === WYSIWYG Editor (TinyMCE) === */
|
||||
.mce-container {
|
||||
border-radius: 8px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mce-toolbar-grp {
|
||||
background-color: #f5f5f5 !important;
|
||||
border-bottom: 1px solid #ddd !important;
|
||||
}
|
||||
30
admin/assets/css/form-field.css
Normal file
@@ -0,0 +1,30 @@
|
||||
.formipay-label {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
font-size: smaller;
|
||||
margin-bottom: 3px
|
||||
}
|
||||
.formipay-input {
|
||||
width: 100%;
|
||||
padding-right: 1em!important;
|
||||
padding-left: 1em!important;
|
||||
}
|
||||
.formipay-input:not([type=radio]):not([type=checkbox]){
|
||||
min-height: 30px;
|
||||
}
|
||||
.formipay-select {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding-right: 1em!important;
|
||||
padding-left: 1em!important;
|
||||
}
|
||||
.formipay-inline-desc {
|
||||
font-size: 12px;
|
||||
color: #666666;
|
||||
}
|
||||
.repeater-child-input:first-child .delete-option {
|
||||
display: none;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
31
admin/assets/css/global-setting.css
Normal file
@@ -0,0 +1,31 @@
|
||||
.stm_metaboxes_grid__inner, .wpcfto_settings_head {
|
||||
max-width: 100%!important;
|
||||
}
|
||||
.wpcfto-settings[data-vue=formipay_settings] .wpcfto-field-aside {
|
||||
width: 25%;
|
||||
}
|
||||
.wpcfto-settings[data-vue=formipay_settings] .wpcfto-field-content {
|
||||
width: 75%;
|
||||
}
|
||||
.wpcfto-repeater-single:not(:first-child) {
|
||||
border-top: 1px solid #ccc!important;
|
||||
}
|
||||
.paypal-instruction-point {
|
||||
list-style: auto;
|
||||
}
|
||||
.global-paypal-instruction ul:not(.paypal-instruction-point) {
|
||||
list-style: disc;
|
||||
}
|
||||
.global-paypal-instruction > h5 {
|
||||
font-size: 16px!important;
|
||||
font-weight: bold;
|
||||
}
|
||||
.global-paypal-instruction b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.global-paypal-instruction ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
61
admin/assets/css/page-access-items.css
Normal file
@@ -0,0 +1,61 @@
|
||||
#formipay-access-items table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
a#add-new-item {
|
||||
color: #277aff;
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #277aff;
|
||||
}
|
||||
a#add-new-item:hover {
|
||||
color: #ffffff;
|
||||
background-color: #277aff;
|
||||
}
|
||||
th.gridjs-th[data-column-id=id],
|
||||
th.gridjs-th[data-column-id=type],
|
||||
th.gridjs-th[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
td.gridjs-td[data-column-id=id],
|
||||
td.gridjs-td[data-column-id=type],
|
||||
td.gridjs-td[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
td.gridjs-td[data-column-id=productRelation] > span {
|
||||
display: flex;
|
||||
gap: .5em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
div#formipay-access-items td svg {
|
||||
margin-right: .25em;
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
.product_related {
|
||||
background-color: #dedede;
|
||||
padding: 5px 7px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
span:has(.status-label) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
span.status-label {
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
span.status-label.publish {
|
||||
background-color: #277aff;
|
||||
color: white;
|
||||
}
|
||||
span.status-label.draft {
|
||||
background-color: #999999;
|
||||
color: white;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
75
admin/assets/css/page-coupons.css
Normal file
@@ -0,0 +1,75 @@
|
||||
#formipay-coupons table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
a#add-new-coupon {
|
||||
color: #277aff;
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #277aff;
|
||||
}
|
||||
a#add-new-coupon:hover {
|
||||
color: #ffffff;
|
||||
background-color: #277aff;
|
||||
}
|
||||
.formipay-form-shortcode {
|
||||
padding: .5em;
|
||||
border-radius: .5em;
|
||||
color: #666666!important;
|
||||
border: 1px solid #b7b7b7!important;
|
||||
}
|
||||
|
||||
td.gridjs-td[data-column-id=productRelation] > span {
|
||||
display: flex;
|
||||
gap: .5em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.product_related {
|
||||
background-color: #dedede;
|
||||
padding: 5px 7px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
span.product_related img {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
th.gridjs-th[data-column-id=id],
|
||||
th.gridjs-th[data-column-id=usages],
|
||||
th.gridjs-th[data-column-id=type],
|
||||
th.gridjs-th[data-column-id=dateLimit],
|
||||
th.gridjs-th[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
td.gridjs-td[data-column-id=id],
|
||||
td.gridjs-td[data-column-id=usages],
|
||||
td.gridjs-td[data-column-id=type],
|
||||
td.gridjs-td[data-column-id=dateLimit] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th.gridjs-th[data-column-id=amount],
|
||||
td.gridjs-td[data-column-id=amount] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span:has(.status-label) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
span.status-label {
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
span.status-label.active {
|
||||
background-color: #277aff;
|
||||
color: white;
|
||||
}
|
||||
span.status-label.inactive {
|
||||
background-color: #999999;
|
||||
color: white;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
77
admin/assets/css/page-forms.css
Normal file
@@ -0,0 +1,77 @@
|
||||
#formipay-forms table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
.formipay-screen-menu a {
|
||||
color: #277aff;
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #277aff;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.formipay-screen-menu a:hover {
|
||||
color: #ffffff;
|
||||
background-color: #277aff;
|
||||
}
|
||||
.formipay-form-shortcode {
|
||||
padding: .5em;
|
||||
border-radius: .5em;
|
||||
color: #666666!important;
|
||||
border: 1px solid #b7b7b7!important;
|
||||
}
|
||||
|
||||
th.gridjs-th[data-column-id=id], th.gridjs-th[data-column-id=date], th.gridjs-th[data-column-id=status],
|
||||
td.gridjs-td[data-column-id=id], td.gridjs-td[data-column-id=date], td.gridjs-td[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
.gridjs-pages > * {
|
||||
padding: 1em 1.5em!important;
|
||||
}
|
||||
span:has(.formipay-form-shortcode){
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
max-width: 100%;
|
||||
flex-wrap: nowrap
|
||||
}
|
||||
.formipay-form-shortcode {
|
||||
flex: 0 1 200px;
|
||||
width: unset!important;
|
||||
max-width: unset!important;
|
||||
min-width: unset!important;
|
||||
}
|
||||
button.copy-shortcode {
|
||||
border: 1px solid #b7b7b7;
|
||||
height: 32px;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
button.copy-shortcode svg {
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
span:has(.status-label) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
span.status-label {
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
span.status-label.publish {
|
||||
background-color: #277aff;
|
||||
color: white;
|
||||
}
|
||||
span.status-label.draft {
|
||||
background-color: #999999;
|
||||
color: white;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
91
admin/assets/css/page-product-taxonomy.css
Normal file
@@ -0,0 +1,91 @@
|
||||
.tablenav.top:has(.no-pages) {
|
||||
display: none;
|
||||
}
|
||||
#col-container {
|
||||
margin-top: 3em;
|
||||
}
|
||||
div#col-left {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
}
|
||||
div#col-left .form-wrap {
|
||||
padding: 1em
|
||||
}
|
||||
div#col-left input, div#col-left select, div#col-left textarea {
|
||||
max-width: none;
|
||||
width: 100%!important;
|
||||
}
|
||||
#col-right .col-wrap {
|
||||
padding-left: 1em
|
||||
}
|
||||
input, textarea{
|
||||
padding: .5em 1em!important;
|
||||
border-radius: .5em!important;
|
||||
color: #666666 !important;
|
||||
border: 1px solid #b7b7b7 !important;
|
||||
}
|
||||
select {
|
||||
padding: .5em 1.5em .5em 1em!important;
|
||||
border-radius: .5em!important;
|
||||
color: #666666 !important;
|
||||
border: 1px solid #b7b7b7 !important;
|
||||
}
|
||||
thead > tr > * {
|
||||
padding: 1em !important;
|
||||
background: #277aff!important;
|
||||
color: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
tfoot > tr > * {
|
||||
padding: 1em!important;
|
||||
border: 1px solid #e5e7eb;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
td, tbody > tr > *:first-child {
|
||||
padding: .5em 1em!important;
|
||||
border: 1px solid #e5e7eb;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
th a {
|
||||
padding: 0!important;
|
||||
}
|
||||
thead a {
|
||||
color: white!important;
|
||||
}
|
||||
td a{
|
||||
padding: 0!important;
|
||||
}
|
||||
table {
|
||||
margin-top: 1.25em!important;
|
||||
border-radius: 8px!important;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.tablenav.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.tablenav.top > .tablenav-pages {
|
||||
display: none;
|
||||
}
|
||||
table > thead {
|
||||
border-radius: 8px 8px 0 0!important;
|
||||
}
|
||||
table > thead > tr > *:first-child {
|
||||
border-top-left-radius: 8px!important;
|
||||
}
|
||||
table > thead > tr > *:last-child {
|
||||
border-top-right-radius: 8px!important;
|
||||
}
|
||||
thead th.sorted span.sorting-indicator.asc::before {
|
||||
color: white!important;
|
||||
}
|
||||
input#submit {
|
||||
background: #277aff!important;
|
||||
color: #ffffff!important;
|
||||
border: unset!important;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
96
admin/assets/css/page-products.css
Normal file
@@ -0,0 +1,96 @@
|
||||
#formipay-forms table td {
|
||||
vertical-align: top;
|
||||
}
|
||||
.formipay-screen-menu a {
|
||||
color: #277aff;
|
||||
font-size: 16px;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #277aff;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.formipay-screen-menu a:hover {
|
||||
color: #ffffff;
|
||||
background-color: #277aff;
|
||||
}
|
||||
|
||||
/** Table **/
|
||||
td.gridjs-td[data-column-id=price] .price {
|
||||
text-wrap: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .5em;
|
||||
justify-content: space-between;
|
||||
}
|
||||
th.gridjs-th[data-column-id=id],
|
||||
th.gridjs-th[data-column-id=type],
|
||||
th.gridjs-th[data-column-id=price],
|
||||
th.gridjs-th[data-column-id=stock],
|
||||
th.gridjs-th[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
td.gridjs-td[data-column-id=id],
|
||||
td.gridjs-td[data-column-id=type],
|
||||
td.gridjs-td[data-column-id=price],
|
||||
td.gridjs-td[data-column-id=stock],
|
||||
td.gridjs-td[data-column-id=status] {
|
||||
text-align: center;
|
||||
}
|
||||
.gridjs-pages > * {
|
||||
padding: 1em 1.5em!important;
|
||||
}
|
||||
span:has(.status-label) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
span.status-label {
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
span.status-label.publish {
|
||||
background-color: #277aff;
|
||||
color: white;
|
||||
}
|
||||
span.status-label.draft {
|
||||
background-color: #999999;
|
||||
color: white;
|
||||
}
|
||||
.top-40 {
|
||||
top: 40px!important;
|
||||
}
|
||||
|
||||
/** SWAL new Product **/
|
||||
div#swal2-html-container table th {
|
||||
width: 45%;
|
||||
}
|
||||
div#swal2-html-container table td {
|
||||
width: 55%;
|
||||
}
|
||||
#swal2-html-container input {
|
||||
border: 1px solid #b7b7b7 !important;
|
||||
border-radius: .5em !important;
|
||||
}
|
||||
#swal2-html-container input:not(type="checkbox"):not(type="radio"){
|
||||
height: 34px!important;
|
||||
padding: 10px 14px!important;
|
||||
width: 100%!important;
|
||||
max-width: unset!important;
|
||||
margin: unset!important;
|
||||
}
|
||||
#swal2-html-container *:is(th, td) > * {
|
||||
margin: unset!important;
|
||||
text-align: left;
|
||||
}
|
||||
#swal2-html-container *:is(th, td){
|
||||
height: 40px;
|
||||
}
|
||||
#swal2-html-container tr:not(:last-child) *:is(th, td) {
|
||||
border-bottom: 1px solid #b7b7b7;
|
||||
}
|
||||
BIN
admin/assets/img/White.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
admin/assets/img/formipay-logo-circle-white.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
admin/assets/img/formipay-logo-circle-white_256.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
admin/assets/img/formipay_display_popup.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
admin/assets/img/formipay_layout_1.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
admin/assets/img/formipay_layout_2.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
admin/assets/img/icons8-dribbble-50.png
Normal file
|
After Width: | Height: | Size: 733 B |
BIN
admin/assets/img/icons8-facebook-50.png
Normal file
|
After Width: | Height: | Size: 709 B |
BIN
admin/assets/img/icons8-facebook-messenger-50.png
Normal file
|
After Width: | Height: | Size: 846 B |
BIN
admin/assets/img/icons8-github-50.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
admin/assets/img/icons8-instagram-50.png
Normal file
|
After Width: | Height: | Size: 778 B |
BIN
admin/assets/img/icons8-link-50.png
Normal file
|
After Width: | Height: | Size: 689 B |
BIN
admin/assets/img/icons8-linkedin-50.png
Normal file
|
After Width: | Height: | Size: 434 B |
BIN
admin/assets/img/icons8-pinterest-50.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
admin/assets/img/icons8-telegram-50.png
Normal file
|
After Width: | Height: | Size: 790 B |
BIN
admin/assets/img/icons8-tiktok-50.png
Normal file
|
After Width: | Height: | Size: 578 B |
BIN
admin/assets/img/icons8-whatsapp-50.png
Normal file
|
After Width: | Height: | Size: 888 B |
BIN
admin/assets/img/icons8-wordpress-50.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
admin/assets/img/icons8-x-50.png
Normal file
|
After Width: | Height: | Size: 754 B |
BIN
admin/assets/img/logistics.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
admin/assets/img/multistep_icon.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
admin/assets/img/multistep_point_shape_circle.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
admin/assets/img/multistep_point_shape_rectangle.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
admin/assets/img/multistep_point_shape_rounded.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
admin/assets/img/multistep_sort.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
admin/assets/img/thankyou_card_style.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
admin/assets/img/thankyou_receipt_style.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
14
admin/assets/js/admin-all-post-type.js
Normal file
@@ -0,0 +1,14 @@
|
||||
jQuery(function($){
|
||||
|
||||
$('#wpbody-content').prepend(`
|
||||
<div class="formipay-screen-menu">
|
||||
<img src="`+formipay_admin.site_url+`/wp-content/plugins/formipay/admin/assets/img/formipay-logo-circle-white_256.png" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1>`+formipay_admin.page_title+`</h1>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
$('form.search-form.wp-clearfix').appendTo('.tablenav.top');
|
||||
$('.wp-heading-inline, .page-title-action').hide();
|
||||
|
||||
});
|
||||
78
admin/assets/js/admin-customers.js
Normal file
@@ -0,0 +1,78 @@
|
||||
jQuery(function($){
|
||||
|
||||
let formipay_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_customers_page.ajax_url+'?action=formipay-tabledata-customers&limit='+document.getElementById('limit').value+'&keyword='+document.getElementById('keyword').value,
|
||||
then: data => {
|
||||
|
||||
// if(data.posts_report){
|
||||
// processPostsReport(data.posts_report);
|
||||
// }
|
||||
|
||||
return data.results.map(
|
||||
form => [form.ID, form.name, form.email, form.phone, form.total_order]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
name: formipay_customers_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_customers_page.columns.name,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<b>${_}</b>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_customers_page.columns.email,
|
||||
},
|
||||
{
|
||||
name: formipay_customers_page.columns.phone,
|
||||
},
|
||||
{
|
||||
name: formipay_customers_page.columns.total_order,
|
||||
formatter: (total_order, row) => gridjs.html(`<span class="status-label ${total_order}">${total_order}</span>`)
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
limit: document.getElementById('limit').value,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-customers'));
|
||||
|
||||
$('#limit, #keyword').on('change', function(){
|
||||
formipay_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_customers_page.ajax_url+'?action=formipay-tabledata-customers&limit='+document.getElementById('limit').value+'&keyword='+document.getElementById('keyword').value,
|
||||
then: data => data.results.map(
|
||||
form => [form.ID, form.name, form.email, form.phone, form.total_order]
|
||||
),
|
||||
total: data => data.total
|
||||
},
|
||||
pagination: {
|
||||
limit: document.getElementById('limit').value,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
}).forceRender();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=form]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=form]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
});
|
||||
946
admin/assets/js/admin-editor.js
Normal file
@@ -0,0 +1,946 @@
|
||||
jQuery(function($){
|
||||
|
||||
let wpcftoLoaded = false;
|
||||
|
||||
var checkWpcftoLoaded = setInterval(() => {
|
||||
const container = $('.wpcfto-tab');
|
||||
if(container.length > 0){
|
||||
wpcftoLoaded = true;
|
||||
$(document).trigger('wpcftoLoaded');
|
||||
clearInterval(checkWpcftoLoaded);
|
||||
}
|
||||
}, 250);
|
||||
|
||||
$(document).on('wpcftoLoaded', function(){
|
||||
update_option_to_data_mapping('initial');
|
||||
});
|
||||
|
||||
function all_active_payments() {
|
||||
|
||||
var items = $('.payment_gateways #active .list-group-item');
|
||||
var active_payments = [];
|
||||
|
||||
if(items.length > 0){
|
||||
$.each(items, function(i, item){
|
||||
var gateway = $(item).attr('id');
|
||||
if(gateway.indexOf(':::') !== -1){
|
||||
gateway = gateway.split(':::')[0];
|
||||
gateway = gateway.replace('_', '-');
|
||||
}
|
||||
// $('[data-submenu=payments_'+gateway+']').show();
|
||||
active_payments.push(gateway);
|
||||
});
|
||||
}
|
||||
|
||||
return active_payments;
|
||||
|
||||
}
|
||||
|
||||
function hide_inactive_payment_submenu() {
|
||||
|
||||
var div = $('[data-section=payments]').siblings('.wpcfto-submenus').find('[data-submenu]:not([data-submenu=payments_general])');
|
||||
var active_payments = all_active_payments();
|
||||
|
||||
if(div.length > 0) {
|
||||
$.each(div, function(x, y){
|
||||
var gateway = $(y).attr('data-submenu').replace('payments_', '');
|
||||
if(jQuery.inArray(gateway, active_payments) !== -1){
|
||||
$(y).slideDown();
|
||||
}else{
|
||||
$(y).slideUp();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
hide_inactive_payment_submenu();
|
||||
}, 1000);
|
||||
|
||||
|
||||
$(document).on('mouseleave', '.payment_gateways .list-group', function(){
|
||||
|
||||
hide_inactive_payment_submenu();
|
||||
|
||||
});
|
||||
|
||||
$(document).on('click', '.formipay-editor-nav .nav-link', function(){
|
||||
$('.formipay-editor-nav').find('.nav-link').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.formipay-editor-tab-content.nav-content-section').addClass('d-none');
|
||||
var tab_content = $(this).data('tab-content');
|
||||
$('.formipay-editor-tab-content'+tab_content).removeClass('d-none');
|
||||
});
|
||||
|
||||
$('.formipay-editor-nav .nav-item:first-child > .nav-link').trigger('click');
|
||||
|
||||
$(document).on('click', '#is_required', function(){
|
||||
if($(this).is(':checked')) {
|
||||
$(this).val('yes');
|
||||
}else{
|
||||
$(this).val('no');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('blur change', '#add_field_form .field select.form-select', function(){
|
||||
var array = ['divider', 'page_break'];
|
||||
if( $.inArray( $(this).val(), array ) !== -1 ) {
|
||||
$('#add_field_form .field:not(.main-field)').slideUp();
|
||||
}else{
|
||||
$('#add_field_form .field:not(.main-field):not(.has-conditional)').slideDown();
|
||||
}
|
||||
});
|
||||
|
||||
function formipay_sortable(){
|
||||
$('#preview-wrapper').sortable({
|
||||
opacity: 0.75,
|
||||
items: '> .preview-field',
|
||||
handle: 'span.grab',
|
||||
change: function(event, ui) {
|
||||
ui.placeholder.css({
|
||||
visibility: 'visible',
|
||||
border : '2px dashed #8c8f94',
|
||||
borderRadius: '10px'
|
||||
});
|
||||
},
|
||||
stop: function(event, ui){
|
||||
update_option_to_data_mapping('update');
|
||||
}
|
||||
});
|
||||
$('.repeater-child-wrapper').sortable({
|
||||
opacity: 0.75,
|
||||
items: '> .repeater-child-input',
|
||||
handle: 'span.grab',
|
||||
change: function(event, ui) {
|
||||
ui.placeholder.css({
|
||||
visibility: 'visible',
|
||||
border : '2px dashed #cccccc',
|
||||
borderRadius: '5px'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
formipay_sortable();
|
||||
|
||||
$(document).on('change blur', '#add_field_form [name=label]', function(){
|
||||
$('#add_field_form [name=field_id]').val($(this).val().toLowerCase().replace(' ', '_'));
|
||||
});
|
||||
|
||||
$(document).on('click', '.add-option', function(e){
|
||||
e.preventDefault();
|
||||
var content = $(this).closest('.repeater-child-input').html();
|
||||
$(this).closest('.repeater-child-wrapper').append(`
|
||||
<div class="repeater-child-input d-flex justify-content-start align-items-start gap-2 my-2">`+content+`
|
||||
</div>`);
|
||||
$('.repeater-child-input:last-child').find('input').val('');
|
||||
$('.repeater-child-input:last-child').find('.add-thumbnail').removeClass('text-info').addClass('text-white');
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-option', function(e){
|
||||
e.preventDefault();
|
||||
$(this).closest('.repeater-child-input').remove();
|
||||
});
|
||||
|
||||
$(document).on('click', 'input.option-field-toggle', function(){
|
||||
var target = $(this).attr('data-child-field');
|
||||
if($(this).is(':checked')){
|
||||
$('.child-field-'+target).show();
|
||||
}else{
|
||||
$('.child-field-'+target).hide();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('change', '#add_field_form .formipay-builder-field:not(.formipay-builder-option-field, [type=checkbox], [type=checkbox])', function(){
|
||||
var value = $(this).val();
|
||||
var name = $(this).attr('name');
|
||||
var the_dependent = $('#add_field_form [data-if-'+name+']');
|
||||
if('' !== value && the_dependent.length > 0){
|
||||
// var all_dependents = $('.has-conditional');
|
||||
$.each(the_dependent, function(x, y){
|
||||
var decoded_value = JSON.parse($(y).attr('data-if-'+name));
|
||||
if($.inArray(value, decoded_value) !== -1){
|
||||
$(y).slideDown();
|
||||
}else{
|
||||
$(y).slideUp();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '.add-field', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var option_image_toggle = 'no';
|
||||
if($('#repeater-child-0_thumbnail').is(':checked')){
|
||||
option_image_toggle = 'yes';
|
||||
}
|
||||
var option_value_toggle = 'no';
|
||||
if($('#repeater-child-2_value').is(':checked')){
|
||||
option_value_toggle = 'yes';
|
||||
}
|
||||
var option_amount_toggle = 'no';
|
||||
if($('#repeater-child-3_amount').is(':checked')){
|
||||
option_amount_toggle = 'yes';
|
||||
}
|
||||
|
||||
var setup = {
|
||||
'label' : $('#add_field_form [name=label]').val(),
|
||||
'field_id' : $('#add_field_form [name=field_id]').val(),
|
||||
'field_type' : $('#add_field_form [name=field_type]').val(),
|
||||
'options_type' : $('#add_field_form [name=options_type]').val(),
|
||||
'placeholder' : $('#add_field_form [name=placeholder]').val(),
|
||||
'default_value' : $('#add_field_form [name=default_value]').val(),
|
||||
'description' : $('#add_field_form [name=description]').val(),
|
||||
'is_required' : $('#add_field_form [name=is_required]').val(),
|
||||
'show_toggle' : {
|
||||
'image' : option_image_toggle,
|
||||
'value' : option_value_toggle,
|
||||
'amount': option_amount_toggle
|
||||
},
|
||||
'layout' : $('#option_grid_columns').val()
|
||||
};
|
||||
|
||||
var options = [];
|
||||
var calculable_field = ['select', 'radio', 'checkbox'];
|
||||
if($.inArray(setup.field_type, calculable_field) !== -1){
|
||||
var single_option = $('.repeater-child-input');
|
||||
if(single_option.length > 0){
|
||||
$.each(single_option, function(a, b){
|
||||
var check_qty;
|
||||
if($(b).find('.repeater-child-input-qty').is(':checked')){
|
||||
check_qty = 'yes';
|
||||
}else{
|
||||
check_qty = 'no';
|
||||
}
|
||||
var option = {
|
||||
'image_id': $(b).find('.field-image-id').val(),
|
||||
'image_url': $(b).find('.field-image-url').val(),
|
||||
'label': $(b).find('.repeater-child-input-label').find('input').val(),
|
||||
'value': $(b).find('.repeater-child-input-value').find('input').val(),
|
||||
'amount': $(b).find('.repeater-child-input-amount').find('input').val(),
|
||||
'weight': $(b).find('.repeater-child-input-weight').find('input').val(),
|
||||
'qty': check_qty
|
||||
}
|
||||
options.push(option);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setup.field_options = options;
|
||||
|
||||
// console.log(setup);
|
||||
|
||||
var setup_string = JSON.stringify(setup);
|
||||
var not_input = ['select', 'checkbox', 'radio'];
|
||||
var is_required = '';
|
||||
var asterisk = '';
|
||||
if(setup.is_required == 'yes'){
|
||||
is_required = '';
|
||||
asterisk = ' <span style="color:red;">(*)</span>';
|
||||
}
|
||||
var hidden = '';
|
||||
if(setup.field_type == 'hidden'){
|
||||
hidden = ' style="opacity: .75;"'
|
||||
}
|
||||
if(!setup.calc_value){
|
||||
setup.calc_value = 0;
|
||||
}
|
||||
|
||||
var preview_content = '';
|
||||
if($.inArray(setup.field_type, not_input) == -1){
|
||||
if($.inArray(setup.field_type, ['divider', 'page_break']) !== -1){
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`" class="label-`+setup.field_type+`">`+setup.label+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<span class="divider-line"></span>
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}else if(setup.field_type == 'country_list') {
|
||||
var country_json = formipay_admin.preset.country_list;
|
||||
// Check if country_json is a string (indicating it might need to be parsed)
|
||||
if (typeof country_json === 'string') {
|
||||
try {
|
||||
country_json = JSON.parse(country_json); // Parse the JSON string into an object
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON:', e); // Log any parsing errors
|
||||
country_json = []; // Fallback to an empty array
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the data type
|
||||
if (!Array.isArray(country_json)) {
|
||||
console.error('Expected an array but got:', country_json);
|
||||
country_json = []; // Fallback to an empty array if not an array
|
||||
}
|
||||
|
||||
var options_html = `<option>-- ${setup.placeholder}</option>`;
|
||||
|
||||
// Loop through each country object
|
||||
$.each(country_json, function(index, country) {
|
||||
// Assuming each country object has 'id' for the value and 'name' for the display text
|
||||
options_html += `<option value="${country.name}">${country.name}</option>`;
|
||||
});
|
||||
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`">`+setup.label+asterisk+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<select id="`+setup.field_id+`" class="formipay-input formipay-form-field" `+is_required+`>
|
||||
`+options_html+`
|
||||
</select>
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}else if(setup.field_type !== 'textarea'){
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`">`+setup.label+asterisk+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<input type="`+setup.field_type+`" id="`+setup.field_id+`" class="formipay-input formipay-form-field" placeholder="`+setup.placeholder+`" data-calc-value="`+setup.calc_value+`" `+is_required+` />
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}else{
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`">`+setup.label+asterisk+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<textarea rows="4" id="`+setup.field_id+`" class="formipay-input formipay-form-field" placeholder="`+setup.placeholder+`" data-calc-value="`+setup.calc_value+`" `+is_required+`></textarea>
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}
|
||||
}else{
|
||||
if(setup.field_type == 'select'){
|
||||
var options = setup.field_options;
|
||||
var options_html = '';
|
||||
if(setup.placeholder !== ''){
|
||||
options_html = '<option>'+setup.placeholder+'</option>';
|
||||
}
|
||||
$.each(options, function(j, k){
|
||||
var label = k.label;
|
||||
var value = label;
|
||||
if('' !== k.value && setup.show_toggle.value == 'yes'){
|
||||
value = k.value;
|
||||
}
|
||||
var calc = 0;
|
||||
if('' !== k.amount && setup.show_toggle.amount == 'yes'){
|
||||
calc = k.amount;
|
||||
}
|
||||
options_html += '<option value="'+value+'" data-calc-value="'+calc+'">'+label+'</option>';
|
||||
});
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`">`+setup.label+asterisk+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<select id="`+setup.field_id+`" class="formipay-input formipay-form-field" `+is_required+`>
|
||||
`+options_html+`
|
||||
</select>
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}else{
|
||||
var options = setup.field_options;
|
||||
var options_html = '';
|
||||
$.each(options, function(j, k){
|
||||
var name = setup.field_id+`-`+j;
|
||||
if(setup.field_type == 'radio'){
|
||||
name = setup.field_id;
|
||||
}
|
||||
var label = k.label;
|
||||
var value = label;
|
||||
if('' !== k.value && setup.show_toggle.value == 'yes'){
|
||||
value = k.value;
|
||||
}
|
||||
var calc = 0;
|
||||
if('' !== k.amount && setup.show_toggle.amount == 'yes'){
|
||||
calc = k.amount;
|
||||
}
|
||||
var image = '';
|
||||
if('' !== k.image_id && '' !== k.image_url){
|
||||
image = `<img src="`+k.image_url+`" style="width: 100%; height: 150px; object-fit: contain;">`;
|
||||
}
|
||||
options_html +=
|
||||
`<div class="formipay-checkbox-group">
|
||||
`+image+`
|
||||
<input type="`+setup.field_type+`" id="`+setup.field_id+`-`+j+`" name="`+name+`" class="formipay-input formipay-form-field" value="`+k.value+`" />
|
||||
<label for="`+setup.field_id+`-`+j+`">`+k.label+`</label>
|
||||
</div>`;
|
||||
});
|
||||
if(setup.layout == ''){
|
||||
setup.layout = 1;
|
||||
}
|
||||
preview_content = `
|
||||
<div class="formipay-field w-100"`+hidden+`>
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="`+setup.field_id+`">`+setup.label+asterisk+`</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="`+setup.field_id+`_config" class="formipay-field-setup" value='`+setup_string+`'>
|
||||
<div class="formipay-checkbox-wrapper" style="display: grid; grid-template-columns: repeat(`+setup.layout+`, 1fr); gap: 10px;">
|
||||
`+options_html+`
|
||||
</div>
|
||||
<p class="formipay-inline-desc">`+setup.description+`</p>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
var hidden = is_required = '';
|
||||
if(setup.type == 'hidden'){
|
||||
hidden = ' style="display: none;"';
|
||||
}
|
||||
if(setup.require == 'yes'){
|
||||
is_required = ' required';
|
||||
}
|
||||
|
||||
// Check if any
|
||||
|
||||
var edit_to = $('.add-field').attr('data-edit-to');
|
||||
var the_existed_field = $('.preview-field[data-field="'+edit_to+'"]');
|
||||
|
||||
if(the_existed_field.length > 0){
|
||||
$('.preview-field[data-field="'+edit_to+'"]').html(`
|
||||
<span class="grab pb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
||||
</svg>
|
||||
</span>
|
||||
`+preview_content+`
|
||||
`);
|
||||
}else{
|
||||
$('#preview-wrapper').append(`
|
||||
<div class="preview-field d-flex gap-2 align-items-center" data-field="`+setup.field_id+`" data-field-type="`+setup.field_type+`">
|
||||
<span class="grab pb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
||||
</svg>
|
||||
</span>
|
||||
`+preview_content+`
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
$('.preview-field[data-field="'+setup.field_id+'"]').attr('data-field-type', setup.field_type);
|
||||
|
||||
// scissors icon
|
||||
if(setup.field_type == 'page_break'){
|
||||
$('.preview-field[data-field="'+setup.field_id+'"]').append(`
|
||||
<span class="scissors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m12 14l-2.35 2.35q.2.375.275.8T10 18q0 1.65-1.175 2.825T6 22t-2.825-1.175T2 18t1.175-2.825T6 14q.425 0 .85.075t.8.275L10 12L7.65 9.65q-.375.2-.8.275T6 10q-1.65 0-2.825-1.175T2 6t1.175-2.825T6 2t2.825 1.175T10 6q0 .425-.075.85t-.275.8L20.6 18.6q.675.675.3 1.538T19.575 21q-.275 0-.537-.112t-.463-.313zm3-3l-2-2l5.575-5.575q.2-.2.463-.312T19.574 3q.95 0 1.313.875t-.313 1.55zM6 8q.825 0 1.413-.587T8 6t-.587-1.412T6 4t-1.412.588T4 6t.588 1.413T6 8m6 4.5q.2 0 .35-.15t.15-.35t-.15-.35t-.35-.15t-.35.15t-.15.35t.15.35t.35.15M6 20q.825 0 1.413-.587T8 18t-.587-1.412T6 16t-1.412.588T4 18t.588 1.413T6 20" />
|
||||
</svg>
|
||||
</span>
|
||||
`)
|
||||
}else{
|
||||
$('.preview-field[data-field="'+setup.field_id+'"] > span.scissors').remove();
|
||||
}
|
||||
|
||||
var builder_fields = $('#add_field_form').find('.formipay-builder-field');
|
||||
if(builder_fields.length > 0){
|
||||
$.each(builder_fields, function(a, b){
|
||||
if($(b).attr('type') == 'checkbox'){
|
||||
$(b).val('no').prop('checked', false);
|
||||
}else{
|
||||
$(b).val('');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('.repeater-child-input:not(:first-child)').remove();
|
||||
$('.repeater-child-input > input').val('');
|
||||
$('.repeater-child-input > .add-thumbnail').removeClass('text-info').addClass('text-white');
|
||||
$('.repeater-child-input .check-qty').prop('checked', false);
|
||||
$('#add_field_form .field.has-conditional').slideUp();
|
||||
|
||||
var all_option_toggle = $('.option-field-toggle');
|
||||
$.each(all_option_toggle, function(p, q){
|
||||
if($(q).is(':checked')){
|
||||
$(q).trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$('.child-field-image-wrapper').find('img').attr('src', '').hide();
|
||||
$('.child-field-image-wrapper').find('i').attr('src', '').show();
|
||||
$('#add_field_form .field:not(.has-conditional)').show();
|
||||
$('[name=field_type]').val('text').change();
|
||||
$('.add-field').removeAttr('data-edit-to').text('Add Field');
|
||||
|
||||
formipay_sortable();
|
||||
|
||||
setTimeout(() => {
|
||||
update_option_to_data_mapping('update');
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
$(document).on('change', '#customer_data-buyer_allow_choose_country_code', function() {
|
||||
update_option_to_data_mapping('update');
|
||||
});
|
||||
|
||||
function update_option_to_data_mapping(initiation) {
|
||||
var fields = $('#preview-wrapper').find('input[type=hidden]');
|
||||
var options = [];
|
||||
$.each(fields, function(increment, field){
|
||||
var value = $(field).val();
|
||||
var config = JSON.parse(value);
|
||||
options.push(config);
|
||||
});
|
||||
var target = $('#customer_data').find('select');
|
||||
target.html('');
|
||||
target.append(`<option value="">${formipay_admin.config.datamapping.placeholder}</option>`);
|
||||
if(options.length > 0){
|
||||
$.each(options, function(increment, option){
|
||||
target.append(`<option value="${option.field_id}">${option.label}</option>`);
|
||||
});
|
||||
}
|
||||
if(initiation == 'initial'){
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_admin.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_check_for_data_mapping_saved_value',
|
||||
post: $('#post_ID').val(),
|
||||
_wpnonce: formipay_admin.nonce
|
||||
},
|
||||
success: function(res) {
|
||||
$.each(res, function(name, value){
|
||||
if(value){
|
||||
$(`[name="${name}"]`).attr('data-current-value', value).val(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}else if(initiation == 'update'){
|
||||
$.each(target, function(increment, select){
|
||||
const current_value = $(select).attr('data-current-value');
|
||||
$(select).attr('data-current-value', current_value).val(current_value);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('change', '#customer_data select', function() {
|
||||
var value = $(this).val();
|
||||
$(this).attr('data-current-value', value);
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-preview-field', function(e){
|
||||
e.preventDefault();
|
||||
$(this).parents('.preview-field').remove();
|
||||
update_option_to_data_mapping('update');
|
||||
});
|
||||
|
||||
$(document).on('click', '.edit-preview-field', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
// recondition all fields
|
||||
$('.option-field-toggle').prop('checked', false);
|
||||
$('.repeater-child-input:not(:first-child)').remove();
|
||||
$('.repeater-child-input:first-child').find('input').val('');
|
||||
// $('.repeater-child-input:first-child').find('.add-thumbnail').removeClass('text-info').addClass('text-white');
|
||||
|
||||
var setup = $(this).closest('.preview-field').find('.formipay-field-setup').val();
|
||||
setup = JSON.parse(setup);
|
||||
console.log(setup);
|
||||
$.each(setup, function(x, y){
|
||||
if(x == 'field_options'){
|
||||
if(y.length > 0){
|
||||
var first_repeater = $('.repeater-child-input:first-child')
|
||||
var repeater_template = first_repeater.html();
|
||||
var repeater_wrapper = $('.repeater-child-wrapper');
|
||||
$.each(y, function(p, q){
|
||||
repeater_wrapper.append(
|
||||
`<div class="repeater-child-input d-flex justify-content-start align-items-start gap-2 my-2">
|
||||
`+repeater_template+`
|
||||
</div>`);
|
||||
var repeater_target = $('.repeater-child-input:last-child');
|
||||
repeater_target.find('.the_title').text(q.label);
|
||||
repeater_target.find('.child-field-label').find('input').val(q.label);
|
||||
repeater_target.find('.child-field-value').find('input').val(q.value);
|
||||
repeater_target.find('.child-field-amount').find('input').val(q.amount);
|
||||
if(q.qty == 'yes'){
|
||||
repeater_target.find('.check-qty').val('yes').prop('checked', true);
|
||||
}else{
|
||||
repeater_target.find('.check-qty').val('no').prop('checked', false);
|
||||
}
|
||||
if('' !== q.image){
|
||||
repeater_target.find('.field-image-id').val(q.image_id);
|
||||
repeater_target.find('.field-image-url').val(q.image_url);
|
||||
repeater_target.find('img').attr('src', q.image_url).removeClass('d-none');
|
||||
repeater_target.find('.child-field-image').hide();
|
||||
// repeater_target.find('.add-thumbnail').removeClass('text-white').addClass('text-info');
|
||||
}
|
||||
repeater_target.show();
|
||||
first_repeater.hide();
|
||||
first_repeater.remove();
|
||||
});
|
||||
$('.repeater-child-input:first-child').find('.open-option');
|
||||
}
|
||||
}else if(x == 'layout'){
|
||||
$('#add_field_form [name="option_grid_columns"]').val(y);
|
||||
}else{
|
||||
$('#add_field_form [name="' + x + '"]').val(y);
|
||||
}
|
||||
});
|
||||
|
||||
$('#add_field_form [name=is_required]').prop('checked', setup.is_required === 'yes');
|
||||
// Handle show_toggle options
|
||||
if ('show_toggle' in setup) {
|
||||
|
||||
if(setup.show_toggle.image === 'yes'){
|
||||
$('#repeater-child-0_thumbnail').trigger('click');
|
||||
}
|
||||
if(setup.show_toggle.value === 'yes'){
|
||||
$('#repeater-child-2_value').trigger('click');
|
||||
}
|
||||
if(setup.show_toggle.amount === 'yes'){
|
||||
$('#repeater-child-3_amount').trigger('click');
|
||||
}
|
||||
}
|
||||
|
||||
formipay_sortable();
|
||||
// Trigger recondition and form change
|
||||
$('.formipay-builder-field[name=field_type]').trigger('change');
|
||||
|
||||
$('.add-field').attr('data-edit-to', setup.field_id).text('Edit Field');
|
||||
});
|
||||
|
||||
if( $('[name=daterange]').val() == '' ){
|
||||
$('[name=daterange]').daterangepicker({
|
||||
timePicker: true,
|
||||
startDate: moment().startOf('hour'),
|
||||
endDate: moment().startOf('hour').add(32, 'hour'),
|
||||
showDropdowns: true,
|
||||
timePicker24Hour: true,
|
||||
locale: {
|
||||
format: 'D-M-Y HH:mm'
|
||||
}
|
||||
});
|
||||
}else{
|
||||
$('[name=daterange]').daterangepicker({
|
||||
timePicker: true,
|
||||
showDropdowns: true,
|
||||
timePicker24Hour: true,
|
||||
locale: {
|
||||
format: 'D-M-Y HH:mm'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click', '[role=switch]', function(){
|
||||
var id = $(this).attr('id');
|
||||
if($(this).is(':checked')){
|
||||
$('#add_field_form [data-if-'+id+'=active]').show();
|
||||
$(this).val('no');
|
||||
}else{
|
||||
$('#add_field_form [data-if-'+id+'=active]').hide();
|
||||
$(this).val('yes');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click change', '#add_field_form [type=radio]', function(){
|
||||
var id = $(this).attr('name');
|
||||
var value = $(this).val();
|
||||
$('#add_field_form [data-if-'+id+']').hide();
|
||||
if($(this).is(':checked')){
|
||||
$('#add_field_form [data-if-'+id+'='+value+']').show();
|
||||
}
|
||||
});
|
||||
|
||||
$('[type=radio]').trigger('change');
|
||||
|
||||
$(document).on('change', '.config-dropdown', function(){
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).val();
|
||||
var attr_value = $('#add_field_form [data-if-'+id+']');
|
||||
|
||||
$('#add_field_form [data-if-'+id+']').hide();
|
||||
|
||||
if(attr_value.length > 0){
|
||||
$.each(attr_value, function(x,y){
|
||||
var this_attr_value = $(y).attr('data-if-'+id);
|
||||
if(this_attr_value.indexOf('::') !== -1){
|
||||
var split = this_attr_value.split('::');
|
||||
if($.inArray(value, split) !== -1){
|
||||
$(y).show();
|
||||
}
|
||||
}else{
|
||||
if(this_attr_value == value){
|
||||
$(y).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('.config-dropdown').trigger('change');
|
||||
|
||||
$(document).on('click', '.open-option', function(e){
|
||||
e.preventDefault();
|
||||
$(this).find('.bi').toggleClass('bi-arrow-up').toggleClass('bi-arrow-down');
|
||||
$(this).closest('.child-fields-wrapper').find('.child-field-wrapper').slideToggle();
|
||||
$(this).closest('.child-field-title').toggleClass('option-detail-opened');
|
||||
});
|
||||
|
||||
var all_checkbox = $('[type="checkbox"]');
|
||||
if(all_checkbox.length > 0){
|
||||
$.each(all_checkbox, function(a,b){
|
||||
if($(b).val() == 'yes'){
|
||||
$(b).val('no').trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function modify_payment_box_behavior() {
|
||||
|
||||
var allbox = $('#payments multi_checkbox');
|
||||
var checkbox_input = $('.payments-payment input[type=checkbox]');
|
||||
var checked_value = [];
|
||||
if(checkbox_input.length > 0){
|
||||
$.each(checkbox_input, function(x, y){
|
||||
if($(y).is(':checked')){
|
||||
checked_value.push($(y).val());
|
||||
$('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').show();
|
||||
}else{
|
||||
$('[data-field=wpcfto_addon_option_payment_'+$(y).val()+']').hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
modify_payment_box_behavior();
|
||||
}, 500);
|
||||
|
||||
$(document).on('click', '.payments-payment input[type=checkbox]', function(){
|
||||
modify_payment_box_behavior();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'span.grab', function(){
|
||||
$(this).css('pointer', 'grab');
|
||||
});
|
||||
|
||||
$(document).on('click', 'span.grab', function(){
|
||||
$(this).css('pointer', 'grabbing');
|
||||
});
|
||||
|
||||
$(document).on('change blur', '.child-field-label input.formipay-builder-field', function(){
|
||||
$(this).closest('.child-fields-wrapper').find('.the_title').text($(this).val());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
// setTimeout(() => {
|
||||
// var autocomplete_fields = $('.wpcfto-box .autocomplete');
|
||||
// if(autocomplete_fields.length > 0){
|
||||
// $.each(autocomplete_fields, function(increment, field){
|
||||
// var label = $(field).find('.wpcfto-field-aside__label').text();
|
||||
// var placeholder = formipay_admin.config.autocomplete.placeholder.replace('{field_label}', label);
|
||||
// var search_input = $(field).find('input');
|
||||
// search_input.attr('placeholder', placeholder);
|
||||
// search_input.parent().attr('data-input-placeholder', placeholder);
|
||||
// });
|
||||
// }
|
||||
// }, 1000);
|
||||
|
||||
// $(document).on('mouseleave blur focusout', '.wpcfto-autocomplete-search input', function(){
|
||||
// var placeholder = $(this).parent().attr('data-input-placeholder');
|
||||
// setTimeout(() => {
|
||||
// $(this).attr('placeholder', placeholder);
|
||||
// }, 500);
|
||||
// });
|
||||
|
||||
$( document ).on( 'click', '.add-thumbnail', function( event ) {
|
||||
|
||||
var gallery_items_frame;
|
||||
const $el = $( this );
|
||||
var target_field = $el.attr('data-field');
|
||||
var target_id = $el.siblings('.'+target_field+'-id');
|
||||
var target_url = $el.siblings('.'+target_field+'-url');
|
||||
var selected = target_id.val();
|
||||
var able_multiple = $el.attr('data-able-multiple');
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( gallery_items_frame ) {
|
||||
|
||||
// Select the attachment when the frame opens
|
||||
gallery_items_frame.on( 'open', function() {
|
||||
var selection = gallery_items_frame.state().get( 'selection' );
|
||||
selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] );
|
||||
});
|
||||
|
||||
// Open the modal.
|
||||
gallery_items_frame.open();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
gallery_items_frame = wp.media.frames.gallery_items = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: 'Choose or upload media',
|
||||
button: {
|
||||
text: 'Select'
|
||||
},
|
||||
states: [
|
||||
new wp.media.controller.Library({
|
||||
title: 'Choose or upload media',
|
||||
filterable: 'all',
|
||||
multiple: able_multiple
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
// Select the attachment when the frame opens
|
||||
gallery_items_frame.on( 'open', function() {
|
||||
var selection = gallery_items_frame.state().get( 'selection' );
|
||||
selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] );
|
||||
});
|
||||
|
||||
gallery_items_frame.on( 'select', function() {
|
||||
attachment = gallery_items_frame.state().get('selection').first().toJSON();
|
||||
target_id.val( attachment.id );
|
||||
target_url.val( attachment.url );
|
||||
if(target_id.val() !== ''){
|
||||
// $el.removeClass('text-white').addClass('text-info d-none');
|
||||
if($el.hasClass('btn')){
|
||||
$el.siblings('i').hide();
|
||||
}else{
|
||||
$el.hide();
|
||||
}
|
||||
$el.siblings('img').removeClass('d-none').attr('src', attachment.url).show();
|
||||
}else{
|
||||
// $el.removeClass('text-info d-none').addClass('text-white');
|
||||
if($el.hasClass('btn')){
|
||||
$el.siblings('i').show();
|
||||
}else{
|
||||
$el.show();
|
||||
}
|
||||
$el.siblings('img').addClass('d-none').hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Open the modal.
|
||||
gallery_items_frame.open();
|
||||
|
||||
});
|
||||
|
||||
$( document ).on( 'click', '.trumbowyg-button-group:has(.trumbowyg-insertImage-button)', function( event ) {
|
||||
|
||||
var gallery_items_frame;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
// Create the media frame.
|
||||
gallery_items_frame = wp.media.frames.gallery_items = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: 'Choose or upload media',
|
||||
button: {
|
||||
text: 'Select'
|
||||
},
|
||||
states: [
|
||||
new wp.media.controller.Library({
|
||||
title: 'Choose or upload media',
|
||||
filterable: 'all',
|
||||
multiple: false
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
gallery_items_frame.on( 'select', function() {
|
||||
attachment = gallery_items_frame.state().get('selection').first().toJSON();
|
||||
var target_input_url = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-input-html input');
|
||||
var target_confirm = $('.trumbowyg-modal.trumbowyg-fixed-top .trumbowyg-modal-submit');
|
||||
target_input_url.val( attachment.url );
|
||||
target_confirm.trigger('click');
|
||||
|
||||
});
|
||||
|
||||
// Open the modal.
|
||||
gallery_items_frame.open();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
174
admin/assets/js/admin-handlebars.js
Normal file
@@ -0,0 +1,174 @@
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
function getParam(key) {
|
||||
var paramsStr = window.location.search.substr(1, window.location.search.length),
|
||||
paramsArr = paramsStr.split("&"),
|
||||
items = [];
|
||||
|
||||
for (var i = 0; i < paramsArr.length; i++) {
|
||||
items[paramsArr[i].split("=")[0]] = paramsArr[i].split("=")[1];
|
||||
}
|
||||
|
||||
if (key != "" && key != undefined) {
|
||||
// return single
|
||||
if (items[key] != undefined) {
|
||||
return items[key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// return all (array)
|
||||
return items;
|
||||
}
|
||||
};
|
||||
|
||||
if (getParam('post')){
|
||||
// Fetch data via AJAX
|
||||
$.ajax({
|
||||
url: formipay_admin.ajax_url, // WordPress AJAX URL
|
||||
method: 'GET',
|
||||
data: {
|
||||
action: 'fetch_formipay_settings',
|
||||
post_id: formipay_admin.form_id, // Assuming you have post ID available globally,
|
||||
_wpnonce: formipay_admin.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
var source = $("#preview-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
fields: response.data.fields
|
||||
};
|
||||
var html = template(context);
|
||||
$("#preview-wrapper").html(html);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch data via AJAX
|
||||
$.ajax({
|
||||
url: formipay_admin.ajax_url, // WordPress AJAX URL
|
||||
method: 'GET',
|
||||
data: {
|
||||
action: 'fetch_formipay_fields',
|
||||
},
|
||||
success: function(response) {
|
||||
var source = $("#add-field-form-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
fields: response.data.fields
|
||||
};
|
||||
var html = template(context);
|
||||
$("#add_field_form").html(html);
|
||||
$('#add_field_form .field select.form-select').trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
// Handlebars helper for comparing equality
|
||||
Handlebars.registerHelper('ifEquals', function(arg1, arg2, options) {
|
||||
return (arg1 == arg2) ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
|
||||
// Handlebars helper for checking inequality
|
||||
Handlebars.registerHelper('ifNotEquals', function(arg1, arg2, options) {
|
||||
return (arg1 != arg2) ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
|
||||
// Handlebars helper for checking if a value is in a list
|
||||
Handlebars.registerHelper('ifIn', function(value, list, options) {
|
||||
return (list.split(' ').indexOf(value) > -1) ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
|
||||
// Handlebars helper for checking if a value is in a list
|
||||
Handlebars.registerHelper('ifNotIn', function(value, list, options) {
|
||||
return (list.split(' ').indexOf(value) > -1) ? options.inverse(this) : options.fn(this);
|
||||
});
|
||||
|
||||
// Handlebars helper for JSON stringify
|
||||
Handlebars.registerHelper('json', function(context) {
|
||||
return JSON.stringify(context);
|
||||
});
|
||||
|
||||
// Handlebars helper to concatenate custom classes
|
||||
Handlebars.registerHelper('custom_class', function(custom_class) {
|
||||
return (custom_class && Array.isArray(custom_class)) ? ' '+custom_class.join(' ') : '';
|
||||
});
|
||||
|
||||
// Handlebars helper to handle conditional classes and display properties
|
||||
Handlebars.registerHelper('conditional_class', function(conditional) {
|
||||
return (conditional && conditional.length > 0) ? ' has-conditional' : '';
|
||||
});
|
||||
|
||||
// Handlebars helper to return label class
|
||||
Handlebars.registerHelper('labelClass', function(fieldType) {
|
||||
return 'label-' + fieldType;
|
||||
});
|
||||
|
||||
// Handlebars helper to return name attribute for checkbox and radio inputs
|
||||
Handlebars.registerHelper('name', function(fieldType, fieldId, index) {
|
||||
return (fieldType == 'radio') ? fieldId : fieldId + '-' + index;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('display', function(conditional) {
|
||||
var display = '';
|
||||
if (conditional) {
|
||||
display = ' style="display:none"';
|
||||
if (Array.isArray(conditional)) {
|
||||
conditional.forEach(function(cond) {
|
||||
display += ' data-if-' + cond.key + "='" + JSON.stringify(cond.value) + "'";
|
||||
});
|
||||
}
|
||||
}
|
||||
return display;
|
||||
});
|
||||
|
||||
// Handlebars helper to format option text
|
||||
Handlebars.registerHelper('formatOption', function(option) {
|
||||
return option.charAt(0).toUpperCase() + option.slice(1).replace('_', ' ');
|
||||
});
|
||||
|
||||
// Handlebars helper for toggle display property
|
||||
Handlebars.registerHelper('toggleDisplay', function(toggle) {
|
||||
return (toggle == 'yes') ? ' style="display:none;"' : '';
|
||||
});
|
||||
|
||||
// Handlebars helper for set grid column for checkbox and radio
|
||||
Handlebars.registerHelper('layoutColumn', function(layout) {
|
||||
return (layout !== '') ? layout : 1;
|
||||
});
|
||||
|
||||
// Handlebars helper for set the first option as selected
|
||||
Handlebars.registerHelper('selectedTheFirstOption', function(index) {
|
||||
return (index == 0) ? ' selected' : '';
|
||||
});
|
||||
|
||||
// Handlebars helper for set the first option as selected
|
||||
Handlebars.registerHelper('countryListOptions', function() {
|
||||
var country_json = formipay_admin.preset.country_list;
|
||||
// Check if country_json is a string (indicating it might need to be parsed)
|
||||
if (typeof country_json === 'string') {
|
||||
try {
|
||||
country_json = JSON.parse(country_json); // Parse the JSON string into an object
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON:', e); // Log any parsing errors
|
||||
country_json = []; // Fallback to an empty array
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the data type
|
||||
if (!Array.isArray(country_json)) {
|
||||
console.error('Expected an array but got:', country_json);
|
||||
country_json = []; // Fallback to an empty array if not an array
|
||||
}
|
||||
|
||||
var options_html = ``; // Initialize options_html variable
|
||||
|
||||
// Loop through each country object
|
||||
$.each(country_json, function(index, country) {
|
||||
// Assuming each country object has 'id' for the value and 'name' for the display text
|
||||
options_html += `<option value="${country.name}">${country.name}</option>`;
|
||||
});
|
||||
|
||||
return options_html;
|
||||
});
|
||||
|
||||
});
|
||||
430
admin/assets/js/admin-order-details.js
Normal file
@@ -0,0 +1,430 @@
|
||||
jQuery(function($){
|
||||
|
||||
Handlebars.registerHelper('ifEquals', function(arg1, arg2, options) {
|
||||
return (arg1 == arg2) ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
Handlebars.registerHelper('nameToTitle', function(arg) {
|
||||
var parse = arg.split('_');
|
||||
var output = [];
|
||||
$.each(parse, function( a, b ){
|
||||
if(b.length <= 3){
|
||||
output.push(b.toUpperCase());
|
||||
}else{
|
||||
output.push(b);
|
||||
}
|
||||
});
|
||||
return output.join(' ');
|
||||
});
|
||||
Handlebars.registerHelper('parsePaymentInfo', function(arg) {
|
||||
var explode = arg.split('-');
|
||||
var explode2 = explode[0].split(':::');
|
||||
var gateway = explode2[0].split('_').join(' ');
|
||||
var channel = explode2[1];
|
||||
return gateway + ' - ' + channel;
|
||||
});
|
||||
Handlebars.registerHelper('ifKeyExists', function(key, obj, options) {
|
||||
// Check if the key exists in the object
|
||||
if (obj && obj.hasOwnProperty(key)) {
|
||||
// If it exists, execute the block
|
||||
return options.fn(this);
|
||||
}
|
||||
// If it does not exist, execute the inverse block (if provided)
|
||||
return options.inverse(this);
|
||||
});
|
||||
|
||||
function ucWords(input) {
|
||||
return input
|
||||
.replace(/_/g, ' ') // Replace underscores with spaces
|
||||
.toLowerCase() // Convert entire string to lowercase first
|
||||
.replace(/^(.)/, function(char) { return char.toUpperCase(); }) // Capitalize the first letter of the first word
|
||||
.replace(/ (.)/g, function(char) { return char.toUpperCase(); }); // Capitalize the first letter after each space
|
||||
}
|
||||
|
||||
let order_id = $('#order_id').val();
|
||||
|
||||
function load_order_data() {
|
||||
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_order_details_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_load_order_data',
|
||||
order: order_id,
|
||||
_wpnonce: formipay_order_details_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
console.log(res);
|
||||
var source = $("#order-item-row-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
items: res.items
|
||||
};
|
||||
var html = template(context);
|
||||
$("#order-items-table tbody").html(html);
|
||||
$('#order-total').html(res.total_formatted);
|
||||
$('#order_status').val(res.status);
|
||||
|
||||
var source = $("#form-data-item-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
datas: res.form_data
|
||||
};
|
||||
var html = template(context);
|
||||
$("#form-data-list").html(html);
|
||||
var editFormDataButton = $('.edit-transaction-data').attr('data-loaded-button-text');
|
||||
$('.edit-transaction-data').text(editFormDataButton).prop('disabled', false);
|
||||
|
||||
var source = $("#form-data-item-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var meta_data = [];
|
||||
$.each(res.meta_data, function(index, meta){
|
||||
if(meta.name !== 'access_method' && meta.name !== 'access_password'){
|
||||
meta_data.push(meta);
|
||||
}
|
||||
});
|
||||
var context = {
|
||||
datas: meta_data
|
||||
};
|
||||
var html = template(context);
|
||||
$("#submission-detail-list").html(html);
|
||||
|
||||
var source = $("#notification-data-template").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
datas: res.notification.sort().reverse()
|
||||
};
|
||||
var html = template(context);
|
||||
$("#notification-list").html(html);
|
||||
|
||||
var source = $("#transaction-timeline-item").html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
datas: res.transaction_timeline.sort().reverse()
|
||||
};
|
||||
var html = template(context);
|
||||
$("#transaction-list").html(html);
|
||||
|
||||
var passMethod = {
|
||||
'magic_link': 'Magic Link',
|
||||
'static_password': 'Static Password'
|
||||
}
|
||||
var source = $('#thankyou-access-template').html();
|
||||
var template = Handlebars.compile(source);
|
||||
var context = {
|
||||
data: {
|
||||
link: res.thankyou.link,
|
||||
pass_method: res.thankyou.pass_method,
|
||||
pass_method_label: passMethod[res.thankyou.pass_method],
|
||||
pass_word: res.thankyou.pass_word
|
||||
}
|
||||
};
|
||||
var html = template(context);
|
||||
$('#access-detail-list').html(html);
|
||||
$('#access_method').val(res.thankyou.pass_method).trigger('change');
|
||||
var editFormDataButton = $('.edit-access-data').attr('data-loaded-button-text');
|
||||
$('.edit-access-data').text(editFormDataButton).prop('disabled', false);
|
||||
if(res.thankyou.pass_method == 'static_password'){
|
||||
$('li.access-password p').text(res.thankyou.pass_word);
|
||||
$('li.access-password').removeClass('d-none');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function set_loading_button(selector, loadingText = '') {
|
||||
var buttonText = selector.text();
|
||||
selector.attr('data-button-text', buttonText);
|
||||
selector.prop('disabled', true);
|
||||
if(loadingText !== '') {
|
||||
selector.html(`
|
||||
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
|
||||
<span role="status">${loadingText}</span>
|
||||
`);
|
||||
}else{
|
||||
selector.html(`
|
||||
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
|
||||
<span class="visually-hidden" role="status">${loadingText}</span>
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
function remove_loading_button(selector) {
|
||||
var buttonText = selector.attr('data-button-text');
|
||||
selector.prop('disabled', false);
|
||||
selector.html(buttonText);
|
||||
}
|
||||
|
||||
load_order_data();
|
||||
|
||||
$(document).on('click', '.timeline-item-image', function(){
|
||||
var imageSrc = $(this).attr('src');
|
||||
$('#image-ligthbox img').attr('src', imageSrc);
|
||||
$('#image-ligthbox').modal('show');
|
||||
});
|
||||
|
||||
$('#order_status').on('change', function() {
|
||||
var status = $(this).val();
|
||||
var order_id = $(this).data('order-id');
|
||||
Swal.fire({
|
||||
html: formipay_order_details_page.order_detail.change_order_status_confirmation,
|
||||
icon: 'question',
|
||||
confirmButtonText: formipay_order_details_page.order_detail.change_order_status_button_confirm,
|
||||
cancelButtonText: formipay_order_details_page.order_detail.change_order_status_button_cancel,
|
||||
showCancelButton: true,
|
||||
reverseButtons: true
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_order_details_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_change_order_status',
|
||||
id: order_id,
|
||||
status: status,
|
||||
_wpnonce: formipay_order_details_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.success){
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'success'
|
||||
});
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.edit-transaction-data').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var $this_button = $(this);
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_order_details_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_check_editable_field',
|
||||
order_id: formipay_order_details_page.order_id,
|
||||
_wpnonce: formipay_order_details_page.nonce
|
||||
},
|
||||
beforeSend: function() {
|
||||
set_loading_button($this_button, formipay_order_details_page.order_detail.edit_button_loading_text);
|
||||
},
|
||||
success: function(res) {
|
||||
remove_loading_button($this_button);
|
||||
$('.edit-transaction-data').addClass('d-none');
|
||||
$('.update-transaction-buttons').removeClass('d-none');
|
||||
$.each(res, function(config, field_data){
|
||||
var field_id = field_data.field_id;
|
||||
var field_current_value = $(`[data-field-name=${field_id}]`).text();
|
||||
$(`[data-field-name=${field_id}]`).attr('data-current-value', field_current_value);
|
||||
|
||||
$(`[data-field-name=${field_id}]`).html(`
|
||||
<input type="${field_data.field_type}" name="${field_id}" value="${$.trim(field_current_value)}" class="form-control rounded border border-secondary-subtle">
|
||||
`);
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
$('.update-transaction-data').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var $this_button = $(this);
|
||||
var editable_inputs = $('#form-data-list').find('input');
|
||||
var editable_field_values = [];
|
||||
$.each(editable_inputs, function(i, input){
|
||||
var this_input = {
|
||||
name: $(input).attr('name'),
|
||||
value: $(input).val()
|
||||
}
|
||||
editable_field_values.push(this_input);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_order_details_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_update_editable_field_data',
|
||||
order_id: formipay_order_details_page.order_id,
|
||||
new_values: editable_field_values,
|
||||
_wpnonce: formipay_order_details_page.nonce
|
||||
},
|
||||
beforeSend: function() {
|
||||
set_loading_button($this_button, formipay_order_details_page.order_detail.update_button_loading_text);
|
||||
},
|
||||
success: function(res){
|
||||
remove_loading_button($this_button);
|
||||
if(res.success){
|
||||
$('.edit-transaction-data').removeClass('d-none');
|
||||
$('.update-transaction-buttons').addClass('d-none');
|
||||
$.each(editable_inputs, function(i, input){
|
||||
var new_value = $(input).val();
|
||||
$(input).parent().removeAttr('data-current-value');
|
||||
$(input).parent().text(new_value);
|
||||
});
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'success'
|
||||
});
|
||||
}else{
|
||||
$.each(editable_inputs, function(i, input){
|
||||
var current_value = $(input).parent().attr('data-current-value');
|
||||
$(input).val(current_value);
|
||||
});
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('.cancel-transaction-data').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var editable_inputs = $('#form-data-list').find('input');
|
||||
$.each(editable_inputs, function(i, input){
|
||||
var current_value = $(input).parent().attr('data-current-value');
|
||||
$(input).parent().text(current_value);
|
||||
});
|
||||
$('.edit-transaction-data').removeClass('d-none');
|
||||
$('.update-transaction-buttons').addClass('d-none');
|
||||
|
||||
});
|
||||
|
||||
$('.edit-access-data').on('click', function(e){
|
||||
e.preventDefault();
|
||||
var $this_button = $(this);
|
||||
set_loading_button($this_button, formipay_order_details_page.order_detail.edit_button_loading_text);
|
||||
|
||||
var current_method = $('li.access-method').attr('data-access-method');
|
||||
$('li.access-method').find('p').after(`
|
||||
<select name="access_method" id="access_method" class="form-select w-100 rounded border border-secondary-subtle" data-order-id="${$('#order_id').val()}" style="max-width: unset;">
|
||||
<option value="magic_link" ${(current_method == 'magic_link') ? 'selected' : ''}>${formipay_order_details_page.order_detail.pass_method.magic_link}</option>
|
||||
<option value="static_password" ${(current_method == 'static_password') ? 'selected' : ''}>${formipay_order_details_page.order_detail.pass_method.static_password}</option>
|
||||
</select>
|
||||
`);
|
||||
$('#access_method').trigger('change');
|
||||
$('li.access-method').find('p').addClass('d-none');
|
||||
remove_loading_button($this_button);
|
||||
$('.edit-access-data').addClass('d-none');
|
||||
$('.update-access-buttons').removeClass('d-none');
|
||||
});
|
||||
|
||||
$(document).on('change', '#access_method', function(){
|
||||
var access_password_li = $(this).closest('li').siblings('.access-password');
|
||||
if($(this).val() == 'static_password'){
|
||||
var password = access_password_li.attr('data-access-password');
|
||||
access_password_li.removeClass('d-none');
|
||||
access_password_li.find('p').after(`
|
||||
<input type="text" id="access_password" class="form-control w-100 rounded border border-secondary-subtle" value="${ password}">
|
||||
`);
|
||||
access_password_li.find('p').addClass('d-none');
|
||||
}else{
|
||||
access_password_li.addClass('d-none');
|
||||
access_password_li.find('input').remove();
|
||||
}
|
||||
});
|
||||
|
||||
function normalize_access_data_card() {
|
||||
var accessMethod = $('li.access-method').attr('data-access-method');
|
||||
var accessPassword = $('li.access-password').attr('data-access-password');
|
||||
$('li.access-method select').remove();
|
||||
$('li.access-method p').removeClass('d-none');
|
||||
$('.edit-access-data').removeClass('d-none');
|
||||
$('.update-access-buttons').addClass('d-none');
|
||||
if( accessMethod == 'magic_link'){
|
||||
$('li.access-password').addClass('d-none');
|
||||
}
|
||||
$('li.access-method p').text(ucWords(accessMethod)).removeClass('d-none');
|
||||
$('li.access-password p').text(ucWords(accessPassword)).removeClass('d-none');
|
||||
$('li.access-password input').remove();
|
||||
}
|
||||
|
||||
$('.cancel-access-data').on('click', function(e){
|
||||
e.preventDefault();
|
||||
normalize_access_data_card();
|
||||
});
|
||||
|
||||
$('.update-access-data').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var $this_button = $(this);
|
||||
var this_method = $('#access_method').val();
|
||||
var this_password = $('#access_password').val()
|
||||
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_order_details_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay_update_digital_access',
|
||||
order_id: formipay_order_details_page.order_id,
|
||||
method: this_method,
|
||||
password: this_password,
|
||||
_wpnonce: formipay_order_details_page.nonce
|
||||
},
|
||||
beforeSend: function() {
|
||||
set_loading_button($this_button, formipay_order_details_page.order_detail.update_button_loading_text);
|
||||
},
|
||||
success: function(res){
|
||||
remove_loading_button($this_button);
|
||||
if(res.success){
|
||||
$('li.access-method').attr('data-access-method', this_method)
|
||||
if(this_method == 'static_password'){
|
||||
$('li.access-password').attr('data-access-password', this_password)
|
||||
}
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'success'
|
||||
});
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
normalize_access_data_card();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$(document).on('click', '.formipay-copy-button', function(e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
var copiedtext = $(this).attr("data-copy-value");
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(copiedtext)
|
||||
.then(() => {
|
||||
$this.html('<i class="bi bi-check-circle-fill"></i> '+$this.attr('data-copied-text'));
|
||||
setTimeout(() => {
|
||||
$this.html('<i class="bi bi-copy"></i> '+$this.attr('data-copy-text'));
|
||||
}, 1200);
|
||||
})
|
||||
.catch((error) => {
|
||||
$this.html('<i class="bi bi-exclamation-circle-fill"></i> '+$this.attr('data-not-copied-text'));
|
||||
setTimeout(() => {
|
||||
$this.html('<i class="bi bi-copy"></i> '+$this.attr('data-copy-text'));
|
||||
}, 1200);
|
||||
});
|
||||
} else {
|
||||
$this.html('<i class="bi bi-check-circle-fill"></i> '+$this.attr('data-not-copied-text'));
|
||||
setTimeout(() => {
|
||||
$this.html('<i class="bi bi-copy"></i> '+$this.attr('data-copy-text'));
|
||||
}, 1200);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
256
admin/assets/js/admin-orders.js
Normal file
@@ -0,0 +1,256 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const formChoices = new Choices('#products', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_orders_page.filter_form.products.placeholder,
|
||||
noResultsText: formipay_orders_page.filter_form.products.noresult_text,
|
||||
itemSelectText: '',
|
||||
});
|
||||
|
||||
const currencyChoices = new Choices('#currencies', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_orders_page.filter_form.currencies.placeholder,
|
||||
noResultsText: formipay_orders_page.filter_form.currencies.noresult_text,
|
||||
itemSelectText: '',
|
||||
allowHTML: true
|
||||
});
|
||||
|
||||
const searchInputs = document.querySelectorAll('.choices__input--cloned');
|
||||
let typingTimer;
|
||||
|
||||
searchInputs.forEach((searchInput) => {
|
||||
searchInput.addEventListener('input', function () {
|
||||
const query = searchInput.value;
|
||||
|
||||
if (query.length >= 3) {
|
||||
clearTimeout(typingTimer);
|
||||
typingTimer = setTimeout(() => {
|
||||
// Find the wrapper (e.g., .product or .currency)
|
||||
const parentWrapper = searchInput.closest('.product, .currency');
|
||||
let searchType = ''; // Initialize search type
|
||||
|
||||
// Determine the type based on the parent wrapper's class
|
||||
if (parentWrapper) {
|
||||
if (parentWrapper.classList.contains('product')) {
|
||||
searchType = 'form';
|
||||
} else if (parentWrapper.classList.contains('currency')) {
|
||||
searchType = 'currency';
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch choices with the determined type
|
||||
fetchChoices(query, searchType);
|
||||
}, 300); // Add a debounce delay
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fetchChoices(query, type) {
|
||||
fetch(formipay_orders_page.ajax_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'formipay_orders_get_choices',
|
||||
search: query,
|
||||
type: type, // Pass the type to the server,
|
||||
_wpnonce: formipay_orders_page.nonce
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
const currentChoices = type === 'form' ? formChoices : currencyChoices;
|
||||
|
||||
currentChoices.clearChoices();
|
||||
currentChoices.setChoices(data, 'value', 'label', true);
|
||||
})
|
||||
.catch((error) => console.error('Error:', error));
|
||||
}
|
||||
|
||||
document.getElementById('reset-filter').addEventListener('click', function(){
|
||||
formChoices.removeActiveItems();
|
||||
currencyChoices.removeActiveItems();
|
||||
|
||||
const input = document.getElementById('order_id');
|
||||
const event = new Event('change', { bubbles: true });
|
||||
|
||||
input.value = '';
|
||||
input.dispatchEvent(event);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
let formipay_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_orders_page.ajax_url+'?action=formipay-tabledata-orders&order_status='+document.getElementById('post_status').value+'&product='+document.getElementById('products').value+'¤cy='+document.getElementById('currencies').value+'&order_id='+document.getElementById('order_id').value+'&_wpnonce='+formipay_orders_page.nonce,
|
||||
then: data => {
|
||||
|
||||
if(data.posts_report){
|
||||
processPostsReport(data.posts_report);
|
||||
}
|
||||
|
||||
return data.results.map(
|
||||
order => [order.ID, order.ID, order.date, order.form, order.total, order.payment_gateway, order.status]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'checkbox',
|
||||
name: gridjs.html(`<input type="checkbox" id="select-all-rows">`),
|
||||
width: '50px',
|
||||
formatter: (_, row) => gridjs.html(
|
||||
`<input type="checkbox" class="formipay-row-checkbox" data-id="${row.cells[0].data}">`
|
||||
)
|
||||
},
|
||||
{
|
||||
name: formipay_orders_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_orders_page.columns.date,
|
||||
formatter: (_, row) => gridjs.html('<span>' + _.split(' ').join('</span><br><span style="font-size: smaller;">') + '</span>')
|
||||
},
|
||||
{
|
||||
name: formipay_orders_page.columns.form,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<b>${_}</b><br>
|
||||
<span class="post-action" style="visibility: hidden;">
|
||||
<a href="${formipay_orders_page.site_url}/wp-admin/admin.php?page=formipay-orders&order_id=${row.cells[0].data}">details</a> | <a href="#" class="delete-order" data-id="${row.cells[0].data}">delete</a>
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_orders_page.columns.total,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="grand_total">
|
||||
<span class="currency">
|
||||
<img src="${_.flag}" height="18">
|
||||
${_.name}
|
||||
</span>
|
||||
<span class="the-total">${_.value}</span>
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
formipay_orders_page.columns.payment_gateway,
|
||||
{
|
||||
name: formipay_orders_page.columns.status,
|
||||
formatter: (status, row) => gridjs.html(`<span class="status-label ${status}">${status}</span>`)
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
limit: document.getElementById('limit').value,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-orders'));
|
||||
|
||||
var $tableContainer = $('.formipay-grid-table');
|
||||
var $deleteBtn = $('#formipay-delete-selected');
|
||||
|
||||
function updateDeleteButtonVisibility() {
|
||||
if ($tableContainer.find('.formipay-row-checkbox:checked').length > 0) {
|
||||
$deleteBtn.show();
|
||||
} else {
|
||||
$deleteBtn.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '.formipay-row-checkbox', function() {
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '#select-all-rows', function() {
|
||||
const is_checked = $(this).is(':checked');
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', is_checked);
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle delete button click
|
||||
$deleteBtn.on('click', function() {
|
||||
var selectedIds = $tableContainer.find('.formipay-row-checkbox:checked').map(function() {
|
||||
return $(this).data('id');
|
||||
}).get();
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_orders_page.modal.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_orders_page.modal.bulk_delete.confirmButton,
|
||||
cancelButtonText: formipay_orders_page.modal.bulk_delete.cancelButton
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_orders_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-bulk-delete-access-item',
|
||||
ids: selectedIds,
|
||||
_wpnonce: formipay_orders_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', false);
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function refresh_table_with_filter() {
|
||||
formipay_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_orders_page.ajax_url+'?action=formipay-tabledata-orders&order_status='+document.getElementById('post_status').value+'&product='+document.getElementById('products').value+'¤cy='+document.getElementById('currencies').value+'&order_id='+document.getElementById('order_id').value+'&_wpnonce='+formipay_orders_page.nonce,
|
||||
then: data => data.results.map(
|
||||
order => [order.ID, order.ID, order.date, order.form, order.total, order.payment_gateway, order.status]
|
||||
),
|
||||
total: data => data.total
|
||||
},
|
||||
pagination: {
|
||||
limit: document.getElementById('limit').value,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
}).forceRender();
|
||||
}
|
||||
|
||||
$('.form-tool, #post_status, #products, #currencies, #order_id').on('change', function(){
|
||||
refresh_table_with_filter();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=form]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=form]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
});
|
||||
69
admin/assets/js/admin-pages.js
Normal file
@@ -0,0 +1,69 @@
|
||||
function numberFormat(nStr) {
|
||||
nStr = parseFloat(nStr).toFixed(2);
|
||||
var x = nStr.split('.');
|
||||
var x1 = x[0];
|
||||
var x2 = x.length > 1 ? '.' + x[1] : '';
|
||||
var rgx = /(\d+)(\d{3})/;
|
||||
while (rgx.test(x1)) {
|
||||
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||||
}
|
||||
return x1 + x2;
|
||||
}
|
||||
|
||||
function processPostsReport(data) {
|
||||
Object.keys(data).forEach(function(status) {
|
||||
// Update the text of elements matching the class
|
||||
var elements = document.querySelectorAll('.' + status + '-post-count');
|
||||
elements.forEach(function(element) {
|
||||
element.textContent = ' (' + data[status] + ')';
|
||||
});
|
||||
|
||||
// Handle the 'trash' status specifically
|
||||
if (status === 'trash' && data[status] > 0) {
|
||||
var wrapper = document.querySelector('.post-status-wrapper');
|
||||
if (wrapper) {
|
||||
wrapper.innerHTML += ' | <a data-value="trash">Trash</a><span class="draft-post-count"> (' + data[status] + ')</span>';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
jQuery(function($){
|
||||
$('.post-status-wrapper a').on('click', function(e){
|
||||
e.preventDefault();
|
||||
$('.post-status-wrapper a').removeAttr('data-active');
|
||||
$(this).attr('data-active', 'true');
|
||||
$('#post_status').val($(this).data('value')).trigger('change');
|
||||
});
|
||||
});
|
||||
|
||||
(function() {
|
||||
var supportsPassive = false;
|
||||
try {
|
||||
var opts = Object.defineProperty({}, 'passive', {
|
||||
get: function() {
|
||||
supportsPassive = true;
|
||||
}
|
||||
});
|
||||
window.addEventListener("testPassive", null, opts);
|
||||
window.removeEventListener("testPassive", null, opts);
|
||||
} catch (e) {}
|
||||
|
||||
if (!supportsPassive) return;
|
||||
|
||||
var origAddEventListener = EventTarget.prototype.addEventListener;
|
||||
EventTarget.prototype.addEventListener = function(type, listener, options) {
|
||||
// Only patch touchstart and touchmove if options is not explicitly passive
|
||||
if (
|
||||
(type === 'touchstart' || type === 'touchmove') &&
|
||||
(options === undefined || options === false || (typeof options === 'object' && !options.passive))
|
||||
) {
|
||||
options = options || {};
|
||||
if (typeof options === 'object') {
|
||||
options.passive = true;
|
||||
}
|
||||
}
|
||||
return origAddEventListener.call(this, type, listener, options);
|
||||
};
|
||||
})();
|
||||
|
||||
359
admin/assets/js/admin-product-editor.js
Normal file
@@ -0,0 +1,359 @@
|
||||
jQuery(function ($) {
|
||||
|
||||
$('a[href="admin.php?page=formipay-products"]').addClass('current').closest('li').addClass('current');
|
||||
|
||||
function autoset_variation_name() {
|
||||
var repeater_single = $('.product_variation_attributes.repeater [parent_repeater="parent"] > .wpcfto-field-content > .wpcfto-repeater-single');
|
||||
$.each(repeater_single, function (key, parent) {
|
||||
var repeater_child = $(parent).find('[field_native_name="product_variation_attributes"]');
|
||||
var attribute_name = repeater_child.find(`[name="product_variation_attributes_${key}_attribute_name"]`).val();
|
||||
var attribute_type = repeater_child.find(`[name="product_variation_attributes_${key}_attribute_type"]`).val();
|
||||
var repeater_child_single = repeater_child.find('.wpcfto-repeater-single');
|
||||
$.each(repeater_child_single, function (index, child) {
|
||||
var label_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_label"]`);
|
||||
var name_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_name"]`);
|
||||
var color_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_color"]`);
|
||||
var color_field_row = color_field.closest('.wpcfto-repeater-field');
|
||||
if (attribute_type == 'color') {
|
||||
color_field_row.show();
|
||||
} else {
|
||||
color_field_row.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('change blur', '[field_native_name_inner="variation_label"] input', function () {
|
||||
autoset_variation_name();
|
||||
});
|
||||
|
||||
$(document).on('click', '.stm_metaboxes_grid .stm_metaboxes_grid__inner .wpcfto-repeater .addArea', function () {
|
||||
autoset_variation_name();
|
||||
});
|
||||
|
||||
var onMetaboxLoaded = setInterval(() => {
|
||||
var repeater_single = $('.product_variation_attributes.repeater [parent_repeater="parent"] > .wpcfto-field-content > .wpcfto-repeater-single');
|
||||
if (repeater_single.length > 0) {
|
||||
autoset_variation_name();
|
||||
clearInterval(onMetaboxLoaded);
|
||||
}
|
||||
}, 250);
|
||||
|
||||
var waitForTable = setInterval(() => {
|
||||
if ($('#product-variables-table').length > 0) {
|
||||
clearInterval(waitForTable);
|
||||
|
||||
// --- PERBAIKAN UTAMA DI SINI ---
|
||||
Vue.component('price-input', {
|
||||
// Gunakan 'value' sebagai prop, sesuai konvensi v-model Vue 2
|
||||
props: {
|
||||
value: [Number, String], // Diubah dari modelValue
|
||||
currencySymbol: String,
|
||||
currencyDecimalDigits: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: this.value // Diubah dari modelValue
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// Amati perubahan pada prop 'value'
|
||||
value(newValue) { // Diubah dari modelValue
|
||||
this.inputValue = newValue;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onInput(e) {
|
||||
const value = e.target.value;
|
||||
this.inputValue = value;
|
||||
// Pancarkan event 'input', sesuai konvensi v-model Vue 2
|
||||
this.$emit('input', value); // Diubah dari 'update:modelValue'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stepValue() {
|
||||
return Math.pow(10, -this.currencyDecimalDigits);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="price-input-wrapper">
|
||||
<span class="price-currency">{{ currencySymbol }}</span>
|
||||
<input type="number" :value="inputValue" @input="onInput" :step="stepValue" placeholder="0" :disabled="disabled" />
|
||||
</div>
|
||||
`
|
||||
});
|
||||
// --- AKHIR DARI PERBAIKAN ---
|
||||
|
||||
new Vue({
|
||||
el: '#product-variables-table',
|
||||
data() {
|
||||
return {
|
||||
tableRows: [],
|
||||
deletedKeys: [],
|
||||
isPhysical: window.product_details?.product_is_physical || false,
|
||||
pricingMethod: window.product_details?.product_pricing_method || 'auto',
|
||||
manualPrices: [],
|
||||
productHasVariation: window.product_details?.product_has_variation || false,
|
||||
jsonValue: '[]',
|
||||
attributeRepeaterWatcher: null,
|
||||
manualPricesWatcher: null,
|
||||
_debounceTimer: null,
|
||||
productType: window.product_details?.product_type || 'digital',
|
||||
currencyDecimalDigits: parseInt(window.product_details?.default_currency_decimal_digits) || 2,
|
||||
currencySymbol: window.product_details?.default_currency_symbol || '$'
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
await this.initializeOrClearTable();
|
||||
this.setupAttributeRepeaterSync();
|
||||
this.setupManualPricesSync();
|
||||
const typeRadios = document.querySelectorAll('input[name="product_type"]');
|
||||
typeRadios.forEach(radio => {
|
||||
radio.addEventListener('change', e => {
|
||||
this.productType = e.target.value;
|
||||
this.isPhysical = e.target.value === 'physical';
|
||||
});
|
||||
});
|
||||
const pricingRadios = document.querySelectorAll('input[name="product_pricing_method"]');
|
||||
pricingRadios.forEach(radio => {
|
||||
radio.addEventListener('change', async e => {
|
||||
this.pricingMethod = e.target.value;
|
||||
await this.rebuildTable();
|
||||
});
|
||||
});
|
||||
const hasVariationToggle = document.querySelector('input[name="product_has_variation"]');
|
||||
if (hasVariationToggle) {
|
||||
hasVariationToggle.addEventListener('change', async (e) => {
|
||||
this.productHasVariation = e.target.checked;
|
||||
await this.initializeOrClearTable();
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.attributeRepeaterWatcher) {
|
||||
this.attributeRepeaterWatcher.disconnect();
|
||||
}
|
||||
if (this.manualPricesWatcher) {
|
||||
this.manualPricesWatcher.disconnect();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async initializeOrClearTable() {
|
||||
if (!this.productHasVariation) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
return;
|
||||
}
|
||||
await this.syncManualPrices();
|
||||
await this.loadProductVariables();
|
||||
},
|
||||
_ensureRowDataStructure(row) {
|
||||
if (this.pricingMethod === 'manual') {
|
||||
if (typeof row.prices === 'undefined') {
|
||||
row.prices = JSON.parse(JSON.stringify(this.manualPrices));
|
||||
delete row.price;
|
||||
delete row.sale;
|
||||
}
|
||||
} else {
|
||||
if (typeof row.price === 'undefined') {
|
||||
row.price = 0;
|
||||
row.sale = 0;
|
||||
delete row.prices;
|
||||
}
|
||||
}
|
||||
if (typeof row.expanded === 'undefined') {
|
||||
row.expanded = false;
|
||||
}
|
||||
return row;
|
||||
},
|
||||
async loadProductVariables() {
|
||||
if (!this.productHasVariation) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
return;
|
||||
}
|
||||
const postId = window.formipayProductId || $('input[name="post_ID"]').val();
|
||||
if (!postId) {
|
||||
await this.buildFromAttributes();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await $.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'get_product_variables',
|
||||
post_id: postId
|
||||
}
|
||||
});
|
||||
if (res.success && Array.isArray(res.data) && res.data.length) {
|
||||
this.tableRows = res.data.map(row => this._ensureRowDataStructure(row));
|
||||
this.deletedKeys = [];
|
||||
this.updateJson();
|
||||
} else {
|
||||
await this.buildFromAttributes();
|
||||
}
|
||||
} catch {
|
||||
await this.buildFromAttributes();
|
||||
}
|
||||
},
|
||||
async buildFromAttributes() {
|
||||
if (!this.productHasVariation) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const attributes = await this.getAttributeRepeaterData();
|
||||
if (!attributes.length) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
return;
|
||||
}
|
||||
const combinations = this.getAllCombinations(attributes);
|
||||
const filtered = combinations.filter(c => !this.deletedKeys.includes(c.key));
|
||||
const newRows = filtered.map(c => {
|
||||
const existing = this.tableRows.find(r => r.key === c.key);
|
||||
if (existing) {
|
||||
this._ensureRowDataStructure(existing);
|
||||
return Object.assign(existing, {
|
||||
name: c.label
|
||||
});
|
||||
}
|
||||
let newRowData = {
|
||||
key: c.key,
|
||||
name: c.label,
|
||||
stock: '',
|
||||
weight: 0,
|
||||
active: true,
|
||||
};
|
||||
return this._ensureRowDataStructure(newRowData);
|
||||
});
|
||||
this.tableRows = newRows;
|
||||
this.updateJson();
|
||||
} catch (e) {
|
||||
console.error("Error building from attributes:", e);
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
}
|
||||
},
|
||||
getAttributeRepeaterData() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
const maxAttempts = 100;
|
||||
const interval = setInterval(() => {
|
||||
const el = $('#variation-product_variation_attributes');
|
||||
if (el.length && el.val()) {
|
||||
try {
|
||||
const data = JSON.parse(el.val());
|
||||
clearInterval(interval);
|
||||
resolve(Array.isArray(data) ? data : []);
|
||||
} catch {
|
||||
clearInterval(interval);
|
||||
reject(new Error('Invalid JSON in attribute repeater'));
|
||||
}
|
||||
} else if (++attempts >= maxAttempts) {
|
||||
clearInterval(interval);
|
||||
reject(new Error('Attribute repeater data not found'));
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
},
|
||||
getAllCombinations(attributes) {
|
||||
const attrVars = attributes
|
||||
.map(attr => (attr.attribute_variations || []).map(v => ({
|
||||
label: v.variation_label
|
||||
})))
|
||||
.filter(arr => arr.length > 0);
|
||||
if (!attrVars.length) return [];
|
||||
const combine = (arrs) => arrs.reduce((a, b) => a.flatMap(d => b.map(e => [].concat(d, e))));
|
||||
const combos = combine(attrVars);
|
||||
return combos.map(combo => {
|
||||
const labels = Array.isArray(combo) ? combo.map(c => c.label) : [combo.label];
|
||||
return {
|
||||
key: labels.join('||'),
|
||||
label: labels.join(' - ')
|
||||
};
|
||||
});
|
||||
},
|
||||
setupAttributeRepeaterSync() {
|
||||
const target = document.getElementById('variation-product_variation_attributes');
|
||||
if (!target) return;
|
||||
const observer = new MutationObserver(() => {
|
||||
clearTimeout(this._debounceTimer);
|
||||
this._debounceTimer = setTimeout(() => this.buildFromAttributes(), 300);
|
||||
});
|
||||
observer.observe(target, {
|
||||
attributes: true,
|
||||
attributeFilter: ['value']
|
||||
});
|
||||
this.attributeRepeaterWatcher = observer;
|
||||
},
|
||||
async syncManualPrices() {
|
||||
const el = document.getElementById('general-product_prices');
|
||||
if (el && el.value) {
|
||||
try {
|
||||
const pricesData = JSON.parse(el.value);
|
||||
this.manualPrices = Array.isArray(pricesData) ? pricesData : [];
|
||||
} catch (e) {
|
||||
this.manualPrices = [];
|
||||
}
|
||||
} else {
|
||||
this.manualPrices = [];
|
||||
}
|
||||
},
|
||||
setupManualPricesSync() {
|
||||
const target = document.getElementById('general-product_prices');
|
||||
if (!target) return;
|
||||
const observer = new MutationObserver(async () => {
|
||||
await this.syncManualPrices();
|
||||
if (this.pricingMethod === 'manual') {
|
||||
this.tableRows.forEach(row => {
|
||||
const newPricesFromRepeater = this.manualPrices;
|
||||
let reconciledPrices = row.prices.filter(existingPrice =>
|
||||
newPricesFromRepeater.some(newPrice => newPrice.currency === existingPrice.currency)
|
||||
);
|
||||
newPricesFromRepeater.forEach(newPrice => {
|
||||
const isAlreadyThere = reconciledPrices.some(p => p.currency === newPrice.currency);
|
||||
if (!isAlreadyThere) {
|
||||
reconciledPrices.push(JSON.parse(JSON.stringify(newPrice)));
|
||||
}
|
||||
});
|
||||
row.prices = reconciledPrices;
|
||||
});
|
||||
}
|
||||
this.updateJson();
|
||||
});
|
||||
observer.observe(target, {
|
||||
attributes: true,
|
||||
attributeFilter: ['value']
|
||||
});
|
||||
this.manualPricesWatcher = observer;
|
||||
},
|
||||
updateJson() {
|
||||
this.jsonValue = JSON.stringify(this.tableRows);
|
||||
},
|
||||
async rebuildTable() {
|
||||
await this.initializeOrClearTable();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tableRows: {
|
||||
handler() {
|
||||
this.updateJson();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 250);
|
||||
|
||||
});
|
||||
217
admin/assets/js/admin-product-editor.jsbak
Normal file
@@ -0,0 +1,217 @@
|
||||
jQuery(function($){
|
||||
|
||||
$('a[href="admin.php?page=formipay-products"]').addClass('current').closest('li').addClass('current');
|
||||
|
||||
function autoset_variation_name() {
|
||||
|
||||
var repeater_single = $('.product_variation_attributes.repeater [parent_repeater="parent"] > .wpcfto-field-content > .wpcfto-repeater-single');
|
||||
$.each(repeater_single, function(key, parent){
|
||||
var repeater_child = $(parent).find('[field_native_name="product_variation_attributes"]');
|
||||
var attribute_name = repeater_child.find(`[name="product_variation_attributes_${key}_attribute_name"]`).val();
|
||||
var attribute_type = repeater_child.find(`[name="product_variation_attributes_${key}_attribute_type"]`).val();
|
||||
var repeater_child_single = repeater_child.find('.wpcfto-repeater-single');
|
||||
$.each(repeater_child_single, function(index, child){
|
||||
var label_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_label"]`);
|
||||
var name_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_name"]`);
|
||||
var color_field = $(`input[name="product_variation_attributes_${key}_attribute_variations_${index}_variation_color"]`);
|
||||
var color_field_row = color_field.closest('.wpcfto-repeater-field');
|
||||
|
||||
if(attribute_type == 'color'){
|
||||
color_field_row.show();
|
||||
}else{
|
||||
color_field_row.hide();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(document).on('change blur', '[field_native_name_inner="variation_label"] input', function(){
|
||||
autoset_variation_name();
|
||||
});
|
||||
|
||||
$(document).on('click', '.stm_metaboxes_grid .stm_metaboxes_grid__inner .wpcfto-repeater .addArea', function() {
|
||||
autoset_variation_name();
|
||||
});
|
||||
|
||||
var onMetaboxLoaded = setInterval(() => {
|
||||
var repeater_single = $('.product_variation_attributes.repeater [parent_repeater="parent"] > .wpcfto-field-content > .wpcfto-repeater-single');
|
||||
if(repeater_single.length > 0){
|
||||
autoset_variation_name();
|
||||
clearInterval(onMetaboxLoaded);
|
||||
}
|
||||
}, 250);
|
||||
|
||||
var waitForTable = setInterval(() => {
|
||||
if ($('#product-variables-table').length > 0) {
|
||||
clearInterval(waitForTable);
|
||||
|
||||
new Vue({
|
||||
el: '#product-variables-table',
|
||||
data() {
|
||||
return {
|
||||
tableRows: [],
|
||||
deletedKeys: [],
|
||||
isPhysical: window.product_details?.product_is_physical || false,
|
||||
jsonValue: '[]',
|
||||
attributeRepeaterWatcher: null,
|
||||
_debounceTimer: null,
|
||||
productType: window.product_details?.product_type || 'digital', // default, will update on mount
|
||||
productCurrencyRaw: window.product_details?.product_currency || 'USD:::United States dollar:::$',
|
||||
currencyDecimalDigits: parseInt(window.product_details?.product_currency_decimal_digits) || 2,
|
||||
currencyDecimalSymbol: window.product_details?.product_currency_decimal_symbol || '.',
|
||||
currencyThousandSeparator: window.product_details?.product_currency_thousand_separator || ',',
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
|
||||
await this.loadProductVariables();
|
||||
this.setupAttributeRepeaterSync();
|
||||
|
||||
// Listen for changes on product_type radios to update reactive data
|
||||
const radios = document.querySelectorAll('input[name="product_type"]');
|
||||
radios.forEach(radio => {
|
||||
radio.addEventListener('change', e => {
|
||||
this.productType = e.target.value;
|
||||
this.isPhysical = e.target.value == 'physical';
|
||||
this.rebuildTable(); // Rebuild the table on type change
|
||||
});
|
||||
});
|
||||
|
||||
// Listen for changes on product_currency select
|
||||
const currencySelect = document.querySelector('select[name="product_currency"]');
|
||||
if (currencySelect) {
|
||||
currencySelect.addEventListener('change', (e) => {
|
||||
this.productCurrencyRaw = e.target.value;
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize currency values
|
||||
this.productCurrencyRaw = window.product_details?.product_currency || 'USD:::United States dollar:::$';
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.attributeRepeaterWatcher) {
|
||||
this.attributeRepeaterWatcher.disconnect();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadProductVariables() {
|
||||
const postId = window.formipayProductId || $('input[name="post_ID"]').val();
|
||||
if (!postId) {
|
||||
await this.buildFromAttributes();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await $.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
data: { action: 'get_product_variables', post_id: postId }
|
||||
});
|
||||
if (res.success && Array.isArray(res.data) && res.data.length) {
|
||||
this.tableRows = res.data;
|
||||
this.deletedKeys = [];
|
||||
this.updateJson();
|
||||
} else {
|
||||
await this.buildFromAttributes();
|
||||
}
|
||||
} catch {
|
||||
await this.buildFromAttributes();
|
||||
}
|
||||
},
|
||||
async buildFromAttributes() {
|
||||
try {
|
||||
const attributes = await this.getAttributeRepeaterData();
|
||||
if (!attributes.length) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
return;
|
||||
}
|
||||
const combinations = this.getAllCombinations(attributes);
|
||||
const filtered = combinations.filter(c => !this.deletedKeys.includes(c.key));
|
||||
const newRows = filtered.map(c => {
|
||||
const existing = this.tableRows.find(r => r.key === c.key);
|
||||
return existing ? Object.assign(existing, { name: c.label }) : {
|
||||
key: c.key,
|
||||
name: c.label,
|
||||
stock: '',
|
||||
price: 0,
|
||||
sale: 0,
|
||||
weight: 0,
|
||||
active: true,
|
||||
};
|
||||
});
|
||||
this.tableRows = newRows;
|
||||
this.updateJson();
|
||||
} catch (e) {
|
||||
this.tableRows = [];
|
||||
this.updateJson();
|
||||
}
|
||||
},
|
||||
getAttributeRepeaterData() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let attempts = 0;
|
||||
const maxAttempts = 100;
|
||||
const interval = setInterval(() => {
|
||||
const el = $('#variation-product_variation_attributes');
|
||||
if (el.length && el.val()) {
|
||||
try {
|
||||
const data = JSON.parse(el.val());
|
||||
clearInterval(interval);
|
||||
resolve(data);
|
||||
} catch {
|
||||
clearInterval(interval);
|
||||
reject(new Error('Invalid JSON in attribute repeater'));
|
||||
}
|
||||
} else if (++attempts >= maxAttempts) {
|
||||
clearInterval(interval);
|
||||
reject(new Error('Attribute repeater data not found'));
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
},
|
||||
getAllCombinations(attributes) {
|
||||
if (!attributes.length) return [];
|
||||
const attrVars = attributes.map(attr =>
|
||||
(attr.attribute_variations || []).map(v => ({ label: v.variation_label }))
|
||||
).filter(arr => arr.length > 0);
|
||||
if (!attrVars.length) return [];
|
||||
const combine = (arrs) => arrs.reduce((a, b) => a.flatMap(d => b.map(e => [].concat(d, e))));
|
||||
const combos = combine(attrVars);
|
||||
return combos.map(combo => {
|
||||
const labels = Array.isArray(combo) ? combo.map(c => c.label) : [combo.label];
|
||||
return { key: labels.join('||'), label: labels.join(' - ') };
|
||||
});
|
||||
},
|
||||
setupAttributeRepeaterSync() {
|
||||
const target = document.getElementById('variation-product_variation_attributes');
|
||||
if (!target) return;
|
||||
const observer = new MutationObserver(mutations => {
|
||||
for (const m of mutations) {
|
||||
if (m.type === 'attributes' && m.attributeName === 'value') {
|
||||
clearTimeout(this._debounceTimer);
|
||||
this._debounceTimer = setTimeout(() => this.buildFromAttributes(), 200);
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(target, { attributes: true, attributeFilter: ['value'] });
|
||||
this.attributeRepeaterWatcher = observer;
|
||||
},
|
||||
updateJson() {
|
||||
this.jsonValue = JSON.stringify(this.tableRows);
|
||||
},
|
||||
rebuildTable() {
|
||||
this.loadProductVariables();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tableRows: {
|
||||
handler() { this.updateJson(); },
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 250);
|
||||
|
||||
});
|
||||
68
admin/assets/js/admin-setting.js
Normal file
@@ -0,0 +1,68 @@
|
||||
jQuery(function($){
|
||||
$(document).on('click', '.show-instruction', function(){
|
||||
$('.global-paypal-instruction').slideToggle();
|
||||
$(this).text(function(i, text){
|
||||
return text === 'Show Instruction' ? 'Hide Instruction' : 'Show Instruction';
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.formipay-connect-paypal', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
url: formipay_admin_setting.ajax_url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'formipay_oneclick_connect',
|
||||
nonce: formipay_admin_setting.nonce
|
||||
},
|
||||
beforeSend: function() {
|
||||
$('#connect-status').html('<div class="notice notice-info"><p>Initiating PayPal connection...</p></div>');
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Open PayPal auth in popup
|
||||
const popup = window.open(
|
||||
response.data.auth_url,
|
||||
'paypal_oauth',
|
||||
'width=600,height=700,scrollbars=yes'
|
||||
);
|
||||
|
||||
// Listen for message from popup
|
||||
window.addEventListener('message', function(event) {
|
||||
if (event.data.type === 'formipay-paypal-connect') {
|
||||
if (event.data.success) {
|
||||
$('#connect-status').html(`
|
||||
<div class="notice notice-success">
|
||||
<p>${event.data.message}</p>
|
||||
<p>Webhook ID: ${event.data.webhook_id}</p>
|
||||
</div>
|
||||
`);
|
||||
} else {
|
||||
$('#connect-status').html(`
|
||||
<div class="notice notice-error">
|
||||
<p>${event.data.message}</p>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#connect-status').html(`
|
||||
<div class="notice notice-error">
|
||||
<p>Connection failed: ${response.data}</p>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$('#connect-status').html(`
|
||||
<div class="notice notice-error">
|
||||
<p>Connection failed: Server error</p>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
30
admin/assets/js/classic-editor.js
Normal file
@@ -0,0 +1,30 @@
|
||||
jQuery(document).ready(function($) {
|
||||
// Smooth toggle for postboxes
|
||||
$('.postbox').each(function() {
|
||||
$(this).on('click', '.hndle', function() {
|
||||
$(this).next('.inside').slideToggle();
|
||||
});
|
||||
});
|
||||
|
||||
// Add class for better styling
|
||||
$('#title').attr('placeholder', 'Enter title here...');
|
||||
$('#publishing-action .spinner').html(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<rect width="6" height="14" x="1" y="4" fill="#0073aa">
|
||||
<animate id="svgSpinnersBarsScaleFade0" fill="freeze" attributeName="y" begin="0;svgSpinnersBarsScaleFade1.end-0.25s" dur="0.75s" values="1;5" />
|
||||
<animate fill="freeze" attributeName="height" begin="0;svgSpinnersBarsScaleFade1.end-0.25s" dur="0.75s" values="22;14" />
|
||||
<animate fill="freeze" attributeName="opacity" begin="0;svgSpinnersBarsScaleFade1.end-0.25s" dur="0.75s" values="1;0.2" />
|
||||
</rect>
|
||||
<rect width="6" height="14" x="9" y="4" fill="#0073aa" opacity="0.4">
|
||||
<animate fill="freeze" attributeName="y" begin="svgSpinnersBarsScaleFade0.begin+0.15s" dur="0.75s" values="1;5" />
|
||||
<animate fill="freeze" attributeName="height" begin="svgSpinnersBarsScaleFade0.begin+0.15s" dur="0.75s" values="22;14" />
|
||||
<animate fill="freeze" attributeName="opacity" begin="svgSpinnersBarsScaleFade0.begin+0.15s" dur="0.75s" values="1;0.2" />
|
||||
</rect>
|
||||
<rect width="6" height="14" x="17" y="4" fill="#0073aa" opacity="0.3">
|
||||
<animate id="svgSpinnersBarsScaleFade1" fill="freeze" attributeName="y" begin="svgSpinnersBarsScaleFade0.begin+0.3s" dur="0.75s" values="1;5" />
|
||||
<animate fill="freeze" attributeName="height" begin="svgSpinnersBarsScaleFade0.begin+0.3s" dur="0.75s" values="22;14" />
|
||||
<animate fill="freeze" attributeName="opacity" begin="svgSpinnersBarsScaleFade0.begin+0.3s" dur="0.75s" values="1;0.2" />
|
||||
</rect>
|
||||
</svg>
|
||||
`);
|
||||
});
|
||||
69
admin/assets/js/formipay-wpmedia-modal.js
Normal file
@@ -0,0 +1,69 @@
|
||||
jQuery(function($){
|
||||
|
||||
$( document ).on( 'click', '.open-media-modal', function( event ) {
|
||||
|
||||
var gallery_items_frame;
|
||||
const $el = $( this );
|
||||
|
||||
var target_field = $el.attr('data-target-field');
|
||||
var target_id = $el.siblings('.'+target_field+'-id');
|
||||
var target_url = $el.siblings('.'+target_field+'-url');
|
||||
var image_preview = $el.siblings('.image-preview');
|
||||
var selected = target_id.val();
|
||||
var able_multiple = $el.attr('data-able-multiple');
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( gallery_items_frame ) {
|
||||
|
||||
// Select the attachment when the frame opens
|
||||
gallery_items_frame.on( 'open', function() {
|
||||
var selection = gallery_items_frame.state().get( 'selection' );
|
||||
selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] );
|
||||
});
|
||||
|
||||
// Open the modal.
|
||||
gallery_items_frame.open();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the media frame.
|
||||
gallery_items_frame = wp.media.frames.gallery_items = wp.media({
|
||||
// Set the title of the modal.
|
||||
title: 'Choose or upload media',
|
||||
button: {
|
||||
text: 'Select'
|
||||
},
|
||||
states: [
|
||||
new wp.media.controller.Library({
|
||||
title: 'Choose or upload media',
|
||||
filterable: 'all',
|
||||
multiple: able_multiple
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
// Select the attachment when the frame opens
|
||||
gallery_items_frame.on( 'open', function() {
|
||||
var selection = gallery_items_frame.state().get( 'selection' );
|
||||
selection.reset( selected ? [ wp.media.attachment( selected ) ] : [] );
|
||||
});
|
||||
|
||||
gallery_items_frame.on( 'select', function() {
|
||||
// We set multiple to false so only get one image from the uploader
|
||||
attachment = gallery_items_frame.state().get('selection').first().toJSON();
|
||||
// Do something with attachment.id and/or attachment.url here
|
||||
target_url.val( attachment.url );
|
||||
target_id.val( attachment.id );
|
||||
// $el.find('.bi-image-alt').hide();
|
||||
image_preview.html('<img src="'+attachment.url+'" width="150px">');
|
||||
// $el.attr('data-id', attachment.id);
|
||||
});
|
||||
|
||||
// Open the modal.
|
||||
gallery_items_frame.open();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
354
admin/assets/js/page-access-items.js
Normal file
@@ -0,0 +1,354 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const formChoices = new Choices('#products', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_access_page.filter_form.products.placeholder,
|
||||
noResultsText: formipay_access_page.filter_form.products.noresult_text,
|
||||
itemSelectText: '',
|
||||
});
|
||||
|
||||
const searchInput = document.querySelector('.choices__input--cloned');
|
||||
let typingTimer;
|
||||
|
||||
searchInput.addEventListener('input', function () {
|
||||
const query = searchInput.value;
|
||||
|
||||
if (query.length >= 3) {
|
||||
clearTimeout(typingTimer);
|
||||
typingTimer = setTimeout(() => {
|
||||
fetchChoices(query);
|
||||
}, 300); // Add a debounce delay
|
||||
}
|
||||
});
|
||||
|
||||
function fetchChoices(query) {
|
||||
fetch(formipay_access_page.ajax_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'formipay_access_items_get_products',
|
||||
search: query,
|
||||
nonce: formipay_access_page.nonce
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
formChoices.clearChoices();
|
||||
formChoices.setChoices( data, 'value', 'label', true);
|
||||
})
|
||||
.catch((error) => console.error('Error:', error));
|
||||
}
|
||||
|
||||
document.getElementById('reset-filter').addEventListener('click', function(){
|
||||
formChoices.removeActiveItems();
|
||||
const event = new Event('change', { bubbles: true });
|
||||
|
||||
document.getElementById('orderby').value = 'ID';
|
||||
document.getElementById('sort_by').value = 'desc';
|
||||
document.getElementById('keyword').value = '';
|
||||
document.getElementById('keyword').dispatchEvent(event);
|
||||
});
|
||||
});
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
let formipay_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_access_page.ajax_url+'?action=formipay-tabledata-access-items&post_status='+document.getElementById('post_status').value+'&product='+document.getElementById('products').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_access_page.nonce,
|
||||
then: data => {
|
||||
|
||||
if(data.posts_report){
|
||||
processPostsReport(data.posts_report);
|
||||
}
|
||||
|
||||
return data.results.map(
|
||||
access => [access.ID, access.ID, access.title, access.type, access.products, access.status]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'checkbox',
|
||||
name: gridjs.html(`<input type="checkbox" id="select-all-rows">`),
|
||||
width: '50px',
|
||||
formatter: (_, row) => gridjs.html(
|
||||
`<input type="checkbox" class="formipay-row-checkbox" data-id="${row.cells[0].data}">`
|
||||
)
|
||||
},
|
||||
{
|
||||
name: formipay_access_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_access_page.columns.title,
|
||||
formatter: (_, row) => {
|
||||
var html = `
|
||||
<b>${_}</b><br>
|
||||
<span class="post-action" style="visibility: hidden;">
|
||||
<a href="${formipay_access_page.site_url}/wp-admin/post.php?post=${row.cells[0].data}&action=edit">edit</a> | <a href="#" class="delete-access" data-id="${row.cells[0].data}">delete</a> | <a href="#" class="duplicate-access" data-id="${row.cells[0].data}">duplicate</a>
|
||||
</span>
|
||||
`;
|
||||
return gridjs.html(html)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: formipay_access_page.columns.type,
|
||||
formatter: (type, row) => {
|
||||
var html;
|
||||
if(type == 'Redirect'){
|
||||
html = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#277aff" d="M11 17H7q-2.075 0-3.537-1.463T2 12t1.463-3.537T7 7h4v2H7q-1.25 0-2.125.875T4 12t.875 2.125T7 15h4zm-3-4v-2h8v2zm5 4v-2h4q1.25 0 2.125-.875T20 12t-.875-2.125T17 9h-4V7h4q2.075 0 3.538 1.463T22 12t-1.463 3.538T17 17z" />
|
||||
</svg>${type}`;
|
||||
}else if(type == 'Download') {
|
||||
html = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#277aff" d="M11 12.15V6.1q-1.9.35-2.95 1.838T7 11h-.5q-1.45 0-2.475 1.025T3 14.5t1.025 2.475T6.5 18h12q1.05 0 1.775-.725T21 15.5t-.725-1.775T18.5 13H17v-2q0-1.2-.55-2.238T15 7V4.675q1.85.875 2.925 2.588T19 11q1.725.2 2.863 1.488T23 15.5q0 1.875-1.312 3.188T18.5 20h-12q-2.275 0-3.887-1.575T1 14.575q0-1.95 1.175-3.475T5.25 9.15q.425-1.8 2.125-3.425T11 4.1q.825 0 1.413.588T13 6.1v6.05l.9-.875q.275-.275.688-.275t.712.3q.275.275.275.7t-.275.7l-2.6 2.6q-.3.3-.7.3t-.7-.3l-2.6-2.6q-.275-.275-.287-.687T8.7 11.3q.275-.275.688-.288t.712.263zm1-1.1" />
|
||||
</svg>${type}`;
|
||||
}else if(type == 'Document') {
|
||||
html = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#277aff" d="M8 13h8v-2H8zm0 3h8v-2H8zm0 3h5v-2H8zm-2 3q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z" />
|
||||
</svg>${type}`;
|
||||
}
|
||||
return gridjs.html(html)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: formipay_access_page.columns.products,
|
||||
formatter: (products, row) => {
|
||||
|
||||
let html = '';
|
||||
|
||||
// Loop through each product in the products array
|
||||
if(products.length > 0){
|
||||
products.forEach(product => {
|
||||
if (product) {
|
||||
html += `
|
||||
<span class="product_related">
|
||||
${product}
|
||||
</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return gridjs.html(html);
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
name: formipay_access_page.columns.status,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="status-label ${_}">${_}</span>
|
||||
`)
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
limit: 10,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-access-items'));
|
||||
|
||||
var $tableContainer = $('.formipay-grid-table');
|
||||
var $deleteBtn = $('#formipay-delete-selected');
|
||||
|
||||
function updateDeleteButtonVisibility() {
|
||||
if ($tableContainer.find('.formipay-row-checkbox:checked').length > 0) {
|
||||
$deleteBtn.show();
|
||||
} else {
|
||||
$deleteBtn.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '.formipay-row-checkbox', function() {
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '#select-all-rows', function() {
|
||||
const is_checked = $(this).is(':checked');
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', is_checked);
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle delete button click
|
||||
$deleteBtn.on('click', function() {
|
||||
var selectedIds = $tableContainer.find('.formipay-row-checkbox:checked').map(function() {
|
||||
return $(this).data('id');
|
||||
}).get();
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_access_page.modal.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_access_page.modal.bulk_delete.confirmButton,
|
||||
cancelButtonText: formipay_access_page.modal.bulk_delete.cancelButton
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_access_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-bulk-delete-access-item',
|
||||
ids: selectedIds,
|
||||
_wpnonce: formipay_access_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', false);
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function refresh_table_with_filter() {
|
||||
formipay_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_access_page.ajax_url+'?action=formipay-tabledata-access-items&post_status='+document.getElementById('post_status').value+'&product='+document.getElementById('products').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value,
|
||||
then: data => data.results.map(
|
||||
access => [access.ID, access.ID, access.title, access.type, access.products, access.status]
|
||||
),
|
||||
total: data => data.total
|
||||
}
|
||||
}).forceRender();
|
||||
}
|
||||
|
||||
$('.form-tool, #post_status').on('change', function(){
|
||||
refresh_table_with_filter();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
$(document).on('click', '#add-new-item', async function(e){
|
||||
e.preventDefault();
|
||||
const { value: coupon_code } = await Swal.fire({
|
||||
input: "text",
|
||||
inputLabel: formipay_access_page.modal.add.title,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_access_page.modal.add.confirmButton,
|
||||
cancelButtonText: formipay_access_page.modal.add.cancelButton,
|
||||
reverseButtons: true,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return formipay_access_page.modal.add.validation;
|
||||
}
|
||||
}
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below, input value is ${coupon_code} */
|
||||
if (result.isConfirmed && result.value) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_access_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-create-access-item-post',
|
||||
title: result.value,
|
||||
nonce: formipay_access_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.success){
|
||||
window.location.href = res.data.edit_post_url;
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-access', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_access_page.modal.delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_access_page.modal.delete.confirmButton,
|
||||
cancelButtonText: formipay_access_page.modal.delete.cancelButton,
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_access_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-delete-access-item',
|
||||
id: data_id,
|
||||
nonce: formipay_access_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.duplicate-access', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_access_page.modal.duplicate.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_access_page.modal.duplicate.confirmButton,
|
||||
cancelButtonText: formipay_access_page.modal.duplicate.cancelButton,
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_access_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-duplicate-access-item',
|
||||
id: data_id,
|
||||
nonce: formipay_access_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
346
admin/assets/js/page-coupons.js
Normal file
@@ -0,0 +1,346 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const choices = new Choices('#products', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_coupons_page.filter_form.products.placeholder,
|
||||
noResultsText: formipay_coupons_page.filter_form.products.noresult_text,
|
||||
itemSelectText: '',
|
||||
});
|
||||
|
||||
const searchInput = document.querySelector('.choices__input--cloned');
|
||||
let typingTimer;
|
||||
|
||||
searchInput.addEventListener('input', function () {
|
||||
const query = searchInput.value;
|
||||
|
||||
if (query.length >= 3) {
|
||||
clearTimeout(typingTimer);
|
||||
typingTimer = setTimeout(() => {
|
||||
fetchChoices(query);
|
||||
}, 300); // Add a debounce delay
|
||||
}
|
||||
});
|
||||
|
||||
function fetchChoices(query) {
|
||||
fetch(formipay_coupons_page.ajax_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'formipay_coupon_get_products',
|
||||
search: query,
|
||||
_wpnonce: formipay_coupons_page.nonce
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
choices.clearChoices();
|
||||
choices.setChoices(data, 'value', 'label', false);
|
||||
})
|
||||
.catch((error) => console.error('Error:', error));
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
let formipay_coupon_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_coupons_page.ajax_url+'?action=formipay-tabledata-coupons&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_coupons_page.nonce,
|
||||
then: data => {
|
||||
|
||||
if(data.posts_report){
|
||||
processPostsReport(data.posts_report);
|
||||
}
|
||||
|
||||
return data.results.map(
|
||||
coupon => [coupon.ID, coupon.ID, coupon.code, coupon.products, coupon.value, coupon.type, coupon.usages, coupon.date_limit, coupon.status, coupon.case_sensitive]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'checkbox',
|
||||
name: gridjs.html(`<input type="checkbox" id="select-all-rows">`),
|
||||
width: '50px',
|
||||
formatter: (_, row) => gridjs.html(
|
||||
`<input type="checkbox" class="formipay-row-checkbox" data-id="${row.cells[0].data}">`
|
||||
)
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.code,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<b>${_}</b><br>
|
||||
<span class="post-action" style="visibility: hidden;">
|
||||
<a href="${formipay_coupons_page.site_url}/wp-admin/post.php?post=${row.cells[0].data}&action=edit">edit</a> | <a href="#" class="delete-coupon" data-id="${row.cells[0].data}">delete</a> | <a href="#" class="duplicate-coupon" data-id="${row.cells[0].data}">duplicate</a>
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.products,
|
||||
formatter: (products, row) => {
|
||||
|
||||
let html = '';
|
||||
|
||||
// Loop through each product in the products array
|
||||
if(products.length > 0){
|
||||
products.forEach(product => {
|
||||
if (product) {
|
||||
const currencyDetails = product.currency.split(':::');
|
||||
const currencyCode = currencyDetails[0];
|
||||
const currencySymbol = currencyDetails[2];
|
||||
|
||||
html += `
|
||||
<span class="product_related">
|
||||
${product.title}<hr>
|
||||
<span class="country-currency">
|
||||
${product.flag ? `<img src="${product.flag}" height="18">` : ''}
|
||||
<span class="currency-in-use">${currencyCode} (${currencySymbol})</span>
|
||||
</span>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return gridjs.html(html);
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.amount,
|
||||
formatter: (_, row) => numberFormat(_)
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.type,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="type-capsule the-type">${_}</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_coupons_page.columns.usages, // { used: 1, limit: 5 }
|
||||
formatter: (_, row) => gridjs.html(`<span class="coupon-used">${_.used}</span>/<span class="coupon-limit">${_.limit}</span>`) // 1/∞
|
||||
},
|
||||
formipay_coupons_page.columns.date_limit,
|
||||
{
|
||||
name: formipay_coupons_page.columns.status,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="status-label ${_.toLowerCase()}">${_}</span>
|
||||
`)
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
limit: 10,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-coupons'));
|
||||
|
||||
var $tableContainer = $('.formipay-grid-table');
|
||||
var $deleteBtn = $('#formipay-delete-selected');
|
||||
|
||||
function updateDeleteButtonVisibility() {
|
||||
if ($tableContainer.find('.formipay-row-checkbox:checked').length > 0) {
|
||||
$deleteBtn.show();
|
||||
} else {
|
||||
$deleteBtn.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '.formipay-row-checkbox', function() {
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$tableContainer.on('change', '#select-all-rows', function() {
|
||||
const is_checked = $(this).is(':checked');
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', is_checked);
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle delete button click
|
||||
$deleteBtn.on('click', function() {
|
||||
var selectedIds = $tableContainer.find('.formipay-row-checkbox:checked').map(function() {
|
||||
return $(this).data('id');
|
||||
}).get();
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_coupons_page.modal.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_coupons_page.modal.bulk_delete.confirmButton,
|
||||
cancelButtonText: formipay_coupons_page.modal.bulk_delete.cancelButton
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_coupons_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-bulk-delete-coupon',
|
||||
ids: selectedIds,
|
||||
_wpnonce: formipay_coupons_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
$tableContainer.find('.formipay-row-checkbox').prop('checked', false);
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function refresh_table_with_filter() {
|
||||
formipay_coupon_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_coupons_page.ajax_url+'?action=formipay-tabledata-coupons&product='+document.getElementById('products').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_coupons_page.nonce,
|
||||
then: data => data.results.map(
|
||||
coupon => [coupon.ID, coupon.ID, coupon.code, coupon.products, coupon.value, coupon.type, coupon.usages, coupon.date_limit, coupon.status, coupon.case_sensitive]
|
||||
),
|
||||
total: data => data.total
|
||||
}
|
||||
}).forceRender();
|
||||
}
|
||||
|
||||
$('.form-tool, #products, #post_status').on('change', function(){
|
||||
refresh_table_with_filter();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=couponCode]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=couponCode]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
$(document).on('input', 'input#swal2-input', function(){
|
||||
const value = $(this).val();
|
||||
$(this).val(value.replace(' ', ''));
|
||||
});
|
||||
|
||||
$(document).on('click', '#add-new-coupon', async function(e){
|
||||
e.preventDefault();
|
||||
const { value: coupon_code } = await Swal.fire({
|
||||
input: "text",
|
||||
inputLabel: formipay_coupons_page.modal.add.title,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_coupons_page.modal.add.confirmButton,
|
||||
cancelButtonText: formipay_coupons_page.modal.add.cancelButton,
|
||||
reverseButtons: true,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return formipay_coupons_page.modal.add.validation;
|
||||
}
|
||||
}
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below, input value is ${coupon_code} */
|
||||
if (result.isConfirmed && result.value) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_coupons_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-create-coupon-post',
|
||||
title: result.value,
|
||||
_wpnonce: formipay_coupons_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.success){
|
||||
window.location.href = res.data.edit_post_url;
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-coupon', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: "Do you want to delete the coupon?",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Delete Permanently",
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_coupons_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-delete-coupon',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_coupons_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_coupon_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.duplicate-coupon', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: "Do you want to duplicate the coupon?",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Confirm",
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_coupons_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-duplicate-coupon',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_coupons_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_coupon_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
320
admin/assets/js/page-forms.js
Normal file
@@ -0,0 +1,320 @@
|
||||
document.getElementById('reset-filter').addEventListener('click', function(){
|
||||
categoryChoices.removeActiveItems();
|
||||
currencyChoices.removeActiveItems();
|
||||
|
||||
const event = new Event('change', { bubbles: true });
|
||||
|
||||
document.getElementById('orderby').value = 'ID';
|
||||
document.getElementById('sort_by').value = 'desc';
|
||||
document.getElementById('keyword').value = '';
|
||||
document.getElementById('keyword').dispatchEvent(event);
|
||||
});
|
||||
|
||||
let formipay_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_forms_page.ajax_url+'?action=formipay-tabledata-forms&post_status='+document.getElementById('post_status').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_forms_page.nonce,
|
||||
then: data => {
|
||||
|
||||
if(data.posts_report){
|
||||
processPostsReport(data.posts_report);
|
||||
}
|
||||
|
||||
return data.results.map(
|
||||
form => [form.ID, form.ID, form.title, form.date, form.status]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'checkbox',
|
||||
name: gridjs.html(`<input type="checkbox" id="select-all-rows">`),
|
||||
width: '50px',
|
||||
formatter: (_, row) => gridjs.html(
|
||||
`<input type="checkbox" class="formipay-row-checkbox" data-id="${row.cells[0].data}">`
|
||||
)
|
||||
},
|
||||
{
|
||||
name: formipay_forms_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_forms_page.columns.title,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<b>${_}</b><br>
|
||||
<span class="post-action" style="visibility: hidden;">
|
||||
<a href="${formipay_forms_page.site_url}/wp-admin/post.php?post=${row.cells[0].data}&action=edit&_wpnonce=${formipay_forms_page.nonce}">edit</a> | <a href="#" class="delete-form" data-id="${row.cells[0].data}">delete</a> | <a href="#" class="duplicate-form" data-id="${row.cells[0].data}">duplicate</a>
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_forms_page.columns.date,
|
||||
formatter: (_, row) => gridjs.html('<span style="text-wrap: nowrap;">' + _.split(' ').join('</span><br><span style="font-size: smaller;">') + '</span>')
|
||||
},
|
||||
{
|
||||
name: formipay_forms_page.columns.status,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="status-label ${_}">${_}</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_forms_page.columns.shortcode,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<input class="formipay-form-shortcode" value="[formipay form=${row.cells[0].data}]" disabled>
|
||||
<button class="copy-shortcode" data-copy="[formipay form=${row.cells[0].data}]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#b7b7b7" d="M9 18q-.825 0-1.412-.587T7 16V4q0-.825.588-1.412T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.587 1.413T18 18zm0-2h9V4H9zm-4 6q-.825 0-1.412-.587T3 20V6h2v14h11v2zm4-6V4z" />
|
||||
</svg> ${formipay_forms_page.toast.copy_button.copy}
|
||||
</button>
|
||||
`)
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
limit: 10,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-forms'));
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
const copyButton = e.target.closest('[data-copy]'); // Check if the clicked element or its parent has the data-copy attribute
|
||||
if (copyButton) {
|
||||
const textToCopy = copyButton.getAttribute('data-copy');
|
||||
|
||||
// Use the Clipboard API to copy text
|
||||
navigator.clipboard.writeText(textToCopy)
|
||||
.then(() => {
|
||||
// Optionally, display a success message
|
||||
copyButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m9.55 18l-5.7-5.7l1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z" />
|
||||
</svg> ${formipay_forms_page.toast.copy_button.copied}`;
|
||||
setTimeout(() => {
|
||||
copyButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#b7b7b7" d="M9 18q-.825 0-1.412-.587T7 16V4q0-.825.588-1.412T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.587 1.413T18 18zm0-2h9V4H9zm-4 6q-.825 0-1.412-.587T3 20V6h2v14h11v2zm4-6V4z" />
|
||||
</svg> ${formipay_forms_page.toast.copy_button.copy}`; // Reset button text
|
||||
}, 2000);
|
||||
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: formipay_forms_page.toast.copy_button.title,
|
||||
toast: true,
|
||||
position: "top-end",
|
||||
showConfirmButton: false,
|
||||
timer: 3000,
|
||||
timerProgressBar: true,
|
||||
customClass: {
|
||||
container: 'top-40'
|
||||
},
|
||||
didOpen: (toast) => {
|
||||
toast.onmouseenter = Swal.stopTimer;
|
||||
toast.onmouseleave = Swal.resumeTimer;
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to copy text: ', err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
var $deleteBtn = $('#formipay-delete-selected');
|
||||
|
||||
function updateDeleteButtonVisibility() {
|
||||
if ($(document).find('.formipay-row-checkbox:checked').length > 0) {
|
||||
$deleteBtn.show();
|
||||
} else {
|
||||
$deleteBtn.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$(document).on('change', '.formipay-row-checkbox', function() {
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$(document).on('change', '#select-all-rows', function() {
|
||||
const is_checked = $(this).is(':checked');
|
||||
$(document).find('.formipay-row-checkbox').prop('checked', is_checked);
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle delete button click
|
||||
$deleteBtn.on('click', function() {
|
||||
var selectedIds = $(document).find('.formipay-row-checkbox:checked').map(function() {
|
||||
return $(this).data('id');
|
||||
}).get();
|
||||
|
||||
console.log(selectedIds);
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_forms_page.modal.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_forms_page.modal.bulk_delete.confirmButton,
|
||||
cancelButtonText: formipay_forms_page.modal.bulk_delete.cancelButton
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_forms_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-bulk-delete-form',
|
||||
ids: selectedIds,
|
||||
_wpnonce: formipay_forms_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
$(document).find('.formipay-row-checkbox').prop('checked', false);
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function refresh_table_with_filter() {
|
||||
formipay_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_forms_page.ajax_url+'?action=formipay-tabledata-forms&post_status='+document.getElementById('post_status').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_forms_page.nonce,
|
||||
then: data => data.results.map(
|
||||
form => [form.ID, form.ID, form.title, form.date, form.status]
|
||||
),
|
||||
total: data => data.total
|
||||
}
|
||||
}).forceRender();
|
||||
}
|
||||
|
||||
$('.form-tool, #post_status').on('change', function(){
|
||||
refresh_table_with_filter();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
$(document).on('click', '#add-new-form', async function(e){
|
||||
e.preventDefault();
|
||||
const { value: title } = await Swal.fire({
|
||||
input: "text",
|
||||
inputLabel: formipay_forms_page.modal.add.title,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_forms_page.modal.add.confirmButton,
|
||||
cancelButtonText: formipay_forms_page.modal.add.cancelButton,
|
||||
reverseButtons: true,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return formipay_forms_page.modal.add.validation;
|
||||
}
|
||||
}
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below, input value is ${coupon_code} */
|
||||
if (result.isConfirmed && result.value) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_forms_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-create-form-post',
|
||||
title: result.value,
|
||||
_wpnonce: formipay_forms_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.success){
|
||||
window.location.href = res.data.edit_post_url;
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-form', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_forms_page.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_forms_page.delete.confirmButton,
|
||||
cancelButtonText: formipay_forms_page.delete.cancelButton,
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_forms_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-delete-form',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_forms_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.duplicate-form', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: "Do you want to duplicate the form?",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Confirm",
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_forms_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-duplicate-form',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_forms_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_table_grid.forceRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
13
admin/assets/js/page-product-taxonomy.js
Normal file
@@ -0,0 +1,13 @@
|
||||
jQuery(function($){
|
||||
$('#wpbody-content').prepend(`
|
||||
<div class="formipay-screen-menu">
|
||||
<img src="`+formipay_product_taxonomy_page.site_url+`/wp-content/plugins/formipay/admin/assets/img/formipay-logo-circle-white_256.png" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1>`+formipay_product_taxonomy_page.page_title+`</h1>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
$('form.search-form.wp-clearfix').appendTo('.tablenav.top');
|
||||
$('.wp-heading-inline').hide();
|
||||
$(`a[href="edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product"]`).addClass('current').closest('li').addClass('current');
|
||||
});
|
||||
371
admin/assets/js/page-products.js
Normal file
@@ -0,0 +1,371 @@
|
||||
const categoryChoices = new Choices('#categories', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_products_page.filter_form.categories.placeholder,
|
||||
noResultsText: formipay_products_page.filter_form.categories.noresult_text,
|
||||
itemSelectText: '',
|
||||
allowHTML: true
|
||||
});
|
||||
|
||||
const currencyChoices = new Choices('#currencies', {
|
||||
searchEnabled: true,
|
||||
searchChoices: false, // Prevent Choices.js from filtering the local list
|
||||
searchResultLimit: 10, // Optional: Limit visible results
|
||||
placeholder: true,
|
||||
placeholderValue: formipay_products_page.filter_form.currencies.placeholder,
|
||||
noResultsText: formipay_products_page.filter_form.currencies.noresult_text,
|
||||
itemSelectText: '',
|
||||
allowHTML: true
|
||||
});
|
||||
|
||||
const searchInput = document.querySelectorAll('.currency .choices__input--cloned');
|
||||
let typingTimer;
|
||||
|
||||
searchInput[0].addEventListener('input', function () {
|
||||
const query = this.value;
|
||||
|
||||
if (query.length >= 3) {
|
||||
clearTimeout(typingTimer);
|
||||
typingTimer = setTimeout(() => {
|
||||
fetchChoices(query);
|
||||
}, 300); // Add a debounce delay
|
||||
}
|
||||
});
|
||||
|
||||
function fetchChoices(query) {
|
||||
fetch(formipay_products_page.ajax_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
action: 'formipay_product_get_currencies',
|
||||
search: query,
|
||||
_wpnonce: formipay_products_page.nonce
|
||||
}),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
currencyChoices.clearChoices();
|
||||
currencyChoices.setChoices( data, 'value', 'label', true);
|
||||
})
|
||||
.catch((error) => console.error('Error:', error));
|
||||
}
|
||||
|
||||
document.getElementById('reset-filter').addEventListener('click', function(){
|
||||
categoryChoices.removeActiveItems();
|
||||
currencyChoices.removeActiveItems();
|
||||
|
||||
const event = new Event('change', { bubbles: true });
|
||||
|
||||
document.getElementById('orderby').value = 'ID';
|
||||
document.getElementById('sort_by').value = 'desc';
|
||||
document.getElementById('keyword').value = '';
|
||||
document.getElementById('keyword').dispatchEvent(event);
|
||||
});
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
let formipay_product_table_grid = new gridjs.Grid({
|
||||
server: {
|
||||
url: formipay_products_page.ajax_url+'?action=formipay-tabledata-products&post_status='+document.getElementById('post_status').value+'¤cy='+document.getElementById('currencies').value+'&category='+document.getElementById('categories').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_products_page.nonce,
|
||||
then: data => {
|
||||
|
||||
if(data.posts_report){
|
||||
processPostsReport(data.posts_report);
|
||||
}
|
||||
|
||||
return data.results.map(
|
||||
product => [product.ID, product.ID, product.title, product.price, product.type, product.stock, product.status]
|
||||
);
|
||||
},
|
||||
total: data => data.total
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'checkbox',
|
||||
name: gridjs.html(`<input type="checkbox" id="select-all-rows">`),
|
||||
width: '50px',
|
||||
formatter: (_, row) => gridjs.html(
|
||||
`<input type="checkbox" class="formipay-row-checkbox" data-id="${row.cells[0].data}">`
|
||||
)
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.id,
|
||||
width: '75px'
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.title,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<b>${_}</b><br>
|
||||
<span class="post-action" style="visibility: hidden;">
|
||||
<a href="${formipay_products_page.site_url}/wp-admin/post.php?post=${row.cells[0].data}&action=edit">edit</a> | <a href="#" class="delete-product" data-id="${row.cells[0].data}">delete</a> | <a href="#" class="duplicate-product" data-id="${row.cells[0].data}">duplicate</a>
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.price,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="price">
|
||||
<img src="${_.flag}" width="20"> ${_.name}
|
||||
</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.type
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.stock,
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="type-capsule the-type">${_}</span>
|
||||
`)
|
||||
},
|
||||
{
|
||||
name: formipay_products_page.columns.status, // { used: 1, limit: 5 }
|
||||
formatter: (_, row) => gridjs.html(`
|
||||
<span class="status-label ${_}">${_}</span>
|
||||
`)
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
limit: 10,
|
||||
server: {
|
||||
url: (prev, page, limit) => `${prev}&limit=${limit}&offset=${page * limit}`
|
||||
},
|
||||
summary: false
|
||||
},
|
||||
className: {
|
||||
table: 'formipay-grid-table'
|
||||
}
|
||||
}).render(document.getElementById('formipay-products'));
|
||||
|
||||
var $deleteBtn = $('#formipay-delete-selected');
|
||||
|
||||
function updateDeleteButtonVisibility() {
|
||||
if ($(document).find('.formipay-row-checkbox:checked').length > 0) {
|
||||
$deleteBtn.show();
|
||||
} else {
|
||||
$deleteBtn.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$(document).on('change', '.formipay-row-checkbox', function() {
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle row and "select all" checkbox changes
|
||||
$(document).on('change', '#select-all-rows', function() {
|
||||
const is_checked = $(this).is(':checked');
|
||||
$(document).find('.formipay-row-checkbox').prop('checked', is_checked);
|
||||
updateDeleteButtonVisibility();
|
||||
});
|
||||
|
||||
// Handle delete button click
|
||||
$deleteBtn.on('click', function() {
|
||||
var selectedIds = $(document).find('.formipay-row-checkbox:checked').map(function() {
|
||||
return $(this).data('id');
|
||||
}).get();
|
||||
|
||||
console.log(selectedIds);
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_products_page.modal.bulk_delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_products_page.modal.bulk_delete.confirmButton,
|
||||
cancelButtonText: formipay_products_page.modal.bulk_delete.cancelButton
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_products_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-bulk-delete-product',
|
||||
ids: selectedIds,
|
||||
_wpnonce: formipay_products_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
formipay_product_table_grid.forceRender();
|
||||
$(document).find('.formipay-row-checkbox').prop('checked', false);
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function refresh_table_with_filter() {
|
||||
formipay_product_table_grid.updateConfig({
|
||||
server: {
|
||||
url: formipay_products_page.ajax_url+'?action=formipay-tabledata-products&post_status='+document.getElementById('post_status').value+'¤cy='+document.getElementById('currencies').value+'&category='+document.getElementById('categories').value+'&orderby='+document.getElementById('orderby').value+'&sort='+document.getElementById('sort_by').value+'&search='+document.getElementById('keyword').value+'&_wpnonce='+formipay_products_page.nonce,
|
||||
then: data => data.results.map(
|
||||
product => [product.ID, product.ID, product.title, product.price, product.type, product.stock, product.status]
|
||||
),
|
||||
total: data => data.total
|
||||
}
|
||||
}).forceRender();
|
||||
$(document) = $('.formipay-grid-table');
|
||||
}
|
||||
|
||||
$('.form-tool, #post_status').on('change', function(){
|
||||
refresh_table_with_filter();
|
||||
});
|
||||
|
||||
$(document).on('mouseover', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'visible');
|
||||
});
|
||||
$(document).on('mouseleave', 'td[data-column-id=title]', function(){
|
||||
$(this).find('.post-action').css('visibility', 'hidden');
|
||||
});
|
||||
|
||||
$(document).on('click', '#add-new-product', async function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var options = [];
|
||||
$.each(formipay_products_page.modal.form.currency_options, function(value, label){
|
||||
options.push(`<option value="${value}">${label}</option>`);
|
||||
});
|
||||
|
||||
// Table-based form HTML
|
||||
const formHtml = `
|
||||
<input id="swal-input-title" class="swal2-input" placeholder="Product Title">
|
||||
<input id="swal-input-price" type="number" min="0" class="swal2-input" placeholder="Price">
|
||||
`;
|
||||
|
||||
// Show the SweetAlert2 modal
|
||||
const { value: title } = await Swal.fire({
|
||||
input: "text",
|
||||
inputLabel: formipay_products_page.modal.add.title,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_products_page.modal.add.confirmButton,
|
||||
cancelButtonText: formipay_products_page.modal.add.cancelButton,
|
||||
reverseButtons: true,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return formipay_products_page.modal.add.validation;
|
||||
}
|
||||
}
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below, input value is ${coupon_code} */
|
||||
if (result.isConfirmed && result.value) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_products_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-create-product-post',
|
||||
title: result.value,
|
||||
_wpnonce: formipay_products_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.success){
|
||||
window.location.href = res.data.edit_post_url;
|
||||
}else{
|
||||
Swal.fire({
|
||||
html: res.data.message,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-product', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_products_page.modal.delete.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_products_page.modal.delete.confirmButton,
|
||||
cancelButtonText: formipay_products_page.modal.delete.cancelButton,
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_products_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-delete-product',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_products_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.duplicate-product', function(e){
|
||||
e.preventDefault();
|
||||
var data_id = $(this).attr('data-id');
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
html: formipay_products_page.modal.duplicate.question,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: formipay_products_page.modal.duplicate.confirmButton,
|
||||
cancelButtonText: formipay_products_page.modal.duplicate.cancelButton,
|
||||
}).then((result) => {
|
||||
/* Read more about isConfirmed, isDenied below */
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: formipay_products_page.ajax_url,
|
||||
data: {
|
||||
action: 'formipay-duplicate-product',
|
||||
id: data_id,
|
||||
_wpnonce: formipay_products_page.nonce
|
||||
},
|
||||
success: function (res) {
|
||||
Swal.fire({
|
||||
title: res.data.title,
|
||||
html: res.data.message,
|
||||
icon: res.data.icon
|
||||
});
|
||||
updateDeleteButtonVisibility();
|
||||
refresh_table_with_filter();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
html: xhr.responseText,
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'formipay-button-error'
|
||||
},
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false,
|
||||
showCloseButton: false,
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
254
admin/assets/json/country.json
Normal file
@@ -0,0 +1,254 @@
|
||||
[
|
||||
{"name": "Afghanistan", "code": "AF", "phone": "93"},
|
||||
{"name": "Albania", "code": "AL", "phone": "355"},
|
||||
{"name": "Algeria", "code": "DZ", "phone": "213"},
|
||||
{"name": "American Samoa", "code": "AS", "phone": "1684"},
|
||||
{"name": "Andorra", "code": "AD", "phone": "376"},
|
||||
{"name": "Angola", "code": "AO", "phone": "244"},
|
||||
{"name": "Anguilla", "code": "AI", "phone": "1264"},
|
||||
{"name": "Antarctica", "code": "AQ", "phone": "672"},
|
||||
{"name": "Antigua and Barbuda", "code": "AG", "phone": "1268"},
|
||||
{"name": "Argentina", "code": "AR", "phone": "54"},
|
||||
{"name": "Armenia", "code": "AM", "phone": "374"},
|
||||
{"name": "Aruba", "code": "AW", "phone": "297"},
|
||||
{"name": "Asia/Pacific Region", "code": "AP", "phone": ""},
|
||||
{"name": "Australia", "code": "AU", "phone": "61"},
|
||||
{"name": "Austria", "code": "AT", "phone": "43"},
|
||||
{"name": "Azerbaijan", "code": "AZ", "phone": "994"},
|
||||
{"name": "Bahamas", "code": "BS", "phone": "1242"},
|
||||
{"name": "Bahrain", "code": "BH", "phone": "973"},
|
||||
{"name": "Bangladesh", "code": "BD", "phone": "880"},
|
||||
{"name": "Barbados", "code": "BB", "phone": "1246"},
|
||||
{"name": "Belarus", "code": "BY", "phone": "375"},
|
||||
{"name": "Belgium", "code": "BE", "phone": "32"},
|
||||
{"name": "Belize", "code": "BZ", "phone": "501"},
|
||||
{"name": "Benin", "code": "BJ", "phone": "229"},
|
||||
{"name": "Bermuda", "code": "BM", "phone": "1441"},
|
||||
{"name": "Bhutan", "code": "BT", "phone": "975"},
|
||||
{"name": "Bolivia", "code": "BO", "phone": "591"},
|
||||
{"name": "Bonaire, Sint Eustatius and Saba", "code": "BQ", "phone": "599"},
|
||||
{"name": "Bosnia and Herzegovina", "code": "BA", "phone": "387"},
|
||||
{"name": "Botswana", "code": "BW", "phone": "267"},
|
||||
{"name": "Bouvet Island", "code": "BV", "phone": "55"},
|
||||
{"name": "Brazil", "code": "BR", "phone": "55"},
|
||||
{"name": "British Indian Ocean Territory", "code": "IO", "phone": "246"},
|
||||
{"name": "Brunei Darussalam", "code": "BN", "phone": "673"},
|
||||
{"name": "Bulgaria", "code": "BG", "phone": "359"},
|
||||
{"name": "Burkina Faso", "code": "BF", "phone": "226"},
|
||||
{"name": "Burundi", "code": "BI", "phone": "257"},
|
||||
{"name": "Cambodia", "code": "KH", "phone": "855"},
|
||||
{"name": "Cameroon", "code": "CM", "phone": "237"},
|
||||
{"name": "Canada", "code": "CA", "phone": "1"},
|
||||
{"name": "Cape Verde", "code": "CV", "phone": "238"},
|
||||
{"name": "Cayman Islands", "code": "KY", "phone": "1345"},
|
||||
{"name": "Central African Republic", "code": "CF", "phone": "236"},
|
||||
{"name": "Chad", "code": "TD", "phone": "235"},
|
||||
{"name": "Chile", "code": "CL", "phone": "56"},
|
||||
{"name": "China", "code": "CN", "phone": "86"},
|
||||
{"name": "Christmas Island", "code": "CX", "phone": "61"},
|
||||
{"name": "Cocos (Keeling) Islands", "code": "CC", "phone": "672"},
|
||||
{"name": "Colombia", "code": "CO", "phone": "57"},
|
||||
{"name": "Comoros", "code": "KM", "phone": "269"},
|
||||
{"name": "Congo", "code": "CG", "phone": "242"},
|
||||
{"name": "Congo, The Democratic Republic of the", "code": "CD", "phone": "242"},
|
||||
{"name": "Cook Islands", "code": "CK", "phone": "682"},
|
||||
{"name": "Costa Rica", "code": "CR", "phone": "506"},
|
||||
{"name": "Croatia", "code": "HR", "phone": "385"},
|
||||
{"name": "Cuba", "code": "CU", "phone": "53"},
|
||||
{"name": "Curaçao", "code": "CW", "phone": "599"},
|
||||
{"name": "Cyprus", "code": "CY", "phone": "357"},
|
||||
{"name": "Czech Republic", "code": "CZ", "phone": "420"},
|
||||
{"name": "Côte d'Ivoire", "code": "CI", "phone": "225"},
|
||||
{"name": "Denmark", "code": "DK", "phone": "45"},
|
||||
{"name": "Djibouti", "code": "DJ", "phone": "253"},
|
||||
{"name": "Dominica", "code": "DM", "phone": "1767"},
|
||||
{"name": "Dominican Republic", "code": "DO", "phone": "1809"},
|
||||
{"name": "Ecuador", "code": "EC", "phone": "593"},
|
||||
{"name": "Egypt", "code": "EG", "phone": "20"},
|
||||
{"name": "El Salvador", "code": "SV", "phone": "503"},
|
||||
{"name": "Equatorial Guinea", "code": "GQ", "phone": "240"},
|
||||
{"name": "Eritrea", "code": "ER", "phone": "291"},
|
||||
{"name": "Estonia", "code": "EE", "phone": "372"},
|
||||
{"name": "Ethiopia", "code": "ET", "phone": "251"},
|
||||
{"name": "Falkland Islands (Malvinas)", "code": "FK", "phone": "500"},
|
||||
{"name": "Faroe Islands", "code": "FO", "phone": "298"},
|
||||
{"name": "Fiji", "code": "FJ", "phone": "679"},
|
||||
{"name": "Finland", "code": "FI", "phone": "358"},
|
||||
{"name": "France", "code": "FR", "phone": "33"},
|
||||
{"name": "French Guiana", "code": "GF", "phone": "594"},
|
||||
{"name": "French Polynesia", "code": "PF", "phone": "689"},
|
||||
{"name": "French Southern Territories", "code": "TF", "phone": "262"},
|
||||
{"name": "Gabon", "code": "GA", "phone": "241"},
|
||||
{"name": "Gambia", "code": "GM", "phone": "220"},
|
||||
{"name": "Georgia", "code": "GE", "phone": "995"},
|
||||
{"name": "Germany", "code": "DE", "phone": "49"},
|
||||
{"name": "Ghana", "code": "GH", "phone": "233"},
|
||||
{"name": "Gibraltar", "code": "GI", "phone": "350"},
|
||||
{"name": "Greece", "code": "GR", "phone": "30"},
|
||||
{"name": "Greenland", "code": "GL", "phone": "299"},
|
||||
{"name": "Grenada", "code": "GD", "phone": "1473"},
|
||||
{"name": "Guadeloupe", "code": "GP", "phone": "590"},
|
||||
{"name": "Guam", "code": "GU", "phone": "1671"},
|
||||
{"name": "Guatemala", "code": "GT", "phone": "502"},
|
||||
{"name": "Guernsey", "code": "GG", "phone": "44"},
|
||||
{"name": "Guinea", "code": "GN", "phone": "224"},
|
||||
{"name": "Guinea-Bissau", "code": "GW", "phone": "245"},
|
||||
{"name": "Guyana", "code": "GY", "phone": "592"},
|
||||
{"name": "Haiti", "code": "HT", "phone": "509"},
|
||||
{"name": "Heard Island and Mcdonald Islands", "code": "HM", "phone": "0"},
|
||||
{"name": "Holy See (Vatican City State)", "code": "VA", "phone": "39"},
|
||||
{"name": "Honduras", "code": "HN", "phone": "504"},
|
||||
{"name": "Hong Kong", "code": "HK", "phone": "852"},
|
||||
{"name": "Hungary", "code": "HU", "phone": "36"},
|
||||
{"name": "Iceland", "code": "IS", "phone": "354"},
|
||||
{"name": "India", "code": "IN", "phone": "91"},
|
||||
{"name": "Indonesia", "code": "ID", "phone": "62"},
|
||||
{"name": "Iran, Islamic Republic Of", "code": "IR", "phone": "98"},
|
||||
{"name": "Iraq", "code": "IQ", "phone": "964"},
|
||||
{"name": "Ireland", "code": "IE", "phone": "353"},
|
||||
{"name": "Isle of Man", "code": "IM", "phone": "44"},
|
||||
{"name": "Israel", "code": "IL", "phone": "972"},
|
||||
{"name": "Italy", "code": "IT", "phone": "39"},
|
||||
{"name": "Jamaica", "code": "JM", "phone": "1876"},
|
||||
{"name": "Japan", "code": "JP", "phone": "81"},
|
||||
{"name": "Jersey", "code": "JE", "phone": "44"},
|
||||
{"name": "Jordan", "code": "JO", "phone": "962"},
|
||||
{"name": "Kazakhstan", "code": "KZ", "phone": "7"},
|
||||
{"name": "Kenya", "code": "KE", "phone": "254"},
|
||||
{"name": "Kiribati", "code": "KI", "phone": "686"},
|
||||
{"name": "Korea, Republic of", "code": "KR", "phone": "82"},
|
||||
{"name": "Kuwait", "code": "KW", "phone": "965"},
|
||||
{"name": "Kyrgyzstan", "code": "KG", "phone": "996"},
|
||||
{"name": "Laos", "code": "LA", "phone": "856"},
|
||||
{"name": "Latvia", "code": "LV", "phone": "371"},
|
||||
{"name": "Lebanon", "code": "LB", "phone": "961"},
|
||||
{"name": "Lesotho", "code": "LS", "phone": "266"},
|
||||
{"name": "Liberia", "code": "LR", "phone": "231"},
|
||||
{"name": "Libyan Arab Jamahiriya", "code": "LY", "phone": "218"},
|
||||
{"name": "Liechtenstein", "code": "LI", "phone": "423"},
|
||||
{"name": "Lithuania", "code": "LT", "phone": "370"},
|
||||
{"name": "Luxembourg", "code": "LU", "phone": "352"},
|
||||
{"name": "Macao", "code": "MO", "phone": "853"},
|
||||
{"name": "Madagascar", "code": "MG", "phone": "261"},
|
||||
{"name": "Malawi", "code": "MW", "phone": "265"},
|
||||
{"name": "Malaysia", "code": "MY", "phone": "60"},
|
||||
{"name": "Maldives", "code": "MV", "phone": "960"},
|
||||
{"name": "Mali", "code": "ML", "phone": "223"},
|
||||
{"name": "Malta", "code": "MT", "phone": "356"},
|
||||
{"name": "Marshall Islands", "code": "MH", "phone": "692"},
|
||||
{"name": "Martinique", "code": "MQ", "phone": "596"},
|
||||
{"name": "Mauritania", "code": "MR", "phone": "222"},
|
||||
{"name": "Mauritius", "code": "MU", "phone": "230"},
|
||||
{"name": "Mayotte", "code": "YT", "phone": "269"},
|
||||
{"name": "Mexico", "code": "MX", "phone": "52"},
|
||||
{"name": "Micronesia, Federated States of", "code": "FM", "phone": "691"},
|
||||
{"name": "Moldova, Republic of", "code": "MD", "phone": "373"},
|
||||
{"name": "Monaco", "code": "MC", "phone": "377"},
|
||||
{"name": "Mongolia", "code": "MN", "phone": "976"},
|
||||
{"name": "Montenegro", "code": "ME", "phone": "382"},
|
||||
{"name": "Montserrat", "code": "MS", "phone": "1664"},
|
||||
{"name": "Morocco", "code": "MA", "phone": "212"},
|
||||
{"name": "Mozambique", "code": "MZ", "phone": "258"},
|
||||
{"name": "Myanmar", "code": "MM", "phone": "95"},
|
||||
{"name": "Namibia", "code": "NA", "phone": "264"},
|
||||
{"name": "Nauru", "code": "NR", "phone": "674"},
|
||||
{"name": "Nepal", "code": "NP", "phone": "977"},
|
||||
{"name": "Netherlands", "code": "NL", "phone": "31"},
|
||||
{"name": "Netherlands Antilles", "code": "AN", "phone": "599"},
|
||||
{"name": "New Caledonia", "code": "NC", "phone": "687"},
|
||||
{"name": "New Zealand", "code": "NZ", "phone": "64"},
|
||||
{"name": "Nicaragua", "code": "NI", "phone": "505"},
|
||||
{"name": "Niger", "code": "NE", "phone": "227"},
|
||||
{"name": "Nigeria", "code": "NG", "phone": "234"},
|
||||
{"name": "Niue", "code": "NU", "phone": "683"},
|
||||
{"name": "Norfolk Island", "code": "NF", "phone": "672"},
|
||||
{"name": "North Korea", "code": "KP", "phone": "850"},
|
||||
{"name": "North Macedonia", "code": "MK", "phone": "389"},
|
||||
{"name": "Northern Mariana Islands", "code": "MP", "phone": "1670"},
|
||||
{"name": "Norway", "code": "NO", "phone": "47"},
|
||||
{"name": "Oman", "code": "OM", "phone": "968"},
|
||||
{"name": "Pakistan", "code": "PK", "phone": "92"},
|
||||
{"name": "Palau", "code": "PW", "phone": "680"},
|
||||
{"name": "Palestinian Territory, Occupied", "code": "PS", "phone": "970"},
|
||||
{"name": "Panama", "code": "PA", "phone": "507"},
|
||||
{"name": "Papua New Guinea", "code": "PG", "phone": "675"},
|
||||
{"name": "Paraguay", "code": "PY", "phone": "595"},
|
||||
{"name": "Peru", "code": "PE", "phone": "51"},
|
||||
{"name": "Philippines", "code": "PH", "phone": "63"},
|
||||
{"name": "Pitcairn Islands", "code": "PN", "phone": "64"},
|
||||
{"name": "Poland", "code": "PL", "phone": "48"},
|
||||
{"name": "Portugal", "code": "PT", "phone": "351"},
|
||||
{"name": "Puerto Rico", "code": "PR", "phone": "1787"},
|
||||
{"name": "Qatar", "code": "QA", "phone": "974"},
|
||||
{"name": "Reunion", "code": "RE", "phone": "262"},
|
||||
{"name": "Romania", "code": "RO", "phone": "40"},
|
||||
{"name": "Russian Federation", "code": "RU", "phone": "7"},
|
||||
{"name": "Rwanda", "code": "RW", "phone": "250"},
|
||||
{"name": "Saint Barthélemy", "code": "BL", "phone": "590"},
|
||||
{"name": "Saint Helena", "code": "SH", "phone": "290"},
|
||||
{"name": "Saint Kitts and Nevis", "code": "KN", "phone": "1869"},
|
||||
{"name": "Saint Lucia", "code": "LC", "phone": "1758"},
|
||||
{"name": "Saint Martin", "code": "MF", "phone": "590"},
|
||||
{"name": "Saint Pierre and Miquelon", "code": "PM", "phone": "508"},
|
||||
{"name": "Saint Vincent and the Grenadines", "code": "VC", "phone": "1784"},
|
||||
{"name": "Samoa", "code": "WS", "phone": "684"},
|
||||
{"name": "San Marino", "code": "SM", "phone": "378"},
|
||||
{"name": "Sao Tome and Principe", "code": "ST", "phone": "239"},
|
||||
{"name": "Saudi Arabia", "code": "SA", "phone": "966"},
|
||||
{"name": "Senegal", "code": "SN", "phone": "221"},
|
||||
{"name": "Serbia", "code": "RS", "phone": "381"},
|
||||
{"name": "Serbia and Montenegro", "code": "CS", "phone": "381"},
|
||||
{"name": "Seychelles", "code": "SC", "phone": "248"},
|
||||
{"name": "Sierra Leone", "code": "SL", "phone": "232"},
|
||||
{"name": "Singapore", "code": "SG", "phone": "65"},
|
||||
{"name": "Sint Maarten", "code": "SX", "phone": "1"},
|
||||
{"name": "Slovakia", "code": "SK", "phone": "421"},
|
||||
{"name": "Slovenia", "code": "SI", "phone": "386"},
|
||||
{"name": "Solomon Islands", "code": "SB", "phone": "677"},
|
||||
{"name": "Somalia", "code": "SO", "phone": "252"},
|
||||
{"name": "South Africa", "code": "ZA", "phone": "27"},
|
||||
{"name": "South Georgia and the South Sandwich Islands", "code": "GS", "phone": "500"},
|
||||
{"name": "South Sudan", "code": "SS", "phone": "211"},
|
||||
{"name": "Spain", "code": "ES", "phone": "34"},
|
||||
{"name": "Sri Lanka", "code": "LK", "phone": "94"},
|
||||
{"name": "Sudan", "code": "SD", "phone": "249"},
|
||||
{"name": "Suriname", "code": "SR", "phone": "597"},
|
||||
{"name": "Svalbard and Jan Mayen", "code": "SJ", "phone": "47"},
|
||||
{"name": "Swaziland", "code": "SZ", "phone": "268"},
|
||||
{"name": "Sweden", "code": "SE", "phone": "46"},
|
||||
{"name": "Switzerland", "code": "CH", "phone": "41"},
|
||||
{"name": "Syrian Arab Republic", "code": "SY", "phone": "963"},
|
||||
{"name": "Taiwan", "code": "TW", "phone": "886"},
|
||||
{"name": "Tajikistan", "code": "TJ", "phone": "992"},
|
||||
{"name": "Tanzania, United Republic of", "code": "TZ", "phone": "255"},
|
||||
{"name": "Thailand", "code": "TH", "phone": "66"},
|
||||
{"name": "Timor-Leste", "code": "TL", "phone": "670"},
|
||||
{"name": "Togo", "code": "TG", "phone": "228"},
|
||||
{"name": "Tokelau", "code": "TK", "phone": "690"},
|
||||
{"name": "Tonga", "code": "TO", "phone": "676"},
|
||||
{"name": "Trinidad and Tobago", "code": "TT", "phone": "1868"},
|
||||
{"name": "Tunisia", "code": "TN", "phone": "216"},
|
||||
{"name": "Turkey", "code": "TR", "phone": "90"},
|
||||
{"name": "Turkmenistan", "code": "TM", "phone": "7370"},
|
||||
{"name": "Turks and Caicos Islands", "code": "TC", "phone": "1649"},
|
||||
{"name": "Tuvalu", "code": "TV", "phone": "688"},
|
||||
{"name": "Uganda", "code": "UG", "phone": "256"},
|
||||
{"name": "Ukraine", "code": "UA", "phone": "380"},
|
||||
{"name": "United Arab Emirates", "code": "AE", "phone": "971"},
|
||||
{"name": "United Kingdom", "code": "GB", "phone": "44"},
|
||||
{"name": "United States", "code": "US", "phone": "1"},
|
||||
{"name": "United States Minor Outlying Islands", "code": "UM", "phone": "1"},
|
||||
{"name": "Uruguay", "code": "UY", "phone": "598"},
|
||||
{"name": "Uzbekistan", "code": "UZ", "phone": "998"},
|
||||
{"name": "Vanuatu", "code": "VU", "phone": "678"},
|
||||
{"name": "Venezuela", "code": "VE", "phone": "58"},
|
||||
{"name": "Vietnam", "code": "VN", "phone": "84"},
|
||||
{"name": "Virgin Islands, British", "code": "VG", "phone": "1284"},
|
||||
{"name": "Virgin Islands, U.S.", "code": "VI", "phone": "1340"},
|
||||
{"name": "Wallis and Futuna", "code": "WF", "phone": "681"},
|
||||
{"name": "Western Sahara", "code": "EH", "phone": "212"},
|
||||
{"name": "Yemen", "code": "YE", "phone": "967"},
|
||||
{"name": "Zambia", "code": "ZM", "phone": "260"},
|
||||
{"name": "Zimbabwe", "code": "ZW", "phone": "263"},
|
||||
{"name": "Åland Islands", "code": "AX", "phone": "358"}
|
||||
]
|
||||
1
admin/assets/json/currencies.json
Normal file
1099
admin/assets/json/flags.json
Normal file
885
admin/functions.php
Normal file
@@ -0,0 +1,885 @@
|
||||
<?php
|
||||
|
||||
function formipay_field_type_collection() {
|
||||
$types = [
|
||||
'text' => __( 'Text', 'formipay' ),
|
||||
'url' => __( 'URL', 'formipay' ),
|
||||
'email' => __( 'Email', 'formipay' ),
|
||||
'tel' => __( 'Telephone', 'formipay' ),
|
||||
'number' => __( 'Number', 'formipay' ),
|
||||
'date' => __( 'Date', 'formipay' ),
|
||||
'datetime' => __( 'Date & Time', 'formipay' ),
|
||||
'color' => __( 'Number', 'formipay' ),
|
||||
'select' => __( 'Select Dropdown', 'formipay' ),
|
||||
'checkbox' => __( 'Checkbox', 'formipay' ),
|
||||
'radio' => __( 'Radio', 'formipay' ),
|
||||
'hidden' => __( 'Hidden', 'formipay' ),
|
||||
'textarea' => __( 'Textarea', 'formipay' ),
|
||||
'divider' => __( 'Divider', 'formipay' ),
|
||||
'page_break' => __( 'Page Break', 'formipay' ),
|
||||
'country_list' => __( 'Preset: Country List', 'formipay' )
|
||||
];
|
||||
|
||||
$types = apply_filters( 'formipay/form-config/field-type', $types);
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
function formipay_currency_array() {
|
||||
|
||||
$json = file_get_contents(FORMIPAY_PATH . 'admin/assets/json/currencies.json');
|
||||
$array = json_decode($json, true);
|
||||
return $array;
|
||||
|
||||
}
|
||||
|
||||
function formipay_country_array() {
|
||||
|
||||
$json = file_get_contents(FORMIPAY_PATH . 'admin/assets/json/country.json');
|
||||
$array = json_decode($json, true);
|
||||
return $array;
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_flag_by_currency($currency) {
|
||||
|
||||
if(strpos($currency, ':::')){
|
||||
$currency = explode(':::', $currency);
|
||||
$currency = $currency[0];
|
||||
}
|
||||
$json = file_get_contents(FORMIPAY_PATH . 'admin/assets/json/flags.json');
|
||||
$array = json_decode($json, true);
|
||||
foreach($array as $country){
|
||||
if($currency == $country['code']){
|
||||
return $country['flag'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function formipay_price_format($num = 0, $post_id = 0){
|
||||
|
||||
$decimal_digits = 2;
|
||||
$decimal_symbol = '.';
|
||||
$thousand_separator_symbol = ',';
|
||||
|
||||
if($post_id > 0 ){
|
||||
$currency_data = explode(':::', get_post_meta($post_id, 'product_currency', true));
|
||||
$decimal_digits = get_post_meta($post_id, 'product_currency_decimal_digits', true);
|
||||
$decimal_symbol = get_post_meta($post_id, 'product_currency_decimal_symbol', true);
|
||||
$thousand_separator_symbol = get_post_meta($post_id, 'product_currency_thousand_separator', true);
|
||||
if(isset($currency_data[2]) && !empty($currency_data[2])){
|
||||
$currency = $currency_data[2];
|
||||
}else{
|
||||
$currency = $currency_data[0];
|
||||
}
|
||||
return $currency .' '. number_format(floatval($num), intval($decimal_digits), $decimal_symbol, $thousand_separator_symbol);
|
||||
}
|
||||
|
||||
return number_format(floatval($num), intval($decimal_digits), $decimal_symbol, $thousand_separator_symbol);
|
||||
|
||||
}
|
||||
|
||||
function formipay_currency_as_options($currency_code = '') {
|
||||
|
||||
$currencies = formipay_currency_array();
|
||||
$result = [];
|
||||
foreach($currencies as $currency){
|
||||
$code = $currency['code'];
|
||||
$currency_id = implode(':::', $currency);
|
||||
if('' !== $currency_code && $code == $currency_code){
|
||||
$result = $currency_id;
|
||||
break;
|
||||
}
|
||||
$result[$currency_id] = ucwords($currency['name']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
function formipay_post_currency($post_id){
|
||||
|
||||
$currency = formipay_get_post_meta($post_id, 'product_currency');
|
||||
$currency = explode(':::', $currency);
|
||||
$currency_symbol = $currency[0];
|
||||
if(isset($currency[2]) && '' !== $currency[2]){
|
||||
$currency_symbol = $currency[2];
|
||||
}
|
||||
|
||||
return $currency_symbol;
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_currency_data_by_value($value, $data='') {
|
||||
|
||||
$currency = explode(':::', $value);
|
||||
|
||||
switch ($data) {
|
||||
case 'title':
|
||||
$output = $currency[1];
|
||||
break;
|
||||
|
||||
case 'symbol':
|
||||
$output = $currency[0];
|
||||
// if(isset($currency[2]) && '' !== $currency[2] && false !== boolval($currency[2])){
|
||||
// $output = $currency[2];
|
||||
// }
|
||||
break;
|
||||
|
||||
default:
|
||||
$output = $value;
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
function formipay_default_currency($return='raw') {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$default_currency = $formipay_settings['payment_default_currency'];
|
||||
|
||||
switch ($return) {
|
||||
|
||||
case 'symbol':
|
||||
$output = formipay_get_currency_data_by_value($default_currency, 'symbol');
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
$output = formipay_get_currency_data_by_value($default_currency, 'title');
|
||||
break;
|
||||
|
||||
case 'decimal_digits':
|
||||
$output = $formipay_settings['payment_default_currency_decimal_digits'];
|
||||
break;
|
||||
|
||||
case 'decimal_symbol':
|
||||
$output = $formipay_settings['payment_default_currency_decimal_symbol'];
|
||||
break;
|
||||
|
||||
case 'thousand_separator':
|
||||
$output = $formipay_settings['payment_default_currency_thousand_separator'];
|
||||
break;
|
||||
|
||||
default:
|
||||
$output = $formipay_settings['payment_default_currency'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_post_meta($post_id, $metakey) {
|
||||
|
||||
$value = get_post_meta($post_id, $metakey, true);
|
||||
|
||||
if(!empty($value) && false !== $value && '' !== $value){
|
||||
return $value;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function formipay_order_status_list() {
|
||||
|
||||
$statuses = array(
|
||||
'on-hold' => 'On Hold',
|
||||
'payment-confirm' => 'Payment Confirmed',
|
||||
'in-progress' => 'In Progress',
|
||||
'shipping' => 'Shipping',
|
||||
'completed' => 'Completed',
|
||||
'failed' => 'Failed',
|
||||
'refunded' => 'Refunded',
|
||||
'cancelled' => 'Cancelled'
|
||||
);
|
||||
|
||||
return $statuses;
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_order($order_id) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$order = apply_filters( 'formipay/order/get', false, $order_id );
|
||||
|
||||
$order_data = [];
|
||||
|
||||
if(false !== $order){
|
||||
foreach($order as $key => $data){
|
||||
$order_data[$key] = maybe_unserialize( $data );
|
||||
if($key == 'items'){
|
||||
foreach($order_data[$key] as $index => $item){
|
||||
$order_data[$key][$index]['subtotal_formatted'] = formipay_price_format($item['subtotal'], $order_data['form_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$order_data['total_formatted'] = formipay_price_format($order_data['total'], $order_data['form_id']);
|
||||
|
||||
// Form Submission Data Process to Readable
|
||||
if(!empty($order_data['form_data'])){
|
||||
$field_types = formipay_field_type_collection();
|
||||
$form_field = get_post_meta($order_data['form_id'], 'formipay_settings', true);
|
||||
$form_field = $form_field['fields'];
|
||||
|
||||
$all_fields = [];
|
||||
foreach($form_field as $key => $field){
|
||||
if(array_key_exists($field['field_type'], $field_types)){
|
||||
$skip = false;
|
||||
if(in_array($field['field_type'], ['divider', 'page_break'])){
|
||||
$options = $field['field_options'];
|
||||
if(!empty($options)){
|
||||
foreach($options as $option){
|
||||
if(!empty($option['amount'])){
|
||||
$skip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(false == $skip){
|
||||
$all_fields[$key] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$proceed_form_data = [];
|
||||
foreach($order_data['form_data'] as $name => $value){
|
||||
switch ($name) {
|
||||
case 'qty':
|
||||
$label = esc_html__( 'Quantity', 'formipay' );
|
||||
break;
|
||||
|
||||
case 'payment':
|
||||
$label = esc_html__( 'Payment', 'formipay' );
|
||||
break;
|
||||
|
||||
case 'coupon_code':
|
||||
$label = esc_html__( 'Coupon Code', 'formipay' );
|
||||
break;
|
||||
|
||||
case 'payment_gateway':
|
||||
$label = esc_html__( 'Payment Gateway', 'formipay' );
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!empty($all_fields[$name.'_config'])){
|
||||
$label = $all_fields[$name.'_config']['label'];
|
||||
}else{
|
||||
$label = '';
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$data_value = $value;
|
||||
if(is_array($value)){
|
||||
$data_value = $value['label'] !== 'undefined' ? $value['label'] : $value['value'];
|
||||
}
|
||||
if($name == 'payment'){
|
||||
if(strpos($value, ':::') !== false){
|
||||
$value = explode(':::', $value);
|
||||
$data_value = isset($value[1]) ? $value[1] : $value[0];
|
||||
// If this is bank_transfer
|
||||
if(
|
||||
$value[0] == 'bank_transfer' &&
|
||||
isset($value[1]) &&
|
||||
strpos($value[1], '-') !== false
|
||||
) {
|
||||
$bank_account = explode('-', $value[1]);
|
||||
$bank_account_index = intval($bank_account[1]) + 1;
|
||||
// translators: %d is the bank account index number.
|
||||
$bank_label = $bank_account[0] . ' (' . sprintf( __( 'Bank Accounts #%d', 'formipay' ), $bank_account_index) . ')';
|
||||
$data_value = $bank_label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$proceed_form_data[$name] = [
|
||||
'name' => $name,
|
||||
'value' => $data_value !== '' ? $data_value : '-',
|
||||
'label' => $label
|
||||
];
|
||||
|
||||
}
|
||||
$order_data['form_data'] = $proceed_form_data;
|
||||
}
|
||||
|
||||
$thankyou_link = site_url( $formipay_settings['thankyou_link'] . '/' . base64_encode( $order_data['form_id'] . ':::' . $order_id ) );
|
||||
|
||||
$order_data['thankyou'] = [
|
||||
'link' => $thankyou_link,
|
||||
'pass_method' => !empty($order_data['meta_data']['access_method']) ? $order_data['meta_data']['access_method'] : 'magic_link',
|
||||
'pass_word' => (!empty($order_data['meta_data']['access_password']) && !empty($order_data['meta_data']['access_method'])) ? $order_data['meta_data']['access_password'] : formipay_generate_password(),
|
||||
];
|
||||
|
||||
if(!empty($order_data['meta_data'])){
|
||||
$proceed_meta_data = [];
|
||||
foreach($order_data['meta_data'] as $name => $value){
|
||||
$label = explode('_', $name);
|
||||
$__label = [];
|
||||
foreach($label as $_label){
|
||||
if(strlen($_label) <= 3){
|
||||
$__label[] = strtoupper($_label);
|
||||
}else{
|
||||
$__label[] = ucfirst($_label);
|
||||
}
|
||||
}
|
||||
$proceed_meta_data[$name] = [
|
||||
'label' => implode(' ', $__label),
|
||||
'name' => $name,
|
||||
'value' => $value !== '' ? $value : '-'
|
||||
];
|
||||
}
|
||||
$order_data['meta_data'] = $proceed_meta_data;
|
||||
}
|
||||
|
||||
// Payment Data Process to Readable
|
||||
if(!empty($order['payment_gateway'])){
|
||||
$trx_data = formipay_get_payment_data($order_id, $order['payment_gateway']);
|
||||
if(false !== $trx_data) {
|
||||
$order_data['transaction'] = $trx_data;
|
||||
}
|
||||
$timeline = [
|
||||
[
|
||||
'time' => $order['created_date'],
|
||||
// translators: %s is the payment gateway name.
|
||||
'activity' => sprintf( __( 'Order created via %s', 'formipay'), ucwords(str_replace( '_', ' ', $order['payment_gateway'])) ),
|
||||
'attachment' => 'none'
|
||||
]
|
||||
];
|
||||
if(!empty($trx_data)){
|
||||
foreach($trx_data as $trx){
|
||||
if($order['payment_gateway'] == 'bank_transfer' && !empty($trx['meta_data']['transfer_receipt'])) {
|
||||
$timeline[] = [
|
||||
'time' => formipay_date($trx['meta_data']['transfer_receipt']['time']),
|
||||
'activity' => __( 'Payment confirmation by uploading transfer receipt.', 'formipay' ),
|
||||
'attachment' => !empty($trx['meta_data']['transfer_receipt']['attachment_url']) ? $trx['meta_data']['transfer_receipt']['attachment_url'] : 'none'
|
||||
];
|
||||
}
|
||||
if($order['payment_gateway'] == 'paypal' && !empty($trx['meta_data']) && $trx['meta_data']['status'] == 'COMPLETED') {
|
||||
$timeline[] = [
|
||||
'time' => formipay_date($trx['meta_data']['update_time']),
|
||||
'activity' => __( 'Payment completed via Paypal.', 'formipay' ),
|
||||
'attachment' => 'none'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$timeline = apply_filters( 'formipay/order/transaction/timeline', $timeline, $order_id );
|
||||
$order_data['transaction_timeline'] = $timeline;
|
||||
}
|
||||
$notif_data = formipay_get_notification_data($order_id);
|
||||
if(false !== $notif_data) {
|
||||
$order_data['notification'] = $notif_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $order_data;
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_payment_data($order_id, $payment_gateway) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if($payment_gateway !== 'cod'){
|
||||
$table_name = $wpdb->prefix . 'formipay_'.$payment_gateway.'_trx';
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_results(
|
||||
$wpdb->prepare("SELECT * FROM %i WHERE `order_id` = %d", $table_name, $order_id), ARRAY_A
|
||||
);
|
||||
|
||||
$trx_data = [];
|
||||
if(false !== $get){
|
||||
foreach($get as $index => $row){
|
||||
foreach($row as $key => $value){
|
||||
$trx_data[$index][$key] = maybe_unserialize( $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
return !empty($trx_data) ? $trx_data : $get;
|
||||
}
|
||||
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
function formipay_get_notification_data($order_id) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'formipay_notification_log';
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_results(
|
||||
$wpdb->prepare("SELECT * FROM %i WHERE `order_id` = %d", $table_name, $order_id), ARRAY_A
|
||||
);
|
||||
|
||||
$notif_data = [];
|
||||
if(false !== $get){
|
||||
foreach($get as $row_key => $row){
|
||||
foreach($row as $key => $value){
|
||||
$notif_data[$row_key][$key] = maybe_unserialize( $value );
|
||||
}
|
||||
$notif_data[$row_key]['recipient'] = $notif_data[$row_key]['notification_data']['to'];
|
||||
$notif_data[$row_key]['title'] = $notif_data[$row_key]['notification_data']['subject'];
|
||||
|
||||
switch ($notif_data[$row_key]['recipient_type']) {
|
||||
case 'email':
|
||||
$icon = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<g fill="#fff">
|
||||
<path d="M22 7.535V17a3 3 0 0 1-2.824 2.995L19 20H5a3 3 0 0 1-2.995-2.824L2 17V7.535l9.445 6.297l.116.066a1 1 0 0 0 .878 0l.116-.066z" />
|
||||
<path d="M19 4c1.08 0 2.027.57 2.555 1.427L12 11.797l-9.555-6.37a3 3 0 0 1 2.354-1.42L5 4z" />
|
||||
</g>
|
||||
</svg>';
|
||||
break;
|
||||
case 'waba':
|
||||
case 'whatsapp':
|
||||
$icon = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#fff" d="M18.497 4.409a10 10 0 0 1-10.36 16.828l-.223-.098l-4.759.849l-.11.011a1 1 0 0 1-.11 0l-.102-.013l-.108-.024l-.105-.037l-.099-.047l-.093-.058l-.014-.011l-.012-.007l-.086-.073l-.077-.08l-.067-.088l-.056-.094l-.034-.07l-.04-.108l-.028-.128l-.012-.102a1 1 0 0 1 0-.125l.012-.1l.024-.11l.045-.122l1.433-3.304l-.009-.014A10 10 0 0 1 5.056 4.83l.215-.203a10 10 0 0 1 13.226-.217M9.5 7.5A1.5 1.5 0 0 0 8 9v1a6 6 0 0 0 6 6h1a1.5 1.5 0 0 0 0-3h-1l-.144.007a1.5 1.5 0 0 0-1.128.697l-.042.074l-.022-.007a4.01 4.01 0 0 1-2.435-2.435l-.008-.023l.075-.041A1.5 1.5 0 0 0 11 10V9a1.5 1.5 0 0 0-1.5-1.5" />
|
||||
</svg>';
|
||||
break;
|
||||
|
||||
default:
|
||||
$icon = '';
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($notif_data) ? $notif_data : $get;
|
||||
|
||||
}
|
||||
|
||||
function formipay_update_order_status($args) {
|
||||
|
||||
$data = wp_parse_args( $args, [
|
||||
'form_id' => 0,
|
||||
'order_id' => 0,
|
||||
'payment_gateway' => '',
|
||||
'status' => 'on-hold'
|
||||
] );
|
||||
|
||||
$order_id = intval($data['order_id']);
|
||||
$order = new Formipay_Order();
|
||||
// $get = $order->get($order_id);
|
||||
$update = $order->update($order_id, [
|
||||
'status' => $data['status']
|
||||
]);
|
||||
|
||||
if(is_wp_error( $update )){
|
||||
$response = [
|
||||
'valid' => false,
|
||||
'message' => str_replace(
|
||||
[
|
||||
'{{order_id}}', '{{system_error_message}}'
|
||||
],
|
||||
[
|
||||
$order_id, $update->get_error_message()
|
||||
],
|
||||
formipay_get_post_meta($data['form_id'], $data['payment_gateway'] . '_confirmation_message_error')
|
||||
)
|
||||
];
|
||||
}else{
|
||||
$response = [
|
||||
'valid' => true,
|
||||
'message' => str_replace(
|
||||
'{{order_id}}',
|
||||
$order_id,
|
||||
formipay_get_post_meta($data['form_id'], $data['payment_gateway'] . '_confirmation_message_success')
|
||||
)
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
|
||||
function formipay_date($format = '', $date = '') {
|
||||
if ($format == '') {
|
||||
$format = get_option('date_format') . ' ' . get_option('time_format');
|
||||
}
|
||||
$timezone = new DateTimeZone(wp_timezone_string());
|
||||
|
||||
if (empty($date)) {
|
||||
$datetime = new DateTime('now', $timezone);
|
||||
} else {
|
||||
// Detect if $date is a timestamp (integer or numeric string)
|
||||
if (is_numeric($date) && (int)$date == $date) {
|
||||
// Create DateTime from timestamp
|
||||
$datetime = new DateTime('@' . $date); // UTC by default
|
||||
$datetime->setTimezone($timezone);
|
||||
} else {
|
||||
// Create DateTime from date string in UTC
|
||||
$datetime = new DateTime($date, new DateTimeZone('UTC'));
|
||||
$datetime->setTimezone($timezone);
|
||||
}
|
||||
}
|
||||
|
||||
if ($format === 'timestamp') {
|
||||
return (int) $datetime->format('U');
|
||||
}
|
||||
|
||||
return $datetime->format($format);
|
||||
}
|
||||
|
||||
|
||||
function formipay_editor_hints() {
|
||||
$hints = [
|
||||
'buyer_name' => __( 'Buyer Name', 'formipay' ),
|
||||
'product_name' => __( 'Product Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'order_date' => __( 'Order Date', 'formipay' ),
|
||||
'order_total' => __( 'Order Total', 'formipay' ),
|
||||
'order_status' => __( 'Order Status', 'formipay' ),
|
||||
'order_details' => __( 'Order Details', 'formipay' ),
|
||||
'form_submission' => __( 'All Field Submissions', 'formipay' ),
|
||||
'payment_details' => __( 'Payment Details', 'formipay' )
|
||||
];
|
||||
|
||||
$hints = apply_filters( 'formipay/form-config/notification/hints', $hints );
|
||||
|
||||
return $hints;
|
||||
}
|
||||
|
||||
function formipay_is_HTML($string){
|
||||
return $string !== wp_strip_all_tags($string) ? true : false ;
|
||||
}
|
||||
|
||||
function allow_style_attribute_for_all_tags($content) {
|
||||
|
||||
// Get all standard HTML tags
|
||||
$allowed_tags = wp_kses_allowed_html('post');
|
||||
|
||||
// Iterate over the allowed tags and add 'style' attribute to each
|
||||
foreach ($allowed_tags as $tag => $attributes) {
|
||||
$allowed_tags[$tag]['style'] = array(); // Allow 'style' attribute
|
||||
}
|
||||
|
||||
// Sanitize the content with the updated allowed tags
|
||||
return wp_kses($content, $allowed_tags);
|
||||
|
||||
}
|
||||
|
||||
function formipay_isPopup($post_id) {
|
||||
if(formipay_get_post_meta($post_id, 'form_display_as') == 'popup'){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function formipay_filesize($attachment_id) {
|
||||
|
||||
$metadata = wp_get_attachment_metadata($attachment_id);
|
||||
$fileSize = $metadata['filesize'];
|
||||
$sizeLabels = ['B', 'KB', 'MB', 'GB'];
|
||||
$index = 0;
|
||||
while ($fileSize >= 1024 && $index < count($sizeLabels) - 1) {
|
||||
$fileSize /= 1024;
|
||||
$index++;
|
||||
}
|
||||
return number_format($fileSize, 2) . ' ' . $sizeLabels[$index];
|
||||
|
||||
}
|
||||
|
||||
function formipay_attachment_icon($attachment_id = 0){
|
||||
|
||||
if($attachment_id > 0){
|
||||
$get_attach = get_post($attachment_id);
|
||||
$mime = $get_attach->post_mime_type;
|
||||
$mime = explode('/', $mime);
|
||||
$type = $mime[1];
|
||||
|
||||
switch ($type) {
|
||||
case 'zip':
|
||||
$icon = '<i class="bi bi-file-earmark-zip formipay-download-icon"></i>';
|
||||
break;
|
||||
|
||||
default:
|
||||
$icon = '<i class="bi bi-filetype-'.$type.' formipay-download-icon"></i>';
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
$icon = '<i class="bi bi-link-45deg formipay-download-icon"></i>';
|
||||
}
|
||||
|
||||
return $icon;
|
||||
|
||||
}
|
||||
|
||||
function order_meta_fields() {
|
||||
return array(
|
||||
'user_id', 'session_id', 'referrer', 'page_url', 'timestamp', 'utm_source', 'utm_medium', 'utm_campaign', 'ip_address', 'user_agent'
|
||||
);
|
||||
}
|
||||
|
||||
function formipay_get_coupon_id_by_code($code, $form_id) {
|
||||
global $wpdb;
|
||||
|
||||
// Validate input early
|
||||
if (empty($code) || empty($form_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get coupon by code directly using title match
|
||||
$coupon_post = false;
|
||||
|
||||
$query = new WP_Query([
|
||||
'post_type' => 'formipay-coupon',
|
||||
'title' => $code,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'all', // or 'ids' if you only need the ID
|
||||
]);
|
||||
|
||||
if (!empty($query->posts)) {
|
||||
$coupon_post = $query->posts[0]; // Returns the post object
|
||||
}
|
||||
|
||||
if (!$coupon_post || $coupon_post->post_status !== 'publish') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$coupon_id = $coupon_post->ID;
|
||||
|
||||
// Check active status first
|
||||
if (formipay_get_post_meta($coupon_id, 'active') !== 'on') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check form restrictions using meta query
|
||||
$allowed_forms = formipay_get_post_meta($coupon_id, 'forms');
|
||||
if (!empty($allowed_forms)) {
|
||||
$forms = array_map('intval', explode(',', $allowed_forms));
|
||||
if (!in_array((int)$form_id, $forms, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Case sensitivity check
|
||||
if (formipay_get_post_meta($coupon_id, 'case_sensitive') === 'on') {
|
||||
$stored_code = get_the_title($coupon_id);
|
||||
if ($code !== $stored_code) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check usage limits using meta counters
|
||||
$use_limit = (int)formipay_get_post_meta($coupon_id, 'use_limit');
|
||||
if ($use_limit > 0) {
|
||||
$usage_count = (int)formipay_get_post_meta($coupon_id, 'usage_count');
|
||||
if ($usage_count >= $use_limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Date validation with proper timezone handling
|
||||
$date_limit = formipay_get_post_meta($coupon_id, 'date_limit');
|
||||
if (!empty($date_limit) && is_numeric($date_limit)) {
|
||||
$current_time = current_time('timestamp', true);
|
||||
if ($current_time > (int)$date_limit) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $coupon_id;
|
||||
}
|
||||
|
||||
|
||||
// Function to check if a string contains HTML tags like <img>, <svg>, or <i>
|
||||
function formipay_contains_html($string) {
|
||||
return preg_match('/<(img|svg|i)(\s|>)/i', $string);
|
||||
}
|
||||
|
||||
function formipay_generate_password() {
|
||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!!!';
|
||||
$charactersLength = strlen($characters);
|
||||
$password = '';
|
||||
|
||||
for ($i = 0; $i < 8; $i++) :
|
||||
$password .= $characters[wp_rand(0, $charactersLength - 1)];
|
||||
endfor;
|
||||
|
||||
$set_password = $password;
|
||||
|
||||
return $set_password;
|
||||
}
|
||||
|
||||
function formipay_customer_mandatory_data() {
|
||||
|
||||
$mandatory_data = ['name'];
|
||||
$formipay_settings = get_option( 'formipay_settings' );
|
||||
if(isset($formipay_settings['customer_mandatory_data'])) {
|
||||
foreach($formipay_settings['customer_mandatory_data'] as $category => $config){
|
||||
if($config['id'] == 'mandatory'){
|
||||
foreach($config['options'] as $data){
|
||||
$mandatory_data[] = $data['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mandatory_data;
|
||||
}
|
||||
|
||||
function formipay_phone_country_code_options() {
|
||||
$codes = formipay_country_array();
|
||||
$options = [];
|
||||
foreach($codes as $code){
|
||||
$country_code = $code['phone'];
|
||||
$options[$country_code] = '(' . $country_code . ') ' . $code['name'];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
function formipay_sanitize_array(array $input) {
|
||||
$sanitized = [];
|
||||
|
||||
foreach ($input as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
// Recursively sanitize nested arrays
|
||||
$sanitized[$key] = formipay_sanitize_array( $value);
|
||||
} else {
|
||||
// Sanitize scalar values (adjust sanitization as needed)
|
||||
$sanitized[$key] = sanitize_text_field( wp_unslash($value));
|
||||
}
|
||||
}
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
|
||||
function formipay_generate_privacy_policy() {
|
||||
// Check if page already exists
|
||||
$existing_page = get_page_by_path('privacy-policy', OBJECT, 'page');
|
||||
|
||||
if (!$existing_page) {
|
||||
// Get site-specific information
|
||||
$site_name = esc_html(get_bloginfo('name'));
|
||||
$site_url = esc_url(home_url());
|
||||
$admin_email = sanitize_email(get_bloginfo('admin_email'));
|
||||
$current_year = formipay_date('Y');
|
||||
|
||||
// Build policy content
|
||||
$content = file_get_contents(FORMIPAY_PATH . '/public/templates/privacy-policy.php');
|
||||
|
||||
// Create privacy policy page
|
||||
$page_id = wp_insert_post([
|
||||
'post_title' => __('Privacy Policy', 'formipay'),
|
||||
'post_name' => 'privacy-policy',
|
||||
'post_content' => $content,
|
||||
'post_status' => 'draft', // Set to draft for admin review
|
||||
'post_type' => 'page',
|
||||
'post_author' => get_current_user_id(),
|
||||
'meta_input' => [
|
||||
'_formipay_generated_policy' => true,
|
||||
'_formipay_policy_version' => '1.0'
|
||||
]
|
||||
]);
|
||||
|
||||
// Add admin notice
|
||||
if ($page_id && !is_wp_error($page_id)) {
|
||||
add_action('admin_notices', function() use ($page_id) {
|
||||
$edit_url = admin_url("post.php?post={$page_id}&action=edit");
|
||||
echo '<div class="notice notice-success">';
|
||||
echo '<p>' . sprintf(
|
||||
// translators: %s is the drafted page URL.
|
||||
esc_html__('Privacy Policy draft created. <a href="%s">Review and publish</a>', 'formipay'),
|
||||
esc_url($edit_url)
|
||||
) . '</p>';
|
||||
echo '</div>';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formipay_thankyoupage_allowed_html() {
|
||||
return [
|
||||
'div' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'data-*' => true
|
||||
],
|
||||
'h1' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'h2' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'h3' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'h4' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'h5' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'h6' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'style' => true
|
||||
],
|
||||
'form' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'action' => true,
|
||||
'method' => true,
|
||||
'enctype' => true
|
||||
],
|
||||
'input' => [
|
||||
'type' => true,
|
||||
'name' => true,
|
||||
'value' => true,
|
||||
'class' => true,
|
||||
'id' => true,
|
||||
'accept' => true,
|
||||
'style' => true,
|
||||
'data-*' => true
|
||||
],
|
||||
'button' => [
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'type' => true,
|
||||
'data-*' => true
|
||||
],
|
||||
'img' => [
|
||||
'src' => true,
|
||||
'alt' => true,
|
||||
'class' => true,
|
||||
'id' => true
|
||||
],
|
||||
'p' => ['class' => true],
|
||||
'b' => [],
|
||||
'i' => ['class' => true],
|
||||
'table' => ['id' => true, 'class' => true],
|
||||
'tbody' => [],
|
||||
'tr' => [],
|
||||
'th' => [],
|
||||
'td' => [],
|
||||
'br' => []
|
||||
];
|
||||
}
|
||||
|
||||
// add_action('admin_notices', function() {
|
||||
// global $current_screen;
|
||||
// echo '<pre>';
|
||||
// print_r($current_screen);
|
||||
// echo '</pre>';
|
||||
// });
|
||||
49
admin/page-access-items.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html(FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png'); ?>" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Access Items', 'formipay' ); ?></h1>
|
||||
<a id="add-new-item"><?php echo esc_html__( '+ Add New Item', 'formipay' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="table-toolbar">
|
||||
<div class="post-status-wrapper">
|
||||
<button id="formipay-delete-selected" style="display:none;">
|
||||
Delete Selected
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M20 6a1 1 0 0 1 .117 1.993L20 8h-.081L19 19a3 3 0 0 1-2.824 2.995L16 22H8c-1.598 0-2.904-1.249-2.992-2.75l-.005-.167L4.08 8H4a1 1 0 0 1-.117-1.993L4 6zm-9.489 5.14a1 1 0 0 0-1.218 1.567L10.585 14l-1.292 1.293l-.083.094a1 1 0 0 0 1.497 1.32L12 15.415l1.293 1.292l.094.083a1 1 0 0 0 1.32-1.497L13.415 14l1.292-1.293l.083-.094a1 1 0 0 0-1.497-1.32L12 12.585l-1.293-1.292l-.094-.083zM14 2a2 2 0 0 1 2 2a1 1 0 0 1-1.993.117L14 4h-4l-.007.117A1 1 0 0 1 8 4a2 2 0 0 1 1.85-1.995L10 2z" />
|
||||
</svg>
|
||||
</button>
|
||||
<input type="hidden" id="post_status" value="all">
|
||||
<a data-value="all" data-active="true"><?php echo esc_html__( 'All', 'formipay' ); ?></a><span class="all-post-count"></span> |
|
||||
<a data-value="publish"><?php echo esc_html__( 'Published', 'formipay' ); ?></a><span class="publish-post-count"></span> |
|
||||
<a data-value="draft"><?php echo esc_html__( 'Draft', 'formipay' ); ?></a><span class="draft-post-count"></span>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<a id="reset-filter">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="#277aff" d="m16.325 18.8l-2.2 2.2L12 18.875l2.2-2.2q-.1-.275-.15-.575t-.05-.6q0-1.45 1.025-2.475T17.5 12q.45 0 .875.113t.8.312L16.8 14.8l1.4 1.4l2.375-2.35q.2.375.313.788T21 15.5q0 1.45-1.025 2.475T17.5 19q-.325 0-.612-.05t-.563-.15m4.45-8.8H18.7q-.65-2.2-2.475-3.6T12 5Q9.075 5 7.037 7.038T5 12q0 1.8.813 3.3T8 17.75V15h2v6H4v-2h2.35Q4.8 17.75 3.9 15.938T3 12q0-1.875.713-3.512t1.924-2.85t2.85-1.925T12 3q3.225 0 5.663 1.988T20.775 10"/></svg>
|
||||
Reset
|
||||
</a>
|
||||
<div class="products">
|
||||
<select id="products" class="form-tool filter-products"></select>
|
||||
</div>
|
||||
<div class="orderby">
|
||||
<select id="orderby" class="form-tool">
|
||||
<option value="ID" selected><?php echo esc_html__( 'ID', 'formipay' ); ?></option>
|
||||
<option value="title"><?php echo esc_html__( 'Title', 'formipay' ); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<select id="sort_by" class="form-tool">
|
||||
<option value="desc" selected>DESC</option>
|
||||
<option value="asc">ASC</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="search">
|
||||
<input type="text" id="keyword" placeholder="Keyword" class="form-tool">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-access-items"></div>
|
||||
</div>
|
||||
39
admin/page-coupons.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html(FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png'); ?>" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Coupons', 'formipay' ); ?></h1>
|
||||
<a id="add-new-coupon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m6 0h6m-3-3v6" />
|
||||
</svg>
|
||||
<?php echo esc_html__( 'New Coupon', 'formipay' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="table-toolbar">
|
||||
<div class="post-status-wrapper">
|
||||
<button id="formipay-delete-selected" style="display:none;">
|
||||
Delete Selected
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M20 6a1 1 0 0 1 .117 1.993L20 8h-.081L19 19a3 3 0 0 1-2.824 2.995L16 22H8c-1.598 0-2.904-1.249-2.992-2.75l-.005-.167L4.08 8H4a1 1 0 0 1-.117-1.993L4 6zm-9.489 5.14a1 1 0 0 0-1.218 1.567L10.585 14l-1.292 1.293l-.083.094a1 1 0 0 0 1.497 1.32L12 15.415l1.293 1.292l.094.083a1 1 0 0 0 1.32-1.497L13.415 14l1.292-1.293l.083-.094a1 1 0 0 0-1.497-1.32L12 12.585l-1.293-1.292l-.094-.083zM14 2a2 2 0 0 1 2 2a1 1 0 0 1-1.993.117L14 4h-4l-.007.117A1 1 0 0 1 8 4a2 2 0 0 1 1.85-1.995L10 2z" />
|
||||
</svg>
|
||||
</button>
|
||||
<input type="hidden" id="post_status" value="all">
|
||||
<a data-value="all" data-active="true"><?php echo esc_html__( 'All', 'formipay' ); ?></a><span class="all-post-count"></span> |
|
||||
<a data-value="active"><?php echo esc_html__( 'Active', 'formipay' ); ?></a><span class="active-post-count"></span> |
|
||||
<a data-value="inactive"><?php echo esc_html__( 'Inactive', 'formipay' ); ?></a><span class="inactive-post-count"></span>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<div class="products">
|
||||
<select id="products" class="filter-products"></select>
|
||||
</div>
|
||||
<div class="search">
|
||||
<input type="text" id="keyword" placeholder="Keyword" class="form-tool">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-coupons"></div>
|
||||
|
||||
</div>
|
||||
1
admin/page-customer-details.php
Normal file
@@ -0,0 +1 @@
|
||||
<h1><?php echo esc_html__('Customer Details', 'formipay'); ?></h1>
|
||||
30
admin/page-customers.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html( FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png' ); ?>" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Customers', 'formipay' ); ?></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="table-toolbar">
|
||||
<div class="filter-bar">
|
||||
<a id="reset-filter">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="#277aff" d="m16.325 18.8l-2.2 2.2L12 18.875l2.2-2.2q-.1-.275-.15-.575t-.05-.6q0-1.45 1.025-2.475T17.5 12q.45 0 .875.113t.8.312L16.8 14.8l1.4 1.4l2.375-2.35q.2.375.313.788T21 15.5q0 1.45-1.025 2.475T17.5 19q-.325 0-.612-.05t-.563-.15m4.45-8.8H18.7q-.65-2.2-2.475-3.6T12 5Q9.075 5 7.037 7.038T5 12q0 1.8.813 3.3T8 17.75V15h2v6H4v-2h2.35Q4.8 17.75 3.9 15.938T3 12q0-1.875.713-3.512t1.924-2.85t2.85-1.925T12 3q3.225 0 5.663 1.988T20.775 10"/></svg>
|
||||
Reset
|
||||
</a>
|
||||
<div class="limit">
|
||||
<select id="limit" class="form-tool">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="keyword">
|
||||
<input id="keyword" class="form-tool" placeholder="<?php echo esc_html__( 'Keyword', 'formipay' ); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-customers"></div>
|
||||
</div>
|
||||
54
admin/page-forms.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html(FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png'); ?>" alt="Formipay" />
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Forms', 'formipay' ); ?></h1>
|
||||
<a id="add-new-form">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m6 0h6m-3-3v6" />
|
||||
</svg>
|
||||
<?php echo esc_html__( 'New Form', 'formipay' ); ?>
|
||||
</a>
|
||||
<button id="formipay-delete-selected" style="display:none;">
|
||||
Delete Selected
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M20 6a1 1 0 0 1 .117 1.993L20 8h-.081L19 19a3 3 0 0 1-2.824 2.995L16 22H8c-1.598 0-2.904-1.249-2.992-2.75l-.005-.167L4.08 8H4a1 1 0 0 1-.117-1.993L4 6zm-9.489 5.14a1 1 0 0 0-1.218 1.567L10.585 14l-1.292 1.293l-.083.094a1 1 0 0 0 1.497 1.32L12 15.415l1.293 1.292l.094.083a1 1 0 0 0 1.32-1.497L13.415 14l1.292-1.293l.083-.094a1 1 0 0 0-1.497-1.32L12 12.585l-1.293-1.292l-.094-.083zM14 2a2 2 0 0 1 2 2a1 1 0 0 1-1.993.117L14 4h-4l-.007.117A1 1 0 0 1 8 4a2 2 0 0 1 1.85-1.995L10 2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="content-container">
|
||||
<div class="table-toolbar">
|
||||
<div class="post-status-wrapper">
|
||||
<input type="hidden" id="post_status" value="all">
|
||||
<a data-value="all" data-active="true"><?php echo esc_html__( 'All', 'formipay' ); ?></a><span class="all-post-count"></span> |
|
||||
<a data-value="publish"><?php echo esc_html__( 'Published', 'formipay' ); ?></a><span class="publish-post-count"></span> |
|
||||
<a data-value="draft"><?php echo esc_html__( 'Draft', 'formipay' ); ?></a><span class="draft-post-count"></span>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<a id="reset-filter">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="#277aff" d="m16.325 18.8l-2.2 2.2L12 18.875l2.2-2.2q-.1-.275-.15-.575t-.05-.6q0-1.45 1.025-2.475T17.5 12q.45 0 .875.113t.8.312L16.8 14.8l1.4 1.4l2.375-2.35q.2.375.313.788T21 15.5q0 1.45-1.025 2.475T17.5 19q-.325 0-.612-.05t-.563-.15m4.45-8.8H18.7q-.65-2.2-2.475-3.6T12 5Q9.075 5 7.037 7.038T5 12q0 1.8.813 3.3T8 17.75V15h2v6H4v-2h2.35Q4.8 17.75 3.9 15.938T3 12q0-1.875.713-3.512t1.924-2.85t2.85-1.925T12 3q3.225 0 5.663 1.988T20.775 10"/></svg>
|
||||
Reset
|
||||
</a>
|
||||
<div class="orderby">
|
||||
<select id="orderby" class="form-tool">
|
||||
<option value="ID" selected><?php echo esc_html__( 'ID', 'formipay' ); ?></option>
|
||||
<option value="title"><?php echo esc_html__( 'Title', 'formipay' ); ?></option>
|
||||
<option value="modified"><?php echo esc_html__( 'Modified Date', 'formipay' ); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<select id="sort_by" class="form-tool">
|
||||
<option value="desc" selected>DESC</option>
|
||||
<option value="asc">ASC</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="search">
|
||||
<input type="text" id="keyword" placeholder="Keyword" class="form-tool">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-forms"></div>
|
||||
</div>
|
||||
</div>
|
||||
276
admin/page-order-details.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html( FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png' ); ?>" alt="Formipay"> <!-- phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -->
|
||||
<div class="screen-title">
|
||||
<h1>
|
||||
<?php echo
|
||||
// translators: %d is the current order ID.
|
||||
sprintf( esc_html__( 'Order %d', 'formipay'), intval(isset($_GET['order_id']) ? $_GET['order_id'] : 0) )
|
||||
?>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<input type="hidden" id="order_id" value="<?php echo intval(isset($_GET['order_id']) ? $_GET['order_id'] : 0); ?>">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-7">
|
||||
<div class="order-detail-card items-card">
|
||||
<div class="card-title mt-3 mb-0"><?php echo esc_html__( 'Items', 'formipay' ); ?></div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<div class="card-body p-0">
|
||||
<table class="table placeholder-glow mb-0" id="order-items-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><span class="placeholder col-6"></span></th>
|
||||
<td><span class="placeholder col-4"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><span class="placeholder col-6"></span></th>
|
||||
<td><span class="placeholder col-4"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><span class="placeholder col-6"></span></th>
|
||||
<td><span class="placeholder col-4"></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="border-bottom-0">
|
||||
<th class="border-bottom-0"><?php echo esc_html__( 'Total Order Value', 'formipay' ); ?></th>
|
||||
<td id="order-total" class="border-bottom-0"><span class="placeholder col-4"></span></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer bg-white d-flex justify-content-between align-items-center px-0" style="padding: .5rem!important;">
|
||||
<?php echo esc_html__( 'Order Status', 'formipay' ); ?>
|
||||
<select name="order_status" id="order_status" class="form-select rounded border border-secondary-subtle" data-order-id="<?php echo intval(isset($_GET['order_id']) ? $_GET['order_id'] : 0); ?>">
|
||||
<?php
|
||||
$order_statuses = formipay_order_status_list();
|
||||
foreach($order_statuses as $key => $status) {
|
||||
echo '<option value='. esc_html($key) .'>'. esc_html($status) .'</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-detail-card form-data-card">
|
||||
<div class="card-title mt-3 w-100 mb-0 d-flex justify-content-between align-items-center">
|
||||
<?php echo esc_html__( 'Form Data', 'formipay' ); ?>
|
||||
<button type="button" class="btn btn-secondary btn-sm edit-transaction-data rounded-4 px-3" data-loaded-button-text="<?php echo esc_html__( 'Edit Data', 'formipay' ); ?>" disabled>
|
||||
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
|
||||
<span class="visually-hidden" role="status"></span>
|
||||
</button>
|
||||
<div class="update-transaction-buttons d-none">
|
||||
<button type="button" class="btn btn-secondary btn-sm cancel-transaction-data rounded-4 px-3"><?php echo esc_html__( 'Cancel', 'formipay' ); ?></button>
|
||||
<button type="button" class="btn btn-primary btn-sm update-transaction-data rounded-4 px-3"><?php echo esc_html__( 'Save Changes', 'formipay' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<div class="card-body p-0 placeholder-glow">
|
||||
<ul class="list-group list-group-flush" id="form-data-list">
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-detail-card transaction-card">
|
||||
<div class="card-title mt-3 mb-0">
|
||||
<?php echo esc_html__( 'Transactions', 'formipay' ); ?>
|
||||
</div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<div class="card-body p-0">
|
||||
<div class="rb-container">
|
||||
<ul class="rb" id="transaction-list">
|
||||
<li class="rb-item placeholder-glow">
|
||||
<span class="placeholder col-3"></span>
|
||||
<span class="placeholder col-10"></span>
|
||||
</li>
|
||||
<li class="rb-item placeholder-glow">
|
||||
<span class="placeholder col-3"></span>
|
||||
<span class="placeholder col-10"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-detail-card notification-card">
|
||||
<div class="card-title mt-3 mb-0"><?php echo esc_html__( 'Notification', 'formipay' ); ?></div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<div class="card-body p-0 placeholder-glow">
|
||||
<ul class="list-group list-group-flush" id="notification-list">
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="order-detail-card submission-detail-card">
|
||||
<div class="card-title mt-3 mb-0"><?php echo esc_html__( 'Submission Details', 'formipay' ); ?></div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<div class="card-body p-0 placeholder-glow">
|
||||
<ul class="list-group list-group-flush" id="submission-detail-list">
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-detail-card product-access-card">
|
||||
<div class="card-title mt-3 w-100 mb-0 d-flex justify-content-between align-items-center">
|
||||
<?php echo esc_html__( 'Product Access', 'formipay' ); ?>
|
||||
<button type="button" class="btn btn-secondary btn-sm edit-access-data rounded-4 px-3" data-loaded-button-text="<?php echo esc_html__( 'Edit Data', 'formipay' ); ?>" disabled>
|
||||
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
|
||||
<span class="visually-hidden" role="status"></span>
|
||||
</button>
|
||||
<div class="update-access-buttons d-none">
|
||||
<button type="button" class="btn btn-secondary btn-sm cancel-access-data rounded-4 px-3"><?php echo esc_html__( 'Cancel', 'formipay' ); ?></button>
|
||||
<button type="button" class="btn btn-primary btn-sm update-access-data rounded-4 px-3"><?php echo esc_html__( 'Save Changes', 'formipay' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-1 border-0 rounded-4 shadow-sm">
|
||||
<form class="card-body p-0 placeholder-glow">
|
||||
<ul class="list-group list-group-flush" id="access-detail-list">
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<b><span class="placeholder col-3"></span></b>
|
||||
<p class="mb-0"><span class="placeholder col-8"></span></p>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" id="image-ligthbox">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body p-0">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder for image lightbox. ?>
|
||||
<img src="" style="width: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script id="order-item-row-template" type="text/x-handlebars-template">
|
||||
{{#each items}}
|
||||
<tr>
|
||||
<th class="item-name fw-normal">{{item}}{{#if qty}}<br><span class="d-flex align-items-center gap-1"><span style="font-size: 10px;">✕</span>{{qty}}{{/if}}</span></th>
|
||||
<td class="item-subtotal">{{subtotal_formatted}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</script>
|
||||
<script id="form-data-item-template" type="text/x-handlebars-template">
|
||||
{{#each datas as |data|}}
|
||||
<li class="list-group-item px-0">
|
||||
<b class="field-name">{{data.label}}</b>
|
||||
<p class="field-value mt-1 mb-0" data-field-name="{{data.name}}">
|
||||
{{data.value}}
|
||||
</p>
|
||||
</li>
|
||||
{{/each}}
|
||||
</script>
|
||||
<script id="notification-data-template" type="text/x-handlebars-template">
|
||||
{{#each datas as |row|}}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center px-0 py-3">
|
||||
<div class="notification-title">
|
||||
<p class="mb-0"><b class="notification-title">{{row.title}}</b> <?php echo esc_html__('to', 'formipay'); ?> <span class="recipient-type">{{row.recipient_type}}</span> <?php echo esc_html__('at', 'formipay'); ?> <b class="notification-date">{{row.meta_data.request_date}}</b></p>
|
||||
<span class="recipient badge text-bg-secondary rounded-pill me-1">
|
||||
{{#ifEquals row.media "email"}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">
|
||||
<g fill="#fff">
|
||||
<path d="M22 7.535V17a3 3 0 0 1-2.824 2.995L19 20H5a3 3 0 0 1-2.995-2.824L2 17V7.535l9.445 6.297l.116.066a1 1 0 0 0 .878 0l.116-.066z" />
|
||||
<path d="M19 4c1.08 0 2.027.57 2.555 1.427L12 11.797l-9.555-6.37a3 3 0 0 1 2.354-1.42L5 4z" />
|
||||
</g>
|
||||
</svg>
|
||||
{{/ifEquals}}
|
||||
{{#ifEquals row.media "whatsapp"}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">
|
||||
<path fill="#fff" d="M18.497 4.409a10 10 0 0 1-10.36 16.828l-.223-.098l-4.759.849l-.11.011a1 1 0 0 1-.11 0l-.102-.013l-.108-.024l-.105-.037l-.099-.047l-.093-.058l-.014-.011l-.012-.007l-.086-.073l-.077-.08l-.067-.088l-.056-.094l-.034-.07l-.04-.108l-.028-.128l-.012-.102a1 1 0 0 1 0-.125l.012-.1l.024-.11l.045-.122l1.433-3.304l-.009-.014A10 10 0 0 1 5.056 4.83l.215-.203a10 10 0 0 1 13.226-.217M9.5 7.5A1.5 1.5 0 0 0 8 9v1a6 6 0 0 0 6 6h1a1.5 1.5 0 0 0 0-3h-1l-.144.007a1.5 1.5 0 0 0-1.128.697l-.042.074l-.022-.007a4.01 4.01 0 0 1-2.435-2.435l-.008-.023l.075-.041A1.5 1.5 0 0 0 11 10V9a1.5 1.5 0 0 0-1.5-1.5" />
|
||||
</svg>
|
||||
{{/ifEquals}}
|
||||
<span class="recipient-text">{{row.recipient}}<span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="badge text-bg-primary rounded-pill notification-status">{{row.status}}</span>
|
||||
</li>
|
||||
{{/each}}
|
||||
</script>
|
||||
<script id="transaction-timeline-item" type="text/x-handlebars-template">
|
||||
{{#each datas as |row|}}
|
||||
<li class="rb-item" ng-repeat="itembx">
|
||||
<div class="timestamp">
|
||||
{{row.time}}
|
||||
</div>
|
||||
<div class="item-title">{{row.activity}}</div>
|
||||
{{#ifEquals row.attachment "none"}}
|
||||
{{else}}
|
||||
<div class="item-thumbnail">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder to show payment receipt. ?>
|
||||
<img src="{{row.attachment}}" alt="payment-receipt" width="250" class="timeline-item-image border border-2 border-secondary shadow-sm rounded-3">
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</script>
|
||||
<script id="thankyou-access-template" type="text/x-handlebars-template">
|
||||
<li class="list-group-item px-0 access-link">
|
||||
<b><?php echo esc_html__('Access Link', 'formipay'); ?></b>
|
||||
<div class="input-group mb-0 access-link-wrapper">
|
||||
<input type="text" class="form-control rounded-start border border-secondary-subtle" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="copy-link-access" value="{{data.link}}" readonly>
|
||||
<button class="btn btn-outline-secondary rounded-end border border-secondary-subtle formipay-copy-button" type="button" id="copy-link-access" data-copy-value="{{data.link}}" data-copied-text="<?php echo esc_html__( 'Copied', 'formipay' ); ?>" data-copy-text="<?php echo esc_html__( 'Copy', 'formipay' ); ?>" data-not-copied-text="<?php echo esc_html__( 'Failed', 'formipay' ); ?>"><i class="bi bi-copy"></i> <?php echo esc_html__( 'Copy', 'formipay' ); ?></button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item px-0 access-method" data-access-method="{{data.pass_method}}">
|
||||
<b><?php echo esc_html__('Access Method', 'formipay'); ?></b>
|
||||
<p class="mb-0">{{data.pass_method_label}}</p>
|
||||
</li>
|
||||
<li class="list-group-item px-0 access-password d-none" data-access-password="{{data.pass_word}}">
|
||||
<b><?php echo esc_html__('Access Password', 'formipay'); ?></b>
|
||||
<p class="mb-0">******</p>
|
||||
</li>
|
||||
</script>
|
||||
42
admin/page-orders.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html(FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png'); ?>" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Orders', 'formipay' ); ?></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="table-toolbar">
|
||||
<div class="post-status-wrapper">
|
||||
<input type="hidden" id="post_status" value="all">
|
||||
<a data-value="all" data-active="true"><?php echo esc_html__( 'All', 'formipay' ); ?></a><span class="all-post-count"></span> |
|
||||
<a data-value="completed"><?php echo esc_html__( 'Completed', 'formipay' ); ?></a><span class="completed-post-count"></span> |
|
||||
<a data-value="on-hold"><?php echo esc_html__( 'On-Hold', 'formipay' ); ?></a><span class="on-hold-post-count"></span>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<a id="reset-filter">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="#277aff" d="m16.325 18.8l-2.2 2.2L12 18.875l2.2-2.2q-.1-.275-.15-.575t-.05-.6q0-1.45 1.025-2.475T17.5 12q.45 0 .875.113t.8.312L16.8 14.8l1.4 1.4l2.375-2.35q.2.375.313.788T21 15.5q0 1.45-1.025 2.475T17.5 19q-.325 0-.612-.05t-.563-.15m4.45-8.8H18.7q-.65-2.2-2.475-3.6T12 5Q9.075 5 7.037 7.038T5 12q0 1.8.813 3.3T8 17.75V15h2v6H4v-2h2.35Q4.8 17.75 3.9 15.938T3 12q0-1.875.713-3.512t1.924-2.85t2.85-1.925T12 3q3.225 0 5.663 1.988T20.775 10"/></svg>
|
||||
Reset
|
||||
</a>
|
||||
<div class="product">
|
||||
<select id="products" class="form-tool"></select>
|
||||
</div>
|
||||
<div class="currency">
|
||||
<select id="currencies" class="form-tool"></select>
|
||||
</div>
|
||||
<div class="limit">
|
||||
<select id="limit" class="form-tool">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="order_id">
|
||||
<input id="order_id" class="form-tool" placeholder="Order ID">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-orders"></div>
|
||||
</div>
|
||||
81
admin/page-products.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<div class="formipay-screen-menu">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment. ?>
|
||||
<img src="<?php echo esc_html(FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white_256.png'); ?>" alt="Formipay">
|
||||
<div class="screen-title">
|
||||
<h1><?php echo esc_html__( 'Products', 'formipay' ); ?></h1>
|
||||
<a id="add-new-product">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m6 0h6m-3-3v6" />
|
||||
</svg>
|
||||
<?php echo esc_html__( 'New Product', 'formipay' ); ?>
|
||||
</a>
|
||||
<a id="form-category" href="<?php echo esc_html(admin_url('edit-tags.php?taxonomy=formipay-form-category&post_type=formipay-form')); ?>">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M10 3H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1m10 0h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1M10 13H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1m7 0a4 4 0 1 1-3.995 4.2L13 17l.005-.2A4 4 0 0 1 17 13" />
|
||||
</svg>
|
||||
<?php echo esc_html__( 'Categories', 'formipay' ); ?>
|
||||
</a>
|
||||
<button id="formipay-delete-selected" style="display:none;">
|
||||
Delete Selected
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M20 6a1 1 0 0 1 .117 1.993L20 8h-.081L19 19a3 3 0 0 1-2.824 2.995L16 22H8c-1.598 0-2.904-1.249-2.992-2.75l-.005-.167L4.08 8H4a1 1 0 0 1-.117-1.993L4 6zm-9.489 5.14a1 1 0 0 0-1.218 1.567L10.585 14l-1.292 1.293l-.083.094a1 1 0 0 0 1.497 1.32L12 15.415l1.293 1.292l.094.083a1 1 0 0 0 1.32-1.497L13.415 14l1.292-1.293l.083-.094a1 1 0 0 0-1.497-1.32L12 12.585l-1.293-1.292l-.094-.083zM14 2a2 2 0 0 1 2 2a1 1 0 0 1-1.993.117L14 4h-4l-.007.117A1 1 0 0 1 8 4a2 2 0 0 1 1.85-1.995L10 2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap">
|
||||
<div class="table-toolbar">
|
||||
<div class="post-status-wrapper">
|
||||
<input type="hidden" id="post_status" value="all">
|
||||
<a data-value="all" data-active="true"><?php echo esc_html__( 'All', 'formipay' ); ?></a><span class="all-post-count"></span> |
|
||||
<a data-value="publish"><?php echo esc_html__( 'Published', 'formipay' ); ?></a><span class="publish-post-count"></span> |
|
||||
<a data-value="draft"><?php echo esc_html__( 'Draft', 'formipay' ); ?></a><span class="draft-post-count"></span>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<a id="reset-filter">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path fill="#277aff" d="m16.325 18.8l-2.2 2.2L12 18.875l2.2-2.2q-.1-.275-.15-.575t-.05-.6q0-1.45 1.025-2.475T17.5 12q.45 0 .875.113t.8.312L16.8 14.8l1.4 1.4l2.375-2.35q.2.375.313.788T21 15.5q0 1.45-1.025 2.475T17.5 19q-.325 0-.612-.05t-.563-.15m4.45-8.8H18.7q-.65-2.2-2.475-3.6T12 5Q9.075 5 7.037 7.038T5 12q0 1.8.813 3.3T8 17.75V15h2v6H4v-2h2.35Q4.8 17.75 3.9 15.938T3 12q0-1.875.713-3.512t1.924-2.85t2.85-1.925T12 3q3.225 0 5.663 1.988T20.775 10"/></svg>
|
||||
Reset
|
||||
</a>
|
||||
<div class="currency">
|
||||
<select id="currencies" class="form-tool"></select>
|
||||
</div>
|
||||
<div class="category">
|
||||
<select id="categories" class="form-tool">
|
||||
<option value=""><?php echo esc_html__( 'All Categories', 'formipay' ); ?></option>
|
||||
<?php
|
||||
$taxonomy = 'formipay-product-category'; // Replace with your actual taxonomy
|
||||
$terms = get_terms(array(
|
||||
'taxonomy' => $taxonomy,
|
||||
'hide_empty' => false, // Set to true to hide empty categories
|
||||
));
|
||||
|
||||
if (!empty($terms) && !is_wp_error($terms)) {
|
||||
foreach ($terms as $term) {
|
||||
echo '<option value="' . intval($term->term_id) . '">' . esc_html($term->name) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="orderby">
|
||||
<select id="orderby" class="form-tool">
|
||||
<option value="ID" selected><?php echo esc_html__( 'ID', 'formipay' ); ?></option>
|
||||
<option value="title"><?php echo esc_html__( 'Title', 'formipay' ); ?></option>
|
||||
<option value="modified"><?php echo esc_html__( 'Modified Date', 'formipay' ); ?></option>
|
||||
<option value="price"><?php echo esc_html__( 'Price Amount', 'formipay' ); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="sort">
|
||||
<select id="sort_by" class="form-tool">
|
||||
<option value="desc" selected>DESC</option>
|
||||
<option value="asc">ASC</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="search">
|
||||
<input type="text" id="keyword" placeholder="Keyword" class="form-tool">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formipay-products"></div>
|
||||
|
||||
</div>
|
||||
31
admin/templates/editor-canvas-vue.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* File ini dipanggil oleh fungsi admin WordPress Anda untuk merender canvas.
|
||||
*/
|
||||
|
||||
// 1. Ambil data awal dari WordPress
|
||||
$post_id = isset($_GET['post']) ? intval($_GET['post']) : 0;
|
||||
$saved_config_json = '[]';
|
||||
if ($post_id > 0) {
|
||||
$formipay_post_meta = get_post_meta($post_id, 'formipay_settings', true);
|
||||
if (!empty($formipay_post_meta['fields'])) {
|
||||
$saved_config_json = json_encode($formipay_post_meta['fields']);
|
||||
}
|
||||
}
|
||||
|
||||
// Data yang akan kita lewatkan ke Vue
|
||||
// Menggantikan objek `formipay_admin` dari kode lama
|
||||
$vue_app_data = [
|
||||
'savedFields' => json_decode($saved_config_json), // Kirim sebagai objek, bukan string
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('formipay-secure-nonce'),
|
||||
'formId' => $post_id,
|
||||
'presets' => [
|
||||
'countryList' => your_function_to_get_countries() // Panggil fungsi PHP Anda di sini
|
||||
],
|
||||
];
|
||||
?>
|
||||
|
||||
<div id="formipay-builder-app" data-app-data='<?php echo esc_attr(json_encode($vue_app_data)); ?>'>
|
||||
<p>Loading Form Builder...</p>
|
||||
</div>
|
||||
230
admin/templates/editor-canvas.php
Normal file
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
$saved_config = [];
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if(isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] == 'edit'){
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$formipay_post_meta = get_post_meta(intval(wp_unslash($_GET['post'])), 'formipay_settings', true);
|
||||
$saved_config = $formipay_post_meta['fields'];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="d-flex mx-0 w-100">
|
||||
<div class="p-3" id="sidebar_panel">
|
||||
<input type="hidden" name="formipay_builder_canvas" value="<?php echo esc_attr( wp_create_nonce('formipay-form-builder-canvas') ) ?>">
|
||||
<div id="add_field_form"></div>
|
||||
</div>
|
||||
<div class="position-relative p-2" id="fields_panel">
|
||||
<div class="position-absolute fw-bold"><?php echo esc_html__('Preview', 'formipay'); ?></div>
|
||||
<div id="preview-wrapper" class="h-100 d-flex flex-column gap-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Config template -->
|
||||
<script id="add-field-form-template" type="text/x-handlebars-template">
|
||||
{{#each fields}}
|
||||
<div class="field mb-2{{custom_class custom_class}}{{conditional_class conditional}}"{{{display conditional}}}>
|
||||
<label for="{{id}}" class="form-label mb-0 small text-white {{#ifIn type "checkbox radio"}}d-none{{/ifIn}}">{{label}}</label>
|
||||
|
||||
{{#ifIn type "text number"}}
|
||||
<input type="{{type}}" name="{{id}}" id="{{id}}" class="form-control formipay-builder-field" value="{{default}}" />
|
||||
{{/ifIn}}
|
||||
|
||||
{{#ifEquals type "select"}}
|
||||
<select name="{{id}}" class="form-select w-100 formipay-builder-field">
|
||||
<option value="">-- Choose Type</option>
|
||||
{{#each options}}
|
||||
<option value="{{@key}}" {{selectedTheFirstOption @index}}>{{this}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
{{/ifEquals}}
|
||||
|
||||
{{#ifIn type "checkbox radio"}}
|
||||
<input type="checkbox" name="{{id}}" id="{{id}}" class="form-control formipay-builder-field" value="no" />
|
||||
<label for="{{id}}" class="form-label mb-0 small text-white">{{label}}</label>
|
||||
{{/ifIn}}
|
||||
|
||||
{{#ifEquals type "textarea"}}
|
||||
<textarea name="{{id}}" id="{{id}}" class="form-control formipay-builder-field">{{default}}</textarea>
|
||||
<p class="mb-0 option-description small text-light">{{description}}</p>
|
||||
{{/ifEquals}}
|
||||
|
||||
{{#ifEquals type "repeater"}}
|
||||
<label class="form-label mb-0 small text-white">{{label}}</label>
|
||||
<div class="d-flex flex-wrap gap-2 justify-content-start align-items-center">
|
||||
{{#each fields}}
|
||||
{{#ifEquals toggle "yes"}}
|
||||
<div class="label-field">
|
||||
<input type="checkbox" class="form-control option-field-toggle" data-child-field="{{id}}" id="repeater-child-{{@index}}_{{id}}">
|
||||
<label for="repeater-child-{{@index}}_{{id}}" class="form-label text-sm mb-0 text-white">Show {{label}}</label>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="repeater-child-wrapper">
|
||||
<div class="repeater-child-input d-flex justify-content-start align-items-start gap-2 my-2">
|
||||
<span class="grab mt-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#fff" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
||||
</svg>
|
||||
</span>
|
||||
<div class="child-fields-wrapper w-100">
|
||||
<div class="child-field-title text-bg-dark py-2 px-3 d-flex justify-content-between align-items-center">
|
||||
<div class="the_title">Option</div>
|
||||
<div class="the_buttons">
|
||||
<button class="btn btn-sm text-bg-light mb-0 add-option">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M9 18q-.825 0-1.412-.587T7 16V4q0-.825.588-1.412T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.587 1.413T18 18zm0-2h9V4H9zm-4 6q-.825 0-1.412-.587T3 20V6h2v14h11v2zm4-6V4z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm text-bg-light mb-0 delete-option">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" />
|
||||
</svg>
|
||||
</i></button>
|
||||
<button class="btn btn-sm text-bg-light mb-0 open-collapse open-option">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m12 15l-5-5h10z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="child-field-wrapper p-2 bg-light text-dark" style="display:none;">
|
||||
<div class="child-field-row row">
|
||||
<div class="child-field-image col-6 child-field-col-1 child-field-thumbnail repeater-child-input-thumbnail" style="display: none;">
|
||||
<div class="child-field-image-wrapper formipay-builder-field">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder to display an image preview and will be managed by JS ?>
|
||||
<img src="" class="d-none" style="width: 100%;" alt="Image Preview"/>
|
||||
<i data-field="field-image" class="bi bi-file-earmark-image-fill pointer fs-3 text-secondary add-thumbnail child-field-image"{{{toggleDisplay toggle}}}></i>
|
||||
<input type="hidden" class="field-image-id d-none">
|
||||
<input type="hidden" class="field-image-url d-none">
|
||||
<button data-field="field-image" class="btn btn-sm add-thumbnail bg-secondary text-white">Choose Image</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col child-field-col-2">
|
||||
<table class="table child-field-input-table">
|
||||
<tbody>
|
||||
{{#each fields}}
|
||||
{{#ifNotIn type "image toggle"}}
|
||||
<tr class="child-field-{{id}} repeater-child-input-{{id}}"{{{toggleDisplay toggle}}}>
|
||||
<th>{{label}}</th>
|
||||
<td>
|
||||
<input type="{{type}}" class="form-control formipay-builder-field formipay-builder-option-field" value="{{default}}" placeholder="{{label}}" />
|
||||
</td>
|
||||
</tr>
|
||||
{{/ifNotIn}}
|
||||
{{#ifEquals type "toggle"}}
|
||||
<tr class="child-field-{{id}}"{{{toggleDisplay toggle}}}>
|
||||
<th>{{label}}</th>
|
||||
<td>
|
||||
<div class="form-check form-switch align-items-baseline mt-2 mb-0 formipay-builder-field formipay-builder-option-field">
|
||||
<input class="form-check-input check-qty repeater-child-input-qty" type="checkbox" role="switch">
|
||||
<label class="form-check-label text-white text-nowrap"><span class="small">✕</span> Quantity</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/ifEquals}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<button type="button" class="btn btn-light add-field w-100">Add Field</button>
|
||||
</script>
|
||||
|
||||
<!-- Preview template -->
|
||||
<script id="preview-template" type="text/x-handlebars-template">
|
||||
{{#each fields}}
|
||||
{{!-- Hidden field --}}
|
||||
<div class="preview-field d-flex gap-2 align-items-center" data-field="{{field_id}}" data-field-type="{{field_type}}" {{#ifEquals field_type "hidden"}}style="opacity: .5;"{{/ifEquals}}>
|
||||
<span class="grab pb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M9 20q-.825 0-1.412-.587T7 18t.588-1.412T9 16t1.413.588T11 18t-.587 1.413T9 20m6 0q-.825 0-1.412-.587T13 18t.588-1.412T15 16t1.413.588T17 18t-.587 1.413T15 20m-6-6q-.825 0-1.412-.587T7 12t.588-1.412T9 10t1.413.588T11 12t-.587 1.413T9 14m6 0q-.825 0-1.412-.587T13 12t.588-1.412T15 10t1.413.588T17 12t-.587 1.413T15 14M9 8q-.825 0-1.412-.587T7 6t.588-1.412T9 4t1.413.588T11 6t-.587 1.413T9 8m6 0q-.825 0-1.412-.587T13 6t.588-1.412T15 4t1.413.588T17 6t-.587 1.413T15 8" />
|
||||
</svg>
|
||||
</span>
|
||||
<div class="formipay-field w-100">
|
||||
<div class="d-flex justify-content-between field-controls">
|
||||
<label for="{{field_id}}" class="{{labelClass field_type}}">{{label}}{{#ifEquals is_required "yes"}} <span style="color: red;">(*)</span>{{/ifEquals}}</label>
|
||||
<div class="field-icons d-flex gap-2 align-items-center the_buttons">
|
||||
<button class="btn btn-sm edit-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M5 19h1.425L16.2 9.225L14.775 7.8L5 17.575zm-2 2v-4.25L16.2 3.575q.3-.275.663-.425t.762-.15t.775.15t.65.45L20.425 5q.3.275.438.65T21 6.4q0 .4-.137.763t-.438.662L7.25 21zM19 6.4L17.6 5zm-3.525 2.125l-.7-.725L16.2 9.225z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-sm delete-preview-field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zm2-4h2V8H9zm4 0h2V8h-2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="{{@key}}" class="formipay-field-setup" value='{{json this}}' />
|
||||
|
||||
{{!-- Input fields --}}
|
||||
{{#ifNotEquals field_type "textarea"}}
|
||||
{{#ifIn field_type "divider page_break select checkbox radio country_list"}}
|
||||
{{#ifEquals field_type "divider"}}
|
||||
<span class="divider-line"></span>
|
||||
{{/ifEquals}}
|
||||
{{#ifEquals field_type "page_break"}}
|
||||
<span class="divider-line"></span>
|
||||
{{/ifEquals}}
|
||||
{{#ifEquals field_type "select"}}
|
||||
<select id="{{field_id}}" class="formipay-input formipay-form-field w-100">
|
||||
{{#if placeholder}}
|
||||
<option>{{placeholder}}</option>
|
||||
{{/if}}
|
||||
{{#each field_options}}
|
||||
<option value="{{this.value}}" data-calc-value="{{this.amount}}">{{this.label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
{{/ifEquals}}
|
||||
{{#ifEquals field_type "country_list"}}
|
||||
<select id="{{field_id}}" class="formipay-input formipay-form-field w-100">
|
||||
<option>-- {{placeholder}}</option>
|
||||
{{{countryListOptions}}}
|
||||
</select>
|
||||
{{/ifEquals}}
|
||||
{{#ifIn field_type "checkbox radio"}}
|
||||
<div class="formipay-checkbox-wrapper" style="grid-template-columns: repeat({{layoutColumn layout}}, 1fr);">
|
||||
{{#each field_options}}
|
||||
<div class="formipay-checkbox-group">
|
||||
{{#if image_url}}
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder to display an image preview and will be managed by JS ?>
|
||||
<img src="{{this.image_url}}" alt="{{this.label}}" style="width: 100%; height: 150px; object-fit: contain;" />
|
||||
{{/if}}
|
||||
<input type="{{../field_type}}" id="{{../config_id}}-{{@index}}" name="{{name ../field_type ../field_id @index}}" class="formipay-input formipay-form-field" value="{{this.value}}" data-calc-value="{{this.amount}}"/>
|
||||
<label for="{{../config_id}}-{{@index}}">{{this.label}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/ifIn}}
|
||||
{{else}}
|
||||
<input type="{{field_type}}" id="{{field_id}}" class="formipay-input formipay-form-field w-100" placeholder="{{placeholder}}" value="{{default_value}}" {{#ifEquals field_type "number"}}data-calc-value="{{calc_value}}"{{/ifEquals}} />
|
||||
{{/ifIn}}
|
||||
{{else}}
|
||||
{{!-- Textarea field --}}
|
||||
<textarea id="{{field_id}}" rows="4" class="formipay-input formipay-form-field w-100" placeholder="{{placeholder}}">{{default_value}}</textarea>
|
||||
{{/ifNotEquals}}
|
||||
|
||||
<p class="formipay-inline-desc">{{description}}</p>
|
||||
</div>
|
||||
{{#ifEquals field_type "page_break"}}
|
||||
<span class="scissors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="m12 14l-2.35 2.35q.2.375.275.8T10 18q0 1.65-1.175 2.825T6 22t-2.825-1.175T2 18t1.175-2.825T6 14q.425 0 .85.075t.8.275L10 12L7.65 9.65q-.375.2-.8.275T6 10q-1.65 0-2.825-1.175T2 6t1.175-2.825T6 2t2.825 1.175T10 6q0 .425-.075.85t-.275.8L20.6 18.6q.675.675.3 1.538T19.575 21q-.275 0-.537-.112t-.463-.313zm3-3l-2-2l5.575-5.575q.2-.2.463-.312T19.574 3q.95 0 1.313.875t-.313 1.55zM6 8q.825 0 1.413-.587T8 6t-.587-1.412T6 4t-1.412.588T4 6t.588 1.413T6 8m6 4.5q.2 0 .35-.15t.15-.35t-.15-.35t-.35-.15t-.35.15t-.15.35t.15.35t.35.15M6 20q.825 0 1.413-.587T8 18t-.587-1.412T6 16t-1.412.588T4 18t.588 1.413T6 20" />
|
||||
</svg>
|
||||
</span>
|
||||
{{/ifEquals}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
|
||||
48
admin/templates/paypal-instruction.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<div class="global-paypal-instruction" style="display:none;">
|
||||
<h5>Step 1: Create a PayPal Business Account</h5>
|
||||
<ul class="paypal-instruction-point">
|
||||
<li><b>Go to PayPal Website:</b> Open your web browser and go to PayPal\'s website.</li>
|
||||
<li><b>Sign Up:</b> Click on <u>Sign Up</u> in the top right corner.</li>
|
||||
<li><b>Select Business Account:</b> Choose the "Business Account" option and click <b>Continue</b>.</li>
|
||||
<li><b>Fill in Your Information:</b> Enter your email address and create a password. Follow the steps to fill in your business information (name, address, etc.).</li>
|
||||
<li><b>Complete Verification:</b> PayPal may ask you to verify your identity by confirming your email address and phone number. Follow the prompts in your email and on the website to complete this step.</li>
|
||||
</ul>
|
||||
<h5>Step 2: Access PayPal Developer Portal.</h5>
|
||||
<ul class="paypal-instruction-point">
|
||||
<li><b>Go to PayPal Developer Website:</b> Open a new browser tab and navigate to the <a href="https://developer.paypal.com/" target="_blank"><u>PayPal Developer site</u></a>.</li>
|
||||
<li><b>Log In:</b> Click “Log In to Dashboard” in the top-right corner and use your PayPal business account credentials to log in.</li>
|
||||
</ul>
|
||||
<h5>Step 3: Create PayPal REST API App</h5>
|
||||
<ul class="paypal-instruction-point">
|
||||
<li><b>Navigate to Dashboard:</b> Once logged in, you will see the Developer Dashboard.</li>
|
||||
<li><b>Click on <u>My Apps & Credentials</u></b>: Look for this option in the left sidebar.</li>
|
||||
<li><span><b>Create an App:</b></span>
|
||||
<ul>
|
||||
<li>Find the “REST API apps” section.</li>
|
||||
<li>Click the "Create App" button.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Name Your App:</b> Give your app a name (e.g., “My WordPress Store”) and click “Create App”.</li>
|
||||
<li><span><b>View Your Credentials:</b></span> Once created, you\'ll see your new app. Here you will find:
|
||||
<ul>
|
||||
<li>Client ID</li>
|
||||
<li>Secret</li>
|
||||
<li>Sandbox and Live credentials (make sure to toggle between Sandbox and Live as needed)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h5>Step 4: Gather Required Merchant Data</h5>
|
||||
<p>Now that you have created your PayPal app, you can gather the required merchant data.</p>
|
||||
<ul class="paypal-instruction-point">
|
||||
<li><b>PayPal Client ID:</b> Copy the Client ID from your app settings.</li>
|
||||
<li><b>PayPal Secret:</b> Copy the Secret from your app settings.</li>
|
||||
<li><b>PayPal Environment:</b> Decide whether you want to work in Sandbox (for testing) or Live (for actual transactions). Make a note of which environment you are using.</li>
|
||||
<li><b>Merchant Email:</b> Log in to your PayPal account and note the email address linked to your account. This is typically the email you used when signing up.</li>
|
||||
</ul>
|
||||
<h5>Final Notes</h5>
|
||||
<ul>
|
||||
<li>Keep your PayPal Client ID and Secret secure; do not share them publicly.</li>
|
||||
<li>Always test your integration in the Sandbox environment before going Live.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="connect-status"></div>
|
||||
114
admin/templates/product-variations.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<div id="product-variables-table" class="wpcfto_generic_field wpcfto_generic_field_html">
|
||||
<div class="wpcfto-field-content">
|
||||
<table class="wpcfto-table formipay-variations-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-cell="toggle">{{ product_details.variation_table.th_toggle }}</th>
|
||||
<th data-cell="name">{{ product_details.variation_table.th_name }}</th>
|
||||
<th data-cell="stock">{{ product_details.variation_table.th_stock }}</th>
|
||||
|
||||
<th data-cell="weight" v-if="isPhysical">{{ product_details.variation_table.th_weight }}</th>
|
||||
|
||||
<template v-if="pricingMethod !== 'manual'">
|
||||
<th data-cell="price">{{ product_details.variation_table.th_price }}</th>
|
||||
<th data-cell="sale">{{ product_details.variation_table.th_sale }}</th>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<th data-cell="prices">{{ product_details.variation_table.th_prices_overall }}</th>
|
||||
</template>
|
||||
|
||||
<th class="toggle-column"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-if="tableRows.length > 0">
|
||||
<template v-for="(row, idx) in tableRows">
|
||||
<tr :key="row.key" :class="['wpcfto-repeater-single', { 'variation-inactive': !row.active }]">
|
||||
|
||||
<td data-cell="toggle" style="text-align:center;">
|
||||
<label class="switch">
|
||||
<input type="checkbox" v-model="row.active" />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</td>
|
||||
|
||||
<td data-cell="name">
|
||||
<input type="text" v-model="row.name" class="wpcfto-admin-input" readonly :disabled="!row.active" />
|
||||
</td>
|
||||
|
||||
<td data-cell="stock">
|
||||
<input type="number" v-model.number="row.stock" class="wpcfto-admin-input" min="0" :placeholder="'∞'" style="width:100%;text-align:right;" :disabled="!row.active" />
|
||||
</td>
|
||||
|
||||
<td v-if="isPhysical" data-cell="weight">
|
||||
<input type="number" v-model.number="row.weight" step="0.01" style="width:100%; text-align:right;" :disabled="!row.active" />
|
||||
</td>
|
||||
|
||||
<template v-if="pricingMethod !== 'manual'">
|
||||
<td data-cell="price">
|
||||
<price-input :value="row.price" @input="row.price = $event" :currency-symbol="currencySymbol" :currency-decimal-digits="currencyDecimalDigits" :disabled="!row.active" />
|
||||
</td>
|
||||
<td data-cell="sale">
|
||||
<price-input :value="row.sale" @input="row.sale = $event" :currency-symbol="currencySymbol" :currency-decimal-digits="currencyDecimalDigits" :disabled="!row.active" />
|
||||
</td>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<td data-cell="prices" class="manual-price-hint">
|
||||
<span @click="row.expanded = !row.expanded">{{ product_details.variation_table.manual_price_hint }}</span>
|
||||
</td>
|
||||
</template>
|
||||
|
||||
<td class="toggle-column" style="text-align:center;">
|
||||
<button v-if="pricingMethod === 'manual' && row.prices.length > 0" @click="row.expanded = !row.expanded" class="button-link child-row-toggle" :class="row.expanded ? 'active' : ''" type="button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<path d="M15 12.915S12.79 15.5 12 15.5s-3-2.585-3-2.585M15 8.5s-2.21 2.585-3 2.585S9 8.5 9 8.5" />
|
||||
</g>
|
||||
</svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="pricingMethod === 'manual' && row.expanded" :key="row.key + '-details'" class="variation-details-row">
|
||||
<td :colspan="isPhysical ? 7 : 6">
|
||||
<div class="variation-details-content">
|
||||
<table class="wpcfto-table inner-table" v-if="row.prices.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ product_details.variation_table.child_th_currency }}</th>
|
||||
<th>{{ product_details.variation_table.child_th_regular }}</th>
|
||||
<th>{{ product_details.variation_table.child_th_sale }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(priceEntry, p_idx) in row.prices" :key="p_idx">
|
||||
<td>{{ priceEntry.currency.split(':::')[1] }} ({{ priceEntry.currency.split(':::')[2] || priceEntry.currency.split(':::')[0] }})</td>
|
||||
<td>
|
||||
<price-input :value="priceEntry.regular_price" @input="priceEntry.regular_price = $event" :currency-symbol="priceEntry.currency.split(':::')[2] || priceEntry.currency.split(':::')[0]" :currency-decimal-digits="parseInt(priceEntry.currency_decimal_digits)" :disabled="!row.active" />
|
||||
</td>
|
||||
<td>
|
||||
<price-input :value="priceEntry.sale_price" @input="priceEntry.sale_price = $event" :currency-symbol="priceEntry.currency.split(':::')[2] || priceEntry.currency.split(':::')[0]" :currency-decimal-digits="parseInt(priceEntry.currency_decimal_digits)" :disabled="!row.active" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p v-else style="padding: 10px; text-align:center;">{{ product_details.variation_table.no_currencies }}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
|
||||
<tbody v-else>
|
||||
<tr>
|
||||
<td :colspan="isPhysical ? 7 : 6" style="text-align:center;color:#8c99a5;">
|
||||
{{ product_details.variation_table.no_variations }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="product_variables" v-model="jsonValue" />
|
||||
</div>
|
||||
</div>
|
||||
57
formipay.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Formipay
|
||||
* Description: -
|
||||
* Version: 1.0.0
|
||||
* Plugin URI: https://formipay.com/
|
||||
* Author: Formipay
|
||||
* Text Domain: formipay
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
|
||||
*
|
||||
* Requires at least: 6.2
|
||||
* Tested up to: 6.8.1
|
||||
*
|
||||
* Copyright: © 2023 Formipay.
|
||||
* License: GNU General Public License v3.0
|
||||
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
define( 'FORMIPAY_NAME', 'Formipay' );
|
||||
define( 'FORMIPAY_VERSION', '1.0.0' );
|
||||
define( 'FORMIPAY_PATH', plugin_dir_path( __FILE__ ) );
|
||||
define( 'FORMIPAY_URL', plugin_dir_url( __FILE__ ) );
|
||||
|
||||
require_once FORMIPAY_PATH . 'admin/functions.php';
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
$prefix = 'Formipay\\';
|
||||
$base_dir = __DIR__ . '/includes/';
|
||||
|
||||
// Check if the class uses the plugin's namespace
|
||||
if (strpos($class, $prefix) !== 0) return;
|
||||
|
||||
// Remove namespace prefix
|
||||
$relative_class = substr($class, strlen($prefix));
|
||||
|
||||
// Convert namespace to file path
|
||||
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
|
||||
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
});
|
||||
|
||||
\Formipay\Init::get_instance();
|
||||
|
||||
// function formipay_add_defer_attribute($tag, $handle) {
|
||||
// if ( 'product-details' === $handle ) {
|
||||
// // Add defer attribute
|
||||
// return str_replace( '<script ', '<script defer ', $tag );
|
||||
// }
|
||||
// return $tag;
|
||||
// }
|
||||
// add_filter( 'script_loader_tag', 'formipay_add_defer_attribute', 10, 2 );
|
||||
BIN
includes/.DS_Store
vendored
Normal file
721
includes/Access.php
Normal file
@@ -0,0 +1,721 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Access {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'cpt'] );
|
||||
add_action( 'admin_menu', [$this, 'add_submenu'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_admin'] );
|
||||
|
||||
add_filter( 'stm_wpcfto_boxes', [$this, 'cpt_post_fields_box'] );
|
||||
add_filter( 'stm_wpcfto_fields', [$this, 'cpt_post_fields_content'] );
|
||||
add_filter( 'formipay/product-config', [$this, 'product_config'], 50 );
|
||||
add_filter( 'formipay/access-config', [$this, 'source_config'] );
|
||||
add_filter( 'formipay/access-config', [$this, 'details_config'] );
|
||||
|
||||
// Admin Page
|
||||
add_action( 'wp_ajax_formipay_access_items_get_products', [$this, 'formipay_access_items_get_products'] );
|
||||
add_action( 'wp_ajax_formipay-tabledata-access-items', [$this, 'formipay_tabledata_access_items'] );
|
||||
add_action( 'wp_ajax_formipay-create-access-item-post', [$this, 'formipay_create_access_item_post'] );
|
||||
add_action( 'wp_ajax_formipay-delete-access-item', [$this, 'formipay_delete_access_item'] );
|
||||
add_action( 'wp_ajax_formipay-bulk-delete-access-item', [$this, 'formipay_bulk_delete_access_item'] );
|
||||
add_action( 'wp_ajax_formipay-duplicate-access-item', [$this, 'formipay_duplicate_access_item'] );
|
||||
|
||||
}
|
||||
|
||||
public function cpt() {
|
||||
|
||||
$labels = array(
|
||||
'name' => __('Access Items', 'formipay'),
|
||||
'singular_name' => __('Access Item', 'formipay'),
|
||||
'add_new' => __('Add New', 'formipay'),
|
||||
'add_new_item' => __('Add New Access Item', 'formipay'),
|
||||
'edit' => __('Edit', 'formipay'),
|
||||
'edit_item' => __('Edit Access Item', 'formipay'),
|
||||
'new_item' => __('New Access Item', 'formipay'),
|
||||
'view' => __('View', 'formipay'),
|
||||
'view_item' => __('View Access Item', 'formipay'),
|
||||
'search_items' => __('Search Access Item', 'formipay'),
|
||||
'not_found' => __('No access items found', 'formipay'),
|
||||
'not_found_in_trash' => __('No access items found in trash', 'formipay'),
|
||||
'parent' => __('Access Item Parent', 'formipay')
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => 'Formipay Access',
|
||||
'description' => __('The items your buyer will get after purchase.', 'formipay'),
|
||||
'labels' => $labels,
|
||||
'public' => false,
|
||||
'supports' => array( 'title' ),
|
||||
'hierarchical' => false,
|
||||
'has_archive' => false,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => false,
|
||||
'show_in_rest' => false,
|
||||
'query_var' => true
|
||||
);
|
||||
|
||||
register_post_type( 'formipay-access', $args );
|
||||
|
||||
}
|
||||
|
||||
public function add_submenu() {
|
||||
|
||||
add_submenu_page(
|
||||
'formipay',
|
||||
__( 'Access Items', 'formipay' ),
|
||||
__( 'Access Items', 'formipay' ),
|
||||
'manage_options',
|
||||
'formipay-access-items',
|
||||
[$this, 'formipay_access_items']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function formipay_access_items() {
|
||||
include_once FORMIPAY_PATH . 'admin/page-access-items.php';
|
||||
}
|
||||
|
||||
public function enqueue_admin() {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Check that we are on the 'Checker' post editor screen
|
||||
if ( $screen->post_type === 'formipay-access' && $screen->base === 'post' ) {
|
||||
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION );
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
|
||||
wp_localize_script( 'sweetalert2', 'formipay_admin', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-access-items') {
|
||||
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], 'all');
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.mermaid.min.css', [], '6.2.0', 'all' );
|
||||
wp_enqueue_style( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'page-access-items', FORMIPAY_URL . 'admin/assets/css/page-access-items.css', [], FORMIPAY_VERSION, 'all' );
|
||||
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
|
||||
wp_enqueue_script( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/js/admin-pages.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.production.min.js', ['jquery'], '6.2.0', true );
|
||||
wp_enqueue_script( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.js', [], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'page-access-items', FORMIPAY_URL . 'admin/assets/js/page-access-items.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
|
||||
wp_localize_script( 'page-access-items', 'formipay_access_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'title' => esc_html__( 'Title', 'formipay' ),
|
||||
'type' => esc_html__( 'Type', 'formipay' ),
|
||||
'products' => esc_html__( 'Product Relation', 'formipay' ),
|
||||
'status' => esc_html__( 'Status', 'formipay' ),
|
||||
],
|
||||
'filter_form' => [
|
||||
'products' => [
|
||||
'placeholder' => esc_html__( 'Filter by Product', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
]
|
||||
],
|
||||
'modal' => [
|
||||
'add' => [
|
||||
'title' => esc_html__( 'Your New Item Title', 'formipay' ),
|
||||
'validation' => esc_html__( 'Item\'s title is still empty. Please input the title before continue', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Create New Item', 'formipay' )
|
||||
],
|
||||
'delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the item?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
|
||||
],
|
||||
'bulk_delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the selected the form(s)?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
'duplicate' => [
|
||||
'question' => esc_html__( 'Do you want to duplicate the item?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-admin-access-nonce')
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function cpt_post_fields_box($boxes) {
|
||||
$boxes['formipay_access_settings'] = array(
|
||||
'post_type' => array('formipay-access'),
|
||||
'label' => __('Details', 'formipay'),
|
||||
);
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
public function cpt_post_fields_content($fields) {
|
||||
|
||||
$fields['formipay_access_settings'] = array();
|
||||
|
||||
$fields = apply_filters( 'formipay/access-config', $fields );
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function product_config($fields){
|
||||
|
||||
// Product Access Group
|
||||
|
||||
$product_access_group = array(
|
||||
'setting_product_access' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Digital Accesses', 'formipay' ),
|
||||
'description' => __( 'List files & URLs that buyer can get after complete the transaction', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'product_accesses' => array(
|
||||
'type' => 'autocomplete',
|
||||
'label' => __( 'Accesses', 'formipay' ),
|
||||
'post_type' => array('formipay-access'),
|
||||
'limit' => 10
|
||||
),
|
||||
'product_access_to_email' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Send Access Magic Link to Email', 'formipay' ),
|
||||
)
|
||||
);
|
||||
|
||||
$product_access_group = apply_filters( 'formipay/product-settings/tab:access/group:product-access', $product_access_group );
|
||||
|
||||
$last_product_access_group = array_key_last($product_access_group);
|
||||
$product_access_group[$last_product_access_group]['group'] = 'ended';
|
||||
|
||||
$product_access_group = apply_filters( 'formipay/product-settings/tab:access', $product_access_group );
|
||||
|
||||
$fields['formipay_product_settings']['access'] = array(
|
||||
'name' => __( 'Access', 'formipay' ),
|
||||
'fields' => $product_access_group
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function source_config($fields) {
|
||||
|
||||
$get_attachments = get_posts([
|
||||
'post_type' => 'attachment',
|
||||
'posts_per_page' => -1
|
||||
]);
|
||||
|
||||
$attachments = [];
|
||||
if(!empty($get_attachments)){
|
||||
foreach($get_attachments as $attachment){
|
||||
$attachments[$attachment->ID] = get_the_title($attachment->ID) . ' (' . $attachment->post_mime_type . ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Group : Fields
|
||||
$field_group = array(
|
||||
'file_url_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Source', 'formipay' ),
|
||||
'description' => __( 'Define the source of this access.', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'access_type' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Type', 'formipay' ),
|
||||
'options' => array(
|
||||
'document' => __( 'Document', 'formipay' ),
|
||||
'redirect' => __( 'Redirect URL', 'formipay' ),
|
||||
'download' => __( 'File', 'formipay' )
|
||||
),
|
||||
'value' => 'document'
|
||||
),
|
||||
'access_document' => array(
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Document', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'document'
|
||||
),
|
||||
),
|
||||
'access_redirect_url' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'URL', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'redirect'
|
||||
),
|
||||
'value' => 'https://'
|
||||
),
|
||||
'access_download_source' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'File Source', 'formipay' ),
|
||||
'options' => array(
|
||||
'wp_media' => __( 'WP Media', 'formipay' ),
|
||||
'external' => __( 'External', 'formipay' )
|
||||
),
|
||||
'dependency' => array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'download'
|
||||
),
|
||||
'value' => 'wp_media'
|
||||
),
|
||||
'access_attachment' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Select File', 'formipay' ),
|
||||
'options' => $attachments,
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'download'
|
||||
),
|
||||
array(
|
||||
'key' => 'access_download_source',
|
||||
'value' => 'wp_media'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&'
|
||||
),
|
||||
'access_url' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'File URL', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'download'
|
||||
),
|
||||
array(
|
||||
'key' => 'access_download_source',
|
||||
'value' => 'external'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'value' => 'https://'
|
||||
)
|
||||
);
|
||||
|
||||
$field_group = apply_filters( 'formipay/access-settings/tab:source/group:source', $field_group );
|
||||
|
||||
$last_field_group = array_key_last($field_group);
|
||||
$field_group[$last_field_group]['group'] = 'ended';
|
||||
|
||||
$button_group = array(
|
||||
'button_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Action Button', 'formipay' ),
|
||||
'description' => __( 'Set your action button for this access', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'button_text' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Button Text', 'formipay' ),
|
||||
'value' => __( 'Download', 'formipay' ),
|
||||
)
|
||||
);
|
||||
|
||||
$button_group = apply_filters( 'formipay/access-settings/tab:source/group:source', $button_group );
|
||||
|
||||
$last_button_group = array_key_last($button_group);
|
||||
$button_group[$last_button_group]['group'] = 'ended';
|
||||
|
||||
$all_group_merged = array_merge($field_group, $button_group);
|
||||
|
||||
$settings_all_fields = apply_filters( 'formipay/access-settings/tab:source', $all_group_merged );
|
||||
|
||||
$fields['formipay_access_settings']['source'] = array(
|
||||
'name' => __('Source', 'formipay'),
|
||||
'fields' => $settings_all_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function details_config($fields) {
|
||||
|
||||
// Group : Fields
|
||||
$field_group = array(
|
||||
'details_access_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Details', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'details_icon' => array(
|
||||
'type' => 'image',
|
||||
'label' => __( 'Custom Thumbnail', 'formipay' ),
|
||||
'description' => __( 'Please note this will be displayed in approx. 36x36 pixels', 'formipay' ),
|
||||
),
|
||||
'details_filetype' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'File Type', 'formipay' ),
|
||||
'description' => __( 'Example: zip for yourfile.zip.', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'download',
|
||||
'section' => 'source'
|
||||
),
|
||||
array(
|
||||
'key' => 'access_download_source',
|
||||
'value' => 'external',
|
||||
'section' => 'source'
|
||||
),
|
||||
),
|
||||
'dependencies' => '&&'
|
||||
),
|
||||
'details_filesize' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('File Size', 'formipay'),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'access_type',
|
||||
'value' => 'download',
|
||||
'section' => 'source'
|
||||
),
|
||||
array(
|
||||
'key' => 'access_download_source',
|
||||
'value' => 'external',
|
||||
'section' => 'source'
|
||||
),
|
||||
),
|
||||
'dependencies' => '&&'
|
||||
),
|
||||
'details_short_description' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Short Description', 'formipay' ),
|
||||
'description' => __( 'You may put some important note to your buyer about this access', 'formipay' )
|
||||
)
|
||||
);
|
||||
|
||||
$field_group = apply_filters( 'formipay/access-settings/tab:details/group:file-information', $field_group );
|
||||
|
||||
$last_field_group = array_key_last($field_group);
|
||||
$field_group[$last_field_group]['group'] = 'ended';
|
||||
|
||||
$details_all_fields = apply_filters( 'formipay/access-settings/tab:details', $field_group );
|
||||
|
||||
$fields['formipay_access_settings']['details'] = array(
|
||||
'name' => __('Details', 'formipay'),
|
||||
'fields' => $details_all_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function formipay_tabledata_access_items() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', '_wpnonce' );
|
||||
|
||||
$args = [
|
||||
'post_type' => 'formipay-access',
|
||||
'posts_per_page' => -1,
|
||||
'post_status' => array( 'pending', 'draft', 'publish' )
|
||||
];
|
||||
|
||||
if(!empty($_REQUEST['post_status']) && 'all' !== $_REQUEST['post_status']){
|
||||
$args['post_status'] = [ sanitize_text_field( wp_unslash( $_REQUEST['post_status'] ) ) ];
|
||||
}
|
||||
|
||||
if(!empty($_REQUEST['product'])){
|
||||
$product_id = intval($_REQUEST['product']);
|
||||
$access_items_ids = formipay_get_post_meta($product_id, 'product_accesses');
|
||||
$access_items_ids = explode(',', $access_items_ids);
|
||||
$args['post__in'] = $access_items_ids;
|
||||
}
|
||||
|
||||
$get_total_access_items = get_posts($args);
|
||||
|
||||
if(isset($_REQUEST['limit'])){
|
||||
$args['posts_per_page'] = intval($_REQUEST['limit']);
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['offset'])){
|
||||
$args['offset'] = intval($_REQUEST['offset']);
|
||||
}
|
||||
|
||||
if(!empty($_REQUEST['search'])){
|
||||
$args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
|
||||
}
|
||||
|
||||
if(!empty($_REQUEST['sort']) && !empty($_REQUEST['orderby'])){
|
||||
$args['order'] = sanitize_text_field( wp_unslash($_REQUEST['sort']) );
|
||||
$args['orderby'] = sanitize_text_field( wp_unslash($_REQUEST['orderby']) );
|
||||
}
|
||||
|
||||
$get_access_items = get_posts($args);
|
||||
|
||||
// All Forms
|
||||
$forms = get_posts([
|
||||
'post_type' => 'formipay-form',
|
||||
'posts_per_page' => -1,
|
||||
]);
|
||||
|
||||
$access_items = [];
|
||||
if(!empty($get_access_items)){
|
||||
foreach($get_access_items as $access){
|
||||
|
||||
$product_titles = [];
|
||||
if(!empty($forms)){
|
||||
foreach($forms as $form){
|
||||
$form_id = $form->ID;
|
||||
$accesses = explode(',', formipay_get_post_meta($form_id, 'product_accesses'));
|
||||
if(in_array($access->ID, $accesses)){
|
||||
$product_titles[] = get_the_title($form_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$access_items[] = [
|
||||
'ID' => $access->ID,
|
||||
'title' => get_the_title($access->ID),
|
||||
'type' => ucfirst(formipay_get_post_meta($access->ID, 'access_type')),
|
||||
'products' => $product_titles,
|
||||
'status' => $access->post_status
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Get status counts using WordPress API
|
||||
$counts = wp_count_posts('formipay-access');
|
||||
$status_counts = [];
|
||||
foreach ($counts as $status => $count) {
|
||||
$status_counts[$status] = $count;
|
||||
}
|
||||
$status_counts['all'] = array_sum($status_counts);
|
||||
|
||||
$response = [
|
||||
'results' => $access_items,
|
||||
'total' => count($get_total_access_items), // Total number of forms
|
||||
'posts_report' => array_map('intval', (array)$status_counts)
|
||||
];
|
||||
|
||||
wp_send_json($response);
|
||||
}
|
||||
|
||||
public function formipay_access_items_get_products() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );
|
||||
|
||||
if (!isset($_POST['search']) || empty($_POST['search'])) {
|
||||
wp_send_json_error( __('No search term provided.', 'formipay') );
|
||||
}
|
||||
|
||||
$search_term = sanitize_text_field( wp_unslash( $_POST['search'] ));
|
||||
|
||||
$query = get_posts([
|
||||
'post_type' => 'formipay-form',
|
||||
's' => $search_term,
|
||||
'posts_per_page' => -1,
|
||||
]);
|
||||
|
||||
$results = [];
|
||||
if(!empty($query)){
|
||||
foreach($query as $post){
|
||||
$results[] = [
|
||||
'value' => $post->ID,
|
||||
'label' => $post->post_title,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json($results);
|
||||
|
||||
}
|
||||
|
||||
public function formipay_create_access_item_post() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );
|
||||
|
||||
if( !empty($_REQUEST['title']) ){
|
||||
$title = sanitize_text_field( wp_unslash($_REQUEST['title']) );
|
||||
$post_id = wp_insert_post( [
|
||||
'post_title' => $title,
|
||||
'post_type' => 'formipay-access',
|
||||
], true );
|
||||
|
||||
if(is_wp_error($post_id)){
|
||||
wp_send_json_error( [
|
||||
'message' => $post_id->get_error_message()
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'edit_post_url' => admin_url('post.php?post='.$post_id.'&action=edit')
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_error( [
|
||||
'message' => esc_html__( 'Item\'s title is empty.', 'formipay' )
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_delete_access_item() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );
|
||||
|
||||
if( empty($_REQUEST['id']) ){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'Failed to delete item. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$post_id = intval($_REQUEST['id']);
|
||||
$delete = wp_delete_post($post_id, true);
|
||||
|
||||
if(is_wp_error( $delete )){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'Failed to delete item. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Deleted', 'formipay' ),
|
||||
'message' => esc_html__( 'Item is deleted permanently.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_bulk_delete_access_item() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );
|
||||
|
||||
if( empty($_REQUEST['ids']) ){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'There is no access item selected. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : [];
|
||||
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
$report = __( 'Done.', 'formipay' );
|
||||
if(!empty($ids)){
|
||||
foreach($ids as $id){
|
||||
$delete = wp_delete_post($id, true);
|
||||
if(is_wp_error( $delete )){
|
||||
$failed++;
|
||||
}else{
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($success > 0){
|
||||
$report .= sprintf( __( ' Deleted %d item(s).', 'formipay' ), $success);
|
||||
}
|
||||
if($failed > 0){
|
||||
$report .= sprintf( __( ' Failed %d item(s).', 'formipay' ), $failed);
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Done!', 'formipay' ),
|
||||
'message' => $report,
|
||||
'icon' => 'info'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_duplicate_access_item() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-access-nonce', 'nonce' );
|
||||
|
||||
if( empty($_REQUEST['id']) ){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Item is not defined.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$post_id = intval($_REQUEST['id']);
|
||||
$post = get_post($post_id);
|
||||
if (!$post) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Item is not defined.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
// Pastikan hanya tipe posting yang bisa diduplikasi
|
||||
if (!in_array($post->post_type, ['formipay-access'])) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Wrong Post Type.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
// Buat duplikat post
|
||||
$duplicate_post = [
|
||||
'post_title' => $post->post_title . ' (Copy)',
|
||||
'post_content' => $post->post_content,
|
||||
'post_status' => 'draft', // Set sebagai draft
|
||||
'post_type' => $post->post_type,
|
||||
'post_author' => $post->post_author,
|
||||
];
|
||||
|
||||
// Masukkan duplikat ke database
|
||||
$new_post_id = wp_insert_post($duplicate_post);
|
||||
|
||||
if (is_wp_error($new_post_id)) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Something happened. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
// Salin semua meta data
|
||||
$meta_data = get_post_meta($post_id);
|
||||
foreach ($meta_data as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
update_post_meta($new_post_id, $key, maybe_unserialize($value));
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__('Duplicated!', 'formipay'),
|
||||
'message' => esc_html__( 'Form is successfully duplicated.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
768
includes/Coupon.php
Normal file
@@ -0,0 +1,768 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Coupon {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'cpt'] );
|
||||
add_action( 'admin_menu', [$this, 'add_submenu'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_admin'] );
|
||||
|
||||
add_filter( 'stm_wpcfto_boxes', [$this, 'cpt_post_fields_box'] );
|
||||
add_filter( 'stm_wpcfto_fields', [$this, 'cpt_post_fields_content'] );
|
||||
add_filter( 'formipay/coupon-config', [$this, 'rule_config'] );
|
||||
add_filter( 'formipay/coupon-config', [$this, 'restriction_config'] );
|
||||
add_filter( 'formipay/admin-editor/layout/static-elements-sort', [$this, 'add_static_element'] );
|
||||
add_action( 'formipay/render/static-element', [$this, 'render_static_element'] );
|
||||
|
||||
add_action( 'wp_ajax_check_coupon_code', [$this, 'check_coupon_code'] );
|
||||
add_action( 'wp_ajax_nopriv_check_coupon_code', [$this, 'check_coupon_code'] );
|
||||
|
||||
// Admin Page
|
||||
add_action( 'wp_ajax_formipay_coupon_get_products', [$this, 'formipay_coupon_get_products'] );
|
||||
add_action( 'wp_ajax_formipay-tabledata-coupons', [$this, 'formipay_tabledata_coupons'] );
|
||||
add_action( 'wp_ajax_formipay-create-coupon-post', [$this, 'formipay_create_coupon_post'] );
|
||||
add_action( 'wp_ajax_formipay-delete-coupon', [$this, 'formipay_delete_coupon'] );
|
||||
add_action( 'wp_ajax_formipay-bulk-delete-coupon', [$this, 'formipay_bulk_delete_coupon'] );
|
||||
add_action( 'wp_ajax_formipay-duplicate-coupon', [$this, 'formipay_duplicate_coupon'] );
|
||||
|
||||
// Order
|
||||
add_filter( 'formipay/order/order-details', [$this, 'order_details'], 99, 3 );
|
||||
// Paypal
|
||||
add_filter( 'formipay/order/paypal/payload/breakdown', [$this, 'add_discount_item'], 99, 3 );
|
||||
|
||||
}
|
||||
|
||||
public function cpt() {
|
||||
|
||||
$labels = array(
|
||||
'name' => __('Coupons', 'formipay'),
|
||||
'singular_name' => __('Coupon', 'formipay'),
|
||||
// 'menu_name' => 'Formipay',
|
||||
'add_new' => __('Add New', 'formipay'),
|
||||
'add_new_item' => __('Add New Coupon', 'formipay'),
|
||||
'edit' => __('Edit', 'formipay'),
|
||||
'edit_item' => __('Edit Coupon', 'formipay'),
|
||||
'new_item' => __('New Coupon', 'formipay'),
|
||||
'view' => __('View', 'formipay'),
|
||||
'view_item' => __('View Coupon', 'formipay'),
|
||||
'search_items' => __('Search Coupon', 'formipay'),
|
||||
'not_found' => __('No coupons found', 'formipay'),
|
||||
'not_found_in_trash' => __('No coupons found in trash', 'formipay'),
|
||||
'parent' => __('Coupon Parent', 'formipay')
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => 'Coupons',
|
||||
'description' => __('Coupon for marketing campaign', 'formipay'),
|
||||
'labels' => $labels,
|
||||
'public' => false,
|
||||
'supports' => array( 'title' ),
|
||||
'hierarchical' => false,
|
||||
'has_archive' => false,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => false,
|
||||
'show_in_rest' => false,
|
||||
'query_var' => true
|
||||
);
|
||||
|
||||
register_post_type( 'formipay-coupon', $args );
|
||||
|
||||
}
|
||||
|
||||
public function add_submenu() {
|
||||
|
||||
add_submenu_page(
|
||||
'formipay',
|
||||
__( 'Coupons', 'formipay' ),
|
||||
__( 'Coupons', 'formipay' ),
|
||||
'manage_options',
|
||||
'formipay-coupons',
|
||||
[$this, 'formipay_coupon'],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function formipay_coupon() {
|
||||
include_once FORMIPAY_PATH . 'admin/page-coupons.php';
|
||||
}
|
||||
|
||||
public function enqueue_admin() {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-coupons') {
|
||||
|
||||
wp_enqueue_style( 'page-coupons', FORMIPAY_URL . 'admin/assets/css/page-coupons.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'page-coupons', FORMIPAY_URL . 'admin/assets/js/page-coupons.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
|
||||
wp_localize_script( 'page-coupons', 'formipay_coupons_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'code' => esc_html__( 'Coupon Code', 'formipay' ),
|
||||
'products' => esc_html__( 'Product Relation', 'formipay' ),
|
||||
'usages' => esc_html__( 'Usages', 'formipay' ),
|
||||
'date_limit' => esc_html__( 'Date Limit', 'formipay' ),
|
||||
'status' => esc_html__( 'Status', 'formipay' ),
|
||||
'type' => esc_html__( 'Type', 'formipay' ),
|
||||
'amount' => esc_html__( 'Amount', 'formipay' )
|
||||
],
|
||||
'filter_form' => [
|
||||
'products' => [
|
||||
'placeholder' => esc_html__( 'Filter by Product', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
]
|
||||
],
|
||||
'modal' => [
|
||||
'add' => [
|
||||
'title' => esc_html__( 'Your New Coupon Code', 'formipay' ),
|
||||
'validation' => esc_html__( 'Coupon code is still empty. Please input the code before continue', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Create New Coupon', 'formipay' )
|
||||
],
|
||||
'delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the coupon?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
|
||||
],
|
||||
'bulk_delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the selected the coupon(s)?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
'duplicate' => [
|
||||
'question' => esc_html__( 'Do you want to duplicate the coupon?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-admin-coupon-page')
|
||||
] );
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( $screen->post_type === 'formipay-coupon' && $screen->base === 'post' ) {
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
|
||||
wp_localize_script( 'sweetalert2', 'formipay_admin', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
] );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function cpt_post_fields_box($boxes) {
|
||||
$boxes['formipay_coupon_settings'] = array(
|
||||
'post_type' => array('formipay-coupon'),
|
||||
'label' => __('Details', 'formipay'),
|
||||
);
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
public function cpt_post_fields_content($fields) {
|
||||
|
||||
$fields['formipay_coupon_settings'] = array();
|
||||
|
||||
$fields = apply_filters( 'formipay/coupon-config', $fields );
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function rule_config($fields) {
|
||||
|
||||
// Group : Rules
|
||||
$rules_group = array(
|
||||
'active' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Active this coupon', 'formipay' ),
|
||||
'value' => true
|
||||
),
|
||||
'rules_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Rules', 'formipay' ),
|
||||
'description' => __( 'Define the rules of this coupon.', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'case_sensitive' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Case Sensitive', 'formipay' ),
|
||||
'description' => __( 'If this activated, coupon codes must be entered with the exact capitalization as specified. <br>
|
||||
For example code <B>SAVE10</b>:<br>
|
||||
- <b>SAVE10</b> is valid<br>
|
||||
- <b>save10</b> is invalid<br>
|
||||
- <b>Save10</b> is invalid.', 'formipay' )
|
||||
),
|
||||
'type' => array(
|
||||
'type' => 'radio',
|
||||
'label' => __( 'Type', 'formipay' ),
|
||||
'options' => array(
|
||||
'fixed' => __( 'Fixed', 'formipay' ),
|
||||
'percentage' => __( 'Percentage', 'formipay' )
|
||||
)
|
||||
),
|
||||
'amount' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Amount', 'formipay' ),
|
||||
'description' => sprintf('<span style="color: red;">' . __( 'Be carefully, this amount is not regarding the currency.', 'formipay') . '</span>' )
|
||||
),
|
||||
'free_shipping' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Free Shipping', 'formipay' ),
|
||||
'description' => __( 'Shipping cost will be free when this coupon applied.', 'formipay' )
|
||||
),
|
||||
'quantity_active' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Influenced by Quantity', 'formipay' ),
|
||||
'description' => __( 'Example: when buyer buy 4 pcs of item, 4 × discount amount will be implemented.', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'type',
|
||||
'value' => 'fixed'
|
||||
)
|
||||
),
|
||||
'max_discount' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Max Discount Amount', 'formipay' ),
|
||||
'description' => __( 'Leave it empty to not limit the max discount amount.', 'formipay' )
|
||||
),
|
||||
);
|
||||
|
||||
$rules_group = apply_filters( 'formipay/coupon-settings/tab:rules/group:rules', $rules_group );
|
||||
|
||||
$last_rules_group = array_key_last($rules_group);
|
||||
$rules_group[$last_rules_group]['group'] = 'ended';
|
||||
|
||||
$all_group_merged = $rules_group;
|
||||
|
||||
$settings_all_fields = apply_filters( 'formipay/coupon-settings/tab:rules', $all_group_merged );
|
||||
|
||||
$settings_fields = [];
|
||||
if(!empty($settings_all_fields)){
|
||||
foreach($settings_all_fields as $key => $value){
|
||||
$settings_fields[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$fields['formipay_coupon_settings']['rules'] = array(
|
||||
'name' => __('Rules', 'formipay'),
|
||||
'fields' => $settings_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function restriction_config($fields) {
|
||||
|
||||
// Group : Restrictions
|
||||
$restriction_group = array(
|
||||
'restriction_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Restrictions', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'use_limit' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Usage Limit', 'formipay' ),
|
||||
'description' => __( 'Leave it empty or 0 (zero) to set it as unlimited usage.', 'formipay' )
|
||||
),
|
||||
'date_limit' => array(
|
||||
'type' => 'date',
|
||||
'label' => __( 'Date Limit', 'formipay' ),
|
||||
'description' => __( 'Chosen date is the last day the coupon can be used. Leave it empty tio set it as no-limit date.', 'formipay' )
|
||||
),
|
||||
'forms' => array(
|
||||
'type' => 'autocomplete',
|
||||
'post_type' => array('formipay-form'),
|
||||
'label' => __( 'These forms can use the coupon', 'formipay' ),
|
||||
'description' => __( 'Leave it empty to enable all forms to use this coupon. <span style="color: red;">Please be carefully, this coupon amount is not regarding the currency of the selected form.</span>', 'formipay' )
|
||||
)
|
||||
);
|
||||
|
||||
$restriction_group = apply_filters( 'formipay/coupon-settings/tab:restriction/group:restrictions', $restriction_group );
|
||||
|
||||
$last_restriction_group = array_key_last($restriction_group);
|
||||
$restriction_group[$last_restriction_group]['group'] = 'ended';
|
||||
|
||||
$details_all_fields = apply_filters( 'formipay/coupon-settings/tab:restriction', $restriction_group );
|
||||
|
||||
$details_fields = [];
|
||||
if(!empty($details_all_fields)){
|
||||
foreach($details_all_fields as $key => $value){
|
||||
$details_fields[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$fields['formipay_coupon_settings']['restriction'] = array(
|
||||
'name' => __('Restrictions', 'formipay'),
|
||||
'fields' => $details_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_static_element($elements) {
|
||||
|
||||
$elements[] = [
|
||||
'id' => 'coupon_field',
|
||||
'label' => __( 'Coupon Field', 'formipay' )
|
||||
];
|
||||
|
||||
return $elements;
|
||||
|
||||
}
|
||||
|
||||
public function render_static_element($element_id) {
|
||||
|
||||
if($element_id == 'coupon_field'){
|
||||
?>
|
||||
<div class="formipay-field-group">
|
||||
<div class="formipay-coupon-field-group">
|
||||
<input type="text" name="coupon_code"
|
||||
class="formipay-input formipay-code-input"
|
||||
value="<?php echo
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['coupon']) ? esc_attr( sanitize_text_field( wp_unslash($_GET['coupon']) ) ) : ''
|
||||
?>" placeholder="<?php echo esc_attr__('Your coupon code', 'formipay'); ?>"
|
||||
data-label="<?php echo esc_attr__('Coupon Code', 'formipay'); ?>">
|
||||
<button type="button" data-text="<?php echo esc_attr__( 'Apply', 'formipay' ); ?>" data-checking="<?php echo esc_attr__( 'Checking...', 'formipay' ); ?>" id="apply_coupon_code"><?php echo esc_attr__( 'Apply', 'formipay' ); ?></button>
|
||||
</div>
|
||||
<div class="formipay-coupon-alert-message"></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function check_coupon_code() {
|
||||
|
||||
check_ajax_referer( 'formipay-frontend-nonce', 'security' );
|
||||
|
||||
$code = isset($_REQUEST['code']) ? sanitize_text_field( wp_unslash($_REQUEST['code']) ) : '';
|
||||
$form_id = isset($_REQUEST['form']) ? intval( $_REQUEST['form'] ) : 0;
|
||||
|
||||
$check_code = formipay_get_coupon_id_by_code($code, $form_id);
|
||||
|
||||
if(false == $check_code){
|
||||
wp_send_json_error( [
|
||||
'message' => __( 'Coupon code is not valid', 'formipay' )
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
|
||||
}
|
||||
|
||||
public function order_details($details, $form_id, $order_data) {
|
||||
|
||||
if( isset($order_data['coupon_code']) && !empty($order_data['coupon_code']) ) {
|
||||
|
||||
$coupon_id = formipay_get_coupon_id_by_code( sanitize_text_field( $order_data['coupon_code'] ), $form_id );
|
||||
|
||||
if(false !== $coupon_id) {
|
||||
|
||||
$amount = floatval( formipay_get_post_meta( $coupon_id, 'amount' ) );
|
||||
$discount = $amount;
|
||||
$coupon_type = formipay_get_post_meta( $coupon_id, 'type' );
|
||||
|
||||
$qty = 1;
|
||||
if( formipay_get_post_meta( $form_id, 'product_quantity_toggle' ) == 'on' ){
|
||||
$qty = intval($order_data['qty']);
|
||||
}
|
||||
|
||||
if( $coupon_type == 'percentage' ){
|
||||
$product_price = floatval( formipay_get_post_meta( $form_id, 'product_price' ) );
|
||||
$amount = $amount / 100;
|
||||
$discount = $product_price * $amount;
|
||||
}
|
||||
|
||||
$amount = $discount * $qty;
|
||||
$amount = $amount * -1;
|
||||
|
||||
$details[] = [
|
||||
'item' => esc_html( $order_data['coupon_code'] ),
|
||||
'amount' => floatval($amount),
|
||||
'subtotal' => floatval($amount),
|
||||
'context' => 'sub'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $details;
|
||||
|
||||
}
|
||||
|
||||
public function count_order_by_coupon_code($coupon_code) {
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix .'formipay_orders';
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$data = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(id) as count FROM %i WHERE `items` LIKE %s", $table, '%' . $wpdb->esc_like($coupon_code) . '%'
|
||||
)
|
||||
);
|
||||
|
||||
return $data[0]->count;
|
||||
|
||||
}
|
||||
|
||||
public function add_discount_item($breakdown, $currency, $order_data) {
|
||||
|
||||
if( isset($order_data['form_data']['coupon_code']) && !empty($order_data['form_data']['coupon_code']) ) {
|
||||
|
||||
$form_id = $order_data['form_id'];
|
||||
$coupon_id = formipay_get_coupon_id_by_code( sanitize_text_field( $order_data['form_data']['coupon_code'] ), $form_id );
|
||||
|
||||
if(false !== $coupon_id) {
|
||||
|
||||
$amount = floatval( formipay_get_post_meta( $coupon_id, 'amount' ) );
|
||||
$discount = $amount;
|
||||
$coupon_type = formipay_get_post_meta( $coupon_id, 'type' );
|
||||
|
||||
$qty = 1;
|
||||
if( formipay_get_post_meta( $form_id, 'product_quantity_toggle' ) == 'on' ){
|
||||
$qty = intval($order_data['form_data']['qty']);
|
||||
}
|
||||
|
||||
if( $coupon_type == 'percentage' ){
|
||||
$product_price = floatval( formipay_get_post_meta( $form_id, 'product_price' ) );
|
||||
$amount = $amount / 100;
|
||||
$discount = $product_price * $amount;
|
||||
}
|
||||
|
||||
$breakdown['item_total']['value'] += $discount;
|
||||
$breakdown['discount'] = array(
|
||||
"currency_code" => $currency,
|
||||
"value" => $discount
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $breakdown;
|
||||
|
||||
}
|
||||
|
||||
public function formipay_tabledata_coupons() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
$args = [
|
||||
'post_type' => 'formipay-coupon',
|
||||
'posts_per_page' => -1,
|
||||
'post_status' => array( 'pending', 'draft', 'publish' )
|
||||
];
|
||||
|
||||
$get_total_coupons = get_posts($args);
|
||||
|
||||
$coupon_status = [
|
||||
'all' => 0,
|
||||
'active' => 0,
|
||||
'inactive' => 0
|
||||
];
|
||||
if(!empty($get_total_coupons)){
|
||||
foreach($get_total_coupons as $coupon){
|
||||
$status = (formipay_get_post_meta($coupon->ID, 'active') == 'on') ? 'active' : 'inactive';
|
||||
$coupon_status['all'] = intval($coupon_status['all']) + 1;
|
||||
if($status == 'active'){
|
||||
$coupon_status['active'] = intval($coupon_status['active']) + 1;
|
||||
}elseif($status == 'inactive'){
|
||||
$coupon_status['inactive'] = intval($coupon_status['inactive']) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['limit'])){
|
||||
$args['posts_per_page'] = intval($_REQUEST['limit']);
|
||||
}
|
||||
|
||||
if(isset($_REQUEST['offset'])){
|
||||
$args['offset'] = intval($_REQUEST['offset']);
|
||||
}
|
||||
|
||||
if(!empty($_REQUEST['search'])){
|
||||
$args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
|
||||
}
|
||||
|
||||
$get_coupons = get_posts($args);
|
||||
|
||||
$coupons = [];
|
||||
if(!empty($get_coupons)){
|
||||
foreach($get_coupons as $key => $coupon){
|
||||
|
||||
$active = true;
|
||||
|
||||
$products = !empty(formipay_get_post_meta($coupon->ID, 'forms')) ? explode(',', formipay_get_post_meta($coupon->ID, 'forms')) : [];
|
||||
$product_titles = [];
|
||||
if(!empty($products)){
|
||||
foreach($products as $product_id){
|
||||
if ( FALSE !== get_post_status( $product_id ) ) {
|
||||
$product_titles[] = [
|
||||
'flag' => formipay_get_flag_by_currency(formipay_get_post_meta($product_id, 'product_currency')),
|
||||
'currency' => formipay_get_post_meta($product_id, 'product_currency'),
|
||||
'title' => get_the_title($product_id)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($_REQUEST['product'])){
|
||||
$product_id = intval($_REQUEST['product']);
|
||||
$forms = formipay_get_post_meta($coupon->ID, 'forms');
|
||||
if(false !== $forms){
|
||||
$forms = explode(',', $forms);
|
||||
$found = false;
|
||||
if(!empty($forms)){
|
||||
foreach($forms as $form_id){
|
||||
if($product_id == $form_id){
|
||||
$active = true;
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
$active = false;
|
||||
}
|
||||
if(false == $found){
|
||||
unset($get_total_coupons[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$date_limit = formipay_get_post_meta($coupon->ID, 'date_limit');
|
||||
|
||||
if($active){
|
||||
$coupons[] = [
|
||||
'ID' => $coupon->ID,
|
||||
'code' => get_the_title($coupon->ID),
|
||||
'products' => $product_titles,
|
||||
'value' => floatval(formipay_get_post_meta($coupon->ID, 'amount')),
|
||||
'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')),
|
||||
'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'),
|
||||
'usages' => [
|
||||
'used' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
|
||||
'limit' => (intval(formipay_get_post_meta($coupon->ID, 'use_limit')) > 0) ? formipay_get_post_meta($coupon->ID, 'use_limit') : '∞'
|
||||
],
|
||||
'date_limit' => false !== $date_limit ? formipay_date('Y-m-d', intval(formipay_get_post_meta($coupon->ID, 'date_limit')) / 1000) : 'none',
|
||||
'status' => (formipay_get_post_meta($coupon->ID, 'active') == 'on') ? 'Active' : 'Inactive'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'results' => $coupons,
|
||||
'total' => count($get_total_coupons), // Total number of forms
|
||||
'posts_report' => array_map('intval', (array)$coupon_status)
|
||||
];
|
||||
|
||||
wp_send_json($response);
|
||||
}
|
||||
|
||||
public function formipay_coupon_get_products() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
if (!isset($_POST['search']) || empty($_POST['search'])) {
|
||||
wp_send_json_error( __('No search term provided.', 'formipay') );
|
||||
}
|
||||
|
||||
$search_term = sanitize_text_field( wp_unslash($_POST['search']) );
|
||||
|
||||
$query = get_posts([
|
||||
'post_type' => 'formipay-form',
|
||||
's' => $search_term,
|
||||
'posts_per_page' => -1,
|
||||
]);
|
||||
|
||||
$results = [];
|
||||
if(!empty($query)){
|
||||
foreach($query as $post){
|
||||
$results[] = [
|
||||
'value' => $post->ID,
|
||||
'label' => $post->post_title,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json($results);
|
||||
|
||||
}
|
||||
|
||||
public function formipay_create_coupon_post() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
$code = isset($_REQUEST['title']) ? sanitize_text_field( wp_unslash($_REQUEST['title']) ) : '';
|
||||
|
||||
if( !empty($code) && '' !== $code ){
|
||||
$post_id = wp_insert_post( [
|
||||
'post_title' => $code,
|
||||
'post_type' => 'formipay-coupon',
|
||||
], true );
|
||||
|
||||
if(is_wp_error($post_id)){
|
||||
wp_send_json_error( [
|
||||
'message' => $post_id->get_error_message()
|
||||
] );
|
||||
}
|
||||
|
||||
update_post_meta($post_id, 'type', 'percentage');
|
||||
update_post_meta($post_id, 'amount', 0);
|
||||
wp_send_json_success( [
|
||||
'edit_post_url' => admin_url('post.php?post='.$post_id.'&action=edit')
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_error( [
|
||||
'message' => esc_html__( 'Coupon code is empty.', 'formipay' )
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_delete_coupon() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
$post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
|
||||
|
||||
$delete = wp_delete_post($post_id, true);
|
||||
|
||||
if(is_wp_error( $delete )){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'Failed to delete coupon. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Deleted', 'formipay' ),
|
||||
'message' => esc_html__( 'Coupon is deleted permanently.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_bulk_delete_coupon() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
if( empty($_REQUEST['ids']) ){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'There is no coupon selected. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : [];
|
||||
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
$report = __( 'Done.', 'formipay' );
|
||||
if(!empty($ids)){
|
||||
foreach($ids as $id){
|
||||
$delete = wp_delete_post($id, true);
|
||||
if(is_wp_error( $delete )){
|
||||
$failed++;
|
||||
}else{
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($success > 0){
|
||||
$report .= sprintf( __( ' Deleted %d coupon(s).', 'formipay' ), $success);
|
||||
}
|
||||
if($failed > 0){
|
||||
$report .= sprintf( __( ' Failed %d coupon(s).', 'formipay' ), $failed);
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Done!', 'formipay' ),
|
||||
'message' => $report,
|
||||
'icon' => 'info'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_duplicate_coupon() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-coupon-page', '_wpnonce' );
|
||||
|
||||
$post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
|
||||
$post = get_post($post_id);
|
||||
if (!$post) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Coupon is not defined.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
if (!in_array($post->post_type, ['formipay-coupon'])) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Wrong Post Type.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$duplicate_post = [
|
||||
'post_title' => $post->post_title . ' ' . __('Copy', 'formipay'),
|
||||
'post_content' => $post->post_content,
|
||||
'post_status' => 'draft', // Set sebagai draft
|
||||
'post_type' => $post->post_type,
|
||||
'post_author' => $post->post_author,
|
||||
];
|
||||
|
||||
// Masukkan duplikat ke database
|
||||
$new_post_id = wp_insert_post($duplicate_post);
|
||||
|
||||
if (is_wp_error($new_post_id)) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Something happened. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
// Salin semua meta data
|
||||
$meta_data = get_post_meta($post_id);
|
||||
foreach ($meta_data as $key => $values) {
|
||||
if($key !== 'forms'){
|
||||
foreach ($values as $value) {
|
||||
add_post_meta($new_post_id, $key, maybe_unserialize($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__('Duplicated!', 'formipay'),
|
||||
'message' => esc_html__( 'Coupon is successfully duplicated.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
451
includes/Customer.php
Normal file
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Customer {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $order_data;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
add_action( 'admin_menu', [$this, 'add_menu'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue'] );
|
||||
add_action( 'wp_ajax_formipay-tabledata-customers', [$this, 'formipay_tabledata_customers'] );
|
||||
add_action( 'wp_ajax_formipay_check_for_data_mapping_saved_value', [$this, 'check_data_mapping'] );
|
||||
|
||||
// Add Global & Form Settings
|
||||
// add_filter( 'formipay/global-settings', [$this, 'global_settings'] );
|
||||
add_filter( 'formipay/global-settings/tab:general', [$this, 'global_settings'], 20 );
|
||||
add_filter( 'formipay/form-config', [$this, 'add_menu_on_product_setting'], 100 );
|
||||
|
||||
// Register new customer by order submitted
|
||||
add_action( 'formipay/order/new', [$this, 'add_customer'] );
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
|
||||
global $wpdb;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_customers` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint(20) DEFAULT 0,
|
||||
`registered_date` datetime DEFAULT '00-00-00 00:00:00',
|
||||
`name` text,
|
||||
`phone` text,
|
||||
`email` text,
|
||||
`purchase_value` float(10, 4) DEFAULT 0,
|
||||
`purchase_count` int,
|
||||
`meta_data` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta($create);
|
||||
|
||||
}
|
||||
|
||||
public function submit($args) {
|
||||
|
||||
$args = wp_parse_args( $args, [
|
||||
'user_id' => 0,
|
||||
'registered_date' => '',
|
||||
'name' => NULL,
|
||||
'phone' => NULL,
|
||||
'email' => NULL,
|
||||
'purchase_value' => 0,
|
||||
'purchase_count' => 0,
|
||||
'meta_data' => []
|
||||
] );
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_customers';
|
||||
|
||||
$insert_data = [
|
||||
'user_id' => intval($args['user_id']),
|
||||
'registered_date' => formipay_date('Y-m-d H:i:s'),
|
||||
'name' => sanitize_text_field( $args['name'] ),
|
||||
'phone' => sanitize_text_field( $args['phone'] ),
|
||||
'email' => sanitize_email( $args['email'] ),
|
||||
'purchase_value' => floatval($args['purchase_value']),
|
||||
'purchase_count' => intval($args['purchase_count']),
|
||||
'meta_data' => maybe_serialize($args['meta_data'])
|
||||
];
|
||||
|
||||
if($args['name'] !== ''){
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$wpdb->insert($table, $insert_data);
|
||||
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function get($customer_id = 0) {
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix .'formipay_customers';
|
||||
if($customer_id == 0){
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i", $table
|
||||
)
|
||||
);
|
||||
}else{
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i WHERE `id` = %d", $table, $customer_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $get;
|
||||
|
||||
}
|
||||
|
||||
public function get_by_email($email) {
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix .'formipay_customers';
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i WHERE `email` = %s", $table, $email
|
||||
), ARRAY_A
|
||||
);
|
||||
|
||||
return $get;
|
||||
}
|
||||
|
||||
public function update($customer_id, $args) {
|
||||
|
||||
$recent_data = $this->get($customer_id);
|
||||
|
||||
$args = wp_parse_args( $args, [
|
||||
'user_id' => $recent_data->user_id,
|
||||
'name' => $recent_data->name,
|
||||
'phone' => $recent_data->phone,
|
||||
'email' => $recent_data->email,
|
||||
'purchase_value' => $recent_data->purchase_value,
|
||||
'purchase_count' => $recent_data->purchase_count,
|
||||
'meta_data' => maybe_unserialize( $recent_data->meta_data )
|
||||
] );
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_customers';
|
||||
|
||||
$insert_data = [
|
||||
'user_id' => intval($args['user_id']),
|
||||
'name' => sanitize_text_field( $args['name'] ),
|
||||
'phone' => sanitize_text_field( $args['phone'] ),
|
||||
'email' => sanitize_email( $args['email'] ),
|
||||
'purchase_value' => floatval($args['purchase_value']),
|
||||
'purchase_count' => intval($args['purchase_count']),
|
||||
'meta_data' => maybe_serialize($args['meta_data'])
|
||||
];
|
||||
|
||||
$where = [ 'id' => $customer_id ];
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$update = $wpdb->update( $table_name, $new_args, $where );
|
||||
|
||||
return $update;
|
||||
|
||||
}
|
||||
|
||||
public function add_menu() {
|
||||
|
||||
add_submenu_page(
|
||||
'formipay',
|
||||
__( 'Customers', 'formipay' ),
|
||||
__( 'Customers', 'formipay' ),
|
||||
'manage_options',
|
||||
'formipay-customers',
|
||||
[$this, 'customers_page']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function enqueue() {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-customers') {
|
||||
|
||||
$customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
|
||||
if(empty($customer_id)){
|
||||
wp_enqueue_style( 'page-customers', FORMIPAY_URL . 'admin/assets/css/admin-customers.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'page-customers', FORMIPAY_URL . 'admin/assets/js/admin-customers.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
}else{
|
||||
wp_enqueue_style( 'bootstrap-icon', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all');
|
||||
wp_enqueue_style( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.min.css', [], '5.3.2' );
|
||||
wp_enqueue_style( 'page-customers', FORMIPAY_URL . 'admin/assets/css/admin-customer-details.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'handlebars', FORMIPAY_URL . 'vendor/HandleBars/handlebars.min.js', [], '4.7.7', true);
|
||||
wp_enqueue_script( 'bootstrap', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap.bundle.min.js', ['jquery'], '5.3.2', true );
|
||||
wp_enqueue_script( 'page-customers', FORMIPAY_URL . 'admin/assets/js/admin-customer-details.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
}
|
||||
|
||||
wp_localize_script( 'page-customers', 'formipay_customers_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'customer_id' => $customer_id,
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'name' => esc_html__( 'Name', 'formipay' ),
|
||||
'email' => esc_html__( 'Email', 'formipay' ),
|
||||
'phone' => esc_html__( 'Phone', 'formipay' ),
|
||||
'total_order' => esc_html__( 'Total Order', 'formipay' ),
|
||||
]
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function customers_page() {
|
||||
|
||||
$customer_id = intval(filter_input(INPUT_GET, 'customer_id', FILTER_SANITIZE_STRING));
|
||||
if(empty($customer_id)){
|
||||
include FORMIPAY_PATH . 'admin/page-customers.php';
|
||||
}else{
|
||||
include FORMIPAY_PATH . 'admin/page-customer-details.php';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function formipay_tabledata_customers() {
|
||||
|
||||
$get_all_customers = $this->get();
|
||||
$customers = [];
|
||||
|
||||
if(!empty($get_all_customers)){
|
||||
foreach($get_all_customers as $customer){
|
||||
$customers[] = [
|
||||
'ID' => $customer->id,
|
||||
'name' => $customer->name,
|
||||
'email' => $customer->email,
|
||||
'phone' => $customer->phone,
|
||||
'total_order' => $customer->purchase_count
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare response data
|
||||
$response = [
|
||||
'results' => $customers,
|
||||
'total' => count($get_all_customers),
|
||||
'posts_report' => $customers
|
||||
];
|
||||
|
||||
wp_send_json($response);
|
||||
|
||||
}
|
||||
|
||||
public function check_data_mapping() {
|
||||
|
||||
check_ajax_referer( 'formipay-form-editor', '_wpnonce' );
|
||||
|
||||
$form_id = isset($_REQUEST['post']) ? intval($_REQUEST['post']) : 0;
|
||||
|
||||
$saved = [
|
||||
'buyer_name' => formipay_get_post_meta($form_id, 'buyer_name'),
|
||||
'buyer_country' => formipay_get_post_meta($form_id, 'buyer_country')
|
||||
];
|
||||
|
||||
$medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
|
||||
|
||||
if(!empty($medias)){
|
||||
foreach($medias as $media) {
|
||||
$saved['buyer_'.$media] = formipay_get_post_meta($form_id, 'buyer_'.$media);
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json($saved);
|
||||
|
||||
}
|
||||
|
||||
public function global_settings($fields) {
|
||||
|
||||
$config = array(
|
||||
'customer_field_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Customer Data', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'customer_mandatory_data' => array(
|
||||
'type' => 'sorter',
|
||||
'label' => __( 'Identities', 'formipay' ),
|
||||
'options' => array(
|
||||
array(
|
||||
'id' => 'optional',
|
||||
'name' => esc_html__( 'Optional', 'formipay' ),
|
||||
'options' => array(
|
||||
array(
|
||||
'id' => 'phone',
|
||||
'label' => esc_html__( 'Phone', 'formipay' ),
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'id' => 'mandatory',
|
||||
'name' => esc_html__( 'Mandatory', 'formipay' ),
|
||||
'options' => array(
|
||||
array(
|
||||
'id' => 'name',
|
||||
'label' => esc_html__( 'Name', 'formipay' ),
|
||||
'icon' => 'fa fa-exclamation',
|
||||
'class' => 'disable'
|
||||
),
|
||||
array(
|
||||
'id' => 'email',
|
||||
'label' => esc_html__( 'Email', 'formipay' ),
|
||||
),
|
||||
)
|
||||
)
|
||||
),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
$fields = array_merge($fields, $config);
|
||||
|
||||
// $customer_settings = apply_filters( 'formipay/global-settings/tab:customer', $config );
|
||||
|
||||
// if(!empty($customer_settings)){
|
||||
// $fields['customer'] = array(
|
||||
// 'name' => __('Customer', 'formipay'),
|
||||
// 'fields' => $customer_settings
|
||||
// );
|
||||
// }
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_menu_on_product_setting($fields) {
|
||||
$medias = apply_filters('formipay/notification/media', ['email', 'phone'] );
|
||||
$customer_mandatory_data = formipay_customer_mandatory_data();
|
||||
|
||||
$customer_fields = [
|
||||
'notification_buyer_identify' => [
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Data Mapping', 'formipay' ),
|
||||
'group' => 'started',
|
||||
'description' => __( 'Match the required data for store the customer data, render shortcode and sending notification (if any)', 'formipay' ),
|
||||
],
|
||||
'buyer_name' => [
|
||||
'type' => 'select',
|
||||
'label' => __( 'Buyer\'s Name Field ID', 'formipay' ),
|
||||
'description' => __( 'Fill in the field ID that represents the buyer\'s name.', 'formipay' ),
|
||||
'required' => true
|
||||
]
|
||||
];
|
||||
|
||||
foreach($medias as $media){
|
||||
|
||||
$customer_fields['buyer_'.$media] = [
|
||||
'type' => 'select',
|
||||
// translators: %s is the media type name.
|
||||
'label' => sprintf( __('Buyer\'s %s Field ID', 'formipay' ), ucfirst($media) ),
|
||||
// translators: %s is the media type name.
|
||||
'description' => sprintf( __( 'Fill in the field ID that represents the buyer\'s %s.', 'formipay' ), ucfirst($media) ),
|
||||
'required' => in_array($media, $customer_mandatory_data) ? true : false
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
if(in_array('phone', $medias)){
|
||||
$customer_fields['buyer_allow_choose_country_code'] = [
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Buyer\'s can choose their own country code', 'formipay' ),
|
||||
'value' => true,
|
||||
'required' => in_array('phone', $customer_mandatory_data) ? true : false
|
||||
];
|
||||
$customer_fields['buyer_country'] = [
|
||||
'type' => 'select',
|
||||
'label' => __('Buyer\'s Country Field', 'formipay' ),
|
||||
'description' => __( 'Fill in the field ID that represents the buyer\'s country. This will define the country phone code.', 'formipay' ),
|
||||
'required' => in_array('phone', $customer_mandatory_data) ? true : false,
|
||||
'dependency' => array(
|
||||
'key' => 'buyer_allow_choose_country_code',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
];
|
||||
$customer_fields['buyer_phone_country_code'] = [
|
||||
'type' => 'select',
|
||||
'label' => __('Buyer\'s Default Country Code', 'formipay' ),
|
||||
'options' => formipay_phone_country_code_options(),
|
||||
'required' => true,
|
||||
'searchable' => true,
|
||||
'required' => in_array('phone', $customer_mandatory_data) ? true : false,
|
||||
'dependency' => array(
|
||||
'key' => 'buyer_allow_choose_country_code',
|
||||
'value' => 'empty'
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
$last_data_mapping_fields = array_key_last($customer_fields);
|
||||
$customer_fields[$last_data_mapping_fields]['group'] = 'ended';
|
||||
|
||||
$fields['formipay_form_settings']['customer_data'] = [
|
||||
'name' => __('Customer Data', 'formipay'),
|
||||
'fields' => $customer_fields
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function add_customer($order_data) {
|
||||
|
||||
$this->order_data = $order_data;
|
||||
$buyer_name_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
|
||||
$buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_email');
|
||||
$buyer_phone_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_phone');
|
||||
|
||||
// Fallback Array
|
||||
$customer_data = [
|
||||
'name' => '',
|
||||
'email' => '',
|
||||
'phone' => ''
|
||||
];
|
||||
|
||||
if(!empty($buyer_name_field) && !empty($this->order_data['form_data'][$buyer_name_field])) {
|
||||
$customer_data['name'] = $this->order_data['form_data'][$buyer_name_field]['value'];
|
||||
}
|
||||
|
||||
if(!empty($buyer_email_field) && !empty($this->order_data['form_data'][$buyer_email_field])) {
|
||||
$customer_data['email'] = $this->order_data['form_data'][$buyer_email_field]['value'];
|
||||
}
|
||||
|
||||
if(!empty($buyer_phone_field) && !empty($this->order_data['form_data'][$buyer_phone_field])) {
|
||||
$customer_data['phone'] = $this->order_data['form_data'][$buyer_phone_field]['value'];
|
||||
}
|
||||
|
||||
$email_is_exist = false;
|
||||
if(!empty($customer_data['email'])){
|
||||
$check = $this->get_by_email($customer_data['email']);
|
||||
if(!empty($check)){
|
||||
$email_is_exist = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(false == $email_is_exist && !empty($customer_data['name'])){
|
||||
$add_customer = $this->submit($customer_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
317
includes/Field.php
Normal file
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Field {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
// Render a text input field
|
||||
public function render_text_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="text" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render an email input field
|
||||
public function render_email_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="email" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a number input field
|
||||
public function render_number_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="number" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a url field
|
||||
public function render_url_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="url" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a telephone field
|
||||
public function render_tel_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="tel" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a date field
|
||||
public function render_date_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="date" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a datetime field
|
||||
public function render_datetime_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="datetime-local" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a color field
|
||||
public function render_color_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<input type="color" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" data-label="'.esc_attr($label).'"'.$required.' '.$calc.'>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a select dropdown field
|
||||
public function render_select_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$options = $args['field_options'] ?? [];
|
||||
$default_value = $args['default_value'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
$options_html = '';
|
||||
foreach ($options as $option) {
|
||||
$value = $option['value'] ?? $option['label'];
|
||||
$selected = ($default_value == $value) ? ' selected' : '';
|
||||
$options_html .= '<option value="'.esc_attr($value).'"'.$selected.'>'.esc_html($option['label']).'</option>';
|
||||
}
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<select id="'.esc_attr($field_id).'" name="'.esc_attr($field_id).'" class="formipay-input formipay-select'.$calculable.'" data-label="'.esc_attr($label).'" data-placeholder="'.esc_attr($placeholder).'"'.$required.' '.$calc.'>
|
||||
'.$options_html.'
|
||||
</select>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a checkbox group field
|
||||
public function render_checkbox_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$options = $args['field_options'] ?? [];
|
||||
$default_value = $args['default_value'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
$options_html = '';
|
||||
foreach ($options as $index => $option) {
|
||||
$value = $option['value'] ?? $option['label'];
|
||||
$checked = ($default_value == $value) ? ' checked' : '';
|
||||
$options_html .= '
|
||||
<label for="'.esc_attr($field_id.'-'.$index).'" class="formipay-label">
|
||||
<input type="checkbox" name="'.esc_attr($field_id).'[]" id="'.esc_attr($field_id.'-'.$index).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'"'.$checked.$required.' '.$calc.'>
|
||||
<span>'.esc_html($option['label']).'</span>
|
||||
</label>';
|
||||
}
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<div class="formipay-checkbox-field-group">'.$options_html.'</div>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a radio group field
|
||||
public function render_radio_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$options = $args['field_options'] ?? [];
|
||||
$default_value = $args['default_value'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
$options_html = '';
|
||||
foreach ($options as $index => $option) {
|
||||
$value = $option['value'] ?? $option['label'];
|
||||
$checked = ($default_value == $value) ? ' checked' : '';
|
||||
$options_html .= '
|
||||
<label for="'.esc_attr($field_id.'-'.$index).'" class="formipay-label">
|
||||
<input type="radio" name="'.esc_attr($field_id).'" id="'.esc_attr($field_id.'-'.$index).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'"'.$checked.$required.' '.$calc.'>
|
||||
<span>'.esc_html($option['label']).'</span>
|
||||
</label>';
|
||||
}
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<div class="formipay-radio-field-group">'.$options_html.'</div>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a textarea field
|
||||
public function render_textarea_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$value = $args['default_value'] ?? '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<textarea class="formipay-input'.$calculable.'" name="'.esc_attr($field_id).'" placeholder="'.esc_attr($placeholder).'" data-label="'.esc_attr($label).'"'.$required.' rows="4" '.$calc.'>'.esc_html($value).'</textarea>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a hidden input field
|
||||
public function render_hidden_field($args) {
|
||||
$value = $args['default_value'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '<input type="hidden" name="'.esc_attr($field_id).'" class="formipay-input'.$calculable.'" value="'.esc_attr($value).'" '.$calc.'>';
|
||||
}
|
||||
|
||||
// Render a divider field
|
||||
public function render_divider($args) {
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group'.$calculable.'" '.$calc.'>
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label divider-label">'.$label.'</label>
|
||||
<span class="divider-line"></span>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a page break field
|
||||
public function render_page_break($args) {
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$description = $args['description'] ?? '';
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
return '
|
||||
<div class="formipay-field-group formipay-page-break'.$calculable.'" '.$calc.'>
|
||||
<div class="formipay-page-break-information">
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label divider-label">'.$label.'</label>
|
||||
<span class="divider-line"></span>
|
||||
'.(!empty($description) ? '<p class="formipay-input-desc">'.esc_html($description).'</p>' : '').'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Render a country list select field
|
||||
public function render_country_list_field($args) {
|
||||
$required = !empty($args['is_required']) && $args['is_required'] === 'yes' ? ' required' : '';
|
||||
$label = $args['label'] ?? '';
|
||||
$field_id = $args['field_id'] ?? '';
|
||||
$placeholder = $args['placeholder'] ?? '';
|
||||
$countries = function_exists('formipay_country_array') ? formipay_country_array() : [];
|
||||
$calculable = $args['calculable'] ?? '';
|
||||
$calc = $args['calc'] ?? '';
|
||||
$options_html = '';
|
||||
foreach ($countries as $country) {
|
||||
$options_html .= '<option value="'.esc_attr($country['name']).'" data-phone-code="'.esc_attr($country['phone']).'">'.esc_html($country['name']).'</option>';
|
||||
}
|
||||
return '
|
||||
<div class="formipay-field-group preset select-searchable'.$calculable.'" '.$calc.'>
|
||||
<label for="'.esc_attr($field_id).'" class="formipay-label">'.$label.($required ? ' <span class="formipay-asterisk">*</span>' : '').'</label>
|
||||
<select id="'.esc_attr($field_id).'" name="'.esc_attr($field_id).'" class="formipay-input formipay-select" data-label="'.esc_attr($label).'" data-placeholder="'.esc_attr($placeholder).'"'.$required.'>
|
||||
'.$options_html.'
|
||||
</select>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
1761
includes/Form.php
Normal file
206
includes/Init.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Init {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'admin_menu', [$this, 'menu'] );
|
||||
add_action( 'admin_footer', [$this, 'admin_global_custom_js'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue'] );
|
||||
add_action( 'plugin_loaded', [$this, 'load_nuxy'] );
|
||||
add_action( 'plugin_loaded', [$this, 'init'] );
|
||||
add_action( 'plugin_loaded', [$this, 'default_config'] );
|
||||
|
||||
}
|
||||
|
||||
public function init() {
|
||||
|
||||
// Integration Class
|
||||
// \Formipay\Integration\Paypal::get_instance();
|
||||
|
||||
// Payment classes
|
||||
\Formipay\Payment\BankTransfer::get_instance();
|
||||
\Formipay\Payment\CashOnDelivery::get_instance();
|
||||
|
||||
// Shipping classes
|
||||
\Formipay\Shipping\FlatRate::get_instance();
|
||||
|
||||
// Notification classes
|
||||
\Formipay\Notification\Notification::get_instance();
|
||||
\Formipay\Notification\Email::get_instance();
|
||||
|
||||
// Core and other classes
|
||||
\Formipay\Field::get_instance();
|
||||
\Formipay\Form::get_instance();
|
||||
\Formipay\Product::get_instance();
|
||||
\Formipay\Access::get_instance();
|
||||
\Formipay\Coupon::get_instance();
|
||||
\Formipay\Settings::get_instance();
|
||||
\Formipay\Order::get_instance();
|
||||
\Formipay\Customer::get_instance();
|
||||
\Formipay\Render::get_instance();
|
||||
\Formipay\Thankyou::get_instance();
|
||||
new \Formipay\Token;
|
||||
|
||||
do_action('formipay_init');
|
||||
}
|
||||
|
||||
public function menu() {
|
||||
|
||||
add_menu_page(
|
||||
'Formipay',
|
||||
'Formipay',
|
||||
'manage_options',
|
||||
'formipay',
|
||||
'',
|
||||
FORMIPAY_URL . 'admin/assets/img/White.png',
|
||||
5
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function load_nuxy() {
|
||||
require_once( FORMIPAY_PATH . 'vendor/wpcfto/WPCFTO.php');
|
||||
}
|
||||
|
||||
public function enqueue() {
|
||||
global $current_screen;
|
||||
|
||||
$formipayCPTs = [
|
||||
'formipay-form' => __( 'Edit Form', 'formipay' ),
|
||||
'formipay-product' => __( 'Edit Product', 'formipay' ),
|
||||
'formipay-coupon' => __( 'Edit Coupon', 'formipay' ),
|
||||
'formipay-access' => __( 'Edit Access', 'formipay' )
|
||||
];
|
||||
|
||||
wp_enqueue_style( 'formipay-admin-global', FORMIPAY_URL . 'admin/assets/css/admin-global.css', [], FORMIPAY_VERSION, 'all');
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
|
||||
if(strpos($current_screen->id, 'formipay') !== false){
|
||||
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.mermaid.min.css', [], '6.2.0', 'all' );
|
||||
|
||||
wp_enqueue_script( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.js', [], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/js/admin-pages.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.production.min.js', ['jquery'], '6.2.0', true );
|
||||
|
||||
}
|
||||
|
||||
if(in_array($current_screen->post_type, array_keys($formipayCPTs)) && $current_screen->base == 'post'){
|
||||
wp_enqueue_style( 'formipay-classic-editor', FORMIPAY_URL . 'admin/assets/css/classic-editor.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'formipay-classic-editor', FORMIPAY_URL . 'admin/assets/js/classic-editor.js', ['jquery'], FORMIPAY_VERSION, true);
|
||||
wp_enqueue_script( 'formipay-screen-menu', FORMIPAY_URL . 'admin/assets/js/admin-all-post-type.js', ['jquery'], FORMIPAY_VERSION, true);
|
||||
wp_localize_script( 'formipay-screen-menu', 'formipay_admin', [
|
||||
'site_url' => site_url(),
|
||||
'page_title' => $formipayCPTs[$current_screen->post_type]
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function admin_global_custom_js() {
|
||||
global $pagenow, $current_screen;
|
||||
?>
|
||||
<script class="formipay-adminjs-global">
|
||||
jQuery(function($){
|
||||
<?php
|
||||
// Formipay Form CPT
|
||||
if( $current_screen->post_type == 'formipay-form' ) {
|
||||
?>
|
||||
$('#toplevel_page_formipay').removeClass('wp-not-current-submenu').addClass('wp-has-current-submenu wp-menu-open');
|
||||
$('a[href="admin.php?page=formipay"]').closest('li').addClass('current');
|
||||
<?php
|
||||
}
|
||||
// Formipay Access CPT
|
||||
if( $current_screen->post_type == 'formipay-product' ) {
|
||||
?>
|
||||
$('#toplevel_page_formipay').removeClass('wp-not-current-submenu').addClass('wp-has-current-submenu wp-menu-open');
|
||||
$('a[href="admin.php?page=formipay-product"]').closest('li').addClass('current');
|
||||
<?php
|
||||
}
|
||||
// Formipay Access CPT
|
||||
if( $current_screen->post_type == 'formipay-access' ) {
|
||||
?>
|
||||
$('#toplevel_page_formipay').removeClass('wp-not-current-submenu').addClass('wp-has-current-submenu wp-menu-open');
|
||||
$('a[href="admin.php?page=formipay-access-items"]').closest('li').addClass('current');
|
||||
<?php
|
||||
}
|
||||
// Formipay Coupon CPT
|
||||
if( $current_screen->post_type == 'formipay-coupon' ) {
|
||||
?>
|
||||
$('#toplevel_page_formipay').removeClass('wp-not-current-submenu').addClass('wp-has-current-submenu wp-menu-open');
|
||||
$('a[href="admin.php?page=formipay-coupon"]').closest('li').addClass('current');
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
public function default_config() {
|
||||
|
||||
$array = array (
|
||||
'thankyou_link' => 'thanks',
|
||||
'thankyou_style' => 'receipt',
|
||||
'thankyou_page_container_bg_color' => '#808080',
|
||||
'thankyou_page_wrapper_bg_color' => '#ffffff',
|
||||
'thankyou_page_wrapper_max_width' => '600',
|
||||
'thankyou_confirmation_dropzone_color' => '#cccccc',
|
||||
'thankyou_confirmation_dropzone_text_color' => '#808080',
|
||||
'thankyou_confirmation_dropzone_instruction' => 'Drag & drop a file here or click to select one',
|
||||
'thankyou_confirmation_submit_button' => 'Upload',
|
||||
'cod_instruction_thankyou' => '<p>Your package will be shipped as soon as possible. Please make sure your <span style="background-color: transparent; color: var(--bs-body-color); text-align: var(--bs-body-text-align);">cash of </span><span style="background-color: transparent; color: var(--bs-body-color); text-align: var(--bs-body-text-align);">{{grand_total}} will be prepared </span><span style="background-color: transparent; color: var(--bs-body-color); text-align: var(--bs-body-text-align);">and you can pay it to the courier who delivers your </span><span style="background-color: transparent; color: var(--bs-body-color); text-align: var(--bs-body-text-align);">{{product_name}}.</span></p>',
|
||||
'cod_instruction_whatsapp' => 'I will prepare the cash of {{grand_total}} for paying the order to the courier who delivers my {{product_name}}.',
|
||||
'cod_confirmation_page_group' => '',
|
||||
'cod_confirmation_page_content' => '<h3 style="text-align: left; margin-bottom: unset; padding: 0px; border: none; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-stretch: inherit; line-height: var(--theme-line-height); font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; --theme-font-weight: 700; --theme-font-size: 30px; --theme-line-height: 1.5;">Confirm Your Order</h3><h6 style="text-align: left; margin-bottom: calc(var(--has-theme-content-spacing, 1)*(.3em + 10px)); padding: 0px; border: none; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-stretch: inherit; line-height: var(--theme-line-height); font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; --theme-font-weight: 700; --theme-font-size: 16px; --theme-line-height: 1.5;">Cash on Delivery</h6><p style="text-align: center; margin-bottom: calc(var(--has-theme-content-spacing, 1)*(.3em + 10px)); padding: 0px; border: none; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-stretch: inherit; line-height: var(--theme-line-height); font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; --theme-font-weight: 700; --theme-font-size: 16px; --theme-line-height: 1.5;"><p style="text-align: left;"><span style="background-color: transparent; color: var(--bs-body-color);">Here is your order details:</span></p><p style="text-align: left;"><span style="background-color: transparent; color: var(--bs-body-color);">{{order_details}}</span></p></p><p style="text-align: center; margin-bottom: calc(var(--has-theme-content-spacing, 1)*(.3em + 10px)); padding: 0px; border: none; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-stretch: inherit; line-height: var(--theme-line-height); font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; --theme-font-weight: 700; --theme-font-size: 16px; --theme-line-height: 1.5;"><p style="text-align: left;"><span style="background-color: transparent; color: var(--bs-body-color);">Please confirm if the package has been arrived</span></p><p style="text-align: left;"><span style="background-color: transparent; color: var(--bs-body-color);">{{confirmation_form}}</span></p></p>',
|
||||
'cod_confirmation_page_width' => '600',
|
||||
'cod_confirmation_table_alignment' => 'left',
|
||||
'cod_confirmation_form_agreement' => 'I have receipt the package and pay as billed to the courier.',
|
||||
'cod_confirmation_form_button' => 'Confirm',
|
||||
'notification_email_footer' => '<p style="text-align: center;">You got this email because of ordering our products in Formipay.<br>Ignore this email if it was not you.</p>',
|
||||
'notification_email_admin_on_hold_group_header' => '',
|
||||
'notification_email_admin_on_hold_toggle' => true,
|
||||
'notification_email_admin_on_hold_title' => 'New Order On-Hold: Action Required',
|
||||
'notification_email_admin_on_hold_content' => '<p>Hello Admin,</p><p><br></p><p>A new order has been placed and is currently on hold, awaiting payment from the buyer. </p><p><br></p><p><strong>Buyer Name:</strong> {{buyer_name}} </p><p><strong>Order ID:</strong> {{order_id}}</p><p><strong>Order Status:</strong> On Hold </p><p><br></p><p>{{order_details}}</p><p><br></p><p>Please review the order and follow up with the buyer to encourage them to complete their payment.</p><p><br></p><p>Best regards,</p><p>Your E-commerce Team</p>',
|
||||
'notification_email_buyer_on_hold_group_header' => '',
|
||||
'notification_email_buyer_on_hold_toggle' => true,
|
||||
'notification_email_buyer_on_hold_title' => 'Your Order is On Hold: Action Needed',
|
||||
'notification_email_buyer_on_hold_content' => '<p>Hello {{buyer_name}},</p><p>Thank you for your recent order! Your order is currently on hold because we have not yet received your payment.</p><p><strong>Order ID:</strong>{{order_id}}</p><p><strong>Order Status:</strong>On Hold</p><p><strong>Payment Timeout:</strong>{{payment_timeout}}</p><p><br></p><p>{{order_details}}</p><p><br></p><p>Please complete your payment within the next {{payment_timeout}} to avoid cancellation. If you have any questions, feel free to reach out.</p><p>Thank you for shopping with us!</p><p><br></p><p>Best,</p><p>Your E-commerce Team</p>',
|
||||
'notification_email_admin_payment_confirm_group_header' => '',
|
||||
'notification_email_admin_payment_confirm_toggle' => true,
|
||||
'notification_email_admin_payment_confirm_title' => 'Payment Confirmed for Order: Immediate Attention Required',
|
||||
'notification_email_admin_payment_confirm_content' => '<p>Hello Admin,</p><p><br></p><p>The buyer has confirmed payment for the following order:Buyer Name: {{buyer_name}} </p><p><br></p><p><strong>Buyer Name:</strong>**Buyer Name:* {{buyer_name}} </p><p><strong>Order ID:</strong>**Order ID: {{order_id}} </p><p><strong>Order Status:</strong>Order Status: Payment Confirmed </p><p><br></p><p>{{order_details}} </p><p><br></p><p>Please take the necessary steps to process this order and prepare for shipment.</p><p><br></p><p>Best regards, </p><p>Your E-commerce Team</p>',
|
||||
'notification_email_buyer_payment_confirm_group_header' => '',
|
||||
'notification_email_buyer_payment_confirm_toggle' => true,
|
||||
'notification_email_buyer_payment_confirm_title' => 'Payment Confirmed for Your Order',
|
||||
'notification_email_buyer_payment_confirm_content' => '<p>Hello {{buyer_name}},</p><p><br></p><p>We\'re excited to let you know that your payment has been confirmed!</p><p><strong><br></strong></p><p><strong>Order ID:</strong> {{order_id}} </p><p><strong>Order Status:</strong> Payment Confirmed </p><p><br></p><p>{{order_details}}<br></p><p><br></p><p>Our team is now preparing your order for shipment. You will receive another update once your items are on their way!</p><p><br></p><p>Thank you for choosing us!</p><p><br></p><p>Best, </p><p>Your E-commerce Team</p><p><br></p>',
|
||||
'notification_email_admin_completed_toggle' => true,
|
||||
'notification_email_admin_completed_title' => 'Order Completed: Final Update',
|
||||
'notification_email_admin_completed_content' => '<p>Hello Admin,</p><p><br></p><p>The following order has been successfully completed:</p><p><strong><br></strong></p><p><strong>Buyer Name:</strong> {{buyer_name}} </p><p><strong>Order ID:</strong> {{order_id}} </p><p><strong>Order Status:</strong> Completed </p><p><br></p><p>{{order_details}} </p><p><br></p><p>No further action is required. Thank you for your continued support!</p><p><br></p><p>Best regards, </p><p>Your E-commerce Team</p><p><br></p>',
|
||||
'notification_email_buyer_completed_toggle' => true,
|
||||
'notification_email_buyer_completed_title' => 'Your Order is Complete!',
|
||||
'notification_email_buyer_completed_content' => '<p>Hello {{buyer_name}},</p><p><br></p><p>Thank you for your order! We are pleased to inform you that your order has been completed.</p><p><br></p><p><strong>Order ID:</strong> {{order_id}} </p><p><strong>Order Status:</strong> Completed </p><p><br></p><p>{{order_details}} </p><p><br></p><p>We hope you enjoy your purchase! If you have any feedback or questions, please let us know.</p><p><br></p><p>Best, </p><p>Your E-commerce Team</p><p><br></p>',
|
||||
);
|
||||
|
||||
if(empty(get_option('formipay_settings'))){
|
||||
update_option('formipay_settings', $array);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
898
includes/Integration/Paypal.php
Normal file
@@ -0,0 +1,898 @@
|
||||
<?php
|
||||
namespace Formipay\Integration;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
use Formipay\Payment\Payment;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Paypal extends Payment {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $gateway = 'paypal';
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
add_action( 'rest_api_init', [$this, 'webhook_endpoint'] );
|
||||
add_action( 'formipay/order/new', [$this, 'add_transaction'], 99 );
|
||||
|
||||
add_filter( 'formipay/form-config/tab:payments/gateways', [$this, 'add_gateway'] );
|
||||
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_paypal_settings'] );
|
||||
add_filter( 'formipay/global-settings/tab:payment', [$this, 'add_settings'] );
|
||||
add_filter( 'formipay/payment-list/paypal/label', [$this, 'set_frontend_label'] );
|
||||
add_filter( 'formipay/payment-list/paypal/logo', [$this, 'set_frontend_logo'] );
|
||||
add_filter( 'formipay/order/result', [$this, 'process_payment'], 99 );
|
||||
add_action( 'parse_query', [$this, 'check_parse_query'] );
|
||||
add_filter( 'formipay/order/payment-details/paypal', [$this, 'render_payment_details'], 999, 4 );
|
||||
|
||||
add_filter('formipay/notification/order/email/action-button', [$this, 'render_email_action_button'], 99, 3 );
|
||||
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
|
||||
global $wpdb;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_paypal_trx` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`created_date` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
`form_id` int DEFAULT 0,
|
||||
`order_id` int DEFAULT 0,
|
||||
`currency_code` text,
|
||||
`total` float(10, 2) DEFAULT 0,
|
||||
`status` text,
|
||||
`meta_data` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta($create);
|
||||
|
||||
}
|
||||
|
||||
public function webhook_endpoint() {
|
||||
register_rest_route('formipay/v1', '/paypal-webhook', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'handle_paypal_webhook'],
|
||||
'permission_callback' => '__return_true'
|
||||
]);
|
||||
}
|
||||
|
||||
public function add_transaction($order_data) {
|
||||
|
||||
$form_id = absint($order_data['form_id'] ?? 0);
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$timeout = isset($formipay_settings['paypal_timeout']) ? (int) $formipay_settings['paypal_timeout'] : 1440;
|
||||
|
||||
$currency_meta = formipay_get_post_meta($form_id, 'product_currency');
|
||||
$currency_parts = explode(':::', $currency_meta);
|
||||
$currency = !empty($currency_parts[0]) ? sanitize_text_field($currency_parts[0]) : '';
|
||||
|
||||
if($this->gateway === ($order_data['payment_gateway'] ?? '')) {
|
||||
|
||||
$submit_args = [
|
||||
'created_date' => formipay_date('Y-m-d H:i:s', strtotime($order_data['created_date'] ?? 'now')),
|
||||
'form_id' => $form_id,
|
||||
'order_id' => absint($order_data['id'] ?? 0),
|
||||
'currency_code' => $currency,
|
||||
'total' => floatval($order_data['total'] ?? 0),
|
||||
'status' => 'PENDING',
|
||||
'meta_data' => maybe_serialize([
|
||||
'request_response' => maybe_serialize($order_data['payment_callback']),
|
||||
'payer_action_url' => esc_url_raw($order_data['redirect_url'] ?? '')
|
||||
])
|
||||
];
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_paypal_trx';
|
||||
|
||||
$format = [
|
||||
'%s', // created_date
|
||||
'%d', // form_id
|
||||
'%d', // order_id
|
||||
'%s', // currency_code
|
||||
'%f', // total
|
||||
'%s', // status
|
||||
'%s' // meta_data
|
||||
];
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$wpdb->insert($table, $submit_args, $format);
|
||||
|
||||
wp_schedule_single_event(
|
||||
(int) formipay_date('timestamp') + $timeout, 'formipay/order/payment-timeout', [
|
||||
'order_id' => $order_data['id'],
|
||||
'payment_gateway' => 'paypal'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function auto_cancel_order_on_timeout($order_id, $payment_gateway) {
|
||||
|
||||
if($payment_gateway == 'paypal'){
|
||||
|
||||
global $wpdb;
|
||||
$order = formipay_get_order($order_id);
|
||||
if($order['status'] !== 'completed'){
|
||||
Order::update($order_id, [
|
||||
'status' => 'cancelled'
|
||||
]);
|
||||
$this->cancel_payment($order_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function get_transaction($order_id = 0) {
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix .'formipay_paypal_trx';
|
||||
if($order_id == 0){
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i", $table
|
||||
)
|
||||
);
|
||||
}else{
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i WHERE `order_id` = %d", $table, $order_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $get;
|
||||
|
||||
}
|
||||
|
||||
public function update_transaction($order_id, $status, $callback) {
|
||||
|
||||
$args = [
|
||||
'status' => sanitize_text_field( $status ),
|
||||
'meta_data' => maybe_serialize( $callback )
|
||||
];
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_paypal_trx';
|
||||
$where = ['order_id' => $order_id];
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$update = $wpdb->update(
|
||||
$table, $args, $where
|
||||
);
|
||||
|
||||
return $update;
|
||||
|
||||
}
|
||||
|
||||
public function add_gateway($gateways) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(isset($formipay_settings['paypal_toggle']) && $formipay_settings['paypal_toggle'] == 'yes') {
|
||||
$gateways[] = [
|
||||
'id' => $this->gateway,
|
||||
'gateway' => __( 'Paypal', 'formipay' )
|
||||
];
|
||||
}
|
||||
|
||||
return $gateways;
|
||||
|
||||
}
|
||||
|
||||
public function add_settings($fields) {
|
||||
|
||||
$payment_instruction = file_get_contents( FORMIPAY_PATH . 'admin/templates/paypal-instruction.html' );
|
||||
|
||||
$paypal_settings = array(
|
||||
$this->gateway.'_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Activate Paypal', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_account_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Paypal Account', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_instruction' => array(
|
||||
'type' => 'notification_message',
|
||||
'description' => $payment_instruction,
|
||||
'buttons' => array(
|
||||
'show_instruction' => array(
|
||||
'text' => __( 'Show Instruction', 'formipay' ),
|
||||
'class' => 'show-instruction'
|
||||
)
|
||||
),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'submenu' => __( 'Paypal', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_client_id' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Client ID', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_secret' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Secret', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_environment' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Environment', 'formipay' ),
|
||||
'options' => array(
|
||||
'sandbox' => __( 'Sandbox', 'formipay' ),
|
||||
'production' => __( 'Production', 'formipay' )
|
||||
),
|
||||
'value' => 'sandbox',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_merchant_email' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Merchant Email', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
$this->gateway.'_timeout' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Payment Timeout (minute)', 'formipay' ),
|
||||
'description' => __( 'Set a timeout to wait for payment. After this timeout is up, the order status automatically changes to cancelled.', 'formipay' ),
|
||||
'value' => 120,
|
||||
'group' => 'ended',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
foreach($paypal_settings as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_paypal_settings($fields) {
|
||||
|
||||
$paypal_settings = array(
|
||||
|
||||
$this->gateway.'_confirmation_notice_message_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Notice Messages', 'formipay' ),
|
||||
'description' => __(
|
||||
'Set notice message on every condition about attempting to confirm the payment', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_update_to_status' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Change status order to', 'formipay' ),
|
||||
'options' => formipay_order_status_list(),
|
||||
'value' => 'payment-confirm',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_success' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Successfully Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('Successfully confirmed payment for #{{order_id}}', 'formipay'),
|
||||
'description' => __('When successfully change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_already_confirmed' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Has Been Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('#{{order_id}} has been confirmed', 'formipay'),
|
||||
'description' => __('When the order status has been the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_error' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Failed to Confirm Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay'),
|
||||
'system_error_message' => __('System Error Message', 'formipay')
|
||||
),
|
||||
'value' => __('Failed to proceed. Error: {{system_error_message}}', 'formipay'),
|
||||
'description' => __('When error to change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
foreach($paypal_settings as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function set_frontend_label($label){
|
||||
|
||||
$label = __( 'Paypal', 'formipay' );
|
||||
|
||||
return $label;
|
||||
|
||||
}
|
||||
|
||||
public function set_frontend_logo($logo){
|
||||
|
||||
if($logo == false){
|
||||
$logo = FORMIPAY_URL . 'public/assets/img/paypal.png';
|
||||
}
|
||||
|
||||
return $logo;
|
||||
|
||||
}
|
||||
|
||||
public function prepare_payload($order_data) {
|
||||
|
||||
// error_log('current order'. $order_data['id'] . ': ' . print_r($order_data, true));
|
||||
|
||||
$form_id = intval($order_data['form_id']);
|
||||
$order_details = $order_data['items'];
|
||||
|
||||
if($this->gateway == $order_data['payment_gateway']){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$grand_total = floatval($order_data['total']);
|
||||
|
||||
// Currency
|
||||
$currency = explode(':::', formipay_get_post_meta($form_id, 'product_currency'));
|
||||
$currency = $currency[0];
|
||||
|
||||
$currency_decimal_digits = formipay_get_post_meta($form_id, 'product_currency_decimal_digits');
|
||||
$currency_decimal_symbol = formipay_get_post_meta($form_id, 'product_currency_decimal_symbol');
|
||||
$currency_thousand_separator = formipay_get_post_meta($form_id, 'product_currency_thousand_separator');
|
||||
|
||||
$slug = 'thankyou';
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
if(formipay_get_post_meta($form_id, 'product_type') == 'digital'){
|
||||
$shipping_preference = 'NO_SHIPPING';
|
||||
}else{
|
||||
$shipping_preference = 'SET_PROVIDED_ADDRESS';
|
||||
}
|
||||
|
||||
// Setup items
|
||||
$items = [];
|
||||
foreach($order_details as $item){
|
||||
$qty = 1;
|
||||
if(!empty($item['qty'])){
|
||||
$qty = $item['qty'];
|
||||
}
|
||||
if(floatval($item['amount']) >= 0){
|
||||
$items[] = [
|
||||
'name' => $item['item'],
|
||||
'unit_amount' => [
|
||||
'currency_code' => $currency,
|
||||
'value' => floatval($item['amount'])
|
||||
],
|
||||
'quantity' => $qty
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$items = apply_filters('formipay/order/paypal/payload/items', $items, $currency, $order_data);
|
||||
|
||||
$breakdown = array(
|
||||
"item_total" => array(
|
||||
"currency_code" => $currency,
|
||||
"value" => $grand_total
|
||||
)
|
||||
);
|
||||
$breakdown = apply_filters('formipay/order/paypal/payload/breakdown', $breakdown, $currency, $order_data);
|
||||
|
||||
$unique_id = $order_data['meta_data']['session_id']['value'];
|
||||
|
||||
$thankyou_link = 'thankyou';
|
||||
if(isset($formipay_settings['thankyou_link']) && !empty($formipay_settings['thankyou_link'])){
|
||||
$thankyou_link = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
$token_manager = new \Formipay\Token();
|
||||
$token = $token_manager->generate(
|
||||
$order_data['id'],
|
||||
$form_id,
|
||||
900 // 15-minute expiration
|
||||
);
|
||||
$access_link = site_url('/'.$thankyou_link.'/' . $token);
|
||||
|
||||
// Prepare the payload
|
||||
$payload = json_encode(array(
|
||||
"intent" => "CAPTURE",
|
||||
"purchase_units" => array(
|
||||
array(
|
||||
"custom_id" => (string)$order_data['id'],
|
||||
"amount" => array(
|
||||
"currency_code" => $currency,
|
||||
"value" => $grand_total, // Format amount
|
||||
"breakdown" => $breakdown
|
||||
),
|
||||
"items" => $items
|
||||
)
|
||||
),
|
||||
'payment_source' => array(
|
||||
'paypal' => array(
|
||||
'experience_context' => array(
|
||||
'return_url' => $access_link . '?paypal-status=success',
|
||||
'cancel_url' => $access_link . '?paypal-status=cancel',
|
||||
'user_action' => 'PAY_NOW',
|
||||
'brand_name' => 'FORMIPAY INC',
|
||||
'local' => 'en-US',
|
||||
'landing_page' => 'LOGIN',
|
||||
'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
|
||||
'shipping_preference' => $shipping_preference
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function process_payment( $order_data ) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if($order_data['payment_gateway'] == 'paypal') {
|
||||
|
||||
$paypal_client_id = $formipay_settings['paypal_client_id'];
|
||||
$paypal_secret = $formipay_settings['paypal_secret'];
|
||||
|
||||
// Set your authentication header
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
|
||||
// Define arguments for wp_remote_post
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
),
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body'
|
||||
);
|
||||
|
||||
$url = 'https://api-m.sandbox.paypal.com/v2';
|
||||
if(isset($formipay_settings[$this->gateway.'_environment']) && $formipay_settings[$this->gateway.'_environment'] == 'production') {
|
||||
$url = 'https://api-m.paypal.com/v2';
|
||||
}
|
||||
|
||||
$payload = $this->prepare_payload($order_data);
|
||||
// error_log('paypal payload:'.print_r($payload, true));
|
||||
$args['body'] = $payload;
|
||||
$url = $url.'/checkout/orders';
|
||||
|
||||
$response = wp_remote_retrieve_body( wp_remote_post($url, $args) );
|
||||
$response = json_decode($response);
|
||||
// error_log('paypal response:'.print_r($response, true));
|
||||
|
||||
$payer_action_link = null;
|
||||
|
||||
foreach ($response->links as $link) {
|
||||
if ($link->rel === 'payer-action') {
|
||||
$payer_action_link = $link->href;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($payer_action_link !== null){
|
||||
$order_data['payment_callback'] = $response;
|
||||
$order_data['redirect_url'] = $payer_action_link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $order_data;
|
||||
|
||||
}
|
||||
|
||||
public function cancel_payment( $order_data ) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if($order_data['payment_gateway'] == 'paypal') {
|
||||
|
||||
$paypal_client_id = $formipay_settings['paypal_client_id'];
|
||||
$paypal_secret = $formipay_settings['paypal_secret'];
|
||||
|
||||
// Set your authentication header
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
|
||||
// Define arguments for wp_remote_post
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
),
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body'
|
||||
);
|
||||
|
||||
$url = 'https://api-m.sandbox.paypal.com/v2';
|
||||
if(isset($formipay_settings[$this->gateway.'_environment']) && $formipay_settings[$this->gateway.'_environment'] == 'production') {
|
||||
$url = 'https://api-m.paypal.com/v2';
|
||||
}
|
||||
|
||||
$payload = $this->prepare_payload($order_data);
|
||||
// error_log('paypal payload:'.print_r($payload, true));
|
||||
$args['body'] = $payload;
|
||||
$url = $url.'/checkout/orders';
|
||||
|
||||
$response = wp_remote_retrieve_body( wp_remote_post($url, $args) );
|
||||
$response = json_decode($response);
|
||||
// error_log('paypal response:'.print_r($response, true));
|
||||
|
||||
$payer_action_link = null;
|
||||
|
||||
foreach ($response->links as $link) {
|
||||
if ($link->rel === 'payer-action') {
|
||||
$payer_action_link = $link->href;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($payer_action_link !== null){
|
||||
$order_data['redirect_url'] = $payer_action_link;
|
||||
}
|
||||
|
||||
do_action('formipay/notification/order', $order_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function check_parse_query() {
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wp_query;
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
// Validate query vars early
|
||||
$query = $wp_query->query;
|
||||
if (
|
||||
is_array($query) &&
|
||||
!empty($query['formipay-payment-confirm']) &&
|
||||
filter_var($query['formipay-payment-confirm'], FILTER_VALIDATE_BOOLEAN) &&
|
||||
!empty($query['gateway']) &&
|
||||
$query['gateway'] === 'paypal'
|
||||
) {
|
||||
// Sanitize and validate token
|
||||
$token_raw = isset($query['formipay-token']) ? $query['formipay-token'] : '';
|
||||
$token_decoded = base64_decode($token_raw, true);
|
||||
if (!$token_decoded) {
|
||||
return;
|
||||
}
|
||||
$token = explode(':::', $token_decoded);
|
||||
if (count($token) < 2) {
|
||||
return;
|
||||
}
|
||||
$form_id = absint($token[0]);
|
||||
$order_id = absint($token[1]);
|
||||
if (!$form_id || !$order_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$check_order = $this->get_transaction($order_id);
|
||||
|
||||
// Check PayPal status and process payment
|
||||
if (!empty($check_order) &&
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['paypal-status']) && sanitize_text_field(wp_unslash($_GET['paypal-status'])) === 'success' &&
|
||||
strtoupper($check_order->status) === 'PENDING'
|
||||
) {
|
||||
$paypal_client_id = isset($formipay_settings['paypal_client_id']) ? $formipay_settings['paypal_client_id'] : '';
|
||||
$paypal_secret = isset($formipay_settings['paypal_secret']) ? $formipay_settings['paypal_secret'] : '';
|
||||
$environment = isset($formipay_settings[$this->gateway . '_environment']) ? $formipay_settings[$this->gateway . '_environment'] : 'sandbox';
|
||||
|
||||
if ($paypal_client_id && $paypal_secret) {
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$paypal_order_id = isset($_GET['token']) ? sanitize_text_field(wp_unslash($_GET['token'])) : '';
|
||||
|
||||
$base_url = ($environment === 'production')
|
||||
? 'https://api-m.paypal.com/v2'
|
||||
: 'https://api-m.sandbox.paypal.com/v2';
|
||||
|
||||
$url = $base_url . '/checkout/orders/' . $paypal_order_id . '/capture';
|
||||
|
||||
$args = [
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
],
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body',
|
||||
'timeout' => 20,
|
||||
];
|
||||
|
||||
$response = wp_remote_post($url, $args);
|
||||
$body = is_wp_error($response) ? null : wp_remote_retrieve_body($response);
|
||||
$response_data = json_decode($body, true);
|
||||
|
||||
if (isset($response_data['status']) && $response_data['status'] === 'COMPLETED') {
|
||||
$update_order_status = formipay_update_order_status([
|
||||
'form_id' => $form_id,
|
||||
'order_id' => $order_id,
|
||||
'payment_gateway' => $this->gateway,
|
||||
'status' => 'completed'
|
||||
]);
|
||||
if (!empty($update_order_status['valid'])) {
|
||||
$capture_details = $response_data['purchase_units'][0]['payments']['captures'][0] ?? [];
|
||||
$this->update_transaction($order_id, $response_data['status'], $capture_details);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine redirect action
|
||||
$action_type = formipay_get_post_meta($form_id, 'submit_action_type');
|
||||
$params = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
|
||||
|
||||
if ($action_type === 'thankyou') {
|
||||
$thankyou_slug = !empty($formipay_settings['thankyou_link'])
|
||||
? sanitize_title($formipay_settings['thankyou_link'])
|
||||
: 'thankyou';
|
||||
wp_safe_redirect(site_url('/' . $thankyou_slug . '/' . $token_raw . '?' . $params));
|
||||
exit;
|
||||
} elseif ($action_type === 'redirect') {
|
||||
$url = formipay_get_post_meta($form_id, 'redirect_url');
|
||||
$url = esc_url_raw($url);
|
||||
if (strpos($url, '?') !== false) {
|
||||
wp_safe_redirect($url . '&' . $params);
|
||||
} else {
|
||||
wp_safe_redirect($url . '?' . $params);
|
||||
}
|
||||
exit;
|
||||
} elseif ($action_type === 'whatsapp') {
|
||||
$order = formipay_get_order($order_id);
|
||||
$order_data = [];
|
||||
if (is_array($order)) {
|
||||
foreach ($order as $key => $data) {
|
||||
$order_data[$key] = maybe_unserialize($data);
|
||||
}
|
||||
}
|
||||
$admin_number = formipay_get_post_meta($form_id, 'whatsapp_admin');
|
||||
$shortcodes = [
|
||||
'{{product_name}}' => get_the_title($form_id),
|
||||
'{{order_id}}' => $order_id,
|
||||
'{{order_date}}' => $order['created_date'] ?? '',
|
||||
'{{order_total}}' => $order['total'] ?? '',
|
||||
'{{order_status}}' => $order['status'] ?? '',
|
||||
'{{order_details}}' => $this->render_order_details($form_id, $order_id, maybe_unserialize($order['items'] ?? '')),
|
||||
'{{payment_details}}' => $this->render_payment_details('', $form_id, $order_data, 'whatsapp'),
|
||||
];
|
||||
$message_template = wp_kses_post(formipay_get_post_meta($form_id, 'whatsapp_message'));
|
||||
$message = strtr($message_template, $shortcodes);
|
||||
$message = str_replace('%250A', '%0A', rawurlencode($message));
|
||||
$whatsapp_url = 'https://api.whatsapp.com/send/?phone=' . urlencode($admin_number) . '&text=' . $message;
|
||||
wp_safe_redirect($whatsapp_url);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handle_paypal_webhook(\WP_REST_Request $request) {
|
||||
$body = $request->get_body();
|
||||
$event = json_decode($body, true);
|
||||
|
||||
if (!$event || empty($event['event_type'])) {
|
||||
return new \WP_Error('invalid_webhook', 'Invalid webhook payload');
|
||||
}
|
||||
|
||||
// Example: get order_id from custom_id or invoice_number in resource
|
||||
$resource = $event['resource'];
|
||||
$order_id = null;
|
||||
|
||||
if (!empty($resource['custom_id'])) {
|
||||
$order_id = intval($resource['custom_id']);
|
||||
} elseif (!empty($resource['invoice_number'])) {
|
||||
$order_id = intval($resource['invoice_number']);
|
||||
}
|
||||
|
||||
if (!$order_id) {
|
||||
return new \WP_Error('missing_order_id', 'Cannot find order ID in webhook');
|
||||
}
|
||||
|
||||
// Map PayPal event to order status
|
||||
switch ($event['event_type']) {
|
||||
case 'PAYMENT.CAPTURE.COMPLETED':
|
||||
$status = 'completed';
|
||||
break;
|
||||
case 'PAYMENT.CAPTURE.PENDING':
|
||||
$status = 'pending';
|
||||
break;
|
||||
case 'PAYMENT.CAPTURE.REFUNDED':
|
||||
case 'PAYMENT.CAPTURE.PARTIALLY_REFUNDED':
|
||||
$status = 'refunded';
|
||||
break;
|
||||
case 'PAYMENT.CAPTURE.DENIED':
|
||||
case 'PAYMENT.CAPTURE.REVERSED':
|
||||
case 'PAYMENT.ORDER.CANCELLED':
|
||||
$status = 'cancelled';
|
||||
break;
|
||||
default:
|
||||
// Ignore unhandled events
|
||||
return rest_ensure_response(['ignored' => true]);
|
||||
}
|
||||
|
||||
// Update order and transaction
|
||||
formipay_update_order_status([
|
||||
'order_id' => $order_id,
|
||||
'payment_gateway' => $this->gateway,
|
||||
'status' => $status
|
||||
]);
|
||||
$this->update_transaction($order_id, $status, $resource);
|
||||
|
||||
return rest_ensure_response(['updated' => true, 'order_id' => $order_id, 'status' => $status]);
|
||||
}
|
||||
|
||||
public function render_order_details($form_id, $order_id, $items) {
|
||||
|
||||
$order = formipay_get_order($order_id);
|
||||
|
||||
$target_length = 40;
|
||||
$message_format = formipay_get_post_meta($form_id, 'whatsapp_message');
|
||||
$order_details_message = '```';
|
||||
if(!empty($items)){
|
||||
foreach($items as $detail){
|
||||
$qty = '';
|
||||
if(isset($detail['qty']) && !empty($detail['qty'])){
|
||||
$qty = $detail['qty'].'×';
|
||||
}
|
||||
$subtotal = formipay_price_format($detail['subtotal'], $form_id);
|
||||
$qty_length = strlen($qty);
|
||||
$subtotal_length = strlen($subtotal);
|
||||
if(floatval($detail['subtotal']) < 0){
|
||||
$subtotal_length = $subtotal_length + 1;
|
||||
}
|
||||
$dot_length = $target_length - ($qty_length + $subtotal_length);
|
||||
$dots = str_repeat('.', intval($dot_length));
|
||||
$order_details_message .= '%0A'.$detail['item'];
|
||||
$order_details_message .= '%0A'.$qty.$dots.$subtotal;
|
||||
}
|
||||
$total = formipay_price_format($order['total'], $form_id);
|
||||
$total_length = strlen($total);
|
||||
$dot_length = $target_length - ($total_length + 6);
|
||||
$dots = str_repeat('.', intval($dot_length));
|
||||
$divider = str_repeat('_', intval($target_length));
|
||||
$order_details_message .= '%0A'.$divider;
|
||||
$order_details_message .= '%0A'.'';
|
||||
$order_details_message .= '%0A'.'Total'.$dots.$total;
|
||||
}
|
||||
$order_details_message .= '%0A```';
|
||||
|
||||
$content = $order_details_message;
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
if($order_data['status'] == 'completed'){
|
||||
return $render;
|
||||
}
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$get_trx = $this->get_transaction($order_data['id']);
|
||||
if(!empty($get_trx)){
|
||||
$meta = maybe_unserialize($get_trx->meta_data);
|
||||
if(isset($meta['payer_action_url']) && !empty($meta['payer_action_url'])){
|
||||
|
||||
if($formipay_settings[$this->gateway.'_toggle'] !== false){
|
||||
if($submit_action_type == 'thankyou'){
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<a id="upload-transfer-receipt" class="formipay-submit-button" href="<?php echo esc_url($meta['payer_action_url']) ?>">
|
||||
<i class="bi bi-paypal"></i> <?php echo esc_html__( 'Pay Now', 'formipay' ); ?>
|
||||
</a>
|
||||
<?php
|
||||
$render = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
}elseif($submit_action_type == 'whatsapp'){
|
||||
|
||||
$slug = 'thankyou';
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
// translators: %s is the Paypal payment URL.
|
||||
$message = sprintf( __('> Payment Link: *%s*', 'formipay'), $meta['payer_action_url'] );
|
||||
|
||||
$render = $message;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $render;
|
||||
|
||||
}
|
||||
|
||||
public function render_email_action_button($button, $recipient, $order_data){
|
||||
|
||||
if(
|
||||
$order_data['payment_gateway'] == $this->gateway &&
|
||||
$order_data['status'] == 'on-hold' &&
|
||||
$recipient !== 'admin'
|
||||
){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$get_trx = $this->get_transaction($order_data['id']);
|
||||
if(!empty($get_trx)){
|
||||
$meta = maybe_unserialize($get_trx->meta_data);
|
||||
if(isset($meta['payer_action_url']) && !empty($meta['payer_action_url'])){
|
||||
|
||||
$button = [
|
||||
'url' => $meta['payer_action_url'],
|
||||
'label' => __( 'Pay Now', 'formipay' )
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $button;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
821
includes/Integration/Paypal.phpbak
Normal file
@@ -0,0 +1,821 @@
|
||||
<?php
|
||||
namespace Formipay\Integration;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
use Formipay\Payment\Payment;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Paypal extends Payment {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $gateway = 'paypal';
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
add_action( 'formipay/order/new', [$this, 'add_transaction'], 99 );
|
||||
|
||||
add_filter( 'formipay/form-config/tab:payments/gateways', [$this, 'add_gateway'] );
|
||||
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_paypal_settings'] );
|
||||
add_filter( 'formipay/global-settings/tab:payment', [$this, 'add_settings'] );
|
||||
add_filter( 'formipay/payment-list/paypal/label', [$this, 'set_frontend_label'] );
|
||||
add_filter( 'formipay/payment-list/paypal/logo', [$this, 'set_frontend_logo'] );
|
||||
add_filter( 'formipay/order/result', [$this, 'process_payment'], 99 );
|
||||
add_action( 'parse_query', [$this, 'check_parse_query'] );
|
||||
add_filter( 'formipay/order/payment-details/paypal', [$this, 'render_payment_details'], 999, 4 );
|
||||
|
||||
add_filter('formipay/notification/order/email/action-button', [$this, 'render_email_action_button'], 99, 3 );
|
||||
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
|
||||
global $wpdb;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_paypal_trx` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`created_date` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
`form_id` int DEFAULT 0,
|
||||
`order_id` int DEFAULT 0,
|
||||
`currency_code` text,
|
||||
`total` float(10, 2) DEFAULT 0,
|
||||
`status` text,
|
||||
`meta_data` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta($create);
|
||||
|
||||
}
|
||||
|
||||
public function add_transaction($order_data) {
|
||||
|
||||
$form_id = absint($order_data['form_id'] ?? 0);
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$timeout = isset($formipay_settings['paypal_timeout']) ? (int) $formipay_settings['paypal_timeout'] : 1440;
|
||||
|
||||
$currency_meta = formipay_get_post_meta($form_id, 'product_currency');
|
||||
$currency_parts = explode(':::', $currency_meta);
|
||||
$currency = !empty($currency_parts[0]) ? sanitize_text_field($currency_parts[0]) : '';
|
||||
|
||||
if($this->gateway === ($order_data['payment_gateway'] ?? '')) {
|
||||
|
||||
$submit_args = [
|
||||
'created_date' => formipay_date('Y-m-d H:i:s', strtotime($order_data['created_date'] ?? 'now')),
|
||||
'form_id' => $form_id,
|
||||
'order_id' => absint($order_data['id'] ?? 0),
|
||||
'currency_code' => $currency,
|
||||
'total' => floatval($order_data['total'] ?? 0),
|
||||
'status' => 'PENDING',
|
||||
'meta_data' => maybe_serialize([
|
||||
'request_response' => maybe_serialize($order_data['payment_callback']),
|
||||
'payer_action_url' => esc_url_raw($order_data['redirect_url'] ?? '')
|
||||
])
|
||||
];
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_paypal_trx';
|
||||
|
||||
$format = [
|
||||
'%s', // created_date
|
||||
'%d', // form_id
|
||||
'%d', // order_id
|
||||
'%s', // currency_code
|
||||
'%f', // total
|
||||
'%s', // status
|
||||
'%s' // meta_data
|
||||
];
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$wpdb->insert($table, $submit_args, $format);
|
||||
|
||||
wp_schedule_single_event(
|
||||
(int) formipay_date('timestamp') + $timeout, 'formipay/order/payment-timeout', [
|
||||
'order_id' => $order_data['id'],
|
||||
'payment_gateway' => 'paypal'
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function auto_cancel_order_on_timeout($order_id, $payment_gateway) {
|
||||
|
||||
if($payment_gateway == 'paypal'){
|
||||
|
||||
global $wpdb;
|
||||
$order = formipay_get_order($order_id);
|
||||
if($order['status'] !== 'completed'){
|
||||
Order::update($order_id, [
|
||||
'status' => 'cancelled'
|
||||
]);
|
||||
$this->cancel_payment($order_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function get_transaction($order_id = 0) {
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix .'formipay_paypal_trx';
|
||||
if($order_id == 0){
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i", $table
|
||||
)
|
||||
);
|
||||
}else{
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i WHERE `order_id` = %d", $table, $order_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $get;
|
||||
|
||||
}
|
||||
|
||||
public function update_transaction($order_id, $status, $callback) {
|
||||
|
||||
$args = [
|
||||
'status' => sanitize_text_field( $status ),
|
||||
'meta_data' => maybe_serialize( $callback )
|
||||
];
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_paypal_trx';
|
||||
$where = ['order_id' => $order_id];
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$update = $wpdb->update(
|
||||
$table, $args, $where
|
||||
);
|
||||
|
||||
return $update;
|
||||
|
||||
}
|
||||
|
||||
public function add_gateway($gateways) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(isset($formipay_settings['paypal_toggle']) && $formipay_settings['paypal_toggle'] == 'yes') {
|
||||
$gateways[] = [
|
||||
'id' => $this->gateway,
|
||||
'gateway' => __( 'Paypal', 'formipay' )
|
||||
];
|
||||
}
|
||||
|
||||
return $gateways;
|
||||
|
||||
}
|
||||
|
||||
public function add_settings($fields) {
|
||||
|
||||
$payment_instruction = file_get_contents( FORMIPAY_PATH . 'admin/templates/paypal-instruction.html' );
|
||||
|
||||
$paypal_settings = array(
|
||||
$this->gateway.'_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Activate Paypal', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_account_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Paypal Account', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_instruction' => array(
|
||||
'type' => 'notification_message',
|
||||
'description' => $payment_instruction,
|
||||
'buttons' => array(
|
||||
'show_instruction' => array(
|
||||
'text' => __( 'Show Instruction', 'formipay' ),
|
||||
'class' => 'show-instruction'
|
||||
)
|
||||
),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'submenu' => __( 'Paypal', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_client_id' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Client ID', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_secret' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Secret', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_environment' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Environment', 'formipay' ),
|
||||
'options' => array(
|
||||
'sandbox' => __( 'Sandbox', 'formipay' ),
|
||||
'production' => __( 'Production', 'formipay' )
|
||||
),
|
||||
'value' => 'sandbox',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_merchant_email' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Merchant Email', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
$this->gateway.'_timeout' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Payment Timeout (minute)', 'formipay' ),
|
||||
'description' => __( 'Set a timeout to wait for payment. After this timeout is up, the order status automatically changes to cancelled.', 'formipay' ),
|
||||
'value' => 120,
|
||||
'group' => 'ended',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
foreach($paypal_settings as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_paypal_settings($fields) {
|
||||
|
||||
$paypal_settings = array(
|
||||
|
||||
$this->gateway.'_confirmation_notice_message_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Notice Messages', 'formipay' ),
|
||||
'description' => __(
|
||||
'Set notice message on every condition about attempting to confirm the payment', 'formipay' ),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_update_to_status' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Change status order to', 'formipay' ),
|
||||
'options' => formipay_order_status_list(),
|
||||
'value' => 'payment-confirm',
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_success' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Successfully Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('Successfully confirmed payment for #{{order_id}}', 'formipay'),
|
||||
'description' => __('When successfully change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_already_confirmed' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Has Been Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('#{{order_id}} has been confirmed', 'formipay'),
|
||||
'description' => __('When the order status has been the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_error' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Failed to Confirm Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay'),
|
||||
'system_error_message' => __('System Error Message', 'formipay')
|
||||
),
|
||||
'value' => __('Failed to proceed. Error: {{system_error_message}}', 'formipay'),
|
||||
'description' => __('When error to change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Paypal', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
foreach($paypal_settings as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function set_frontend_label($label){
|
||||
|
||||
$label = __( 'Paypal', 'formipay' );
|
||||
|
||||
return $label;
|
||||
|
||||
}
|
||||
|
||||
public function set_frontend_logo($logo){
|
||||
|
||||
if($logo == false){
|
||||
$logo = FORMIPAY_URL . 'public/assets/img/paypal.png';
|
||||
}
|
||||
|
||||
return $logo;
|
||||
|
||||
}
|
||||
|
||||
public function prepare_payload($order_data) {
|
||||
|
||||
// error_log('current order'. $order_data['id'] . ': ' . print_r($order_data, true));
|
||||
|
||||
$form_id = intval($order_data['form_id']);
|
||||
$order_details = $order_data['items'];
|
||||
|
||||
if($this->gateway == $order_data['payment_gateway']){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$grand_total = floatval($order_data['total']);
|
||||
|
||||
// Currency
|
||||
$currency = explode(':::', formipay_get_post_meta($form_id, 'product_currency'));
|
||||
$currency = $currency[0];
|
||||
|
||||
$currency_decimal_digits = formipay_get_post_meta($form_id, 'product_currency_decimal_digits');
|
||||
$currency_decimal_symbol = formipay_get_post_meta($form_id, 'product_currency_decimal_symbol');
|
||||
$currency_thousand_separator = formipay_get_post_meta($form_id, 'product_currency_thousand_separator');
|
||||
|
||||
$slug = 'thankyou';
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
if(formipay_get_post_meta($form_id, 'product_type') == 'digital'){
|
||||
$shipping_preference = 'NO_SHIPPING';
|
||||
}else{
|
||||
$shipping_preference = 'SET_PROVIDED_ADDRESS';
|
||||
}
|
||||
|
||||
// Setup items
|
||||
$items = [];
|
||||
foreach($order_details as $item){
|
||||
$qty = 1;
|
||||
if(!empty($item['qty'])){
|
||||
$qty = $item['qty'];
|
||||
}
|
||||
if(floatval($item['amount']) >= 0){
|
||||
$items[] = [
|
||||
'name' => $item['item'],
|
||||
'unit_amount' => [
|
||||
'currency_code' => $currency,
|
||||
'value' => floatval($item['amount'])
|
||||
],
|
||||
'quantity' => $qty
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$items = apply_filters('formipay/order/paypal/payload/items', $items, $currency, $order_data);
|
||||
|
||||
$breakdown = array(
|
||||
"item_total" => array(
|
||||
"currency_code" => $currency,
|
||||
"value" => $grand_total
|
||||
)
|
||||
);
|
||||
$breakdown = apply_filters('formipay/order/paypal/payload/breakdown', $breakdown, $currency, $order_data);
|
||||
|
||||
$unique_id = $order_data['meta_data']['session_id']['value'];
|
||||
|
||||
// Prepare the payload
|
||||
$payload = json_encode(array(
|
||||
"intent" => "CAPTURE",
|
||||
"purchase_units" => array(
|
||||
array(
|
||||
"amount" => array(
|
||||
"currency_code" => $currency,
|
||||
"value" => $grand_total, // Format amount
|
||||
"breakdown" => $breakdown
|
||||
),
|
||||
"items" => $items
|
||||
)
|
||||
),
|
||||
'payment_source' => array(
|
||||
'paypal' => array(
|
||||
'experience_context' => array(
|
||||
'return_url' => site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($order_data['form_id'].':::'.$order_data['id'].':::'.$unique_id).'?paypal-status=success'),
|
||||
'cancel_url' => site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($order_data['form_id'].':::'.$order_data['id'].':::'.$unique_id).'?paypal-status=cancel'),
|
||||
'user_action' => 'PAY_NOW',
|
||||
'brand_name' => 'FORMIPAY INC',
|
||||
'local' => 'en-US',
|
||||
'landing_page' => 'LOGIN',
|
||||
'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
|
||||
'shipping_preference' => $shipping_preference
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function process_payment( $order_data ) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if($order_data['payment_gateway'] == 'paypal') {
|
||||
|
||||
$paypal_client_id = $formipay_settings['paypal_client_id'];
|
||||
$paypal_secret = $formipay_settings['paypal_secret'];
|
||||
|
||||
// Set your authentication header
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
|
||||
// Define arguments for wp_remote_post
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
),
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body'
|
||||
);
|
||||
|
||||
$url = 'https://api-m.sandbox.paypal.com/v2';
|
||||
if(isset($formipay_settings[$this->gateway.'_environment']) && $formipay_settings[$this->gateway.'_environment'] == 'production') {
|
||||
$url = 'https://api-m.paypal.com/v2';
|
||||
}
|
||||
|
||||
$payload = $this->prepare_payload($order_data);
|
||||
// error_log('paypal payload:'.print_r($payload, true));
|
||||
$args['body'] = $payload;
|
||||
$url = $url.'/checkout/orders';
|
||||
|
||||
$response = wp_remote_retrieve_body( wp_remote_post($url, $args) );
|
||||
$response = json_decode($response);
|
||||
// error_log('paypal response:'.print_r($response, true));
|
||||
|
||||
$payer_action_link = null;
|
||||
|
||||
foreach ($response->links as $link) {
|
||||
if ($link->rel === 'payer-action') {
|
||||
$payer_action_link = $link->href;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($payer_action_link !== null){
|
||||
$order_data['payment_callback'] = $response;
|
||||
$order_data['redirect_url'] = $payer_action_link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $order_data;
|
||||
|
||||
}
|
||||
|
||||
public function cancel_payment( $order_data ) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if($order_data['payment_gateway'] == 'paypal') {
|
||||
|
||||
$paypal_client_id = $formipay_settings['paypal_client_id'];
|
||||
$paypal_secret = $formipay_settings['paypal_secret'];
|
||||
|
||||
// Set your authentication header
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
|
||||
// Define arguments for wp_remote_post
|
||||
$args = array(
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
),
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body'
|
||||
);
|
||||
|
||||
$url = 'https://api-m.sandbox.paypal.com/v2';
|
||||
if(isset($formipay_settings[$this->gateway.'_environment']) && $formipay_settings[$this->gateway.'_environment'] == 'production') {
|
||||
$url = 'https://api-m.paypal.com/v2';
|
||||
}
|
||||
|
||||
$payload = $this->prepare_payload($order_data);
|
||||
// error_log('paypal payload:'.print_r($payload, true));
|
||||
$args['body'] = $payload;
|
||||
$url = $url.'/checkout/orders';
|
||||
|
||||
$response = wp_remote_retrieve_body( wp_remote_post($url, $args) );
|
||||
$response = json_decode($response);
|
||||
// error_log('paypal response:'.print_r($response, true));
|
||||
|
||||
$payer_action_link = null;
|
||||
|
||||
foreach ($response->links as $link) {
|
||||
if ($link->rel === 'payer-action') {
|
||||
$payer_action_link = $link->href;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($payer_action_link !== null){
|
||||
$order_data['redirect_url'] = $payer_action_link;
|
||||
}
|
||||
|
||||
do_action('formipay/notification/order', $order_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function check_parse_query() {
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wp_query;
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
// Validate query vars early
|
||||
$query = $wp_query->query;
|
||||
if (
|
||||
is_array($query) &&
|
||||
!empty($query['formipay-payment-confirm']) &&
|
||||
filter_var($query['formipay-payment-confirm'], FILTER_VALIDATE_BOOLEAN) &&
|
||||
!empty($query['gateway']) &&
|
||||
$query['gateway'] === 'paypal'
|
||||
) {
|
||||
// Sanitize and validate token
|
||||
$token_raw = isset($query['formipay-token']) ? $query['formipay-token'] : '';
|
||||
$token_decoded = base64_decode($token_raw, true);
|
||||
if (!$token_decoded) {
|
||||
return;
|
||||
}
|
||||
$token = explode(':::', $token_decoded);
|
||||
if (count($token) < 2) {
|
||||
return;
|
||||
}
|
||||
$form_id = absint($token[0]);
|
||||
$order_id = absint($token[1]);
|
||||
if (!$form_id || !$order_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$check_order = $this->get_transaction($order_id);
|
||||
|
||||
// Check PayPal status and process payment
|
||||
if (!empty($check_order) &&
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['paypal-status']) && sanitize_text_field(wp_unslash($_GET['paypal-status'])) === 'success' &&
|
||||
strtoupper($check_order->status) === 'PENDING'
|
||||
) {
|
||||
$paypal_client_id = isset($formipay_settings['paypal_client_id']) ? $formipay_settings['paypal_client_id'] : '';
|
||||
$paypal_secret = isset($formipay_settings['paypal_secret']) ? $formipay_settings['paypal_secret'] : '';
|
||||
$environment = isset($formipay_settings[$this->gateway . '_environment']) ? $formipay_settings[$this->gateway . '_environment'] : 'sandbox';
|
||||
|
||||
if ($paypal_client_id && $paypal_secret) {
|
||||
$auth = base64_encode($paypal_client_id . ':' . $paypal_secret);
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$paypal_order_id = isset($_GET['token']) ? sanitize_text_field(wp_unslash($_GET['token'])) : '';
|
||||
|
||||
$base_url = ($environment === 'production')
|
||||
? 'https://api-m.paypal.com/v2'
|
||||
: 'https://api-m.sandbox.paypal.com/v2';
|
||||
|
||||
$url = $base_url . '/checkout/orders/' . $paypal_order_id . '/capture';
|
||||
|
||||
$args = [
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Basic ' . $auth,
|
||||
],
|
||||
'method' => 'POST',
|
||||
'data_format' => 'body',
|
||||
'timeout' => 20,
|
||||
];
|
||||
|
||||
$response = wp_remote_post($url, $args);
|
||||
$body = is_wp_error($response) ? null : wp_remote_retrieve_body($response);
|
||||
$response_data = json_decode($body, true);
|
||||
|
||||
if (isset($response_data['status']) && $response_data['status'] === 'COMPLETED') {
|
||||
$update_order_status = formipay_update_order_status([
|
||||
'form_id' => $form_id,
|
||||
'order_id' => $order_id,
|
||||
'payment_gateway' => $this->gateway,
|
||||
'status' => 'completed'
|
||||
]);
|
||||
if (!empty($update_order_status['valid'])) {
|
||||
$capture_details = $response_data['purchase_units'][0]['payments']['captures'][0] ?? [];
|
||||
$this->update_transaction($order_id, $response_data['status'], $capture_details);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine redirect action
|
||||
$action_type = formipay_get_post_meta($form_id, 'submit_action_type');
|
||||
$params = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
|
||||
|
||||
if ($action_type === 'thankyou') {
|
||||
$thankyou_slug = !empty($formipay_settings['thankyou_link'])
|
||||
? sanitize_title($formipay_settings['thankyou_link'])
|
||||
: 'thankyou';
|
||||
wp_safe_redirect(site_url('/' . $thankyou_slug . '/' . $token_raw . '?' . $params));
|
||||
exit;
|
||||
} elseif ($action_type === 'redirect') {
|
||||
$url = formipay_get_post_meta($form_id, 'redirect_url');
|
||||
$url = esc_url_raw($url);
|
||||
if (strpos($url, '?') !== false) {
|
||||
wp_safe_redirect($url . '&' . $params);
|
||||
} else {
|
||||
wp_safe_redirect($url . '?' . $params);
|
||||
}
|
||||
exit;
|
||||
} elseif ($action_type === 'whatsapp') {
|
||||
$order = formipay_get_order($order_id);
|
||||
$order_data = [];
|
||||
if (is_array($order)) {
|
||||
foreach ($order as $key => $data) {
|
||||
$order_data[$key] = maybe_unserialize($data);
|
||||
}
|
||||
}
|
||||
$admin_number = formipay_get_post_meta($form_id, 'whatsapp_admin');
|
||||
$shortcodes = [
|
||||
'{{product_name}}' => get_the_title($form_id),
|
||||
'{{order_id}}' => $order_id,
|
||||
'{{order_date}}' => $order['created_date'] ?? '',
|
||||
'{{order_total}}' => $order['total'] ?? '',
|
||||
'{{order_status}}' => $order['status'] ?? '',
|
||||
'{{order_details}}' => $this->render_order_details($form_id, $order_id, maybe_unserialize($order['items'] ?? '')),
|
||||
'{{payment_details}}' => $this->render_payment_details('', $form_id, $order_data, 'whatsapp'),
|
||||
];
|
||||
$message_template = wp_kses_post(formipay_get_post_meta($form_id, 'whatsapp_message'));
|
||||
$message = strtr($message_template, $shortcodes);
|
||||
$message = str_replace('%250A', '%0A', rawurlencode($message));
|
||||
$whatsapp_url = 'https://api.whatsapp.com/send/?phone=' . urlencode($admin_number) . '&text=' . $message;
|
||||
wp_safe_redirect($whatsapp_url);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render_order_details($form_id, $order_id, $items) {
|
||||
|
||||
$order = formipay_get_order($order_id);
|
||||
|
||||
$target_length = 40;
|
||||
$message_format = formipay_get_post_meta($form_id, 'whatsapp_message');
|
||||
$order_details_message = '```';
|
||||
if(!empty($items)){
|
||||
foreach($items as $detail){
|
||||
$qty = '';
|
||||
if(isset($detail['qty']) && !empty($detail['qty'])){
|
||||
$qty = $detail['qty'].'×';
|
||||
}
|
||||
$subtotal = formipay_price_format($detail['subtotal'], $form_id);
|
||||
$qty_length = strlen($qty);
|
||||
$subtotal_length = strlen($subtotal);
|
||||
if(floatval($detail['subtotal']) < 0){
|
||||
$subtotal_length = $subtotal_length + 1;
|
||||
}
|
||||
$dot_length = $target_length - ($qty_length + $subtotal_length);
|
||||
$dots = str_repeat('.', intval($dot_length));
|
||||
$order_details_message .= '%0A'.$detail['item'];
|
||||
$order_details_message .= '%0A'.$qty.$dots.$subtotal;
|
||||
}
|
||||
$total = formipay_price_format($order['total'], $form_id);
|
||||
$total_length = strlen($total);
|
||||
$dot_length = $target_length - ($total_length + 6);
|
||||
$dots = str_repeat('.', intval($dot_length));
|
||||
$divider = str_repeat('_', intval($target_length));
|
||||
$order_details_message .= '%0A'.$divider;
|
||||
$order_details_message .= '%0A'.'';
|
||||
$order_details_message .= '%0A'.'Total'.$dots.$total;
|
||||
}
|
||||
$order_details_message .= '%0A```';
|
||||
|
||||
$content = $order_details_message;
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
if($order_data['status'] == 'completed'){
|
||||
return $render;
|
||||
}
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$get_trx = $this->get_transaction($order_data['id']);
|
||||
if(!empty($get_trx)){
|
||||
$meta = maybe_unserialize($get_trx->meta_data);
|
||||
if(isset($meta['payer_action_url']) && !empty($meta['payer_action_url'])){
|
||||
|
||||
if($formipay_settings[$this->gateway.'_toggle'] !== false){
|
||||
if($submit_action_type == 'thankyou'){
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<a id="upload-transfer-receipt" class="formipay-submit-button" href="<?php echo esc_url($meta['payer_action_url']) ?>">
|
||||
<i class="bi bi-paypal"></i> <?php echo esc_html__( 'Pay Now', 'formipay' ); ?>
|
||||
</a>
|
||||
<?php
|
||||
$render = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
}elseif($submit_action_type == 'whatsapp'){
|
||||
|
||||
$slug = 'thankyou';
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
// translators: %s is the Paypal payment URL.
|
||||
$message = sprintf( __('> Payment Link: *%s*', 'formipay'), $meta['payer_action_url'] );
|
||||
|
||||
$render = $message;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $render;
|
||||
|
||||
}
|
||||
|
||||
public function render_email_action_button($button, $recipient, $order_data){
|
||||
|
||||
if(
|
||||
$order_data['payment_gateway'] == $this->gateway &&
|
||||
$order_data['status'] == 'on-hold' &&
|
||||
$recipient !== 'admin'
|
||||
){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$get_trx = $this->get_transaction($order_data['id']);
|
||||
if(!empty($get_trx)){
|
||||
$meta = maybe_unserialize($get_trx->meta_data);
|
||||
if(isset($meta['payer_action_url']) && !empty($meta['payer_action_url'])){
|
||||
|
||||
$button = [
|
||||
'url' => $meta['payer_action_url'],
|
||||
'label' => __( 'Pay Now', 'formipay' )
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $button;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
797
includes/Notification/Email.php
Normal file
@@ -0,0 +1,797 @@
|
||||
<?php
|
||||
namespace Formipay\Notification;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Email extends Notification {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $formipay_settings;
|
||||
|
||||
private $order_data;
|
||||
private $payment_timeout;
|
||||
|
||||
private $email_template = null;
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action('formipay/notification/order/email', [$this, 'notification'] );
|
||||
add_action('formipay/notification/access/email', [$this, 'access_link'] );
|
||||
add_action('formipay/notification/order/email/trigger-event', [$this, 'send_email'], 999 );
|
||||
|
||||
$this->formipay_settings = get_option('formipay_settings');
|
||||
|
||||
}
|
||||
|
||||
private function get_email_template() {
|
||||
if ($this->email_template === null) {
|
||||
$this->email_template = file_get_contents(FORMIPAY_PATH . 'notification/email_templates/email-page-template.html');
|
||||
}
|
||||
return $this->email_template;
|
||||
}
|
||||
|
||||
public function notification($order_data) {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
$this->order_data = $order_data;
|
||||
|
||||
$recipient_type = apply_filters('formipay/notification/recipients', ['admin', 'buyer'] );
|
||||
|
||||
$order_status = str_replace('-', '_', $this->order_data['status']);
|
||||
|
||||
foreach($recipient_type as $recipient){
|
||||
|
||||
if(
|
||||
false !== boolval($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_toggle']) &&
|
||||
!empty($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_title']) &&
|
||||
!empty($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_content'])
|
||||
) {
|
||||
|
||||
$recipient_email = '';
|
||||
$buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_email');
|
||||
|
||||
if($recipient == 'admin' && false !== boolval($formipay_settings['notification_email_admin_recipient'])){
|
||||
$recipient_email = $formipay_settings['notification_email_admin_recipient'];
|
||||
}elseif( $recipient == 'buyer' && !empty($buyer_email_field)) {
|
||||
$recipient_email = $this->order_data['form_data'][$buyer_email_field];
|
||||
}
|
||||
|
||||
if( '' !== $recipient_email ){
|
||||
|
||||
$args = [
|
||||
'order_id' => $this->order_data['id'],
|
||||
'recipient_type' => $recipient,
|
||||
'media' => 'email',
|
||||
'notification_data' => [
|
||||
'to' => $recipient_email,
|
||||
'subject' => $formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_title'],
|
||||
'content' => $this->process_content($recipient)
|
||||
],
|
||||
'meta_data' => [
|
||||
'request_date' => formipay_date('Y-m-d H:i:s')
|
||||
]
|
||||
];
|
||||
|
||||
$notification_id = parent::insert_notification_data($args);
|
||||
|
||||
if(false !== $notification_id){
|
||||
wp_schedule_single_event( time() + 15, 'formipay/notification/order/email/trigger-event', [$notification_id] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do_action( 'formipay/notification/order/email/trigger', $recipient, $order_data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function send_email($notification_id) {
|
||||
|
||||
$get = parent::get_notification_data_by_id($notification_id);
|
||||
|
||||
if(false !== $get){
|
||||
|
||||
$metadata = maybe_unserialize( $get->meta_data );
|
||||
$get_data = maybe_unserialize( $get->notification_data );
|
||||
$status = $get->status;
|
||||
if(!empty($get_data)){
|
||||
$send_mail = wp_mail(
|
||||
sanitize_email( $get_data['to'] ),
|
||||
$get_data['subject'],
|
||||
$get_data['content'],
|
||||
array('Content-Type: text/html; charset=UTF-8')
|
||||
);
|
||||
if(!is_wp_error($send_mail)){
|
||||
$status = 'sent';
|
||||
}else{
|
||||
$status = 'error';
|
||||
$metadata['error_message'] = $send_mail->get_error_messages();
|
||||
}
|
||||
|
||||
$metadata['update_date'] = formipay_date('Y-m-d H:i:s');
|
||||
$args = [
|
||||
'status' => $status,
|
||||
'meta_data' => $metadata
|
||||
];
|
||||
|
||||
\Formipay_Notification::update_notification_data($notification_id, $args);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function access_link($order_data) {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
$this->order_data = $order_data;
|
||||
$buyer_email_field = formipay_get_post_meta($order_data['form_id'], 'notification_email_buyer_recipient');
|
||||
|
||||
if(
|
||||
!empty($formipay_settings['notification_email_access_link_title']) &&
|
||||
!empty($formipay_settings['notification_email_access_link_content']) &&
|
||||
!empty($buyer_email_field)
|
||||
) {
|
||||
|
||||
$recipient = 'buyer';
|
||||
$recipient_email = '';
|
||||
foreach($order_data['form_data'] as $form_data){
|
||||
if($form_data['name'] == $buyer_email_field){
|
||||
$recipient_email = $form_data['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( '' !== $recipient_email ){
|
||||
$send_mail = wp_mail(
|
||||
sanitize_email( $recipient_email ),
|
||||
$formipay_settings['notification_email_access_link_title'],
|
||||
$this->process_content('buyer', 'access_link'),
|
||||
array('Content-Type: text/html; charset=UTF-8')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do_action( 'formipay/notification/access/email/trigger', $recipient, $order_data);
|
||||
|
||||
}
|
||||
|
||||
public function process_content($recipient, $context='order') {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
$order_status = str_replace('-', '_', $this->order_data['status']);
|
||||
|
||||
$order_body_template = $formipay_settings['notification_email_' . $recipient . '_' . $order_status . '_content'];
|
||||
$accesslink_body_template = $formipay_settings['notification_email_access_link_content'];
|
||||
|
||||
$body_template = $context == 'order' ? $order_body_template : $accesslink_body_template;
|
||||
|
||||
$buyer_name = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
|
||||
if(!empty($buyer_name)){
|
||||
$buyer_name_field = $buyer_name;
|
||||
$buyer_name = $this->order_data['form_data'][$buyer_name_field]['value'];
|
||||
}
|
||||
|
||||
// Prepare the replacements for shortcodes
|
||||
$replacements = [
|
||||
'{{image_logo}}' => $this->get_image_logo(),
|
||||
'{{email_content}}' => $this->get_content($body_template, $context),
|
||||
'{{action_button}}' => $context == 'order' ? $this->get_action_button($recipient) : '',
|
||||
'{{footer_message}}' => $this->get_footer_message(),
|
||||
'{{social_links}}' => $this->get_social_links()
|
||||
];
|
||||
|
||||
// Load the email template
|
||||
$email_template = $this->get_email_template();
|
||||
|
||||
// Replace the shortcodes in the email template
|
||||
$email_template = strtr($email_template, $replacements);
|
||||
|
||||
return $email_template;
|
||||
}
|
||||
|
||||
private function get_content_depracated($body_template, $context) {
|
||||
$form_id = $this->order_data['form_id'];
|
||||
$order_data = $this->order_data;
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
// Cache frequently used settings and meta values
|
||||
$buyer_name_field = formipay_get_post_meta($form_id, 'buyer_name');
|
||||
$payment_gateway = $order_data['form_data']['payment_gateway'];
|
||||
$payment_timeout = !empty($formipay_settings[$payment_gateway . '_timeout'])
|
||||
? formipay_date($order_data['created_date'] . ' + ' . $formipay_settings[$payment_gateway . '_timeout'] . ' minutes')
|
||||
: '';
|
||||
|
||||
$lines = explode('<p><br></p>', $body_template);
|
||||
$content = '';
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
|
||||
if (strpos($line, '{{order_details}}') !== false) {
|
||||
$content .= '<tr class="wp-block-editor-paragraphblock-v1">
|
||||
<td valign="top" style="color:#5f5f5f;letter-spacing:0;word-break:normal;font-size: 1rem;padding:1rem 0;background-color:#ffffff;">';
|
||||
$content .= $this->convert_order_details();
|
||||
$content .= '</td></tr>';
|
||||
} else {
|
||||
$content .= '<tr class="wp-block-editor-paragraphblock-v1">
|
||||
<td valign="top" style="color:#5f5f5f;letter-spacing:0;word-break:normal;font-size: 1rem;padding:1rem 2rem;background-color:#ffffff;">';
|
||||
|
||||
// Replace placeholders with actual data
|
||||
$replacements = [
|
||||
'{{buyer_name}}' => !empty($buyer_name_field) ? $order_data['form_data'][$buyer_name_field] : '',
|
||||
'{{order_id}}' => $order_data['id'],
|
||||
'{{order_status}}' => $order_data['status'],
|
||||
'{{payment_timeout}}' => $payment_timeout
|
||||
];
|
||||
$line = strtr( $line, $replacements );
|
||||
|
||||
if ($context === 'access_link') {
|
||||
$meta_data = $order_data['meta_data'];
|
||||
$meta_session_id = '';
|
||||
foreach($meta_data as $meta){
|
||||
if($meta['name'] == 'session_id'){
|
||||
$meta_session_id = $meta['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$thankyou_link = 'thankyou';
|
||||
if(isset($formipay_settings['thankyou_link']) && !empty($formipay_settings['thankyou_link'])){
|
||||
$thankyou_link = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
$access_link = site_url('/'.$thankyou_link.'/' . base64_encode("$form_id:::{$order_data['id']}:::{$meta_session_id}"));
|
||||
$line = str_replace(
|
||||
[
|
||||
'{{access_link}}',
|
||||
'{{access_button}}'
|
||||
],
|
||||
[
|
||||
$access_link,
|
||||
$this->get_action_button('buyer', 'access_link', ['url' => $access_link, 'label' => 'Access Link'])
|
||||
],
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
$content .= $line;
|
||||
$content .= '</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function get_content($body_template, $context) {
|
||||
$form_id = $this->order_data['form_id'];
|
||||
$order_data = $this->order_data;
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
// Cache frequently used settings and meta values
|
||||
$buyer_name_field = formipay_get_post_meta($form_id, 'buyer_name');
|
||||
$payment_gateway = $order_data['form_data']['payment_gateway']['label'];
|
||||
$this->payment_timeout = $payment_timeout = !empty($formipay_settings[$payment_gateway . '_timeout'])
|
||||
? formipay_date($order_data['created_date'] . ' + ' . $formipay_settings[$payment_gateway . '_timeout'] . ' minutes')
|
||||
: '';
|
||||
|
||||
$lines = explode('</p>', $body_template);
|
||||
$content = '';
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim(str_replace('<p>', '', $line));
|
||||
if(in_array($line, ['', '<br>'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strpos($line, '{{order_details}}') !== false) {
|
||||
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad">
|
||||
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
|
||||
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Order Details', 'formipay' ) . '</span>
|
||||
</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
$content .= $this->convert_order_details();
|
||||
} elseif (strpos($line, '{{order_items}}') !== false) {
|
||||
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad">
|
||||
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
|
||||
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Order Items', 'formipay' ) . '</span>
|
||||
</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
$content .= $this->convert_order_items();
|
||||
} elseif (strpos($line, '{{buyer_details}}') !== false) {
|
||||
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad">
|
||||
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
|
||||
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Buyer Details', 'formipay' ) . '</span>
|
||||
</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
$content .= $this->convert_buyer_details();
|
||||
} else {
|
||||
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word;" width="100%"><tr><td class="pad"><div style="color:#101112;direction:ltr;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:400;letter-spacing:0px;line-height:120%;text-align:left;mso-line-height-alt:19.2px;">';
|
||||
|
||||
// Replace placeholders with actual data
|
||||
$replacements = [
|
||||
'{{buyer_name}}' => !empty($buyer_name_field) ? $order_data['form_data'][$buyer_name_field]['value'] : '',
|
||||
'{{order_id}}' => $order_data['id'],
|
||||
'{{order_status}}' => $order_data['status'],
|
||||
'{{payment_timeout}}' => $payment_timeout
|
||||
];
|
||||
$line = strtr( $line, $replacements );
|
||||
|
||||
if ($context === 'access_link') {
|
||||
$meta_data = $order_data['meta_data'];
|
||||
$meta_session_id = '';
|
||||
foreach($meta_data as $meta){
|
||||
if($meta['name'] == 'session_id'){
|
||||
$meta_session_id = $meta['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$thankyou_link = 'thankyou';
|
||||
if(isset($formipay_settings['thankyou_link']) && !empty($formipay_settings['thankyou_link'])){
|
||||
$thankyou_link = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
$token = Token::generate(
|
||||
$order_data['id'],
|
||||
$form_id,
|
||||
900 // 15-minute expiration
|
||||
);
|
||||
$access_link = site_url('/'.$thankyou_link.'/' . $token);
|
||||
$line = str_replace(
|
||||
[
|
||||
'{{access_link}}',
|
||||
'{{access_button}}'
|
||||
],
|
||||
[
|
||||
$access_link,
|
||||
$this->get_action_button('buyer', 'access_link', ['url' => $access_link, 'label' => __('Access Link', 'formipay')])
|
||||
],
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
$content .= $line;
|
||||
$content .= '</div></td></tr></table>';
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Function to get the logo image
|
||||
private function get_image_logo() {
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
if(empty($formipay_settings['notification_email_logo'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$logo_url = wp_get_attachment_image_url($formipay_settings['notification_email_logo'], 'full');
|
||||
|
||||
if(false == $logo_url){
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template Baru
|
||||
*/
|
||||
|
||||
return '<table border="0" cellpadding="0" cellspacing="0" class="image_block block-1" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; margin: 2rem 0;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="width:100%;">
|
||||
<div align="center" class="alignment" style="line-height:10px">
|
||||
<div style="max-width: 480px;">
|
||||
' . wp_get_attachment_image($formipay_settings['notification_email_logo'], 'full', false, array(
|
||||
'style' => 'display: block; height: auto; border: 0;',
|
||||
'width' => '360'
|
||||
)) . '
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
}
|
||||
|
||||
// Function to convert order details
|
||||
private function convert_order_details_depracated() {
|
||||
|
||||
if(empty($this->order_data['items'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<table role="presentation" align="left" border="0" class="single-column" width="320" style="width:100%;float:left;border-collapse:collapse !important" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
|
||||
<?php foreach($this->order_data['items'] as $item){ ?>
|
||||
|
||||
<tr class="wp-block-editor-paragraphblock-v1" style="border-bottom: 1px solid #CECECE">
|
||||
<td valign="top" style="padding:20px 20px 20px 2rem;background-color:#ffffff">
|
||||
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;">
|
||||
<span style="font-weight: bold; line-height: 1.25rem;" class="bold"><?php echo esc_html($item['item']); ?></span>
|
||||
</p>
|
||||
</td>
|
||||
<td valign="top" style="padding:20px 2rem 20px 20px;background-color:#ffffff">
|
||||
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;text-align:right;min-width:175px;">
|
||||
<?php echo esc_html(formipay_price_format($item['subtotal'], $this->order_data['form_id'])); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="wp-block-editor-paragraphblock-v1">
|
||||
<td valign="top" style="padding:20px 20px 20px 2rem;background-color:#ffffff">
|
||||
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;">
|
||||
<span style="font-weight: bold; line-height: 1.25rem;" class="bold"><?php echo esc_html__('Total', 'formipay'); ?></span>
|
||||
</p>
|
||||
</td>
|
||||
<td valign="top" style="padding:20px 2rem 20px 20px;background-color:#ffffff;min-width:175px;">
|
||||
<p class="paragraph" style="color:<?php echo esc_html($button_background_color['active']); ?>;text-align:right;font-size:1.5rem;margin:0;letter-spacing:0;word-break:normal;">
|
||||
<span style="font-weight: bold" class="bold">
|
||||
<?php echo esc_html(formipay_price_format($this->order_data['total'], $this->order_data['form_id'])); ?>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
$order_details_html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $order_details_html;
|
||||
|
||||
}
|
||||
|
||||
// Function to convert order details
|
||||
private function convert_order_details() {
|
||||
|
||||
if(empty($this->order_data['items'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-4" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="padding: 0;">
|
||||
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
|
||||
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
|
||||
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Order ID', 'formipay' ); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo intval($this->order_data['id']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Order Status', 'formipay' ); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($this->order_data['status']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Payment Timeout', 'formipay' ); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($this->payment_timeout); ?> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
$order_details_html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $order_details_html;
|
||||
|
||||
}
|
||||
|
||||
// Function to convert order items
|
||||
private function convert_order_items() {
|
||||
|
||||
if(empty($this->order_data['items'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-6" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="padding: 0;">
|
||||
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
|
||||
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
|
||||
<thead style="vertical-align: top; font-size: 16px; line-height: 120%;">
|
||||
<tr>
|
||||
<th style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Item', 'formipay' ); ?></th>
|
||||
<th style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html__( 'Amount', 'formipay' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
|
||||
|
||||
<?php foreach($this->order_data['items'] as $item){ ?>
|
||||
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html($item['item']); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html(formipay_price_format($item['subtotal'], $this->order_data['form_id'])); ?></td>
|
||||
</tr>
|
||||
|
||||
<?php } ?>
|
||||
<tr style="border-top: 1px solid #ccc">
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%">
|
||||
<strong style="color: <?php echo esc_html($button_background_color['regular']); ?>;"><?php echo esc_html__( 'Total', 'formipay' ); ?></strong>
|
||||
</td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%">
|
||||
<strong style="color: <?php echo esc_html($button_background_color['regular']); ?>;"><?php echo esc_html(formipay_price_format($this->order_data['total'], $this->order_data['form_id'])); ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
$order_items_html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $order_items_html;
|
||||
|
||||
}
|
||||
|
||||
// Function to convert buyer details
|
||||
private function convert_buyer_details() {
|
||||
|
||||
if(empty($this->order_data['items'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
// $buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'notification_email_buyer_recipient');
|
||||
$field_buyer_name = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
|
||||
$buyer_name = !empty($this->order_data['form_data'][$field_buyer_name]) ? $this->order_data['form_data'][$field_buyer_name] : '';
|
||||
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-8" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="padding: 0;">
|
||||
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
|
||||
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
|
||||
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Name', 'formipay' ); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($buyer_name); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$customer_data = apply_filters('formipay/customer/data-mapping', ['email', 'phone'] );
|
||||
foreach($customer_data as $data){
|
||||
if(false !== formipay_get_post_meta($this->order_data['form_id'], 'notification_'.$data.'_buyer_recipient')) {
|
||||
$field_name = formipay_get_post_meta($this->order_data['form_id'], 'notification_'.$data.'_buyer_recipient');
|
||||
$field_value = !empty($order_data['form_data'][$field_name]) ? $order_data['form_data'][$field_name] : '';
|
||||
if($field_value !== ''){
|
||||
?>
|
||||
<tr>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html(ucwords($data)); ?></td>
|
||||
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($field_value); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
$buyer_details_html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $buyer_details_html;
|
||||
|
||||
}
|
||||
|
||||
private function get_action_button_depracated($recipient, $context='order', $button=[]) {
|
||||
|
||||
if($context == 'order' && empty($button)) {
|
||||
$button = apply_filters( 'formipay/notification/order/email/action-button', [], $recipient, $this->order_data );
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
if(!empty($button)){
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
$button_text_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_text_color'), true );
|
||||
ob_start();
|
||||
if($context == 'order'){
|
||||
?>
|
||||
<tr class="wp-block-editor-buttonblock-v1" align="center">
|
||||
<td style="background-color:#ffffff;padding-top:40px;padding-right:20px;padding-bottom:60px;padding-left:20px;width:100%" valign="top">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" class="button-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top" class="button-CzEb4_za43eNTBt_C1QR7 button-td button-td-primary" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;overflow:hidden">
|
||||
<a href="<?php echo esc_url($button['url']); ?>" style="color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}elseif($context == 'access_link'){
|
||||
?>
|
||||
<a href="<?php echo esc_url($button['url']); ?>" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
|
||||
<?php
|
||||
}
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function get_action_button($recipient, $context='order', $button=[]) {
|
||||
|
||||
if($context == 'order' && empty($button)) {
|
||||
$button = apply_filters( 'formipay/notification/order/email/action-button', [], $recipient, $this->order_data );
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
if(!empty($button)){
|
||||
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
|
||||
$button_text_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_text_color'), true );
|
||||
ob_start();
|
||||
if($context == 'order'){
|
||||
?>
|
||||
<div class="spacer_block block-9" style="height:2rem;line-height:15px;font-size:1px;"></div>
|
||||
<table border="0" cellpadding="10" cellspacing="0" class="button_block block-10" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad" style="padding: 0;">
|
||||
<div align="center" class="alignment">
|
||||
<a href="<?php echo esc_url($button['url']); ?>" style="color:#ffffff;text-decoration:none;" target="_blank">
|
||||
<!--[if mso]>
|
||||
<v:roundrect
|
||||
xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word" href="<?php echo esc_url($button['url']); ?>" style="height:52px;width:460px;v-text-anchor:middle;" arcsize="58%" fillcolor="#7747FF">
|
||||
<v:stroke dashstyle="Solid" weight="0px" color="#7747FF"/>
|
||||
<w:anchorlock/>
|
||||
<v:textbox inset="0px,0px,0px,0px">
|
||||
<center dir="false" style="color:#ffffff;font-family:sans-serif;font-size:16px">
|
||||
<![endif]-->
|
||||
<span class="button" style="background-color: <?php echo esc_html($button_background_color['regular']); ?>; border-bottom: 0px solid transparent; border-left: 0px solid transparent; border-radius: 30px; border-right: 0px solid transparent; border-top: 0px solid transparent; color:<?php echo esc_html($button_text_color['regular']); ?>; display: inline-block; font-family: Arial, Helvetica, sans-serif; font-size: 16px; font-weight: 400; mso-border-alt: none; padding: 10px 0; text-align: center; width: 100%; word-break: keep-all; letter-spacing: normal;">
|
||||
<span style="color:<?php echo esc_html($button_text_color['regular']); ?>;word-break: break-word; line-height: 32px;"><?php echo esc_html($button['label']); ?></span>
|
||||
</span>
|
||||
<!--[if mso]>
|
||||
</center>
|
||||
</v:textbox>
|
||||
</v:roundrect>
|
||||
<![endif]-->
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="spacer_block block-11" style="height:2rem;line-height:15px;font-size:1px;"></div>
|
||||
<?php
|
||||
}elseif($context == 'access_link'){
|
||||
?>
|
||||
<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
|
||||
<tr>
|
||||
<td class="pad">
|
||||
<a href="<?php echo esc_url($button['url']); ?>" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function get_footer_message_depracated() {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
if(empty($formipay_settings['notification_email_footer'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$footer = sprintf('<tr>
|
||||
<td align="center" style="padding: 20px;">
|
||||
<p>%s</p>
|
||||
</td>
|
||||
</tr>', wp_kses_post($formipay_settings['notification_email_footer']) );
|
||||
|
||||
return $footer;
|
||||
|
||||
}
|
||||
|
||||
private function get_footer_message() {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
if(empty($formipay_settings['notification_email_footer'])){
|
||||
return;
|
||||
}
|
||||
|
||||
$footer = '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word; margin-bottom: 2rem;" width="100%">
|
||||
<tr>
|
||||
<td class="pad">
|
||||
<div style="color:#101112;direction:ltr;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:400;letter-spacing:0px;line-height:120%;text-align:left;mso-line-height-alt:19.2px;">
|
||||
'.wp_kses_post($formipay_settings['notification_email_footer']).'
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>';
|
||||
|
||||
return $footer;
|
||||
|
||||
}
|
||||
|
||||
private function get_social_links() {
|
||||
|
||||
$formipay_settings = $this->formipay_settings;
|
||||
|
||||
$content = '';
|
||||
|
||||
if(!empty($formipay_settings['notification_email_footer_links'])){
|
||||
$links = [];
|
||||
foreach($formipay_settings['notification_email_footer_links'] as $link){
|
||||
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment.
|
||||
$links[] = '<a href="'.esc_url($link['link']).'" style="margin:0 10px;"><img src="' . FORMIPAY_URL . 'admin/assets/img/icons8-' . esc_html($link['type']) . '-50.png" width="24"></a>';
|
||||
}
|
||||
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word; margin-bottom: 2rem;" width="100%"><tr><td class="pad" style="text-align: center;">';
|
||||
$content .= implode('', $links);
|
||||
$content .= '</td></tr></table>';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
512
includes/Notification/Notification.php
Normal file
@@ -0,0 +1,512 @@
|
||||
<?php
|
||||
namespace Formipay\Notification;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Notification {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
add_filter( 'formipay/global-settings/tab:general', [$this, 'global_settings_general'], 40 );
|
||||
add_filter( 'formipay/global-settings', [$this, 'add_menu_on_global_setting'], 40 );
|
||||
add_filter( 'formipay/form-config', [$this, 'add_menu_on_product_setting'], 100 );
|
||||
|
||||
add_action( 'formipay/notification/order', [$this, 'order_trigger'] );
|
||||
add_action( 'formipay/notification/access', [$this, 'access_trigger'] );
|
||||
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
|
||||
global $wpdb;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_notification_log` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int,
|
||||
`customer_id` int,
|
||||
`order_id` int,
|
||||
`recipient_type` text,
|
||||
`media` text,
|
||||
`notification_data` longtext,
|
||||
`status` text,
|
||||
`meta_data` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta($create);
|
||||
|
||||
}
|
||||
|
||||
public function insert_notification_data($args) {
|
||||
|
||||
$args = wp_parse_args( $args, [
|
||||
'order_id' => 0,
|
||||
'recipient_type' => 'admin',
|
||||
'media' => 'email',
|
||||
'notification_data' => [],
|
||||
'status' => 'pending',
|
||||
'meta_data' => []
|
||||
] );
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_notification_log';
|
||||
|
||||
$insert_data = [
|
||||
'order_id' => intval($args['order_id']),
|
||||
'recipient_type' => sanitize_text_field($args['recipient_type']),
|
||||
'media' => sanitize_text_field($args['media']),
|
||||
'notification_data' => maybe_serialize($args['notification_data']),
|
||||
'status' => sanitize_text_field($args['status']),
|
||||
'meta_data' => maybe_serialize($args['meta_data'])
|
||||
];
|
||||
|
||||
if($args['order_id'] > 0){
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$wpdb->insert($table, $insert_data);
|
||||
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_notification_data_by_id($notification_id) {
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_notification_log';
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$get = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM %i WHERE `id` = %d", $table, $notification_id
|
||||
)
|
||||
);
|
||||
|
||||
return $get;
|
||||
|
||||
}
|
||||
|
||||
public function update_notification_data($notification_id, $args) {
|
||||
|
||||
$recent_data = $this->get_notification_data_by_id($notification_id);
|
||||
|
||||
$args = wp_parse_args( $args, [
|
||||
'order_id' => $recent_data->order_id,
|
||||
'recipient_type' => $recent_data->recipient_type,
|
||||
'media' => $recent_data->media,
|
||||
'notification_data' => maybe_unserialize($recent_data->notification_data),
|
||||
'status' => $recent_data->status,
|
||||
'meta_data' => maybe_unserialize($recent_data->meta_data)
|
||||
] );
|
||||
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'formipay_notification_log';
|
||||
|
||||
$new_args = [
|
||||
'order_id' => intval($args['order_id']),
|
||||
'recipient_type' => sanitize_text_field($args['recipient_type']),
|
||||
'media' => sanitize_text_field($args['media']),
|
||||
'notification_data' => maybe_serialize($args['notification_data']),
|
||||
'status' => sanitize_text_field($args['status']),
|
||||
'meta_data' => maybe_serialize($args['meta_data'])
|
||||
];
|
||||
|
||||
$where = [ 'id' => $notification_id ];
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$update = $wpdb->update( $table_name, $new_args, $where );
|
||||
|
||||
return $update;
|
||||
|
||||
}
|
||||
|
||||
public function global_settings_general($fields) {
|
||||
|
||||
$medias = apply_filters('formipay/notification/media', ['email'] );
|
||||
$notification_fields = [
|
||||
'notification_type_group' => [
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Notification Type', 'formipay'),
|
||||
'group' => 'started',
|
||||
],
|
||||
];
|
||||
foreach($medias as $key => $media){
|
||||
$notification_fields['notification_'.$media.'_active'] = [
|
||||
'type' => 'checkbox',
|
||||
'label' => sprintf( __( '%s Notification', 'formipay'), ucfirst($media) ),
|
||||
'value' => true
|
||||
];
|
||||
}
|
||||
|
||||
$last_notification_field = count($notification_fields) - 1;
|
||||
$notification_fields[$last_notification_field]['group'] = 'ended';
|
||||
|
||||
$notification_fields['notification_email_sender_group_header'] = [
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Email Settings', 'formipay'),
|
||||
'group' => 'started',
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
|
||||
foreach($medias as $key => $media){
|
||||
$notification_fields['notification_'.$media.'_admin_recipient'] = [
|
||||
'type' => 'text',
|
||||
// translators: %s is the media type name.
|
||||
'label' => sprintf( __( 'Admin\'s %s', 'formipay'), ucfirst($media) ),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
}
|
||||
$notification_fields['notification_name_admin_recipient'] = [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Admin\'s Name', 'formipay'),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
|
||||
$notification_fields['notification_email_logo'] = [
|
||||
'type' => 'image',
|
||||
'label' => __('Logo Image', 'formipay'),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_footer'] = [
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Email Footer', 'formipay'),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_footer_links'] = [
|
||||
'type' => 'repeater',
|
||||
'label' => __( 'Icon Links', 'formipay' ),
|
||||
'fields' => [
|
||||
'type' => [
|
||||
'type' => 'select',
|
||||
'label' => __( 'Type', 'formipay' ),
|
||||
'is_group_title' => true,
|
||||
'options' => [
|
||||
'dribbble' => 'Dribbble',
|
||||
'facebook' => 'Facebook',
|
||||
'facebook-messenger' => 'Messenger',
|
||||
'github' => 'Github',
|
||||
'instagram' => 'Instagram',
|
||||
'link' => 'Link',
|
||||
'linkedin' => 'Linkedin',
|
||||
'pinterest' => 'Pinterest',
|
||||
'telegram' => 'Telegram',
|
||||
'tiktok' => 'Tiktok',
|
||||
'whatsapp' => 'WhatsApp',
|
||||
'wordpress' => 'WordPress',
|
||||
'x' => 'X'
|
||||
],
|
||||
],
|
||||
'link' => [
|
||||
'type' => 'text',
|
||||
'label' => __( 'URL', 'formipay' )
|
||||
]
|
||||
],
|
||||
'group' => 'ended',
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty'
|
||||
]
|
||||
];
|
||||
|
||||
$fields = array_merge($fields, $notification_fields);
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_menu_on_global_setting($fields) {
|
||||
|
||||
$hints = formipay_editor_hints();
|
||||
$statuses = formipay_order_status_list();
|
||||
$medias = apply_filters('formipay/notification/media', ['email'] );
|
||||
|
||||
|
||||
$notification_fields = [];
|
||||
|
||||
// access link
|
||||
|
||||
$notification_fields['notification_email_access_link_group'] = [
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Access Link', 'formipay' ),
|
||||
'description' => __( 'This notification type is for responding request for access when people visit the thankyou page that contain any of your digital access (including files and URLs)', 'formipay' ),
|
||||
'group' => 'started',
|
||||
'submenu' => __( 'Access Link', 'formipay' ),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_access_link_title'] = [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Title', 'formipay' ),
|
||||
'value' => __( 'Your New Purchased Access Link', 'formipay' ),
|
||||
'submenu' => __( 'Access Link', 'formipay' ),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_access_link_content'] = [
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Content', 'formipay' ),
|
||||
'hints' => [
|
||||
'buyer_name' => __( 'Buyer Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'access_button' => __( 'Access Button', 'formipay' ),
|
||||
'access_link' => __( 'Access Link', 'formipay' ),
|
||||
],
|
||||
'submenu' => __( 'Access Link', 'formipay' ),
|
||||
'value' => '<p>Hello {{buyer_name}},</p><p><br></p><p>Anyone request to access your purchase order ID <span style="background-color: transparent;">{{order_id}}</span><span style="background-color: transparent;">. Here is the new access link:</span></p><p>{{access_button}}<br></p><p><br></p><p>Here is the raw link if there is issue with the button:</p><p>{{access_link}}</p><p><br></p><p>Do not give access to others to make sure your purcase safe. Please ignore this email if it was not you.</p><p><br></p><p>Best regards,</p><p>Your E-commerce Team</p>',
|
||||
'group' => 'ended',
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
|
||||
foreach($statuses as $key => $status){
|
||||
$status_key = str_replace('-', '_', $key);
|
||||
|
||||
$notification_fields['notification_email_admin_'.$status_key.'_group_header'] = [
|
||||
'type' => 'group_title',
|
||||
// translators: %s is the status of order.
|
||||
'label' => sprintf( __( 'Email Notification Admin (%s)', 'formipay' ), $status),
|
||||
'group' => 'started',
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_admin_'.$status_key.'_toggle'] = [
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Activate', 'formipay'),
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_admin_'.$status_key.'_title'] = [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Title', 'formipay' ),
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
[
|
||||
'key' => 'notification_email_admin_'.$status_key.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
],
|
||||
[
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
],
|
||||
'dependencies' => '&&'
|
||||
];
|
||||
$notification_fields['notification_email_admin_'.$status_key.'_content'] = [
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Content', 'formipay' ),
|
||||
'hints' => [
|
||||
'order_details' => __( 'Order Details', 'formipay' ),
|
||||
'order_items' => __( 'Order Items', 'formipay' ),
|
||||
'buyer_details' => __( 'Buyer Details', 'formipay' ),
|
||||
'buyer_name' => __( 'Buyer Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'order_status' => __( 'Order Status', 'formipay' ),
|
||||
'payment_timeout' => __( 'Payment Timeout', 'formipay' )
|
||||
],
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
[
|
||||
'key' => 'notification_email_admin_'.$status_key.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
],
|
||||
[
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
],
|
||||
'dependencies' => '&&',
|
||||
'group' => 'ended',
|
||||
];
|
||||
|
||||
$notification_fields['notification_email_buyer_'.$status_key.'_group_header'] = [
|
||||
'type' => 'group_title',
|
||||
// translators: %s is the status of order.
|
||||
'label' => sprintf( __( 'Email Notification Buyer (%s)', 'formipay' ), $status),
|
||||
'group' => 'started',
|
||||
'submenu' => esc_html($status),
|
||||
'description' => __( 'Email notification for buyer only available if your form is contain email field type', 'formipay'),
|
||||
];
|
||||
$notification_fields['notification_email_buyer_'.$status_key.'_toggle'] = [
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Activate', 'formipay'),
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
];
|
||||
$notification_fields['notification_email_buyer_'.$status_key.'_title'] = [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Title', 'formipay' ),
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
[
|
||||
'key' => 'notification_email_buyer_'.$status_key.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
],
|
||||
[
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
],
|
||||
'dependencies' => '&&'
|
||||
];
|
||||
$notification_fields['notification_email_buyer_'.$status_key.'_content'] = [
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Content', 'formipay' ),
|
||||
'hints' => [
|
||||
'order_details' => __( 'Order Details', 'formipay' ),
|
||||
'order_items' => __( 'Order Items', 'formipay' ),
|
||||
'buyer_details' => __( 'Buyer Details', 'formipay' ),
|
||||
'buyer_name' => __( 'Buyer Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'order_status' => __( 'Order Status', 'formipay' ),
|
||||
'payment_timeout' => __( 'Payment Timeout', 'formipay' )
|
||||
],
|
||||
'submenu' => esc_html($status),
|
||||
'dependency' => [
|
||||
[
|
||||
'key' => 'notification_email_buyer_'.$status_key.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
],
|
||||
[
|
||||
'key' => 'notification_email_active',
|
||||
'value' => 'not_empty',
|
||||
'section' => 'General'
|
||||
]
|
||||
],
|
||||
'dependencies' => '&&',
|
||||
'group' => 'ended',
|
||||
];
|
||||
|
||||
$notification_fields = apply_filters('formipay/settings/notification/fields/'.$status_key, $notification_fields);
|
||||
|
||||
}
|
||||
|
||||
$fields['notification'] = [
|
||||
'name' => __('Notification', 'formipay'),
|
||||
'fields' => $notification_fields
|
||||
];
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_menu_on_product_setting($fields) {
|
||||
|
||||
$notification_fields = [];
|
||||
|
||||
$hints = formipay_editor_hints();
|
||||
$statuses = formipay_order_status_list();
|
||||
|
||||
foreach($statuses as $key => $status){
|
||||
$status_key = str_replace('-', '_', $key);
|
||||
|
||||
$notification_fields['product_notification_email_buyer_'.$status_key.'_group_header'] = [
|
||||
'type' => 'group_title',
|
||||
// translators: %s is the status of order.
|
||||
'label' => sprintf( __( 'Email Notification Buyer (%s)', 'formipay' ), $status),
|
||||
'group' => 'started',
|
||||
'description' => __( 'Email notification for buyer only available if your form is contain email field type', 'formipay'),
|
||||
];
|
||||
|
||||
$notification_fields['product_notification_email_buyer_'.$status_key.'_toggle'] = [
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Replace Content', 'formipay'),
|
||||
];
|
||||
|
||||
$notification_fields['product_notification_email_buyer_'.$status_key.'_content'] = [
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Email Content', 'formipay' ),
|
||||
'hints' => $hints,
|
||||
'dependency' => [
|
||||
'key' => 'product_notification_email_buyer_'.$status_key.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
],
|
||||
'group' => 'ended',
|
||||
];
|
||||
|
||||
$notification_fields = apply_filters('formipay/product/notification/fields/', $notification_fields, $status_key);
|
||||
|
||||
}
|
||||
|
||||
$fields['formipay_form_settings']['notification'] = [
|
||||
'name' => __('Notification', 'formipay'),
|
||||
'fields' => $notification_fields
|
||||
];
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function order_trigger($order_data) {
|
||||
|
||||
$medias = apply_filters('formipay/notification/media', ['email'] );
|
||||
$order_status = $order_data['status'];
|
||||
|
||||
if(!empty($medias)){
|
||||
foreach($medias as $media){
|
||||
do_action(
|
||||
'formipay/notification/order/'.$media, $order_data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function access_trigger($order_data) {
|
||||
|
||||
$medias = apply_filters('formipay/notification/media', ['email'] );
|
||||
|
||||
if(!empty($medias)){
|
||||
foreach($medias as $media){
|
||||
do_action(
|
||||
'formipay/notification/access/'.$media, $order_data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1259
includes/Order.php
Normal file
725
includes/Payment/BankTransfer.php
Normal file
@@ -0,0 +1,725 @@
|
||||
<?php
|
||||
namespace Formipay\Payment;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
use Formipay\Order as Order;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class BankTransfer extends Payment {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $gateway = 'bank_transfer';
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'init', [$this, 'create_db'] );
|
||||
add_action( 'formipay/order/new', [$this, 'add_transaction'], 99 );
|
||||
add_action( 'formipay/order/payment-timeout', [$this, 'auto_cancel_order_on_timeout'] );
|
||||
|
||||
add_filter( 'formipay/order/order-details', [$this, 'add_unique_code_details'], 89, 3 );
|
||||
add_filter( 'formipay/form-config/tab:payments/gateways', [$this, 'add_gateway'] );
|
||||
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_bank_transfer_settings'] );
|
||||
add_filter( 'formipay/global-settings/tab:payment', [$this, 'add_settings'] );
|
||||
add_filter( 'formipay/order/payment-details/bank_transfer', [$this, 'render_payment_details'], 999, 4 );
|
||||
|
||||
add_action('wp_ajax_formipay_bank_transfer_confirmation', [$this, 'handle_formipay_bank_transfer_confirmation'] );
|
||||
add_action('wp_ajax_nopriv_formipay_bank_transfer_confirmation', [$this, 'handle_formipay_bank_transfer_confirmation'] );
|
||||
|
||||
add_filter('formipay/notification/order/email/action-button', [$this, 'render_email_action_button'], 99, 3 );
|
||||
|
||||
}
|
||||
|
||||
public function create_db() {
|
||||
|
||||
global $wpdb;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
|
||||
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_bank_transfer_trx` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`created_date` datetime DEFAULT CURRENT_TIMESTAMP,
|
||||
`form_id` int DEFAULT 0,
|
||||
`order_id` int DEFAULT 0,
|
||||
`channel` text NOT NULL,
|
||||
`total` float(10, 2) DEFAULT 0,
|
||||
`unique_code` int DEFAULT 0,
|
||||
`meta_data` text,
|
||||
PRIMARY KEY (`id`)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
dbDelta($create);
|
||||
|
||||
}
|
||||
|
||||
public function add_transaction($order_data) {
|
||||
global $wpdb;
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$timeout = isset($formipay_settings['bank_transfer_timeout']) ? (int) $formipay_settings['bank_transfer_timeout'] : 1440;
|
||||
$table = $wpdb->prefix . 'formipay_bank_transfer_trx';
|
||||
|
||||
if ($order_data['payment_gateway'] == 'bank_transfer') {
|
||||
$submit_args = [
|
||||
'created_date' => formipay_date('Y-m-d H:i:s', strtotime($order_data['created_date'])),
|
||||
'form_id' => intval($order_data['form_id']),
|
||||
'order_id' => intval($order_data['id']),
|
||||
'channel' => sanitize_text_field(str_replace($order_data['payment_gateway'].':::', '', $order_data['form_data']['payment'])),
|
||||
'total' => floatval($order_data['total']),
|
||||
'unique_code' => sanitize_text_field($this->check_unique_code()),
|
||||
'meta_data' => maybe_serialize(array())
|
||||
];
|
||||
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
||||
$inserted = $wpdb->insert($table, $submit_args);
|
||||
|
||||
wp_schedule_single_event(
|
||||
(int) formipay_date('timestamp') + $timeout, 'formipay/order/payment-timeout', [
|
||||
'order_id' => $order_data['id'],
|
||||
'payment_gateway' => 'bank_transfer'
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function auto_cancel_order_on_timeout($order_id, $payment_gateway) {
|
||||
|
||||
if($payment_gateway == 'bank_transfer'){
|
||||
|
||||
global $wpdb;
|
||||
$order = formipay_get_order($order_id);
|
||||
if($order['status'] !== 'completed'){
|
||||
Order::update($order_id, [
|
||||
'status' => 'cancelled'
|
||||
]);
|
||||
}
|
||||
$this->cancel_payment($order);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function cancel_payment($order_data){
|
||||
do_action('formipay/notification/order', $order_data);
|
||||
}
|
||||
|
||||
public function check_unique_code() {
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'formipay_bank_transfer_trx';
|
||||
|
||||
// Get the highest existing ID efficiently
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$max_id = $wpdb->get_var("SELECT MAX(id) FROM $table");
|
||||
|
||||
$unique_code = !is_null($max_id) ? ($max_id + 1) : 1;
|
||||
|
||||
$operation = get_option('bank_transfer_unique_code_operation');
|
||||
return ($operation == 'add') ? $unique_code : "-{$unique_code}";
|
||||
}
|
||||
|
||||
public function add_unique_code_details($details, $form_id, $order_data){
|
||||
|
||||
if( floatval(formipay_get_post_meta($form_id, 'product_price')) > 0 &&
|
||||
$order_data['payment_gateway'] == 'bank_transfer'
|
||||
){
|
||||
|
||||
$details[] = [
|
||||
'item' => __( 'Unique Code', 'formipay' ),
|
||||
'amount' => $this->check_unique_code(),
|
||||
'subtotal' => floatval($this->check_unique_code()),
|
||||
'context' => floatval($this->check_unique_code()) < 0 ? 'sub' : 'add'
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
public function add_gateway($gateways){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(isset($formipay_settings[$this->gateway.'_toggle']) && false !== $formipay_settings[$this->gateway.'_toggle']){
|
||||
|
||||
if(isset($formipay_settings[ $this->gateway.'_channels' ]) && !empty($formipay_settings[ $this->gateway.'_channels' ])){
|
||||
$channels = $formipay_settings[ $this->gateway.'_channels' ];
|
||||
$channel_options = [];
|
||||
if(!empty($channels)){
|
||||
foreach($channels as $index => $channel){
|
||||
$id = $this->gateway.':::'.$channel[$this->gateway.'_name'].'-'.$index;
|
||||
$gateways[] = [
|
||||
'id' => $id,
|
||||
'gateway' => __( 'Bank', 'formipay' ),
|
||||
'channel' => $channel[$this->gateway.'_name']
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $gateways;
|
||||
|
||||
}
|
||||
|
||||
public function add_bank_transfer_settings($fields){
|
||||
|
||||
$banktransfer_field = array(
|
||||
$this->gateway.'_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Settings', 'formipay' ),
|
||||
'description' => __( 'This will be shown in thank-you page and implemented when buyer uses one of Bank Transfer\'s channels', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_text_section_intro' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Payment Details Intro', 'formipay' ),
|
||||
'value' => __( 'Please complete payment to:', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_confirmation_submit_button' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Payment Confirmation Submit Button Text', 'formipay' ),
|
||||
'value' => __( 'Upload', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
),
|
||||
$this->gateway.'_confirmation_notice_message_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Notice Messages', 'formipay' ),
|
||||
'description' => __(
|
||||
'Set notice message on every condition about attempting to confirm the payment', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_update_to_status' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Change status order to', 'formipay' ),
|
||||
'options' => formipay_order_status_list(),
|
||||
'value' => 'payment-confirm',
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_success' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Successfully Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('Successfully confirmed payment for #{{order_id}}', 'formipay'),
|
||||
'description' => __('When successfully change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_already_confirmed' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Has Been Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('#{{order_id}} has been confirmed', 'formipay'),
|
||||
'description' => __('When the order status has been the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_error' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Failed to Confirm Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay'),
|
||||
'system_error_message' => __('System Error Message', 'formipay')
|
||||
),
|
||||
'value' => __('Failed to proceed. Error: {{system_error_message}}', 'formipay'),
|
||||
'description' => __('When error to change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
foreach($banktransfer_field as $key => $value){
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_settings($settings) {
|
||||
$bank_transfer = array(
|
||||
'my_code_field' => [
|
||||
'type' => 'ace_editor',
|
||||
'label' => __('Custom Code', 'formipay'),
|
||||
'lang' => 'javascript', // or 'css', 'html', etc.
|
||||
'theme' => 'chrome',
|
||||
'value' => '', // default value
|
||||
'required' => true,
|
||||
],
|
||||
$this->gateway.'_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Activate Bank Transfer', 'formipay'),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_general_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'General', 'formipay' ),
|
||||
'group' => 'started',
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_timeout' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Payment Timeout (minute)', 'formipay' ),
|
||||
'description' => __( 'Set a timeout to wait for payment. After this timeout is up, the order status automatically changes to cancelled.', 'formipay' ),
|
||||
'value' => 120,
|
||||
'group' => 'ended',
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_unique_codes' => array(
|
||||
'type' => 'repeater',
|
||||
'label' => esc_html__( 'Unique Codes', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'description' => __( 'Get unique total amount by adding unique code.', 'formipay' ),
|
||||
'fields' => array(
|
||||
'unique_code_currency' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Currency', 'formipay' ),
|
||||
'description' => __( 'This setting is only applied when the selected currency matches the form currency.', 'formipay' ),
|
||||
'options' => formipay_currency_as_options(),
|
||||
'is_group_title' => true,
|
||||
'searchable' => true,
|
||||
'required' => true
|
||||
),
|
||||
'unique_code_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Activate', 'formipay' ),
|
||||
'description' => __( 'Generate unique code for this currency.', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
'unique_code_increment_step' => array(
|
||||
'type' => 'number',
|
||||
'label' => esc_html__( 'Increment Step', 'formipay' ),
|
||||
'value' => 0.01,
|
||||
'step' => 0.001,
|
||||
'required' => true
|
||||
),
|
||||
'unique_code_max' => array(
|
||||
'type' => 'number',
|
||||
'label' => esc_html__( 'Max Amount', 'formipay' ),
|
||||
'value' => 0.01,
|
||||
'step' => 0.001,
|
||||
'required' => true
|
||||
),
|
||||
'unique_code_operation' => array(
|
||||
'type' => 'select',
|
||||
'label' => __('Operation', 'formipay'),
|
||||
'options' => array(
|
||||
'sub' => __( '(-) Decrease Total Amount by Unique Code', 'formipay' ),
|
||||
'add' => __( '(+) Increase Total Amount by Unique Code', 'formipay' ),
|
||||
),
|
||||
'value' => 'add',
|
||||
'dependency'=> array(
|
||||
array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
array(
|
||||
'key' => $this->gateway.'_unique_code_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'required' => true,
|
||||
),
|
||||
)
|
||||
),
|
||||
$this->gateway.'_confirmation_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Form', 'formipay' ),
|
||||
'description' => __( 'for order that use Bank Transfer gateway only.', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'bank_transfer_toggle',
|
||||
'value' => 'not_empty',
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_dropzone_color' => array(
|
||||
'type' => 'color',
|
||||
'label' => __( 'Dropzone Box Background color', 'formipay' ),
|
||||
'value' => '#cccccc',
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'bank_transfer_toggle',
|
||||
'value' => 'not_empty',
|
||||
),
|
||||
),
|
||||
$this->gateway.'_confirmation_dropzone_text_color' => array(
|
||||
'type' => 'color',
|
||||
'label' => __( 'Dropzone Box Text Color', 'formipay' ),
|
||||
'value' => '#808080',
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'bank_transfer_toggle',
|
||||
'value' => 'not_empty',
|
||||
),
|
||||
),
|
||||
$this->gateway.'_confirmation_dropzone_instruction' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Dropzone Instruction', 'formipay' ),
|
||||
'value' => __( 'Drag & drop a file here or click to select one', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'bank_transfer_toggle',
|
||||
'value' => 'not_empty',
|
||||
),
|
||||
),
|
||||
$this->gateway.'_confirmation_submit_button' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Submit Button', 'formipay' ),
|
||||
'value' => __( 'Upload', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'bank_transfer_toggle',
|
||||
'value' => 'not_empty',
|
||||
),
|
||||
'group' => 'ended'
|
||||
),
|
||||
$this->gateway.'_settings_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Account List', 'formipay' ),
|
||||
'description' => __( 'Add all of your preferred bank accounts to receive the payment', 'formipay' ),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_channels' => array(
|
||||
'type' => 'repeater',
|
||||
'label' => __('Bank Accounts', 'formipay'),
|
||||
'fields' => array(
|
||||
$this->gateway.'_name' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Bank Name', 'formipay' ),
|
||||
'required' => true,
|
||||
'is_group_title' => true
|
||||
),
|
||||
$this->gateway.'_account' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Bank Account', 'formipay' ),
|
||||
'required' => true
|
||||
),
|
||||
$this->gateway.'_account_holder' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Bank Account Holder', 'formipay' ),
|
||||
'required' => true
|
||||
),
|
||||
$this->gateway.'_logo' => array(
|
||||
'type' => 'image',
|
||||
'label' => __( 'Bank Logo', 'formipay' ),
|
||||
'required' => true
|
||||
),
|
||||
),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'submenu' => __( 'Bank Transfer', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
foreach($bank_transfer as $key => $value){
|
||||
$settings[$key] = $value;
|
||||
}
|
||||
|
||||
return $settings;
|
||||
|
||||
}
|
||||
|
||||
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
if(in_array($order_data['status'], ['completed', 'payment-confirm'])){
|
||||
return $render;
|
||||
}
|
||||
|
||||
$get_order = formipay_get_order($order_data['id']);
|
||||
|
||||
$selected_payment = ''; // bank_transfer:::BNI-0
|
||||
$payment_gateway = '';
|
||||
if(!empty($get_order['form_data'])){
|
||||
foreach($get_order['form_data'] as $_form_data){
|
||||
if($_form_data['name'] == 'payment') {
|
||||
$selected_payment = $_form_data['value'];
|
||||
}
|
||||
if($_form_data['name'] == 'payment_gateway') {
|
||||
$payment_gateway = $_form_data['value'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if('' !== $selected_payment){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
if($formipay_settings[$payment_gateway.'_toggle'] !== false){
|
||||
$gateway_channel = [];
|
||||
if(!empty($formipay_settings[$payment_gateway.'_channels'])){
|
||||
foreach($formipay_settings[$payment_gateway.'_channels'] as $channel){
|
||||
if(strpos($selected_payment, $channel[$payment_gateway.'_name']) !== false){
|
||||
$gateway_channel = $channel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($gateway_channel)){
|
||||
if($submit_action_type == 'thankyou'){
|
||||
ob_start();
|
||||
?>
|
||||
<span><?php echo esc_html(formipay_get_post_meta($form_id, 'bank_transfer_text_section_intro')); ?></span>
|
||||
<?php
|
||||
if(!empty($gateway_channel['bank_transfer_logo'])){
|
||||
echo '<br>'.wp_get_attachment_image( $gateway_channel['bank_transfer_logo'], 'thumbnail', false );
|
||||
}
|
||||
?>
|
||||
<div class="payment-bank_transfer payment-response-container">
|
||||
<table id="payment-details">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo esc_html__( 'Order ID', 'formipay' ); ?></th>
|
||||
<td><?php echo '#'.intval($order_data['id']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Bank Name', 'formipay'); ?></th>
|
||||
<td><?php echo esc_html($gateway_channel['bank_transfer_name']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Bank Account', 'formipay'); ?></th>
|
||||
<td>
|
||||
<p class="bank-account" data-copy-value="<?php echo esc_attr($gateway_channel['bank_transfer_account']) ?>">
|
||||
<b><?php echo esc_html($gateway_channel['bank_transfer_account']) ?></b>
|
||||
</p>
|
||||
<button class="formipay-copy-button"
|
||||
data-copy-text="<?php echo esc_attr__( 'Copy', 'formipay' ); ?>"
|
||||
data-copied-text="<?php echo esc_attr__( 'Copied', 'formipay' ); ?>"
|
||||
data-not-copied-text="<?php echo esc_attr__( 'Not copied!', 'formipay' ); ?>"
|
||||
>
|
||||
<i class="bi bi-copy"></i> <?php echo esc_html__( 'Copy', 'formipay' ); ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Bank Account Holder', 'formipay'); ?></th>
|
||||
<td><?php echo esc_html($gateway_channel['bank_transfer_account_holder']); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Payment Total', 'formipay'); ?></th>
|
||||
<td>
|
||||
<p class="payment-total" data-copy-value="<?php echo esc_attr($order_data['total']) ?>">
|
||||
<b><?php echo esc_html(formipay_price_format($order_data['total'], $form_id)); ?></b>
|
||||
</p>
|
||||
<button class="formipay-copy-button"
|
||||
data-copy-text="<?php echo esc_attr__( 'Copy', 'formipay' ); ?>"
|
||||
data-copied-text="<?php echo esc_attr__( 'Copied', 'formipay' ); ?>"
|
||||
data-not-copied-text="<?php echo esc_attr__( 'Not copied!', 'formipay' ); ?>"
|
||||
>
|
||||
<i class="bi bi-copy"></i> <?php echo esc_html__( 'Copy', 'formipay' ); ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<form id="uploadForm" class="dropzone">
|
||||
<input type="hidden" name="action" value="formipay_bank_transfer_confirmation">
|
||||
<input type="hidden" name="order_id" value="<?php echo esc_attr($order_data['id']); ?>">
|
||||
<input type="hidden" name="form_id" value="<?php echo esc_attr($order_data['form_id']); ?>">
|
||||
<input type="hidden" name="total_amount" value="<?php echo esc_attr($order_data['total']); ?>">
|
||||
<input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce('formipay_bank_transfer_confirmation')); ?>">
|
||||
|
||||
<div class="dropzone-area" id="dropzoneArea">
|
||||
<input type="file" name="file" id="fileInput" style="display: none;" accept="image/jpeg, image/png" />
|
||||
<div id="thumbnailPreview" style="display: none;">
|
||||
<?php // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a placeholder and will be managed by JS. ?>
|
||||
<img id="previewImage" src="" alt="Image Preview"/>
|
||||
</div>
|
||||
<i class="bi bi-image"></i>
|
||||
<div><?php echo esc_html($formipay_settings['bank_transfer_confirmation_dropzone_instruction']); ?></div>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="upload-transfer-receipt" class="formipay-submit-button"><?php echo esc_html(formipay_get_post_meta($form_id, 'bank_transfer_confirmation_submit_button')); ?></button>
|
||||
</form>
|
||||
<?php
|
||||
$render = ob_get_clean();
|
||||
|
||||
}elseif($submit_action_type == 'whatsapp'){
|
||||
|
||||
$slug = 'thankyou';
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
// translators: %d is the order ID.
|
||||
$message = sprintf( esc_html__( 'Order ID: *%d*', 'formipay'), $order_data['id'] );
|
||||
// translators: %s is the chosen bank name.
|
||||
$message .= "%0A".sprintf( esc_html__( 'Bank Name: *%s*', 'formipay'), $gateway_channel['bank_transfer_name'] );
|
||||
// translators: %s is the chosen bank account.
|
||||
$message .= "%0A".sprintf( esc_html__( 'Bank Account: *%s*', 'formipay'), $gateway_channel['bank_transfer_account'] );
|
||||
// translators: %s is the chosen bank account holder name.
|
||||
$message .= "%0A".sprintf( esc_html__( 'Bank Account Holder: *%s*', 'formipay'), $gateway_channel['bank_transfer_account_holder'] );
|
||||
// translators: %s is the total amount of order.
|
||||
$message .= "%0A".sprintf( esc_html__( 'Payment Total: *%s*', 'formipay'), formipay_price_format($order_data['total'], $form_id) );
|
||||
// translators: %s is the payment confirmation URL.
|
||||
$message .= "%0A%0A> ".sprintf( esc_html__( 'Upload your transfer receipt to confirm the payment to %s', 'formipay' ), site_url('/'.$slug.'/'.base64_encode($form_id.':::'.$order_data['id'].':::'.$order_data['meta_data']['session_id'])));
|
||||
|
||||
$render = $message;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $render;
|
||||
|
||||
}
|
||||
|
||||
public function handle_formipay_bank_transfer_confirmation() {
|
||||
|
||||
// Capability check
|
||||
// if (!current_user_can('edit_posts')) {
|
||||
// wp_send_json_error(['message' => __('Permission denied', 'formipay')]);
|
||||
// exit;
|
||||
// }
|
||||
|
||||
// Nonce verification
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'formipay_bank_transfer_confirmation')) {
|
||||
wp_send_json_error(['message' => __('Nonce verification failed', 'formipay')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Parameter sanitization
|
||||
$form_id = isset($_POST['form_id']) ? sanitize_text_field(wp_unslash($_POST['form_id'])) : '';
|
||||
$order_id = isset($_POST['order_id']) ? sanitize_text_field(wp_unslash($_POST['order_id'])) : '';
|
||||
|
||||
// File validation
|
||||
if (empty($_FILES['file']['tmp_name']) || !is_uploaded_file(sanitize_text_field($_FILES['file']['tmp_name']))) {
|
||||
wp_send_json_error(['message' => __('Invalid file upload', 'formipay')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (isset($_FILES['file']['error']) && $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
|
||||
wp_send_json_error(array('message' => __('File upload error', 'formipay')));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Require the WordPress file system
|
||||
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
||||
// Use wp_handle_upload() to save the file
|
||||
$movefile = wp_handle_upload($_FILES['file'], array('test_form' => false));
|
||||
|
||||
if ($movefile && !isset($movefile['error'])) {
|
||||
// File is uploaded successfully; now save it to media library
|
||||
$file_path = $movefile['file'];
|
||||
$file_type = wp_check_filetype(basename($file_path), null);
|
||||
$attachment = array(
|
||||
'post_mime_type' => $file_type['type'],
|
||||
'post_title' => 'receipt-order-'.$order_id.'-'.sanitize_file_name(basename($file_path)),
|
||||
'post_content' => '',
|
||||
'post_status' => 'inherit'
|
||||
);
|
||||
|
||||
// Insert the attachment in the media library
|
||||
$attach_id = wp_insert_attachment($attachment, $file_path);
|
||||
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
||||
$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
|
||||
wp_update_attachment_metadata($attach_id, $attach_data);
|
||||
|
||||
$update = formipay_update_order_status([
|
||||
'form_id' => $form_id,
|
||||
'order_id' => $order_id,
|
||||
'status' => 'payment-confirm',
|
||||
'payment_gateway' => 'bank_transfer'
|
||||
]);
|
||||
|
||||
|
||||
if($update['valid']){
|
||||
// Edit TRX DB
|
||||
$meta_data = [
|
||||
'transfer_receipt' => [
|
||||
'time' => time(),
|
||||
'attachment_id' => $attach_id,
|
||||
'attachment_url' => $movefile['url']
|
||||
]
|
||||
];
|
||||
|
||||
global $wpdb;
|
||||
$trx_db = $wpdb->prefix.'formipay_bank_transfer_trx';
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$wpdb->update( $trx_db, ['meta_data' => maybe_serialize($meta_data)], ['order_id' => $order_id] );
|
||||
}else{
|
||||
wp_delete_attachment( $attach_id, true );
|
||||
}
|
||||
|
||||
wp_send_json( [
|
||||
'success' => boolval($update['valid']),
|
||||
'data' => [
|
||||
'message' => $update['message'],
|
||||
'icon' => (boolval($update['valid']) == true) ? 'success' : 'info'
|
||||
]
|
||||
] );
|
||||
}
|
||||
|
||||
// Send an error response back
|
||||
wp_send_json_error([
|
||||
'message' => 'File could not be saved. Error: ' . $movefile['error']
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function render_email_action_button($button, $recipient, $order_data){
|
||||
|
||||
if(
|
||||
$order_data['payment_gateway'] == $this->gateway &&
|
||||
$order_data['status'] == 'on-hold' &&
|
||||
$recipient !== 'admin'
|
||||
){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$slug = 'thankyou';
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
$button = [
|
||||
'url' => site_url('/'.$slug.'/'.base64_encode($order_data['form_id'].':::'.$order_data['id'])),
|
||||
'label' => formipay_get_post_meta($order_data['form_id'], 'bank_transfer_confirmation_submit_button')
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $button;
|
||||
|
||||
}
|
||||
|
||||
public function process_payment($order_data) {
|
||||
return $order_data;
|
||||
}
|
||||
|
||||
}
|
||||
581
includes/Payment/CashOnDelivery.php
Normal file
@@ -0,0 +1,581 @@
|
||||
<?php
|
||||
namespace Formipay\Payment;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class CashOnDelivery extends Payment {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $gateway = 'cod';
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'formipay/global-settings/tab:payment', [$this, 'add_settings'] );
|
||||
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_cod_setings'] );
|
||||
add_filter( 'formipay/form-config/tab:payments/gateways', [$this, 'add_gateway'] );
|
||||
add_filter( 'formipay/payment-list/cod/logo', [$this, 'set_frontend_logo'] );
|
||||
add_filter( 'formipay/order/order-details', [$this, 'add_fee'], 999, 3 );
|
||||
add_filter( 'formipay/order/payment-details/cod', [$this, 'render_payment_details'], 999, 4 );
|
||||
|
||||
add_action( 'template_redirect', [$this, 'check_parse_query'], 999 );
|
||||
|
||||
add_filter( 'formipay/thankyou/shortcodes', [$this, 'add_order_shortcodes'], 999, 4 );
|
||||
add_action('wp_ajax_formipay_cod_confirmation', [$this, 'handle_formipay_cod_confirmation'] );
|
||||
add_action('wp_ajax_nopriv_formipay_cod_confirmation', [$this, 'handle_formipay_cod_confirmation'] );
|
||||
|
||||
}
|
||||
|
||||
public function add_transaction($order_data){
|
||||
return;
|
||||
}
|
||||
|
||||
public function cancel_payment($order_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
public function add_settings($settings) {
|
||||
|
||||
$cod = array(
|
||||
$this->gateway.'_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __('Activate Cash On Delivery', 'formipay'),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' )
|
||||
),
|
||||
$this->gateway.'_settings_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'General', 'formipay' ),
|
||||
'description' => __( 'Set the rule of Cash On Delivery', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_label' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Label', 'formipay'),
|
||||
'value' => __( 'COD', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_item_name' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Item Name', 'formipay'),
|
||||
'value' => __( 'COD Fee', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_icon' => array(
|
||||
'type' => 'image',
|
||||
'label' => __('Icon', 'formipay'),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_fee_amount' => array(
|
||||
'type' => 'number',
|
||||
'label' => __('Fee Amount', 'formipay'),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_fee_type' => array(
|
||||
'type' => 'select',
|
||||
'label' => __('Fee Type', 'formipay'),
|
||||
'options' => array(
|
||||
'fixed' => __( 'Fixed Amount', 'formipay' ),
|
||||
'percentage' => __( 'Percentage', 'formipay' )
|
||||
),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'ended'
|
||||
),
|
||||
$this->gateway.'_details_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Instruction', 'formipay' ),
|
||||
'description' => __( 'Set instruction to buyer how to pay with COD method.', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_instruction_thankyou' => array(
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Thankyou Screen', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'hints' => array(
|
||||
'product_name' => __( 'Product Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'grand_total' => __( 'Order Total', 'formipay' ),
|
||||
'confirmation_page_link' => __( 'Confirmation Page Link', 'formipay' )
|
||||
),
|
||||
'value' => '<p>Please prepare your cash of <span style="text-align: var(--bs-body-text-align);">{{grand_total}} </span><span style="text-align: var(--bs-body-text-align);">and pay it to the courier who delivers your </span>{{product_name}}.</p>',
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
$this->gateway.'_instruction_whatsapp' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'WhatsApp Message', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'hints' => array(
|
||||
'product_name' => __( 'Product Name', 'formipay' ),
|
||||
'order_id' => __( 'Order ID', 'formipay' ),
|
||||
'grand_total' => __( 'Order Total', 'formipay' ),
|
||||
'confirmation_page_link' => __( 'Confirmation Page Link', 'formipay' )
|
||||
),
|
||||
'value' => 'Please prepare your cash of {{grand_total}} and pay it to the courier who delivers your {{product_name}}.',
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'ended'
|
||||
),
|
||||
$this->gateway.'_confirmation_page_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Page', 'formipay' ),
|
||||
'description' => sprintf(
|
||||
// translators: %s is the site URL.
|
||||
__(
|
||||
'<p>Set confirmation page for buyer to confirm that they have receive the package and pay the order to courier.</p>
|
||||
<p>Confirmation magic URL: <code>%s/payment-confirm/cod/{{autogenerated_token}}</code></p>'
|
||||
, 'formipay' ), site_url()),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_page_content' => array(
|
||||
'type' => 'tinymce',
|
||||
'label' => __( 'Page Content', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_details' => __( 'Order Details', 'formipay' ),
|
||||
'confirmation_form' => __( 'Confirmation Form', 'formipay' ),
|
||||
),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_confirmation_page_width' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Page Width', 'formipay' ),
|
||||
'value' => '600',
|
||||
'description' => __( 'in pixel (px)', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_confirmation_table_alignment' => array(
|
||||
'type' => 'radio',
|
||||
'label' => __('Table Content Alignment', 'formipay'),
|
||||
'value' => 'center',
|
||||
'options' => array(
|
||||
'left' => '<i class="bi bi-text-left"></i> Left',
|
||||
'center' => '<i class="bi bi-text-center"></i> Center',
|
||||
'right' => '<i class="bi bi-text-right"></i> Right',
|
||||
),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_confirmation_form_agreement' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Agreement', 'formipay' ),
|
||||
'value' => __( 'I have receipt the package and pay as billed to the courier.', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
$this->gateway.'_confirmation_form_button' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Button Text', 'formipay' ),
|
||||
'value' => __( 'Confirm', 'formipay' ),
|
||||
'submenu' => __( 'Cash On Delivery', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => $this->gateway.'_toggle',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
'group' => 'ended',
|
||||
)
|
||||
);
|
||||
|
||||
foreach($cod as $key => $value){
|
||||
$settings[$key] = $value;
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function add_cod_setings($fields) {
|
||||
|
||||
$cod_settings = array(
|
||||
$this->gateway.'_confirmation_notice_message_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Confirmation Notice Messages', 'formipay' ),
|
||||
'description' => __( 'Set notice message on every condition about attempting to confirm the payment', 'formipay' ),
|
||||
'submenu' => __( 'COD', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->gateway.'_confirmation_update_to_status' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Change status order to', 'formipay' ),
|
||||
'options' => formipay_order_status_list(),
|
||||
'value' => 'payment-confirm',
|
||||
'submenu' => __( 'COD', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_success' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Successfully Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('Successfully confirmed COD #{{order_id}}', 'formipay'),
|
||||
'description' => __('When successfully change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'COD', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_already_confirmed' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Has Been Confirmed Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay')
|
||||
),
|
||||
'value' => __('#{{order_id}} has been confirmed', 'formipay'),
|
||||
'description' => __('When the order status has been the preferred one', 'formipay'),
|
||||
'submenu' => __( 'COD', 'formipay' ),
|
||||
),
|
||||
$this->gateway.'_confirmation_message_error' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Failed to Confirm Message', 'formipay' ),
|
||||
'hints' => array(
|
||||
'order_id' => __('Order ID', 'formipay'),
|
||||
'system_error_message' => __('System Error Message', 'formipay')
|
||||
),
|
||||
'value' => __('Failed to proceed. Error: {{system_error_message}}', 'formipay'),
|
||||
'description' => __('When error to change the order status to the preferred one', 'formipay'),
|
||||
'submenu' => __( 'COD', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
foreach($cod_settings as $key => $value){
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_gateway($gateways) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(isset($formipay_settings['cod_toggle']) && false !== $formipay_settings['cod_toggle']){
|
||||
// $gateways['cod'] = __('Cash On Delivery', 'formipay');
|
||||
$gateways[] = [
|
||||
'id' => $this->gateway,
|
||||
'gateway' => __( 'COD', 'formipay' ),
|
||||
];
|
||||
}
|
||||
|
||||
return $gateways;
|
||||
|
||||
}
|
||||
|
||||
public function set_frontend_logo($logo){
|
||||
|
||||
if($logo == false){
|
||||
$logo = FORMIPAY_URL . 'public/assets/img/cod_default_icon.png';
|
||||
}
|
||||
|
||||
return $logo;
|
||||
|
||||
}
|
||||
|
||||
public function add_fee($details, $form_id, $order_data){
|
||||
|
||||
if($order_data['payment_gateway'] == 'cod'){
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
$fee_amount = $formipay_settings['cod_fee_amount'];
|
||||
$fee_type = $formipay_settings['cod_fee_type'];
|
||||
if($fee_type == 'percentage'){
|
||||
$grand_total = 0;
|
||||
if(!empty($details)){
|
||||
foreach($details as $detail){
|
||||
$grand_total += $detail['subtotal'];
|
||||
}
|
||||
}
|
||||
$fee_amount = $grand_total * floatval($fee_amount) / 100;
|
||||
}
|
||||
|
||||
$details[] = [
|
||||
'item' => $formipay_settings['cod_item_name'],
|
||||
'amount' => $fee_amount,
|
||||
'subtotal' => $fee_amount
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
if($order_data['payment_gateway'] == 'cod'){
|
||||
|
||||
$render = '';
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$render .= ($submit_action_type == 'thankyou') ? '<div class="cod-instruction" style="text-align:'.formipay_get_post_meta($form_id, 'thankyou_screen_table_alignment').';">' : '';
|
||||
|
||||
$replacements = [
|
||||
'{{product_name}}' => get_the_title($form_id),
|
||||
'{{order_id}}' => $order_data['id'],
|
||||
'{{grand_total}}' => formipay_price_format($order_data['total'], $form_id),
|
||||
'{{confirmation_page_link}}' => site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($form_id.':::'.$order_data['id']))
|
||||
];
|
||||
|
||||
$render .= strtr( $formipay_settings['cod_instruction_'.$submit_action_type], $replacements );
|
||||
$render .= ($submit_action_type == 'thankyou') ? '</div>' : '';
|
||||
|
||||
}
|
||||
|
||||
return $render;
|
||||
|
||||
}
|
||||
|
||||
public function check_parse_query() {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(is_admin()) :
|
||||
return;
|
||||
endif;
|
||||
|
||||
if(
|
||||
!is_admin() &&
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-payment-confirm', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-payment-confirm']) &&
|
||||
array_key_exists('gateway', $wp_query->query) &&
|
||||
'cod' === $wp_query->query['gateway']
|
||||
) :
|
||||
|
||||
$token = explode(':::', base64_decode($wp_query->query['formipay-token']));
|
||||
$form_id = $token[0];
|
||||
$order_id = $token[1];
|
||||
|
||||
$thankyou_slug = 'thankyou';
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$thankyou_slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
$order = formipay_get_order($order_id);
|
||||
if($order['payment_gateway'] !== 'cod'){
|
||||
wp_safe_redirect( site_url('/'.$thankyou_slug.'/'.$wp_query->query['formipay-token']) );
|
||||
}
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($form_id, 'button_bg_color'), true );
|
||||
$button_text_color = json_decode(formipay_get_post_meta($form_id, 'button_text_color'), true );
|
||||
$button_border_color = json_decode( formipay_get_post_meta($form_id, 'button_border_color'), true );
|
||||
|
||||
get_header();
|
||||
?>
|
||||
<style>
|
||||
body {
|
||||
--formipay-confirmation-page-width: <?php echo esc_html($formipay_settings[$this->gateway.'_confirmation_page_width']); ?>px;
|
||||
--formipay-confirmation-page-table-alignment: <?php echo esc_html($formipay_settings[$this->gateway.'_confirmation_table_alignment']) ?>;
|
||||
--formipay-button-submit-bg-color: <?php echo esc_html($button_background_color['regular']) ?? '#000000'; ?>;
|
||||
--formipay-button-submit-bg-color-hover: <?php echo esc_html($button_background_color['hover']) ?? '#ffffff'; ?>;
|
||||
--formipay-button-submit-bg-color-active: <?php echo esc_html($button_background_color['active']) ?? '#ffffff'; ?>;
|
||||
--formipay-button-submit-text-color: <?php echo esc_html($button_text_color['regular']) ?? '#ffffff'; ?>;
|
||||
--formipay-button-submit-text-color-hover: <?php echo esc_html($button_text_color['hover']) ?? '#000000'; ?>;
|
||||
--formipay-button-submit-text-color-active: <?php echo esc_html($button_text_color['active']) ?? '#000000'; ?>;
|
||||
--formipay-button-submit-border-color: <?php echo esc_html($button_border_color['regular']) ?? '#000000;' ?>;
|
||||
--formipay-button-submit-border-color-hover: <?php echo esc_html($button_border_color['hover']) ?? '#ffffff'; ?>;
|
||||
--formipay-button-submit-border-color-active: <?php echo esc_html($button_border_color['active']) ?? '#ffffff'; ?>;
|
||||
}
|
||||
</style>
|
||||
<div class="formipay-container">
|
||||
<div class="formipay-content-wrapper">
|
||||
<?php
|
||||
echo wp_kses_post(str_replace(
|
||||
[
|
||||
'{{order_details}}',
|
||||
'{{confirmation_form}}'
|
||||
],
|
||||
[
|
||||
$this->render_order_details_table($form_id, $order_id),
|
||||
$this->render_confirmation_form($form_id, $order_id)
|
||||
],
|
||||
$formipay_settings[$this->gateway.'_confirmation_page_content']
|
||||
))
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
get_footer();
|
||||
|
||||
exit;
|
||||
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function render_confirmation_form($form_id, $order_id){
|
||||
|
||||
$formipay_settings = get_option( 'formipay_settings' );
|
||||
$order = formipay_get_order($order_id);
|
||||
|
||||
ob_start();
|
||||
|
||||
if($order['status'] == 'on-hold') {
|
||||
?>
|
||||
<form id="formipay-cod-confirmation">
|
||||
<input type="hidden" id="form_id" value="<?php echo intval($form_id); ?>">
|
||||
<input type="hidden" id="order_id" value="<?php echo intval($order_id); ?>">
|
||||
<?php wp_nonce_field('formipay_cod_confirmation', 'formipay_nonce'); ?>
|
||||
<div class="formipay-agreement">
|
||||
<input id="cod_agreement" type="checkbox" class="formipay-input">
|
||||
<label for="cod_agreement"><?php echo esc_html($formipay_settings['cod_confirmation_form_agreement']); ?></label>
|
||||
</div>
|
||||
<div class="formipay-button-wrapper">
|
||||
<button type="button" id="confirm-cod-order" class="formipay-submit-button" disabled><?php echo esc_html($formipay_settings['cod_confirmation_form_button']); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function render_order_details_table($form_id, $order_id) {
|
||||
ob_start();
|
||||
?>
|
||||
<table id="order-details">
|
||||
<tbody>
|
||||
<?php
|
||||
$order = formipay_get_order($order_id);
|
||||
if(false !== $order){
|
||||
$items = maybe_unserialize($order['items']);
|
||||
foreach($items as $item){
|
||||
$label = ucwords(str_replace('_', ' ', $item['item']));
|
||||
if(!in_array($label, ['payment', 'payment_gateway'])){
|
||||
$qty = '';
|
||||
if(isset($item['qty']) && !empty($item['qty'])){
|
||||
$qty = ' × '.$item['qty'];
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th><?php echo esc_html($label) . esc_html($qty); ?></th>
|
||||
<td><?php echo esc_html(formipay_price_format($item['subtotal'], $form_id)); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr class="formipay-grand-total-row">
|
||||
<th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
|
||||
<td><?php echo esc_html(formipay_price_format($order['total'], $form_id)); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function handle_formipay_cod_confirmation() {
|
||||
|
||||
// Check nonce
|
||||
$nonce_valid = check_ajax_referer('formipay_cod_confirmation', 'formipay_nonce', false);
|
||||
|
||||
// Handle the valid nonce case
|
||||
if ($nonce_valid) {
|
||||
// Retrieve the data
|
||||
$form_id = isset($_POST['form_id']) ? sanitize_text_field( wp_unslash($_POST['form_id']) ) : '';
|
||||
$order_id = isset($_POST['order_id']) ? sanitize_text_field( wp_unslash($_POST['order_id']) ) : '';
|
||||
|
||||
$update = formipay_update_order_status([
|
||||
'form_id' => $form_id,
|
||||
'order_id' => $order_id,
|
||||
'status' => 'payment-confirm',
|
||||
'payment_gateway' => 'cod'
|
||||
]);
|
||||
|
||||
wp_send_json( [
|
||||
'success' => boolval($update['valid']),
|
||||
'data' => [
|
||||
'message' => $update['message'],
|
||||
'icon' => (boolval($update['valid']) == true) ? 'success' : 'info'
|
||||
]
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
// Nonce is invalid, handle the error
|
||||
wp_send_json_error([
|
||||
'message' => 'Security check failed. Please try again.',
|
||||
'icon' => 'error'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function add_order_shortcodes($shortcodes, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
if($order_data['payment_gateway'] == $this->gateway){
|
||||
|
||||
$confirmation_page_link = site_url('/payment-confirm/'.$this->gateway.'/'.base64_encode($form_id.':::'.$order_data['id']));
|
||||
$shortcodes['payment_confirmation_form'] = '<a href="'.$confirmation_page_link.'" target="_blank">C.O.D Confirmation</a>';
|
||||
|
||||
}
|
||||
|
||||
return $shortcodes;
|
||||
|
||||
}
|
||||
|
||||
public function process_payment($order_data) {
|
||||
return $order_data;
|
||||
}
|
||||
|
||||
}
|
||||
289
includes/Payment/Payment.php
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
namespace Formipay\Payment;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
abstract class Payment {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
abstract public function add_gateway($gateways);
|
||||
abstract public function add_transaction($order_data);
|
||||
abstract public function process_payment($order_data);
|
||||
abstract public function cancel_payment($order_data);
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_filter( 'formipay/global-settings', [$this, 'add_setting_payment_menu'], 20 );
|
||||
add_filter( 'formipay/form-config', [$this, 'add_form_payment_menu'], 79 );
|
||||
|
||||
add_filter( 'formipay/form-config/tab:payments', [$this, 'add_responsive_grid'], 1012 );
|
||||
add_filter( 'formipay/frontend/payment-list', [$this, 'add_payment_list'], 999, 2 );
|
||||
|
||||
add_filter( 'formipay/order/shortcodes', [$this, 'add_order_shortcodes'], 999, 4 );
|
||||
add_filter( 'formipay/thankyou/shortcodes', [$this, 'add_order_shortcodes'], 999, 4 );
|
||||
add_filter( 'formipay/order/process-data', [$this, 'add_payment_in_process_data'], 999, 2 );
|
||||
add_filter( 'formipay/order/payment-details', [$this, 'render_payment_details'], 999, 4 );
|
||||
|
||||
add_action( 'init', [$this, 'set_endpoint'], 999);
|
||||
add_filter( 'query_vars', [$this, 'set_query_vars'], 899);
|
||||
add_action( 'wp_enqueue_scripts', [$this, 'frontend_enqueue'] );
|
||||
add_filter( 'pre_get_document_title', [$this, 'payment_confirm_page_title'], 1000 );
|
||||
|
||||
}
|
||||
|
||||
public function add_setting_payment_menu($fields){
|
||||
|
||||
$general_payment_settings = array();
|
||||
|
||||
$payment_settings = apply_filters( 'formipay/global-settings/tab:payment', $general_payment_settings );
|
||||
|
||||
if(!empty($payment_settings)){
|
||||
$fields['payment'] = array(
|
||||
'name' => __('Payment', 'formipay'),
|
||||
'fields' => $payment_settings
|
||||
);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_form_payment_menu($fields) {
|
||||
|
||||
$gateways = apply_filters( 'formipay/form-config/tab:payments/gateways', [] );
|
||||
|
||||
$payment_options = [];
|
||||
if(!empty($gateways)){
|
||||
foreach($gateways as $gateway){
|
||||
$id = $gateway['id'];
|
||||
$label = $gateway['gateway'];
|
||||
if(isset($gateway['channel'])){
|
||||
$label .= ' - '.$gateway['channel'];
|
||||
}
|
||||
$payment_options[] = [
|
||||
'id' => $id,
|
||||
'label' => $label
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$payment_fields = [
|
||||
'payment_section_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Payment Section', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'payment_section_title' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Payment Section Title', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'value' => 'Payment Methods',
|
||||
),
|
||||
'payment_gateways' => array(
|
||||
'type' => 'sorter',
|
||||
'label' => __( 'Choose one or any', 'formipay' ),
|
||||
'options' => array(
|
||||
array(
|
||||
'id' => 'inactive',
|
||||
'name' => __( 'Inactive', 'formipay' ),
|
||||
'options' => $payment_options,
|
||||
),
|
||||
array(
|
||||
'id' => 'active',
|
||||
'name' => __( 'Active', 'formipay' ),
|
||||
'options' => [],
|
||||
)
|
||||
),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
),
|
||||
'payment_label' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Show Payment Label', 'formipay' ),
|
||||
'description' => __( 'Show payment label in the payment options on the frontend.', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
];
|
||||
|
||||
$payment_fields = apply_filters( 'formipay/form-config/tab:payments', $payment_fields );
|
||||
|
||||
$fields['formipay_form_settings']['payments'] = array(
|
||||
'name' => __( 'Payments', 'formipay' ),
|
||||
'fields' => $payment_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_responsive_grid($channels) {
|
||||
$channels['payment_responsive_box'] = array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Responsive', 'formipay' ),
|
||||
'description' => __( 'Set responsive grid payment card options' , 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'group' => 'started',
|
||||
);
|
||||
|
||||
$channels['payment_desktop_columns'] = array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Desktop View', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'value' => 4
|
||||
);
|
||||
|
||||
$channels['payment_tablet_columns'] = array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Tablet View', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'value' => 3
|
||||
);
|
||||
|
||||
$channels['payment_mobile_columns'] = array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Mobile View', 'formipay' ),
|
||||
'submenu' => __( 'General', 'formipay' ),
|
||||
'value' => 2,
|
||||
'group' => 'ended'
|
||||
);
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
public function add_payment_list($payment_list, $form_id) {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
$payment_gateways = json_decode(formipay_get_post_meta($form_id, 'payment_gateways'), true);
|
||||
foreach($payment_gateways as $payment){
|
||||
if($payment['id'] == 'active' && !empty($payment['options'])){
|
||||
foreach($payment['options'] as $option){
|
||||
$id = $option['id'];
|
||||
$_pay = explode(':::', $id);
|
||||
$gateway = $_pay[0];
|
||||
if(formipay_get_post_meta($form_id, 'product_type') == 'digital' && $gateway == 'cod'){
|
||||
continue;
|
||||
}
|
||||
if(isset($formipay_settings[$gateway.'_channels']) && isset($_pay[1])){
|
||||
$channel = $_pay[1];
|
||||
if(strpos($channel, '-')){
|
||||
$channel = explode('-', $channel);
|
||||
$channel_index = $channel[1];
|
||||
$payment_list[$id] = $formipay_settings[$gateway.'_channels'][$channel_index];
|
||||
}
|
||||
}else{
|
||||
$label = $icon = '';
|
||||
if(isset($formipay_settings[$gateway.'_label']) && !empty($formipay_settings[$gateway.'_label'])){
|
||||
$label = $formipay_settings[$gateway.'_label'];
|
||||
}
|
||||
if(isset($formipay_settings[$gateway.'_icon']) && !empty($formipay_settings[$gateway.'_icon'])){
|
||||
$icon = $formipay_settings[$gateway.'_icon'];
|
||||
}
|
||||
$payment_list[$id] = array(
|
||||
$gateway.'_name' => apply_filters( 'formipay/payment-list/'.$gateway.'/label', $label),
|
||||
$gateway.'_logo' => apply_filters( 'formipay/payment-list/'.$gateway.'/logo', $icon)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $payment_list;
|
||||
|
||||
}
|
||||
|
||||
public function add_order_shortcodes($shortcodes, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
$shortcodes['payment_details'] = apply_filters( 'formipay/order/payment-details', '', $form_id, $order_data, $submit_action_type );
|
||||
|
||||
return $shortcodes;
|
||||
|
||||
}
|
||||
|
||||
public function render_payment_details($render, $form_id, $order_data, $submit_action_type) {
|
||||
|
||||
$payment_gateway = $order_data['payment_gateway'];
|
||||
|
||||
$render = apply_filters( 'formipay/order/payment-details/'.$payment_gateway, $render, $form_id, $order_data, $submit_action_type );
|
||||
|
||||
ob_start();
|
||||
echo wp_kses($render, formipay_thankyoupage_allowed_html());
|
||||
$content = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function add_payment_in_process_data($order_data, $form_id) {
|
||||
|
||||
$payment = explode(':::', $order_data['payment']);
|
||||
$payment_gateway = $payment[0];
|
||||
$order_data['payment_gateway'] = $payment_gateway;
|
||||
|
||||
return $order_data;
|
||||
|
||||
}
|
||||
|
||||
public function set_endpoint() {
|
||||
|
||||
add_rewrite_rule(
|
||||
'^payment-confirm/([^/]*)/([^/]*)/?',
|
||||
'index.php?formipay-payment-confirm=1&gateway=$matches[1]&formipay-token=$matches[2]',
|
||||
'top'
|
||||
);
|
||||
|
||||
flush_rewrite_rules();
|
||||
|
||||
}
|
||||
|
||||
public function set_query_vars($vars){
|
||||
|
||||
$vars[] = 'formipay-payment-confirm';
|
||||
$vars[] = 'gateway';
|
||||
$vars[] = 'formipay-token';
|
||||
return $vars;
|
||||
|
||||
}
|
||||
|
||||
public function frontend_enqueue() {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
if(
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-payment-confirm', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-payment-confirm'])
|
||||
) :
|
||||
|
||||
wp_enqueue_style( 'formipay-payment-confirm', FORMIPAY_URL . 'public/assets/css/payment-confirm.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'formipay-payment-confirm', FORMIPAY_URL . 'public/assets/js/payment-confirm.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function payment_confirm_page_title($title) {
|
||||
global $wp_query;
|
||||
|
||||
if(
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-payment-confirm', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-payment-confirm'])
|
||||
) :
|
||||
|
||||
$gateway = $wp_query->query['gateway'];
|
||||
$gateway = strlen($gateway) > 3 ? ucwords( str_replace('_', ' ', $gateway) ) : strtoupper($gateway);
|
||||
|
||||
$title = $gateway . ' Confirmation' . ' - ' . get_bloginfo('name');
|
||||
|
||||
endif;
|
||||
|
||||
return $title;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
932
includes/Product.php
Normal file
@@ -0,0 +1,932 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Product {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'cpt'] );
|
||||
add_action( 'init', [$this, 'taxonomy'] );
|
||||
add_action( 'admin_menu', [$this, 'add_submenu'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_admin'] );
|
||||
|
||||
add_filter( 'stm_wpcfto_boxes', [$this, 'cpt_post_fields_box'] );
|
||||
add_filter( 'stm_wpcfto_fields', [$this, 'cpt_post_fields_content'] );
|
||||
add_filter( 'formipay/product-config', [$this, 'general_config'], 20 );
|
||||
add_filter( 'formipay/product-config', [$this, 'variations_config'], 40 );
|
||||
add_filter( 'formipay/product-config', [$this, 'stock_config'], 60 );
|
||||
|
||||
add_action( 'wp_ajax_formipay-tabledata-products', [$this, 'formipay_tabledata_products'] );
|
||||
add_action( 'wp_ajax_formipay-create-product-post', [$this, 'formipay_create_product_post'] );
|
||||
add_action( 'wp_ajax_formipay-delete-product', [$this, 'formipay_delete_product'] );
|
||||
add_action( 'wp_ajax_formipay-bulk-delete-product', [$this, 'formipay_bulk_delete_product'] );
|
||||
add_action( 'wp_ajax_formipay-duplicate-product', [$this, 'formipay_duplicate_product'] );
|
||||
|
||||
add_action( 'wp_ajax_formipay_product_get_currencies', [$this, 'formipay_product_get_currencies'] );
|
||||
add_action( 'wp_ajax_get_product_variables', [$this, 'get_product_variables'] );
|
||||
|
||||
add_action('save_post', [$this, 'save_product'], 10, 2);
|
||||
|
||||
}
|
||||
|
||||
public function cpt() {
|
||||
|
||||
$labels = array(
|
||||
'name' => __('Products', 'formipay'),
|
||||
'singular_name' => __('Product', 'formipay'),
|
||||
'menu_name' => 'Formipay',
|
||||
'add_new' => __('Add New', 'formipay'),
|
||||
'add_new_item' => __('Add New Product', 'formipay'),
|
||||
'edit' => __('Edit', 'formipay'),
|
||||
'edit_item' => __('Edit Product', 'formipay'),
|
||||
'new_item' => __('New Product', 'formipay'),
|
||||
'view' => __('View', 'formipay'),
|
||||
'view_item' => __('View Product', 'formipay'),
|
||||
'search_items' => __('Search Product', 'formipay'),
|
||||
'not_found' => __('No products found', 'formipay'),
|
||||
'not_found_in_trash' => __('No products found in trash', 'formipay'),
|
||||
'parent' => __('Product Parent', 'formipay')
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'label' => 'Products',
|
||||
'labels' => $labels,
|
||||
'public' => true,
|
||||
'supports' => array( 'title' ),
|
||||
'hierarchical' => true,
|
||||
'taxonomies' => array( 'formipay-product-category' ),
|
||||
'has_archive' => true,
|
||||
'rewrite' => array( 'slug' => 'product' ),
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => false,
|
||||
'show_in_rest' => true,
|
||||
'query_var' => true
|
||||
);
|
||||
|
||||
register_post_type( 'formipay-product', $args );
|
||||
|
||||
}
|
||||
|
||||
public function taxonomy() {
|
||||
register_taxonomy( 'formipay-product-category', 'formipay-product', array(
|
||||
'rewrite' => array( 'slug' => 'product/category' ),
|
||||
'hierarchical' => true
|
||||
) );
|
||||
}
|
||||
|
||||
public function add_submenu() {
|
||||
|
||||
add_submenu_page(
|
||||
'formipay',
|
||||
__( 'Products', 'formipay' ),
|
||||
__( 'Products', 'formipay' ),
|
||||
'manage_options',
|
||||
'formipay-products',
|
||||
[$this, 'formipay_products'],
|
||||
);
|
||||
add_submenu_page(
|
||||
'formipay',
|
||||
__('Categories', 'formipay'),
|
||||
'└ ' . __('Categories', 'formipay'),
|
||||
'manage_options',
|
||||
'edit-tags.php?taxonomy=formipay-product-category&post_type=formipay-product',
|
||||
null,
|
||||
5
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function enqueue_admin() {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-products') {
|
||||
|
||||
wp_enqueue_style( 'page-products', FORMIPAY_URL . 'admin/assets/css/page-products.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'page-products', FORMIPAY_URL . 'admin/assets/js/page-products.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
|
||||
wp_localize_script( 'page-products', 'formipay_products_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'title' => esc_html__( 'Title', 'formipay' ),
|
||||
'price' => esc_html__( 'Price', 'formipay' ),
|
||||
'type' => esc_html__( 'Type', 'formipay' ),
|
||||
'stock' => esc_html__( 'Stock', 'formipay' ),
|
||||
'status' => esc_html__( 'Status', 'formipay' ),
|
||||
],
|
||||
'filter_form' => [
|
||||
'categories' => [
|
||||
'placeholder' => esc_html__( 'Filter by Category', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
],
|
||||
'currencies' => [
|
||||
'placeholder' => esc_html__( 'Filter by Currency', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
]
|
||||
],
|
||||
'modal' => [
|
||||
'form' => [
|
||||
'currency_options' => formipay_currency_as_options()
|
||||
],
|
||||
'add' => [
|
||||
'title' => esc_html__( 'Your New Product Data', 'formipay' ),
|
||||
'validation' => esc_html__( '{{field}} is required', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Create New Product', 'formipay' )
|
||||
],
|
||||
'delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the product?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
|
||||
],
|
||||
'bulk_delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the selected the product(s)?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
'duplicate' => [
|
||||
'question' => esc_html__( 'Do you want to duplicate the product?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-admin-product-page')
|
||||
] );
|
||||
}
|
||||
|
||||
if($current_screen->base == 'post' && $current_screen->post_type == 'formipay-product'){
|
||||
global $post;
|
||||
$product_id = $post->ID;
|
||||
// Get pricing method, default to 'auto' if not set
|
||||
$pricing_method = formipay_get_post_meta($product_id, 'product_pricing_method') ?: 'auto';
|
||||
$has_variation = (bool) formipay_get_post_meta($product_id, 'product_has_variation', true);
|
||||
|
||||
wp_enqueue_style( 'product-details', FORMIPAY_URL . 'admin/assets/css/admin-product-editor.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'product-details', FORMIPAY_URL . 'admin/assets/js/admin-product-editor.js', ['jquery', 'vue.js'], FORMIPAY_VERSION, true );
|
||||
wp_localize_script( 'product-details', 'product_details', [
|
||||
'default_currency' => formipay_default_currency(),
|
||||
'default_currency_title' => formipay_default_currency('title'),
|
||||
'default_currency_symbol' => formipay_default_currency('symbol'),
|
||||
'default_currency_decimal_digits' => formipay_default_currency('decimal_digits'),
|
||||
'default_currency_decimal_symbol' => formipay_default_currency('decimal_symbol'),
|
||||
'default_currency_thousand_separator' => formipay_default_currency('thousand_separator'),
|
||||
'product_type' => formipay_get_post_meta($product_id, 'product_type') ?: 'digital',
|
||||
'product_is_physical' => formipay_get_post_meta($product_id, 'product_type') == 'physical',
|
||||
'product_pricing_method' => $pricing_method, // Pass pricing method to JS
|
||||
'product_has_variation' => $has_variation,
|
||||
'variation_table' => [
|
||||
'th_toggle' => __('Active', 'formipay'),
|
||||
'th_name' => __('Title', 'formipay'),
|
||||
'th_stock' => __('Stock', 'formipay'),
|
||||
'th_price' => __('Regular Price', 'formipay'),
|
||||
'th_sale' => __('Sale Price', 'formipay'),
|
||||
'th_weight' => __('Weight', 'formipay'),
|
||||
'th_prices_overall' => __('Prices', 'formipay'), // New header for manual mode
|
||||
'manual_price_hint' => __('Prices set manually below', 'formipay'), // New hint for manual mode cell
|
||||
'child_th_currency' => __('Currency', 'formipay'), // Child table header
|
||||
'child_th_regular' => __('Regular Price', 'formipay'), // Child table header
|
||||
'child_th_sale' => __('Sale Price', 'formipay'), // Child table header
|
||||
'no_variations' => __( 'No variations available', 'formipay' )
|
||||
]
|
||||
] );
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
if($current_screen->taxonomy == 'formipay-product-category') {
|
||||
wp_enqueue_style( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/css/admin-pages.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.mermaid.min.css', [], '6.2.0', 'all' );
|
||||
wp_enqueue_style( 'page-product-taxonomy', FORMIPAY_URL . 'admin/assets/css/page-product-taxonomy.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'formipay-admin-pages', FORMIPAY_URL . 'admin/assets/js/admin-pages.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'gridjs', FORMIPAY_URL . 'vendor/GridJS/gridjs.production.min.js', ['jquery'], '6.2.0', true );
|
||||
wp_enqueue_script( 'page-product-taxonomy', FORMIPAY_URL . 'admin/assets/js/page-product-taxonomy.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
wp_localize_script( 'page-product-taxonomy', 'formipay_product_taxonomy_page', [
|
||||
'site_url' => site_url(),
|
||||
'page_title' => esc_html__( 'Product Categories', 'formipay' )
|
||||
] );
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
wp_localize_script( 'sweetalert2', 'formipay_admin', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function formipay_products() {
|
||||
include_once FORMIPAY_PATH . 'admin/page-products.php';
|
||||
}
|
||||
|
||||
public function cpt_post_fields_box($boxes) {
|
||||
$boxes['formipay_product_settings'] = array(
|
||||
'post_type' => array('formipay-product'),
|
||||
'label' => __('Config', 'formipay'),
|
||||
);
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
public function cpt_post_fields_content($fields) {
|
||||
|
||||
$fields['formipay_product_settings'] = array();
|
||||
|
||||
$fields = apply_filters( 'formipay/product-config', $fields );
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function general_config($fields) {
|
||||
|
||||
// Product Details Group
|
||||
$product_details_group = array(
|
||||
'setting_product_details' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Product Details', 'formipay' ),
|
||||
'description' => __( 'All details about the products sold using this form.', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'product_type' => array(
|
||||
'type' => 'radio',
|
||||
'label' => __('Product Type', 'formipay'),
|
||||
'options' => array(
|
||||
'digital' => 'Digital',
|
||||
'physical' => 'Physical'
|
||||
),
|
||||
'value' => 'digital',
|
||||
'required' => true
|
||||
),
|
||||
'product_description' => array(
|
||||
'type' => 'tinymce',
|
||||
'label' => __('Description', 'formipay'),
|
||||
)
|
||||
);
|
||||
|
||||
$product_details_group = apply_filters( 'formipay/product-settings/tab:general/group:product-details', $product_details_group );
|
||||
|
||||
$last_product_details_group = array_key_last($product_details_group);
|
||||
$product_details_group[$last_product_details_group]['group'] = 'ended';
|
||||
|
||||
// Product Currency Group
|
||||
$product_currency_group = array(
|
||||
'setting_product_pricing' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Pricing', 'formipay' ),
|
||||
'description' => __( 'Carefully set these options below.', 'formipay' ),
|
||||
'group' => 'started',
|
||||
),
|
||||
'product_pricing_method' => array(
|
||||
'type' => 'radio',
|
||||
'label' => __('Product Pricing Method', 'formipay'),
|
||||
'options' => array(
|
||||
'manual' => 'Manual Price Set',
|
||||
'auto' => 'Auto via Currency Exchange API'
|
||||
),
|
||||
'value' => 'manual',
|
||||
'required' => true
|
||||
),
|
||||
'product_regular_price' => array(
|
||||
'type' => 'number',
|
||||
'label' => sprintf( __('Regular Price (%s)', 'formipay'), formipay_default_currency('symbol') ),
|
||||
'value' => 0,
|
||||
'step' => 0.01,
|
||||
'required' => true,
|
||||
'dependency' => [
|
||||
'key' => 'product_pricing_method',
|
||||
'value' => 'auto'
|
||||
]
|
||||
),
|
||||
'product_sale_price' => array(
|
||||
'type' => 'number',
|
||||
'label' => sprintf( __('Sale Price (%s)', 'formipay'), formipay_default_currency('symbol') ),
|
||||
'value' => 0,
|
||||
'step' => 0.01,
|
||||
'dependency' => [
|
||||
'key' => 'product_pricing_method',
|
||||
'value' => 'auto'
|
||||
]
|
||||
),
|
||||
'product_prices' => [
|
||||
'type' => 'repeater',
|
||||
'label' => __( 'Prices', 'formipay' ),
|
||||
'description' => __( 'You can set price with multiple currency', 'formipay' ),
|
||||
'fields' => [
|
||||
'regular_price' => array(
|
||||
'type' => 'number',
|
||||
'label' => __('Regular Price', 'formipay'),
|
||||
'value' => 0,
|
||||
'step' => 0.01,
|
||||
'required' => true
|
||||
),
|
||||
'sale_price' => array(
|
||||
'type' => 'number',
|
||||
'label' => __('Sale Price', 'formipay'),
|
||||
'value' => 0,
|
||||
'step' => 0.01
|
||||
),
|
||||
'currency' => array(
|
||||
'type' => 'select',
|
||||
'label' => __('Currency', 'formipay'),
|
||||
'value' => 'IDR:::Indonesian rupiah:::Rp',
|
||||
'options' => formipay_currency_as_options(),
|
||||
'required' => true,
|
||||
'searchable' => true,
|
||||
'is_group_title' => true
|
||||
),
|
||||
'currency_decimal_digits' => array(
|
||||
'type' => 'number',
|
||||
'label' => __('Decimal Digits', 'formipay'),
|
||||
'value' => '2',
|
||||
'required' => true
|
||||
),
|
||||
'currency_decimal_symbol' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Decimal Symbol', 'formipay'),
|
||||
'value' => '.',
|
||||
'required' => true
|
||||
),
|
||||
'currency_thousand_separator' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Thousand Separator Symbol', 'formipay'),
|
||||
'value' => ',',
|
||||
'required' => true
|
||||
),
|
||||
],
|
||||
'dependency' => [
|
||||
'key' => 'product_pricing_method',
|
||||
'value' => 'manual'
|
||||
]
|
||||
],
|
||||
);
|
||||
|
||||
$product_currency_group = apply_filters( 'formipay/product-settings/tab:general/group:product-currency', $product_currency_group );
|
||||
|
||||
$last_product_currency_group = array_key_last($product_currency_group);
|
||||
$product_currency_group[$last_product_currency_group]['group'] = 'ended';
|
||||
|
||||
|
||||
$general_all_fields = array_merge($product_details_group, $product_currency_group);
|
||||
|
||||
$general_all_fields = apply_filters( 'formipay/product-settings/tab:general', $general_all_fields );
|
||||
|
||||
$fields['formipay_product_settings']['general'] = array(
|
||||
'name' => __('General', 'formipay'),
|
||||
'fields' => $general_all_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function variations_config($fields) {
|
||||
// Product Variations Attribute Group
|
||||
$product_attributes_group = array(
|
||||
'setting_product_variations' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Attributes', 'formipay' ),
|
||||
'description' => __( 'First we need to build the attribute of this product. For example Color, Size, License Site Count.', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'product_has_variation' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Product has variations', 'formipay' ),
|
||||
),
|
||||
'product_variation_attributes' => array(
|
||||
'type' => 'repeater',
|
||||
'label' => __('Attributes', 'formipay'),
|
||||
'description' => __( 'Your attributes will generate variation automatically.', 'formipay' ),
|
||||
'fields' => [
|
||||
'attribute_name' => [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Attribute Name', 'formipay' ),
|
||||
'description' => __( 'e.g. Color, Size, etc', 'formipay' ),
|
||||
'is_group_title' => true
|
||||
],
|
||||
'attribute_variations' => [
|
||||
'type' => 'repeater',
|
||||
'label' => esc_html__( 'Variation', 'formipay' ),
|
||||
'fields' => [
|
||||
'variation_label' => [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Title', 'formipay' ),
|
||||
'description' => __( 'e.g. Color, Size, etc', 'formipay' ),
|
||||
'required' => true,
|
||||
'is_group_title' => true
|
||||
],
|
||||
'variation_value_type' => [
|
||||
'type' => 'select',
|
||||
'label' => __( 'Value Type', 'formipay' ),
|
||||
'options' => [
|
||||
'text' => __( 'Text', 'formipay' ),
|
||||
'number' => __( 'Number', 'formipay' ),
|
||||
'color' => __( 'Color', 'formipay' ),
|
||||
],
|
||||
'value' => 'text'
|
||||
],
|
||||
'variation_value_text' => [
|
||||
'type' => 'text',
|
||||
'label' => __( 'Value', 'formipay' ),
|
||||
'required' => true,
|
||||
'dependency' => array(
|
||||
'key' => 'variation_value_type',
|
||||
'value' => 'text'
|
||||
),
|
||||
],
|
||||
'variation_value_number' => [
|
||||
'type' => 'number',
|
||||
'label' => __( 'Value', 'formipay' ),
|
||||
'required' => true,
|
||||
'dependency' => array(
|
||||
'key' => 'variation_value_type',
|
||||
'value' => 'number'
|
||||
),
|
||||
],
|
||||
'variation_value_color' => [
|
||||
'type' => 'color',
|
||||
'label' => __( 'Value', 'formipay' ),
|
||||
'required' => true,
|
||||
'dependency' => array(
|
||||
'key' => 'variation_value_type',
|
||||
'value' => 'color'
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'dependency' => array(
|
||||
'key' => 'product_has_variation',
|
||||
'value' => 'not_empty'
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$product_attributes_group = apply_filters( 'formipay/product-settings/tab:general/group:product-attributes', $product_attributes_group );
|
||||
|
||||
$last_product_attributes_group = array_key_last($product_attributes_group);
|
||||
$product_attributes_group[$last_product_attributes_group]['group'] = 'ended';
|
||||
|
||||
// Product Variations Attribute Group
|
||||
|
||||
// Define your product variations field group somewhere in your plugin/theme
|
||||
$product_variations_table_html = file_get_contents(FORMIPAY_PATH . 'admin/templates/product-variations.php');
|
||||
|
||||
$product_variations_group = [
|
||||
'variation_table' => [
|
||||
'type' => 'html',
|
||||
'label' => __( 'Variations', 'formipay' ),
|
||||
'html' => $product_variations_table_html
|
||||
],
|
||||
];
|
||||
|
||||
$variation_all_fields = array_merge($product_attributes_group, $product_variations_group);
|
||||
|
||||
$variation_all_fields = apply_filters( 'formipay/product-settings/tab:variations', $variation_all_fields );
|
||||
|
||||
$fields['formipay_product_settings']['variation'] = array(
|
||||
'name' => __('Variations', 'formipay'),
|
||||
'fields' => $variation_all_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
public function stock_config($fields) {
|
||||
|
||||
// Product Quantity Group
|
||||
$product_quantity_group = array(
|
||||
'setting_product_quantity' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Quantity Settings', 'formipay' ),
|
||||
'description' => __( 'You can activate this if you will manage the stock.', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'product_quantity_toggle' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Activate Quantity', 'formipay' ),
|
||||
),
|
||||
'product_quantity_range' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Quantity Range Step', 'formipay' ),
|
||||
'value' => 1,
|
||||
'dependency' => array(
|
||||
'key' => 'product_quantity_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
'product_minimum_purchase' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Minimum Purchase', 'formipay' ),
|
||||
'value' => 1,
|
||||
'dependency' => array(
|
||||
'key' => 'product_quantity_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
),
|
||||
'product_stock' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Stock', 'formipay' ),
|
||||
'description' => __('Set -1 for unlimited stock', 'formipay'),
|
||||
'value' => -1,
|
||||
'dependency' => array(
|
||||
'key' => 'product_quantity_toggle',
|
||||
'value' => 'not_empty'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$product_quantity_group = apply_filters( 'formipay/product-settings/tab:stock/group:product-quantity', $product_quantity_group );
|
||||
|
||||
$last_product_quantity_group = array_key_last($product_quantity_group);
|
||||
$product_quantity_group[$last_product_quantity_group]['group'] = 'ended';
|
||||
|
||||
$stock_all_fields = apply_filters( 'formipay/product-settings/tab:stock', $product_quantity_group );
|
||||
|
||||
$fields['formipay_product_settings']['stock'] = array(
|
||||
'name' => __('Stock & Quantity', 'formipay'),
|
||||
'fields' => $stock_all_fields
|
||||
);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function formipay_tabledata_products() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
global $wpdb;
|
||||
|
||||
// Initialize default args
|
||||
$base_args = [
|
||||
'post_type' => 'formipay-product',
|
||||
'post_status' => ['publish', 'draft', 'pending'],
|
||||
'fields' => 'ids' // Optimize initial query
|
||||
];
|
||||
|
||||
// Handle status filtering
|
||||
if (isset($_REQUEST['post_status']) && 'all' !== $_REQUEST['post_status']) {
|
||||
$base_args['post_status'] = [sanitize_key($_REQUEST['post_status'])];
|
||||
}
|
||||
|
||||
// Currency filtering
|
||||
if (!empty($_REQUEST['currency'])) {
|
||||
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||
$base_args['meta_query'] = [
|
||||
[
|
||||
'key' => 'product_currency',
|
||||
'value' => sanitize_text_field(wp_unslash($_REQUEST['currency'])),
|
||||
'compare' => 'LIKE'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Category filtering
|
||||
if (!empty($_REQUEST['category'])) {
|
||||
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
|
||||
$base_args['tax_query'] = [
|
||||
[
|
||||
'taxonomy' => 'formipay-product-category',
|
||||
'field' => 'term_id',
|
||||
'terms' => absint($_REQUEST['category'])
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Search functionality
|
||||
if (!empty($_REQUEST['search'])) {
|
||||
$base_args['s'] = isset($_REQUEST['search']) ? sanitize_text_field(wp_unslash($_REQUEST['search'])) : '';
|
||||
}
|
||||
|
||||
// Sorting
|
||||
if (!empty($_REQUEST['orderby'])) {
|
||||
$orderby = sanitize_key($_REQUEST['orderby']);
|
||||
$order = isset($_REQUEST['sort']) ? sanitize_key($_REQUEST['sort']) : 'ASC';
|
||||
|
||||
if ('price' === $orderby) {
|
||||
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
||||
$base_args['meta_key'] = 'product_price';
|
||||
$base_args['orderby'] = 'meta_value_num';
|
||||
} else {
|
||||
$base_args['orderby'] = $orderby;
|
||||
}
|
||||
$base_args['order'] = $order;
|
||||
}
|
||||
|
||||
// Pagination
|
||||
if (isset($_REQUEST['limit'])) {
|
||||
$base_args['posts_per_page'] = absint($_REQUEST['limit']);
|
||||
}
|
||||
if (isset($_REQUEST['offset'])) {
|
||||
$base_args['offset'] = intval($_REQUEST['offset']);
|
||||
}
|
||||
|
||||
// Main query
|
||||
$query = new \WP_Query($base_args);
|
||||
$product_ids = $query->posts;
|
||||
$total_products = $query->found_posts;
|
||||
|
||||
// Process results
|
||||
$products = [];
|
||||
foreach ($product_ids as $product_id) {
|
||||
$product = get_post($product_id);
|
||||
|
||||
$currency = explode(':::', get_post_meta($product_id, 'product_currency', true));
|
||||
$categories = wp_get_post_terms($product_id, 'formipay-product-category', ['fields' => 'names']);
|
||||
|
||||
$products[] = [
|
||||
'ID' => $product_id,
|
||||
'title' => $product->post_title,
|
||||
'category' => implode(', ', $categories),
|
||||
'type' => formipay_get_post_meta($product_id, 'product_type'),
|
||||
'stock' => formipay_get_post_meta($product_id, 'stock') ?: '∞',
|
||||
'price' => [
|
||||
'flag' => formipay_get_flag_by_currency($currency[0] ?? ''),
|
||||
'name' => formipay_price_format(
|
||||
get_post_meta($product_id, 'price', true),
|
||||
$product_id
|
||||
)
|
||||
],
|
||||
'status' => $product->post_status,
|
||||
];
|
||||
}
|
||||
|
||||
// Get status counts using WordPress API
|
||||
$counts = wp_count_posts('formipay-product');
|
||||
$status_counts = [];
|
||||
foreach ($counts as $status => $count) {
|
||||
$status_counts[$status] = $count;
|
||||
}
|
||||
$status_counts['all'] = array_sum($status_counts);
|
||||
|
||||
wp_send_json([
|
||||
'results' => $products,
|
||||
'total' => $total_products,
|
||||
'posts_report' => array_map('intval', (array)$status_counts)
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function formipay_create_product_post() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
$title = isset($_REQUEST['title']) ? sanitize_text_field( wp_unslash($_REQUEST['title']) ) : '';
|
||||
|
||||
if( !empty($title) && '' !== $title ){
|
||||
$post_id = wp_insert_post( [
|
||||
'post_title' => $title,
|
||||
'post_type' => 'formipay-product',
|
||||
], true );
|
||||
|
||||
if(is_wp_error($post_id)){
|
||||
wp_send_json_error( [
|
||||
'message' => $post_id->get_error_message()
|
||||
] );
|
||||
}
|
||||
|
||||
update_post_meta($post_id, 'product_currency', 'USD:::United States dollar:::$'); // Note:: Ganti dengan default currency dari global settings
|
||||
|
||||
wp_send_json_success( [
|
||||
'edit_post_url' => admin_url('post.php?post='.$post_id.'&action=edit')
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_error( [
|
||||
'message' => esc_html__( 'Product\'s title is empty.', 'formipay' )
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_product_get_currencies() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
$search = isset($_REQUEST['search']) ? sanitize_text_field( wp_unslash($_REQUEST['search']) ) : '';
|
||||
|
||||
$countries = formipay_currency_array();
|
||||
$results = [];
|
||||
foreach($countries as $country){
|
||||
$country_name = strtolower($country['name']);
|
||||
$country_search = strtolower($search);
|
||||
if(strpos($country_name, $country_search) !== false || $country_search == strtolower($country['code'])){
|
||||
$results[] = [
|
||||
'value' => $country['code'],
|
||||
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment.
|
||||
'label' => '<img src="'.formipay_get_flag_by_currency($country['code']).'" height="18" style="margin-bottom: -3px;"> '.$country['name']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json( $results );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_delete_product() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
$form_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : '';
|
||||
|
||||
$delete = wp_delete_post($form_id, true);
|
||||
|
||||
if(is_wp_error( $delete )){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'Failed to delete product. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Deleted', 'formipay' ),
|
||||
'message' => esc_html__( 'Product is deleted permanently.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_bulk_delete_product() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
if( empty($_REQUEST['ids']) ){
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__( 'Failed', 'formipay' ),
|
||||
'message' => esc_html__( 'There is no product selected. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$ids = isset($_REQUEST['ids']) ? $_REQUEST['ids'] : [];
|
||||
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
if(!empty($ids)){
|
||||
foreach($ids as $id){
|
||||
$delete = wp_delete_post($id, true);
|
||||
if(is_wp_error( $delete )){
|
||||
$failed++;
|
||||
}else{
|
||||
$success++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($success > 0){
|
||||
$report .= sprintf( __( ' Deleted %d product(s).', 'formipay' ), $success);
|
||||
}
|
||||
if($failed > 0){
|
||||
$report .= sprintf( __( ' Failed %d product(s).', 'formipay' ), $failed);
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__( 'Done!', 'formipay' ),
|
||||
'message' => $report,
|
||||
'icon' => 'info'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
public function formipay_duplicate_product() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
||||
|
||||
$post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : '';
|
||||
$post = get_post($post_id);
|
||||
if (!$post) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Product is not defined.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
if (!in_array($post->post_type, ['formipay-product'])) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Wrong Post Type.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$duplicate_post = [
|
||||
'post_title' => $post->post_title . ' (Copy)',
|
||||
'post_content' => $post->post_content,
|
||||
'post_status' => 'draft', // Set sebagai draft
|
||||
'post_type' => $post->post_type,
|
||||
'post_author' => $post->post_author,
|
||||
];
|
||||
|
||||
$new_post_id = wp_insert_post($duplicate_post);
|
||||
|
||||
if (is_wp_error($new_post_id)) {
|
||||
wp_send_json_error( [
|
||||
'title' => esc_html__('Failed', 'formipay'),
|
||||
'message' => esc_html__( 'Something happened. Please try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$meta_data = get_post_meta($post_id);
|
||||
foreach ($meta_data as $key => $values) {
|
||||
foreach ($values as $value) {
|
||||
update_post_meta($new_post_id, $key, maybe_unserialize($value));
|
||||
}
|
||||
}
|
||||
|
||||
$taxonomies = get_object_taxonomies($post->post_type);
|
||||
foreach ($taxonomies as $taxonomy) {
|
||||
$terms = wp_get_object_terms($post_id, $taxonomy, ['fields' => 'slugs']);
|
||||
wp_set_object_terms($new_post_id, $terms, $taxonomy);
|
||||
}
|
||||
|
||||
wp_send_json_success( [
|
||||
'title' => esc_html__('Duplicated!', 'formipay'),
|
||||
'message' => esc_html__( 'Product is successfully duplicated.', 'formipay' ),
|
||||
'icon' => 'success'
|
||||
] );
|
||||
}
|
||||
|
||||
public function get_product_variables() {
|
||||
$post_id = intval($_POST['post_id'] ?? 0);
|
||||
$data = get_post_meta($post_id, 'product_variables', true);
|
||||
$json = is_string($data) ? json_decode($data, true) : [];
|
||||
if(is_array($json)){
|
||||
wp_send_json_success( $json );
|
||||
}
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
public function save_product_depracated($post_id, $post) {
|
||||
// Verify nonce and permissions here if you have a nonce field (recommended)
|
||||
|
||||
// Avoid autosave and revision saves
|
||||
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
||||
if (wp_is_post_revision($post_id)) return;
|
||||
|
||||
// Check user permissions
|
||||
if (!current_user_can('edit_post', $post_id)) return;
|
||||
|
||||
if (isset($_POST['product_variables'])) {
|
||||
// Sanitize input (JSON string)
|
||||
$product_variables_json = wp_unslash($_POST['product_variables']); // Remove slashes added by WP
|
||||
$product_variables = json_decode($product_variables_json, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($product_variables)) {
|
||||
// Save the meta as JSON string or serialized array
|
||||
update_post_meta($post_id, 'product_variables', $product_variables_json);
|
||||
} else {
|
||||
// Invalid JSON, optionally delete meta or handle error
|
||||
delete_post_meta($post_id, 'product_variables');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function save_product( $post_id ) {
|
||||
|
||||
// 1. Verifikasi Nonce untuk keamanan
|
||||
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'update-post_' . $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Abaikan jika ini adalah autosave
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Periksa izin pengguna
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Periksa apakah data 'product_variables' dikirim
|
||||
if ( ! isset( $_POST['product_variables'] ) ) {
|
||||
// Jika tidak ada data, mungkin kita ingin menghapus meta yang lama
|
||||
delete_post_meta( $post_id, 'product_variables' );
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Ambil data, lakukan sanitasi dasar, dan simpan
|
||||
$variations_data_json = $_POST['product_variables'];
|
||||
|
||||
// Sanitasi: wp_slash() penting untuk memastikan JSON string disimpan dengan benar,
|
||||
// terutama jika mengandung karakter kutip.
|
||||
$sanitized_variations_data = wp_unslash( $variations_data_json );
|
||||
|
||||
// Simpan data ke database. WordPress akan menangani serialisasi jika perlu.
|
||||
update_post_meta( $post_id, 'product_variables', $sanitized_variations_data );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
638
includes/Render.php
Normal file
@@ -0,0 +1,638 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
use Formipay\Field;
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Render {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $display_label;
|
||||
private $show_label;
|
||||
private $asterisk;
|
||||
|
||||
private static $form_ids = [];
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*/
|
||||
private function __construct() {
|
||||
add_shortcode('formipay', [$this, 'shortcode']);
|
||||
add_action('wp_enqueue_scripts', [$this, 'public_enqueue_style'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode handler.
|
||||
*
|
||||
* @param array $atts
|
||||
* @param string|null $content
|
||||
* @return string|false
|
||||
*/
|
||||
public function shortcode($atts, $content = null) {
|
||||
$atts = shortcode_atts(['form' => 0], $atts, 'formipay');
|
||||
|
||||
if ($atts['form'] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_id = intval($atts['form']);
|
||||
$currency = 'Rp. ';
|
||||
|
||||
if ($post_id > 0) {
|
||||
$currency = formipay_post_currency($post_id);
|
||||
self::$form_ids[] = $post_id;
|
||||
}
|
||||
|
||||
$form_settings = get_post_meta($post_id, 'formipay_settings', true);
|
||||
$point_symbol = formipay_get_post_meta($post_id, 'multistep_point_symbol');
|
||||
$point_icons = formipay_get_post_meta($post_id, 'multistep_point_icons');
|
||||
$page_breaks = [];
|
||||
if(!empty($form_settings['fields'])){
|
||||
foreach($form_settings['fields'] as $field){
|
||||
if($field['field_type'] == 'page_break'){
|
||||
if($point_symbol == 'icon'){
|
||||
$icons = json_decode($point_icons, true);
|
||||
foreach($icons as $icon){
|
||||
if($icon['field_id'] == $field['field_id']){
|
||||
$field['icon'] = $icon['script'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$page_breaks[] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
ob_start();
|
||||
|
||||
$timezone = get_option('timezone_string', 'Asia/Jakarta');
|
||||
|
||||
$require_login = formipay_get_post_meta($post_id, 'require_login') === 'on';
|
||||
$scheduled = formipay_get_post_meta($post_id, 'schedule_toggle') === 'on';
|
||||
$render = true;
|
||||
|
||||
if ($require_login && !is_user_logged_in()) {
|
||||
$render = false;
|
||||
echo '<div class="formipay-message">' . wp_kses_post(formipay_get_post_meta($post_id, 'require_login_message')) . '</div>';
|
||||
} elseif ($scheduled) {
|
||||
$date_range = explode(',', formipay_get_post_meta($post_id, 'daterange'));
|
||||
$date_from = new DateTime($date_range[0], new DateTimeZone($timezone));
|
||||
$date_to = new DateTime($date_range[1], new DateTimeZone($timezone));
|
||||
$now = new DateTime('now', new DateTimeZone($timezone));
|
||||
|
||||
if ($date_from > $now) {
|
||||
$render = false;
|
||||
?>
|
||||
<div class="formipay-message">
|
||||
<?php echo wp_kses_post(formipay_get_post_meta($post_id, 'waiting_message')); ?>
|
||||
</div>
|
||||
<?php
|
||||
} elseif ($now > $date_to) {
|
||||
$render = false;
|
||||
?>
|
||||
<div class="formipay-message">
|
||||
<?php echo wp_kses_post(formipay_get_post_meta($post_id, 'expired_message')); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ($render && $form_settings && is_array($form_settings['fields']) && count($form_settings['fields']) > 0) {
|
||||
$this->public_enqueue_scripts();
|
||||
$button_background_color = json_decode(formipay_get_post_meta($post_id, 'button_bg_color'), true );
|
||||
$button_text_color = json_decode(formipay_get_post_meta($post_id, 'button_text_color'), true );
|
||||
$button_border_color = json_decode( formipay_get_post_meta($post_id, 'button_border_color'), true );
|
||||
|
||||
?>
|
||||
<div class="formipay-form-wrapper">
|
||||
<style>
|
||||
body {
|
||||
--formipay-button-submit-bg-color: <?php echo esc_html($button_background_color['regular'] ?? '#000000'); ?>;
|
||||
--formipay-button-submit-bg-color-hover: <?php echo esc_html($button_background_color['hover'] ?? '#ffffff'); ?>;
|
||||
--formipay-button-submit-bg-color-active: <?php echo esc_html($button_background_color['active'] ?? '#ffffff'); ?>;
|
||||
--formipay-button-submit-text-color: <?php echo esc_html($button_text_color['regular'] ?? '#ffffff'); ?>;
|
||||
--formipay-button-submit-text-color-hover: <?php echo esc_html($button_text_color['hover'] ?? '#000000') ?>;
|
||||
--formipay-button-submit-text-color-active: <?php echo esc_html($button_text_color['active'] ?? '#000000'); ?>;
|
||||
--formipay-button-submit-border-color: <?php echo esc_html($button_border_color['regular'] ?? '#000000'); ?>;
|
||||
--formipay-button-submit-border-color-hover: <?php echo esc_html($button_border_color['hover'] ?? '#ffffff'); ?>;
|
||||
--formipay-button-submit-border-color-active: <?php echo esc_html($button_border_color['active'] ?? '#ffffff'); ?>;
|
||||
--formipay-required-field-sign-color: <?php echo esc_html(formipay_get_post_meta($post_id, 'required_field_color')); ?>;
|
||||
--formipay-payment-desktop-columns: <?php echo intval(formipay_get_post_meta($post_id, 'payment_desktop_columns') ?? 4); ?>;
|
||||
--formipay-payment-tablet-columns: <?php echo intval(formipay_get_post_meta($post_id, 'payment_tablet_columns') ?? 3) ?>;
|
||||
--formipay-payment-mobile-columns: <?php echo intval(formipay_get_post_meta($post_id, 'payment_mobile_columns') ?? 2) ?>;
|
||||
<?php
|
||||
if(formipay_isPopup($post_id)){
|
||||
$popup_button_background_color = json_decode(formipay_get_post_meta($post_id, 'popup_button_bg_color'), true );
|
||||
$popup_button_text_color = json_decode(formipay_get_post_meta($post_id, 'popup_button_text_color'), true );
|
||||
$popup_button_border_color = json_decode( formipay_get_post_meta($post_id, 'popup_button_border_color'), true );
|
||||
?>
|
||||
--formipay-popup-button-bg-color: <?php echo esc_html($popup_button_background_color['regular'] ?? '#000000'); ?>;
|
||||
--formipay-popup-button-bg-color-hover: <?php echo esc_html($popup_button_background_color['hover'] ?? '#ffffff'); ?>;
|
||||
--formipay-popup-button-bg-color-active: <?php echo esc_html($popup_button_background_color['active'] ?? '#ffffff'); ?>;
|
||||
--formipay-popup-button-text-color: <?php echo esc_html($popup_button_text_color['regular'] ?? '#ffffff'); ?>;
|
||||
--formipay-popup-button-text-color-hover: <?php echo esc_html($popup_button_text_color['hover'] ?? '#000000'); ?>;
|
||||
--formipay-popup-button-text-color-active: <?php echo esc_html($popup_button_text_color['active'] ?? '#000000'); ?>;
|
||||
--formipay-popup-button-border-color: <?php echo esc_html($popup_button_border_color['regular'] ?? '#000000'); ?>;
|
||||
--formipay-popup-button-border-color-hover: <?php echo esc_html($popup_button_border_color['hover'] ?? '#ffffff'); ?>;
|
||||
--formipay-popup-button-border-color-active: <?php echo esc_html($popup_button_border_color['active'] ?? '#ffffff'); ?>;
|
||||
--formipay-popup-backdrop-color: <?php echo esc_html(formipay_get_post_meta($post_id, 'popup_content_wrapper_backdrop_color') ?? 'rgba(0,0,0,0.75)'); ?>;
|
||||
--formipay-popup-wrapper-width: <?php echo esc_html(formipay_get_post_meta($post_id, 'popup_content_wrapper_width')); ?>px;
|
||||
--formipay-popup-button-width: <?php echo esc_html(formipay_get_post_meta($post_id, 'popup_button_width') == 'fullwidth' ? '100%' : 'fit-content'); ?>;
|
||||
<?php
|
||||
}
|
||||
if(count($page_breaks) > 0 && !is_admin()){
|
||||
?>
|
||||
--formipay-page-break-count: <?php echo count($page_breaks) + 1 ?>;
|
||||
<?php
|
||||
}
|
||||
switch (formipay_get_post_meta($post_id, 'multistep_point_shape')) {
|
||||
case 'rectangle':
|
||||
?>
|
||||
--formipay-step-shape-radius: 0%;
|
||||
<?php
|
||||
break;
|
||||
case 'rounded':
|
||||
?>
|
||||
--formipay-step-shape-radius: 25%;
|
||||
<?php
|
||||
break;
|
||||
|
||||
default:
|
||||
?>
|
||||
--formipay-step-shape-radius: 50%;
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
switch (formipay_get_post_meta($post_id, 'multistep_btn_size')) {
|
||||
case 'smaller_than_submit':
|
||||
?>
|
||||
--formipay-step-button-size: .5em 1em;
|
||||
--formipay-step-button-text-size: smaller;
|
||||
--formipay-step-button-height: 32px;
|
||||
<?php
|
||||
break;
|
||||
case 'larger_than_submit':
|
||||
?>
|
||||
--formipay-step-button-size: 1em 2em;
|
||||
--formipay-step-button-text-size: larger;
|
||||
--formipay-step-button-height: 48px;
|
||||
<?php
|
||||
break;
|
||||
|
||||
default:
|
||||
?>
|
||||
--formipay-step-button-size: .75em 1.5em;
|
||||
--formipay-step-button-text-size: inherit;
|
||||
--formipay-step-button-height: 40px;
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
?>
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php if(formipay_isPopup($post_id)) { ?>
|
||||
<div class="formipay-popup modal" id="formipay-popup-<?php echo intval($post_id); ?>">
|
||||
<?php } ?>
|
||||
|
||||
<form class="formipay-form" data-form-id="<?php echo intval($post_id); ?>" id="formipay-form-<?php echo intval($post_id); ?>">
|
||||
<input type="hidden" id="product_name" value="<?php echo esc_attr(get_the_title($post_id)); ?>">
|
||||
<input type="hidden" id="product_price" value="<?php echo esc_attr(formipay_get_post_meta($post_id, 'product_price')); ?>">
|
||||
|
||||
<?php if(formipay_isPopup($post_id) && !empty(formipay_get_post_meta($post_id, 'popup_content_wrapper_title'))) { ?>
|
||||
<h4 class="formipay-popup-title"><?php echo esc_html(formipay_get_post_meta($post_id, 'popup_content_wrapper_title')); ?></h4>
|
||||
<?php } ?>
|
||||
|
||||
<div class="formipay-form-body formipay-<?php echo (count($page_breaks) > 0 && !is_admin()) ? '1' : esc_attr(formipay_get_post_meta($post_id, 'form_layout_columns')); ?>-cols">
|
||||
<div class="form-fields-wrapper">
|
||||
<?php if(!empty(formipay_get_post_meta($post_id, 'product_description'))) { ?>
|
||||
<div class="formipay-description">
|
||||
<?php echo wp_kses_post(formipay_get_post_meta($post_id, 'product_description')); ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php
|
||||
$label_show = formipay_get_post_meta($post_id, 'label_visibility') !== 'hide';
|
||||
$this->display_label = !$label_show ? ' formipay-hidden-element' : '';
|
||||
$this->asterisk = formipay_get_post_meta($post_id, 'required_field_sign') === 'text' ? formipay_get_post_meta($post_id, 'required_text') : '(*)';
|
||||
|
||||
if(count($page_breaks) > 0 && !is_admin()){
|
||||
$this->render_top_pagination_process($page_breaks, $point_symbol);
|
||||
}
|
||||
|
||||
foreach ($form_settings['fields'] as $field_id => $field) {
|
||||
|
||||
$field_id = str_replace('_config', '', $field_id);
|
||||
$field['field_id'] = $field_id;
|
||||
|
||||
$field['placeholder'] = formipay_get_post_meta($post_id, 'field_placeholder') === 'label'
|
||||
? ($field['label'] ?? '')
|
||||
: ($field['placeholder'] ?? '');
|
||||
|
||||
$field['calculable'] = in_array($field['field_type'], ['hidden', 'select', 'checkbox', 'radio']) ? ' formipay-input-calculable' : '';
|
||||
$field['calc_value'] = $field['calc_value'] ?? 0;
|
||||
$field['calc'] = in_array($field['field_type'], ['hidden']) ? 'data-calc-value="' . $field['calc_value'] . '"' : '';
|
||||
|
||||
$this->render_field($post_id, $field_id, $field);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
<?php
|
||||
if(count($page_breaks) > 0 && !is_admin()){
|
||||
?>
|
||||
<div class="formipay-field-group formipay-page-break formipay-page-break-payment">
|
||||
<div class="formipay-page-break-information">
|
||||
<label for="<?php echo esc_attr($field_id); ?>" class="formipay-label divider-label <?php echo esc_attr($display_label); ?>">
|
||||
<?php echo esc_html__('Payment', 'formipay'); ?>
|
||||
</label>
|
||||
<span class="divider-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
$this->render_bottom_pagination_process($post_id, $page_breaks);
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="formipay-static-elements">
|
||||
<div class="result-wrapper">
|
||||
|
||||
<input class="formipay-meta-input" type="hidden" name="user_id" value="<?php echo is_user_logged_in() ? esc_attr( absint( get_current_user_id() ) ) : ''; ?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="session_id" value="<?php echo esc_attr( sanitize_text_field( uniqid('', true) ) ); ?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="referrer" value="<?php echo isset($_SERVER['HTTP_REFERER']) ? esc_attr( esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) ) : ''; ?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="page_url" value="<?php echo isset($_SERVER['REQUEST_URI']) ? esc_attr( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) : ''; ?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="timestamp" value="<?php echo esc_attr( absint( time() ) ); ?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="utm_source" value="<?php echo
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['utm_source']) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['utm_source'] ) ) ) : '';
|
||||
?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="utm_medium" value="<?php echo
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['utm_medium']) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['utm_medium'] ) ) ) : '';
|
||||
?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="utm_campaign" value="<?php echo
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['utm_campaign']) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['utm_campaign'] ) ) ) : '';
|
||||
?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="ip_address" value="<?php echo
|
||||
isset($_SERVER['REMOTE_ADDR']) ? esc_attr( sanitize_text_field( wp_unslash($_SERVER['REMOTE_ADDR']) ) ) : '';
|
||||
?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="user_agent" value="<?php echo
|
||||
isset($_SERVER['HTTP_USER_AGENT']) ? esc_attr( sanitize_text_field( wp_unslash($_SERVER['HTTP_USER_AGENT']) ) ) : '';
|
||||
?>">
|
||||
<input class="formipay-meta-input" type="hidden" name="device_type" value="<?php echo esc_attr( ( strpos( sanitize_text_field( wp_unslash($_SERVER['HTTP_USER_AGENT']) ), 'Mobile' ) !== false ) ? 'Mobile' : 'Desktop' ); ?>">
|
||||
|
||||
<?php
|
||||
$static_element_sort = json_decode(formipay_get_post_meta($post_id, 'form_static_elements_sort'), true);
|
||||
$static_element_active = $static_element_sort[1]['options'];
|
||||
if(!empty($static_element_active)){
|
||||
foreach($static_element_active as $element){
|
||||
switch ($element['id']) {
|
||||
case 'payment_methods':
|
||||
$this->render_payment_options($post_id);
|
||||
break;
|
||||
case 'coupon_fields':
|
||||
?>
|
||||
<div class="formipay-field-group">
|
||||
<div class="formipay-coupon-field-group">
|
||||
<input type="text" name="coupon_code"
|
||||
class="formipay-input formipay-code-input"
|
||||
value="<?php echo
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
isset($_GET['coupon']) ? esc_attr( sanitize_text_field( wp_unslash($_GET['coupon'] ) ) ) : ''
|
||||
?>" placeholder="Your coupon code"
|
||||
data-label="Coupon Code">
|
||||
<button type="button" data-text="<?php echo esc_html__( 'Apply', 'formipay' ); ?>" data-checking="<?php echo esc_html__( 'Checking...', 'formipay' ); ?>" id="apply_coupon_code"><?php echo esc_html__( 'Apply', 'formipay' ); ?></button>
|
||||
</div>
|
||||
<div class="formipay-coupon-alert-message"></div>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
case 'order_review':
|
||||
?>
|
||||
<div class="form-calculation form-calculate-<?php echo esc_attr($post_id); ?>">
|
||||
<h4><?php echo esc_html(formipay_get_post_meta($post_id, 'order_review_title')); ?></h4>
|
||||
<table id="formipay-review-order">
|
||||
<tbody>
|
||||
<tr class="formipay-product-row formipay-item-row main">
|
||||
<?php
|
||||
$price = formipay_get_post_meta($post_id, 'product_price');
|
||||
if(formipay_get_post_meta($post_id, 'product_quantity_toggle') == 'on') {
|
||||
$stock = formipay_get_post_meta($post_id, 'product_stock');
|
||||
$stock_html = '';
|
||||
if($stock > -1){
|
||||
$stock = ' max="'.$stock.'"';
|
||||
}
|
||||
?>
|
||||
<th>
|
||||
<?php echo esc_html(get_the_title($post_id)); ?> <br>
|
||||
<span class="product-qty-wrapper">
|
||||
<button type="button" class="product-qty qty-min">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14" />
|
||||
</svg>
|
||||
</button>
|
||||
<input type="number" class="product-qty formipay-qty-input" value="<?php echo intval(formipay_get_post_meta($post_id, 'product_quantity_range')); ?>" step="<?php echo intval(formipay_get_post_meta($post_id, 'product_quantity_range')); ?>" min="<?php echo intval(formipay_get_post_meta($post_id, 'product_minimum_purchase')); ?>"<?php echo esc_html($stock) ?>>
|
||||
<button type="button" class="product-qty qty-plus">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v14m-7-7h14" />
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</th>
|
||||
<td class="product_price"><?php echo esc_html(formipay_price_format(floatval($price) * intval(formipay_get_post_meta($post_id, 'product_quantity_range')), $post_id)); ?></td>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<th>
|
||||
<?php echo esc_html(get_the_title($post_id)); ?> <input type="hidden" class="formipay-qty-input" value="1">
|
||||
</th>
|
||||
<td><?php echo esc_html(formipay_price_format(floatval($price), $post_id)); ?></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
<tr class="formipay-total-row">
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
<tr class="formipay-grand-total-row">
|
||||
<th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
|
||||
<td class="grand_total"><?php echo esc_html(formipay_price_format(floatval($price), $post_id)); ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
case 'submit_button':
|
||||
|
||||
?>
|
||||
|
||||
<button type="submit" class="formipay-submit-button"
|
||||
data-button-text="<?php echo esc_attr(formipay_get_post_meta($post_id, 'button_text')); ?>"
|
||||
style="width: <?php echo formipay_get_post_meta($post_id, 'button_width') == 'fit-content' ? 'fit-content' : '100%' ?>;
|
||||
margin-left: <?php echo formipay_get_post_meta($post_id, 'button_position') !== 'left' ? 'auto' : 'unset' ?>;
|
||||
margin-right: <?php echo formipay_get_post_meta($post_id, 'button_position') !== 'right' ? 'auto' : 'unset' ?>;">
|
||||
<?php echo esc_html(formipay_get_post_meta($post_id, 'button_text')); ?> - <?php echo esc_html(formipay_price_format(floatval($price), $post_id)); ?>
|
||||
</button>
|
||||
|
||||
<?php
|
||||
break;
|
||||
case 'submit_response_notice':
|
||||
?>
|
||||
<div class="submit-response formipay-message" style="display: none;"></div>
|
||||
<?php
|
||||
break;
|
||||
|
||||
default:
|
||||
do_action('formipay/render/static-element', $element['id']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if(formipay_isPopup($post_id) && false == boolval(formipay_get_post_meta($post_id, 'popup_click_selector'))) { ?>
|
||||
</div>
|
||||
<div class="formipay-popup-trigger">
|
||||
<a data-modal="#formipay-popup-<?php echo intval($post_id); ?>"
|
||||
class="formipay-open-popup-button"
|
||||
style="width: <?php echo formipay_get_post_meta($post_id, 'popup_button_width') == 'fit-content' ? 'fit-content' : '100%' ?>;
|
||||
margin-left: <?php echo formipay_get_post_meta($post_id, 'popup_button_alignment') !== 'left' ? 'auto' : 'unset' ?>;
|
||||
margin-right: <?php echo formipay_get_post_meta($post_id, 'popup_button_alignment') !== 'right' ? 'auto' : 'unset' ?>;">
|
||||
<?php echo esc_html(formipay_get_post_meta($post_id, 'popup_button_text')); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
private function render_field($post_id, $field_id, $field) {
|
||||
$type = $field['field_type'];
|
||||
// Normalize method name for Field class
|
||||
$method = "render_{$type}_field";
|
||||
if (method_exists(Field::get_instance(), $method)) {
|
||||
echo Field::get_instance()->$method($field);
|
||||
} else {
|
||||
// Optionally handle unknown field types
|
||||
do_action('formipay/render/custom-field-type', $type, $field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render payment options
|
||||
*/
|
||||
private function render_payment_options($post_id) {
|
||||
|
||||
$payments = apply_filters( 'formipay/frontend/payment-list', [], $post_id );
|
||||
|
||||
?>
|
||||
<div class="formipay-field-group">
|
||||
<label class="formipay-label"><?php echo esc_html(formipay_get_post_meta($post_id, 'payment_section_title')); ?></label>
|
||||
<div class="formipay-payments">
|
||||
<?php
|
||||
$unique_code = wp_rand(1, 999);
|
||||
if(!empty($payments)){
|
||||
foreach ($payments as $value => $payment) {
|
||||
$channel = explode(':::', $value);
|
||||
$gateway = $channel[0];
|
||||
$payment_non_label_class = formipay_get_post_meta($post_id, 'payment_label') == 'on' ? '' : 'payment-logo-only';
|
||||
$logo = '';
|
||||
|
||||
// Check if payment logo is an attachment ID or URL
|
||||
if (!empty($payment[$gateway.'_logo'])) {
|
||||
if (is_numeric($payment[$gateway.'_logo'])) {
|
||||
// Media library image
|
||||
$logo = wp_get_attachment_image(
|
||||
intval($payment[$gateway.'_logo']),
|
||||
['100', '40'],
|
||||
false,
|
||||
[
|
||||
'class' => 'formipay-payment-logo formipay-'.$gateway.'-logo '.$payment_non_label_class,
|
||||
'loading' => 'lazy'
|
||||
]
|
||||
);
|
||||
} else {
|
||||
// Static plugin image (add PHPCS ignore)
|
||||
$logo_url = $payment[$gateway.'_logo'];
|
||||
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
|
||||
$logo = '<img src="' . esc_url($logo_url) . '"
|
||||
width="100"
|
||||
height="40"
|
||||
class="formipay-payment-logo formipay-'.$gateway.'-logo '.$payment_non_label_class.'"
|
||||
alt="' . esc_attr($payment[$gateway.'_name']) . '"
|
||||
loading="lazy">';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="formipay-payment-option-group">
|
||||
<label for="<?php echo esc_attr($value) ?>" class="formipay-label">
|
||||
<input type="radio"
|
||||
name="payment"
|
||||
class="formipay-input formipay-input-calculable formipay-payment-channel"
|
||||
id="<?php echo esc_attr($value); ?>"
|
||||
value="<?php echo esc_attr($value); ?>"
|
||||
required>
|
||||
<?php echo $logo; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php if(formipay_get_post_meta($post_id, 'payment_label') == 'on') { ?>
|
||||
<span class="formipay-payment-name formipay-<?php echo esc_attr($gateway) ?>-name">
|
||||
<?php echo esc_html($payment[$gateway.'_name']); ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render progess pages (on top)
|
||||
*/
|
||||
private function render_top_pagination_process($page_breaks, $point_symbol){
|
||||
|
||||
$payment_symbol = count($page_breaks) + 1;
|
||||
if($point_symbol == 'icon'){
|
||||
$payment_symbol = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19H6a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v4.5M3 10h18m-5 9h6m-3-3l3 3l-3 3M7.005 15h.005M11 15h2" />
|
||||
</svg>';
|
||||
}
|
||||
|
||||
if(!empty($page_breaks)){
|
||||
?>
|
||||
<div class="formipay-top-pagination">
|
||||
<?php
|
||||
foreach($page_breaks as $index => $page){
|
||||
$index = $index + 1;
|
||||
$symbol = $index;
|
||||
if($point_symbol == 'icon'){
|
||||
$symbol = '<span class="pagination-icon">'.$page['icon'].'</span>';
|
||||
}
|
||||
?>
|
||||
<div class="formipay-progress" data-page-number="<?php echo intval($index) ?>">
|
||||
<div class="formipay-index-wrapper">
|
||||
<span class="formipay-page-index"><?php echo wp_kses_post($symbol) ?></span>
|
||||
<span class="formipay-page-label"><?php echo esc_html($page['label']) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div class="formipay-progress" data-page-number="<?php echo count($page_breaks) + 1 ?>">
|
||||
<div class="formipay-index-wrapper">
|
||||
<span class="formipay-page-index"><?php echo wp_kses_post($payment_symbol); ?></span>
|
||||
<span class="formipay-page-label"><?php echo esc_html__( 'Payment', 'formipay' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function render_bottom_pagination_process($post_id, $page_breaks) {
|
||||
|
||||
if(!empty($page_breaks)){
|
||||
?>
|
||||
<div class="formipay-bottom-pagination">
|
||||
<button type="button" class="formipay-page-break-prev-button" disabled>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h6m3 0h1.5m3 0h.5M5 12l4 4m-4-4l4-4" />
|
||||
</svg>
|
||||
<?php echo esc_html(formipay_get_post_meta($post_id, 'multistep_btn_prev_text')); ?>
|
||||
</button>
|
||||
<button type="button" class="formipay-page-break-next-button">
|
||||
<?php echo esc_html(formipay_get_post_meta($post_id, 'multistep_btn_next_text')); ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h.5m3 0H10m3 0h6m-4 4l4-4m-4-4l4 4" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue public scripts and styles.
|
||||
*/
|
||||
|
||||
public function public_enqueue_style() {
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.5', 'all');
|
||||
wp_enqueue_style( 'jquery-modal', FORMIPAY_URL . 'vendor/jQueryModal/jquery.modal.min.css', [], '0.9.1', 'all');
|
||||
wp_enqueue_style( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'formipay-form', FORMIPAY_URL . 'public/assets/css/form-style.css', [], FORMIPAY_VERSION, 'all');
|
||||
wp_enqueue_style( 'formipay-popup', FORMIPAY_URL . 'public/assets/css/popup-style.css', [], FORMIPAY_VERSION, 'all');
|
||||
}
|
||||
|
||||
public function public_enqueue_scripts() {
|
||||
|
||||
wp_enqueue_script( 'jquery-blockui', FORMIPAY_URL . 'vendor/jQuery-UI/jquery.blockUI.min.js', ['jquery'], FORMIPAY_VERSION, true);
|
||||
wp_enqueue_script( 'jquery-clipboard', FORMIPAY_URL . 'vendor/ClipboardJS/clipboard.min.js', ['jquery'], '2.0.11', true);
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
|
||||
wp_enqueue_script( 'jquery-modal', FORMIPAY_URL . 'vendor/jQueryModal/jquery.modal.min.js', ['jquery'], '0.9.1', true);
|
||||
wp_enqueue_script( 'choices', FORMIPAY_URL . 'vendor/ChoicesJS/choices.min.js', [], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'formipay-popup', FORMIPAY_URL . 'public/assets/js/popup-action.js', ['jquery', 'choices'], FORMIPAY_VERSION, true);
|
||||
wp_enqueue_script( 'formipay-form', FORMIPAY_URL . 'public/assets/js/form-action.js', ['jquery', 'choices'], FORMIPAY_VERSION, true);
|
||||
// Localize data for all forms
|
||||
$form_data = [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'frontend_nonce' => wp_create_nonce('formipay-frontend-nonce'),
|
||||
'nonce' => wp_create_nonce('formipay_order_submit'),
|
||||
'forms' => $this->get_form_data()
|
||||
];
|
||||
wp_localize_script('formipay-form', 'formipay_form', $form_data);
|
||||
|
||||
}
|
||||
|
||||
private function get_form_data(){
|
||||
$form_data = [];
|
||||
foreach (array_unique(self::$form_ids) as $post_id) {
|
||||
$form_data[$post_id] = [
|
||||
'form_id' => $post_id,
|
||||
'currency' => formipay_post_currency($post_id),
|
||||
'buyer_phone_field' => formipay_get_post_meta($post_id, 'buyer_phone'),
|
||||
'buyer_country_field' => formipay_get_post_meta($post_id, 'buyer_country'),
|
||||
'buyer_phone_allow' => (bool) formipay_get_post_meta($post_id, 'buyer_allow_choose_country_code'),
|
||||
'buyer_phone_country_code' => formipay_get_post_meta($post_id, 'buyer_phone_country_code'),
|
||||
'decimal_digits' => formipay_get_post_meta($post_id, 'product_currency_decimal_digits'),
|
||||
'decimal_symbol' => formipay_get_post_meta($post_id, 'product_currency_decimal_symbol'),
|
||||
'thousand_separator' => formipay_get_post_meta($post_id, 'product_currency_thousand_separator'),
|
||||
'notice_empty_text_message' => formipay_get_post_meta($post_id, 'empty_required_text_field'),
|
||||
'notice_empty_select_message' => formipay_get_post_meta($post_id, 'empty_required_select_field'),
|
||||
'notice_empty_agreement_message' => formipay_get_post_meta($post_id, 'empty_required_agreement_field'),
|
||||
'quantity_toggle' => formipay_get_post_meta($post_id, 'product_quantity_toggle'),
|
||||
'quantity_step' => formipay_get_post_meta($post_id, 'product_quantity_range'),
|
||||
'quantity_min' => formipay_get_post_meta($post_id, 'product_minimum_purchase'),
|
||||
'quantity_stock' => formipay_get_post_meta($post_id, 'product_stock'),
|
||||
'button_text' => formipay_get_post_meta($post_id, 'button_text'),
|
||||
'button_processing_text' => formipay_get_post_meta($post_id, 'button_processing_text'),
|
||||
'isPopup' => formipay_isPopup($post_id),
|
||||
'trigger_selector' => formipay_get_post_meta($post_id, 'popup_click_selector') ?
|
||||
formipay_get_post_meta($post_id, 'popup_trigger_selector') :
|
||||
'.formipay-open-popup-button',
|
||||
'modal_selector' => '#formipay-popup-' . $post_id
|
||||
];
|
||||
}
|
||||
|
||||
return $form_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
219
includes/Settings.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Settings {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
/**
|
||||
* Initializes the plugin by setting filters and administration functions.
|
||||
*/
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_filter( 'wpcfto_options_page_setup', [$this, 'theme_option'] );
|
||||
add_action( 'admin_enqueue_scripts', [$this, 'enqueue'] );
|
||||
|
||||
}
|
||||
|
||||
public function theme_option($setups){
|
||||
|
||||
$general_fields = array(
|
||||
'business_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Business', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'business_name' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Business Name', 'formipay' ),
|
||||
'description' => __( 'This may be displayed on payment gateway like Paypal as a merchant name.', 'formipay' ),
|
||||
'required' => true,
|
||||
'group' => 'ended'
|
||||
),
|
||||
'currency_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Currency', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'payment_default_currency' => array(
|
||||
'type' => 'select',
|
||||
'label' => __('Default Currency', 'formipay'),
|
||||
'value' => 'IDR:::Indonesian rupiah:::Rp',
|
||||
'options' => formipay_currency_as_options(),
|
||||
'required' => true,
|
||||
'searchable' => true,
|
||||
),
|
||||
'payment_default_currency_decimal_digits' => array(
|
||||
'type' => 'number',
|
||||
'label' => __('Decimal Digits', 'formipay'),
|
||||
'value' => '2',
|
||||
'required' => true,
|
||||
),
|
||||
'payment_default_currency_decimal_symbol' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Decimal Symbol', 'formipay'),
|
||||
'value' => '.',
|
||||
'required' => true,
|
||||
),
|
||||
'payment_default_currency_thousand_separator' => array(
|
||||
'type' => 'text',
|
||||
'label' => __('Thousand Separator Symbol', 'formipay'),
|
||||
'value' => ',',
|
||||
'required' => true,
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
$general_fields = apply_filters( 'formipay/global-settings/tab:general', $general_fields );
|
||||
|
||||
$pages_fields = array(
|
||||
|
||||
'thankyou_page_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Thank-You Page Style', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'thankyou_link' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Thank-You Page Link', 'formipay' ),
|
||||
'value' => 'thankyou',
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'required' => true
|
||||
),
|
||||
'thankyou_style' => array(
|
||||
'type' => 'image_select',
|
||||
'label' => esc_html__( 'Style', 'formipay' ),
|
||||
'width' => 100,
|
||||
'height' => 100,
|
||||
'value' => 'receipt',
|
||||
'options' => array(
|
||||
'card' => array(
|
||||
'alt' => 'Card',
|
||||
'img' => FORMIPAY_URL . 'admin/assets/img/thankyou_card_style.png'
|
||||
),
|
||||
'receipt' => array(
|
||||
'alt' => 'Receipt',
|
||||
'img' => FORMIPAY_URL . 'admin/assets/img/thankyou_receipt_style.png'
|
||||
),
|
||||
),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'required' => true
|
||||
),
|
||||
'thankyou_page_container_bg_color' => array(
|
||||
'type' => 'color',
|
||||
'label' => __( 'Container Background Color', 'formipay' ),
|
||||
'value' => '#808080',
|
||||
'description' => __( 'Container is the main div on Thank-You Page contents', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
),
|
||||
'thankyou_page_wrapper_bg_color' => array(
|
||||
'type' => 'color',
|
||||
'label' => __( 'Wrapper Background Color', 'formipay' ),
|
||||
'value' => '#ffffff',
|
||||
'description' => __( 'Wrapper is the div that fit to Thank-You Page contents width', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
),
|
||||
'thankyou_page_wrapper_max_width' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Wrapper Max Width', 'formipay' ),
|
||||
'value' => '600',
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'group' => 'ended',
|
||||
'required' => true
|
||||
),
|
||||
'thankyou_page_restriction_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Restriction Access', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'group' => 'started'
|
||||
),
|
||||
'thankyou_page_restriction_thumbnail' => array(
|
||||
'type' => 'image',
|
||||
'label' => __( 'Thumbnail', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' )
|
||||
),
|
||||
'thankyou_page_restriction_title' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Title', 'formipay' ),
|
||||
'value' => __( 'Request to Access', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' )
|
||||
),
|
||||
'thankyou_page_restriction_message' => array(
|
||||
'type' => 'hint_textarea',
|
||||
'label' => __( 'Message', 'formipay' ),
|
||||
'value' => __( 'Input your {{media}} to get new access link.', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'hints' => array(
|
||||
'media' => __( 'Contact Media', 'formipay' )
|
||||
),
|
||||
'description' => __( 'Use {{media}} shortcode to define what media of contact the buyer can receive the access link.', 'formipay' )
|
||||
),
|
||||
'thankyou_page_restriction_button' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Request Access Button', 'formipay' ),
|
||||
'value' => __( 'Get Access Link', 'formipay' ),
|
||||
'submenu' => __( 'Thank-You Page', 'formipay' ),
|
||||
'group' => 'ended'
|
||||
)
|
||||
);
|
||||
|
||||
$pages_fields = apply_filters( 'formipay/global-settings/tab:pages', $pages_fields );
|
||||
|
||||
$global = array(
|
||||
'General' => array(
|
||||
'name' => __( 'General', 'formipay' ),
|
||||
'fields' => $general_fields
|
||||
),
|
||||
'Pages' => array(
|
||||
'name' => __( 'Pages', 'formipay' ),
|
||||
'fields' => $pages_fields
|
||||
)
|
||||
);
|
||||
|
||||
$global = apply_filters( 'formipay/global-settings', $global );
|
||||
|
||||
foreach($global as $key => $value){
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
$setups[] = array(
|
||||
'option_name' => 'formipay_settings',
|
||||
'title' => __('Formipay', 'formipay'),
|
||||
'sub_title' => __('Settings', 'formipay'),
|
||||
'logo' => FORMIPAY_URL . 'admin/assets/img/formipay-logo-circle-white.png',
|
||||
'page' => array(
|
||||
'parent_slug' => 'formipay',
|
||||
'page_title' => __('Formipay Settings', 'formipay'),
|
||||
'menu_title' => __('Settings', 'formipay'),
|
||||
'menu_slug' => 'formipay-settings',
|
||||
'position' => 40,
|
||||
),
|
||||
|
||||
'fields' => $fields
|
||||
);
|
||||
|
||||
return $setups;
|
||||
}
|
||||
|
||||
public function enqueue() {
|
||||
|
||||
global $current_screen;
|
||||
|
||||
if ( $current_screen->id === 'formipay_page_formipay-settings' ) {
|
||||
wp_enqueue_style('admin-setting-style', FORMIPAY_URL . 'admin/assets/css/global-setting.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script('admin-setting-script', FORMIPAY_URL . 'admin/assets/js/admin-setting.js', ['jquery'], FORMIPAY_VERSION, true);
|
||||
|
||||
wp_localize_script( 'admin-setting-script', 'formipay_admin_setting', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'nonce' => wp_create_nonce('formipay-admin-nonce')
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
147
includes/Shipping/FlatRate.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace Formipay\Shipping;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
use Formipay\Shipping\Shipping;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class FlatRate extends Shipping {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $shipping_method = 'flat_rate';
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
add_filter( 'formipay/product-config/tab:shipping/method', [$this, 'add_shipping_method'], 15 );
|
||||
add_filter( 'formipay/product-config/tab:shipping', [$this, 'add_shipping_settings'], 15 );
|
||||
|
||||
// Add to order details
|
||||
add_filter( 'formipay/order/order-details', [$this, 'add_shipping_to_order_details'], 99, 3 );
|
||||
|
||||
}
|
||||
|
||||
public function add_shipping_method($shipping_methods){
|
||||
|
||||
$shipping_methods['flat_rate'] = [
|
||||
'method' => __( 'Flat Rate', 'formipay' ),
|
||||
];
|
||||
|
||||
return $shipping_methods;
|
||||
|
||||
}
|
||||
|
||||
public function add_shipping_settings($fields) {
|
||||
|
||||
$flat_rate_fields = array(
|
||||
$this->shipping_method.'_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Flat Rate Setup', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'started'
|
||||
),
|
||||
$this->shipping_method.'_type' => array(
|
||||
'type' => 'select',
|
||||
'label' => __( 'Type', 'formipay' ),
|
||||
'options' => array(
|
||||
'fixed' => __( 'Fixed', 'formipay' ),
|
||||
'percentage' => __( 'Percentage', 'formipay' )
|
||||
),
|
||||
'value' => 'fixed',
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
),
|
||||
$this->shipping_method.'_amount' => array(
|
||||
'type' => 'number',
|
||||
'label' => __( 'Amount', 'formipay' ),
|
||||
'value' => '10',
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
),
|
||||
$this->shipping_method.'_label' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Label', 'formipay' ),
|
||||
'description' => __( 'This will be shown in Order Review and Order Details', 'formipay' ),
|
||||
'value' => __( 'Shipping Fee', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'flat_rate'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
foreach($flat_rate_fields as $key => $value){
|
||||
$fields[$key] = $value;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_shipping_to_order_details( $details, $form_id, $order_data ) {
|
||||
|
||||
if( formipay_get_post_meta($form_id, 'product_type') == 'physical' && formipay_get_post_meta($form_id, 'shipping_method')){
|
||||
|
||||
$amount = floatval( formipay_price_format( formipay_get_post_meta( $form_id, 'flat_rate_amount' ) ) );
|
||||
|
||||
if( formipay_get_post_meta($form_id, 'flat_rate_type') == 'percentage' ) {
|
||||
$price = floatval( formipay_get_post_meta($form_id, 'product_price') );
|
||||
$calculate = $price * $amount / 100;
|
||||
$amount = floatval($calculate);
|
||||
}
|
||||
|
||||
$details[] = [
|
||||
'item' => formipay_get_post_meta($form_id, 'flat_rate_label'),
|
||||
'amount' => $amount,
|
||||
'subtotal' => $amount
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $details;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
160
includes/Shipping/Shipping.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
namespace Formipay\Shipping;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
abstract class Shipping {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
abstract public function add_shipping_method($shipping_methods);
|
||||
abstract public function add_shipping_settings($fields);
|
||||
abstract public function add_shipping_to_order_details($details, $form_id, $order_data);
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_filter( 'formipay/global-settings', [$this, 'add_setting_shipping_menu'], 15 );
|
||||
add_filter( 'formipay/product-config', [$this, 'add_form_shipping_menu'], 75 );
|
||||
|
||||
}
|
||||
|
||||
public function add_setting_shipping_menu($fields){
|
||||
|
||||
$shipping_settings = [];
|
||||
|
||||
$shipping_settings = apply_filters( 'formipay/global-settings/tab:shipping', $shipping_settings );
|
||||
|
||||
if(!empty($shipping_settings)){
|
||||
$fields['shipping'] = array(
|
||||
'name' => __('Shipping', 'formipay'),
|
||||
'fields' => $shipping_settings
|
||||
);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
public function add_form_shipping_menu($fields) {
|
||||
|
||||
$shipping_methods = apply_filters( 'formipay/product-settings/tab:shipping/method', [
|
||||
'free_shipping' => [
|
||||
'method' => __( 'Free Shipping', 'formipay' )
|
||||
]
|
||||
] );
|
||||
|
||||
$shipping_options = [];
|
||||
$shipping_fields = [];
|
||||
|
||||
foreach($shipping_methods as $id => $shipping){
|
||||
// $id = $shipping['id'];
|
||||
$label = $shipping['method'];
|
||||
if(isset($shipping['courier'])){
|
||||
$label .= ' - '.$shipping['courier'];
|
||||
if(isset($shipping['service'])){
|
||||
$label .= ' - '.$shipping['service'];
|
||||
}
|
||||
}
|
||||
$shipping_options[$id] = $label;
|
||||
}
|
||||
|
||||
$shipping_fields = [
|
||||
'shipping_notice' => array(
|
||||
'type' => 'notification_message',
|
||||
'image' => FORMIPAY_URL . 'admin/assets/img/logistics.png',
|
||||
'description' => __( '
|
||||
<h1>No Shipping Method Available</h1>
|
||||
<p>Shipping methods only for physical product type. If you insist to use shipping method, change your product type first</p>
|
||||
', 'formipay' ),
|
||||
'dependency' => array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'digital',
|
||||
'section' => 'general'
|
||||
),
|
||||
),
|
||||
'shipping_method' => array(
|
||||
'type' => 'radio',
|
||||
'label' => esc_html__('Shipping Methods', 'formipay'),
|
||||
'options' => $shipping_options,
|
||||
'dependency' => array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
)
|
||||
];
|
||||
|
||||
$free_shipping_fields = array(
|
||||
'free_shipping_group' => array(
|
||||
'type' => 'group_title',
|
||||
'label' => __( 'Free Shipping Setup', 'formipay' ),
|
||||
'description' => __( 'Will not add any shipping fee to the order', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'free_shipping'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'started'
|
||||
),
|
||||
'free_shipping_label' => array(
|
||||
'type' => 'text',
|
||||
'label' => __( 'Label', 'formipay' ),
|
||||
'value' => __( 'Free Shipping', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'free_shipping'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
),
|
||||
'free_shipping_add_to_order_review' => array(
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Show in Order Review', 'formipay' ),
|
||||
'dependency' => array(
|
||||
array(
|
||||
'key' => 'product_type',
|
||||
'value' => 'physical',
|
||||
'section' => 'general'
|
||||
),
|
||||
array(
|
||||
'key' => 'shipping_method',
|
||||
'value' => 'free_shipping'
|
||||
)
|
||||
),
|
||||
'dependencies' => '&&',
|
||||
'group' => 'ended'
|
||||
),
|
||||
);
|
||||
|
||||
foreach($free_shipping_fields as $key => $value) {
|
||||
$shipping_fields[$key] = $value;
|
||||
}
|
||||
|
||||
$shipping_fields = apply_filters( 'formipay/product-settings/tab:shipping', $shipping_fields );
|
||||
|
||||
if(!empty($shipping_fields)){
|
||||
$fields['formipay_product_settings']['shipping'] = array(
|
||||
'name' => __( 'Shipping', 'formipay' ),
|
||||
'fields' => $shipping_fields
|
||||
);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
695
includes/Thankyou.php
Normal file
@@ -0,0 +1,695 @@
|
||||
<?php
|
||||
namespace Formipay;
|
||||
use Formipay\Traits\SingletonTrait;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
class Thankyou {
|
||||
|
||||
use SingletonTrait;
|
||||
|
||||
private $form_id;
|
||||
private $order_data;
|
||||
private $order_details;
|
||||
private $form_submit;
|
||||
|
||||
protected function __construct() {
|
||||
|
||||
add_action( 'init', [$this, 'set_endpoint'], 999);
|
||||
add_filter( 'query_vars', [$this, 'set_query_vars'], 899);
|
||||
add_action( 'wp_enqueue_scripts', [$this, 'frontend_enqueue'] );
|
||||
add_filter( 'pre_get_document_title', [$this, 'page_title'], 1012 );
|
||||
|
||||
add_action( 'template_redirect', [$this, 'check_parse_query'], 999 );
|
||||
|
||||
add_action( 'wp_ajax_request_access_link', [$this, 'request_access_link'] );
|
||||
add_action( 'wp_ajax_nopriv_request_access_link', [$this, 'request_access_link'] );
|
||||
|
||||
}
|
||||
|
||||
public function set_endpoint() {
|
||||
|
||||
$slug = 'thankyou';
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
if(!empty($formipay_settings['thankyou_link'])){
|
||||
$slug = $formipay_settings['thankyou_link'];
|
||||
}
|
||||
|
||||
add_rewrite_rule(
|
||||
'^'.$slug.'/([^/]*)/?',
|
||||
'index.php?formipay-thankyou=1&formipay-token=$matches[1]',
|
||||
'top'
|
||||
);
|
||||
|
||||
flush_rewrite_rules();
|
||||
|
||||
}
|
||||
|
||||
public function set_query_vars($vars){
|
||||
|
||||
$vars[] = 'formipay-thankyou';
|
||||
$vars[] = 'formipay-token';
|
||||
return $vars;
|
||||
|
||||
}
|
||||
|
||||
public function check_parse_query() {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if(is_admin()) :
|
||||
return;
|
||||
endif;
|
||||
|
||||
if(
|
||||
!is_admin() &&
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-thankyou', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-thankyou'])
|
||||
) :
|
||||
|
||||
|
||||
$token_value = sanitize_text_field($wp_query->query['formipay-token']);
|
||||
$token_manager = new \Formipay\Token();
|
||||
|
||||
// New token validation
|
||||
if ($token_data = $token_manager->validate($token_value)) {
|
||||
$this->form_id = $form_id = $token_data['form_id'];
|
||||
$this->order_id = $order_id = $token_data['order_id'];
|
||||
$token_manager->increment_usage($token_value);
|
||||
}
|
||||
else {
|
||||
wp_die('Invalid access token');
|
||||
}
|
||||
|
||||
$this->order = $order = formipay_get_order($order_id);
|
||||
|
||||
$this->order_details = $order['items'];
|
||||
$this->form_submit = $order['form_data'];
|
||||
|
||||
$button_background_color = json_decode(formipay_get_post_meta($form_id, 'button_bg_color'), true );
|
||||
$button_text_color = json_decode(formipay_get_post_meta($form_id, 'button_text_color'), true );
|
||||
$button_border_color = json_decode( formipay_get_post_meta($form_id, 'button_border_color'), true );
|
||||
|
||||
include_once FORMIPAY_PATH . 'public/templates/thank-you.php';
|
||||
exit;
|
||||
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function process_order_meta() {
|
||||
$order_meta = [];
|
||||
if(!empty($this->order['meta_data'])){
|
||||
foreach($this->order['meta_data'] as $meta_data){
|
||||
$key = $meta_data['name'];
|
||||
$value = $meta_data['value'];
|
||||
$order_meta[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $order_meta;
|
||||
}
|
||||
|
||||
public function access_method() {
|
||||
$order_meta = $this->process_order_meta();
|
||||
|
||||
$access_method = 'magic_link';
|
||||
if(isset($order_meta['access_method'])) {
|
||||
$access_method = $order_meta['access_method'];
|
||||
}
|
||||
|
||||
return $access_method;
|
||||
}
|
||||
|
||||
public function frontend_enqueue() {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
if(
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-thankyou', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-thankyou'])
|
||||
) :
|
||||
|
||||
wp_enqueue_style( 'bs-icons', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all');
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.5', 'all');
|
||||
wp_enqueue_style( 'formipay-form-style', FORMIPAY_URL . 'public/assets/css/form-style.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_style( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/css/thankyou.css', [], FORMIPAY_VERSION, 'all' );
|
||||
|
||||
wp_enqueue_script( 'jquery-blockui', FORMIPAY_URL . 'vendor/jQuery-UI/jquery.blockUI.min.js', ['jquery'], '2.7.0', true);
|
||||
wp_enqueue_script( 'jquery-clipboard', FORMIPAY_URL . 'vendor/ClipboardJS/clipboard.min.js', ['jquery'], '2.0.11', true);
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
|
||||
wp_enqueue_script( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/js/thankyou.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
wp_enqueue_script( 'formipay-access-request', FORMIPAY_URL . 'public/assets/js/access-link-request.js', ['jquery'], FORMIPAY_VERSION, true );
|
||||
|
||||
$order_id = $this->order['id'];
|
||||
|
||||
wp_localize_script( 'formipay-thankyou', 'formipay_thankyou', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'order_id' => $this->order_id,
|
||||
'access_method' => $this->access_method(),
|
||||
'email_validation' => [
|
||||
'error' => [
|
||||
'message' => __( 'Input a valid email address', 'formipay' )
|
||||
]
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-thankyou-nonce')
|
||||
] );
|
||||
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function can_access() {
|
||||
|
||||
$order_id = $this->order['id'];
|
||||
// $order_meta = $this->order['meta_data'];
|
||||
$order_meta = $this->process_order_meta();
|
||||
|
||||
$order_ip_address = $order_meta['ip_address'];
|
||||
$order_user_agent = $order_meta['user_agent'];
|
||||
$order_device_type = $order_meta['device_type'];
|
||||
|
||||
$current_ip_address = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
|
||||
$current_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
|
||||
$current_device_type = (isset($_SERVER['HTTP_USER_AGENT']) && strpos(sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])), 'Mobile') !== false) ? 'Mobile' : 'Desktop';
|
||||
|
||||
$can_access = false;
|
||||
|
||||
if(
|
||||
$order_ip_address === $current_ip_address &&
|
||||
$order_user_agent === $current_user_agent &&
|
||||
$order_device_type === $current_device_type
|
||||
) {
|
||||
|
||||
$cookie = $this->get_cookie();
|
||||
|
||||
if(
|
||||
!empty($order_meta['session_id']) &&
|
||||
!empty($cookie) &&
|
||||
isset($cookie[$order_id]) && $cookie[$order_id] == $order_meta['session_id']
|
||||
){
|
||||
|
||||
$can_access = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $can_access;
|
||||
|
||||
}
|
||||
|
||||
public function render_view() {
|
||||
$thankyou_content = formipay_get_post_meta($this->form_id, 'thankyou_screen_content');
|
||||
$formipay_order_statuses = formipay_order_status_list();
|
||||
$this_order_status = $formipay_order_statuses[ $this->order['status']];
|
||||
|
||||
$buyer_name = '';
|
||||
if(!empty(formipay_get_post_meta($this->form_id, 'buyer_name'))){
|
||||
$buyer_name_field = formipay_get_post_meta($this->form_id, 'buyer_name');
|
||||
if(!empty($this->order['form_data'])){
|
||||
foreach($this->order['form_data'] as $_form_data){
|
||||
if($_form_data['name'] == $buyer_name_field){
|
||||
$buyer_name = $_form_data['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$shortcodes = [
|
||||
'buyer_name' => $buyer_name,
|
||||
'product_name' => get_the_title($this->form_id),
|
||||
'order_id' => $this->order['id'],
|
||||
'order_date' => $this->order['created_date'],
|
||||
'order_total' => '<p data-copy-value="' . $this->order['total'] . '" style="margin-bottom: .25em;">' . formipay_price_format( $this->order['total'], $this->form_id ) . '</p>
|
||||
<button class="formipay-copy-button" data-copy-text="Copy" data-copied-text="Copied" data-not-copied-text="Not copied!" style="font-size: 14px;">
|
||||
<i class="bi bi-copy"></i>Copy
|
||||
</button>',
|
||||
'order_status' => $this_order_status,
|
||||
'order_details' => $this->render_order_details(),
|
||||
'form_submission' => $this->render_form_submit()
|
||||
];
|
||||
|
||||
$shortcodes = apply_filters( 'formipay/thankyou/shortcodes', $shortcodes, $this->form_id, $this->order, 'thankyou' );
|
||||
|
||||
$replacements = [];
|
||||
if(!empty($shortcodes)){
|
||||
foreach($shortcodes as $key => $value){
|
||||
$replacements['{{'.$key.'}}'] = $value;
|
||||
}
|
||||
}
|
||||
$thankyou_content = strtr($thankyou_content, $replacements);
|
||||
|
||||
return $thankyou_content;
|
||||
}
|
||||
|
||||
public function view_access() {
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
|
||||
<main class="formipay-thank-you" role="main">
|
||||
<section class="formipay-content-wrapper receipt" aria-label="Order Receipt">
|
||||
<div class="formipay-the-contents">
|
||||
<?php echo wp_kses($this->render_view(), formipay_thankyoupage_allowed_html()); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php if($this->access_items() !== '') { ?>
|
||||
<section class="formipay-content-wrapper receipt downloads" aria-label="Downloads">
|
||||
<div class="formipay-the-contents">
|
||||
<?php echo $this->can_access() ? $this->access_items() : wp_kses($this->request_access(), formipay_thankyoupage_allowed_html()); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php } ?>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// echo $content;
|
||||
echo wp_kses($content, formipay_thankyoupage_allowed_html());
|
||||
// echo wp_kses_post( $content );
|
||||
|
||||
}
|
||||
|
||||
public function request_access() {
|
||||
|
||||
$formipay_settings = get_option('formipay_settings');
|
||||
|
||||
if($this->order['status'] !== 'completed') {
|
||||
return;
|
||||
}
|
||||
|
||||
$active_media = [];
|
||||
|
||||
if( formipay_get_post_meta($this->form_id, 'product_access_to_email') == 'on'){
|
||||
$active_media[] = 'email';
|
||||
}
|
||||
|
||||
$active_media = apply_filters('formipay/order/access/active-media', $active_media, $this->form_id);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="request-thumbnail">
|
||||
<?php
|
||||
echo wp_get_attachment_image( $formipay_settings['thankyou_page_restriction_thumbnail'], 'full', false, [
|
||||
'width' => '120'
|
||||
] );
|
||||
?>
|
||||
</div>
|
||||
<h2 id="access-request-heading"><?php echo esc_html($formipay_settings['thankyou_page_restriction_title']); ?></h2>
|
||||
<form action="" class="request-for-access">
|
||||
<div class="formipay-field-group" style="margin-bottom: 1em;">
|
||||
<?php if($this->access_method() == 'magic_link') { ?>
|
||||
<input type="text" name="access-pass-request" id="access-pass"
|
||||
class="formipay-input"
|
||||
value="" placeholder="Input <?php echo esc_html( implode('/', $active_media) ); ?>" required>
|
||||
<p>
|
||||
<?php echo
|
||||
esc_html(
|
||||
str_replace('{{media}}', implode(',', $active_media) ,$formipay_settings['thankyou_page_restriction_message'])
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php } elseif($this->access_method() == 'static_password') { ?>
|
||||
<input type="password" name="access_password" id="access-pass"
|
||||
class="formipay-input"
|
||||
value="" placeholder="Input <?php echo esc_html( 'Password' ); ?>" required>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<button type="submit" id="request_access_to_media" class="formipay-submit-button" disabled>
|
||||
<?php echo esc_html( $formipay_settings['thankyou_page_restriction_button'] ); ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function request_access_link() {
|
||||
|
||||
check_ajax_referer( 'formipay-thankyou-nonce', '_wpnonce' );
|
||||
|
||||
$pass = isset($_REQUEST['pass']) ? sanitize_text_field( wp_unslash($_REQUEST['pass']) ) : '';
|
||||
$order_id = isset($_REQUEST['order']) ? intval($_REQUEST['order']) : 0;
|
||||
$method = isset($_REQUEST['method']) ? sanitize_text_field( wp_unslash($_REQUEST['method']) ) : '';
|
||||
|
||||
$order = formipay_get_order($order_id);
|
||||
|
||||
$formipay_order = new Formipay_Order();
|
||||
$formipay_get_order = $formipay_order->get($order_id);
|
||||
$order_meta_data = maybe_unserialize($formipay_get_order->meta_data);
|
||||
|
||||
$valid = false;
|
||||
// validate pass
|
||||
if($method == 'magic_link'){
|
||||
$email_field_name = formipay_get_post_meta($order['form_id'], 'notification_email_buyer_recipient');
|
||||
// $email_purchase = $order['form_data'][$email_field_name];
|
||||
$email_purchase = '';
|
||||
foreach($order['form_data'] as $form_data){
|
||||
if($form_data['name'] == $email_field_name){
|
||||
$email_purchase = $form_data['value'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($email_purchase !== $pass){
|
||||
wp_send_json( [
|
||||
'title' => __( 'Wrong email!', 'formipay' ),
|
||||
'message' => __( 'You must enter an email address that matches the email you used during purchase.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
}
|
||||
|
||||
if($method == 'static_password'){
|
||||
|
||||
if(
|
||||
!empty($order_meta_data['access_password']) &&
|
||||
$pass !== $order_meta_data['access_password']
|
||||
) {
|
||||
wp_send_json([
|
||||
'title' => __( 'Password is invalid', 'formipay' ),
|
||||
'message' => __( 'Please input a valid password to access this page.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
]);
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
|
||||
}
|
||||
|
||||
if(!$valid){
|
||||
wp_send_json([
|
||||
'title' => __( 'Not provided access method', 'formipay' ),
|
||||
'message' => __( 'Contact the web master for further information or try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
]);
|
||||
}
|
||||
|
||||
// $order_meta_data = $order['meta_data'];
|
||||
|
||||
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
|
||||
$order_meta_data['session_id'] = uniqid();
|
||||
$order_meta_data['ip_address'] = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field( wp_unslash($_SERVER['REMOTE_ADDR']) ) : '';
|
||||
$order_meta_data['user_agent'] = $user_agent;
|
||||
$order_meta_data['device_type'] = (strpos( $user_agent, 'Mobile') !== false) ? 'Mobile' : 'Desktop';
|
||||
|
||||
$update = $formipay_order->update(
|
||||
$order['id'],
|
||||
[
|
||||
'meta_data' => $order_meta_data
|
||||
]
|
||||
);
|
||||
|
||||
if(is_wp_error( $update )){
|
||||
|
||||
wp_send_json( [
|
||||
'title' => __( 'Failed!', 'formipay' ),
|
||||
'message' => __( 'Something\'s happened. Contact the web master for further information or try again.', 'formipay' ),
|
||||
'icon' => 'error'
|
||||
] );
|
||||
|
||||
}
|
||||
|
||||
$cookie = $this->get_cookie();
|
||||
$cookie[$order_id] = $order_meta_data['session_id'];
|
||||
setcookie( 'fp_access', maybe_serialize($cookie), time() + 86400, '/' );
|
||||
|
||||
if($method == 'magic_link'){
|
||||
do_action('formipay/notification/access/email', $order);
|
||||
wp_send_json( [
|
||||
'title' => __( 'Access Link Sent!', 'formipay' ),
|
||||
'message' => __( 'Check your Inbox (or maybe Spam) to find a new access link so you can get digital access of this purchase.', 'formipay' ),
|
||||
'icon' => 'success',
|
||||
'action' => 'idle'
|
||||
] );
|
||||
}elseif($method == 'static_password') {
|
||||
wp_send_json( [
|
||||
'title' => __( 'Password is Valid!', 'formipay' ),
|
||||
'message' => __( 'You will be redirected to new link. Please wait.', 'formipay' ),
|
||||
'icon' => 'success',
|
||||
'action' => 'reload'
|
||||
] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function access_items() {
|
||||
|
||||
$content = '';
|
||||
|
||||
if($this->order['status'] == 'completed' && !empty( formipay_get_post_meta($this->form_id, 'product_accesses') ) ){
|
||||
// $downloads = json_decode( formipay_get_post_meta($this->form_id, 'product_access_downloads'), true );
|
||||
$accesses = explode(',', formipay_get_post_meta($this->form_id, 'product_accesses'));
|
||||
if(!empty($accesses)){
|
||||
ob_start();
|
||||
foreach($accesses as $access){
|
||||
|
||||
$type = formipay_get_post_meta( $access, 'access_type' );
|
||||
$button_text = formipay_get_post_meta( $access, 'button_text' );
|
||||
|
||||
if($type == 'download'){
|
||||
$source = formipay_get_post_meta( $access, 'access_download_source' );
|
||||
if($source == 'external'){
|
||||
$link = formipay_get_post_meta( $access, 'access_url' );
|
||||
$filesize = formipay_get_post_meta( $access, 'details_filesize' );
|
||||
}elseif($source == 'wp_media'){
|
||||
$attachment_id = formipay_get_post_meta( $access, 'access_attachment' );
|
||||
$link = wp_get_attachment_url($attachment_id);
|
||||
$filesize = size_format( filesize( get_attached_file( $attachment_id ) ), 2 );
|
||||
}
|
||||
}elseif($type == 'redirect'){
|
||||
$link = formipay_get_post_meta( $access, 'access_redirect_url' );
|
||||
$attachment_id = 0;
|
||||
$filesize = '';
|
||||
}
|
||||
|
||||
$image = formipay_attachment_icon($attachment_id);
|
||||
if(!empty(formipay_get_post_meta($access, 'details_icon'))){
|
||||
$image = wp_get_attachment_image(formipay_get_post_meta($access, 'details_icon'), 'thumbnail', false, [
|
||||
'width' => '36',
|
||||
'height' => '36'
|
||||
]);
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="formipay-single-download">
|
||||
<?php echo wp_kses_post($image); ?>
|
||||
<div class="formipay-download-information">
|
||||
<div class="formipay-file-info">
|
||||
<span class="formipay-file-title">
|
||||
<?php echo esc_html(get_the_title( $access )); ?>
|
||||
</span>
|
||||
<?php if(false !== formipay_get_post_meta($access, 'details_short_description')) { ?>
|
||||
<p class="formipay-access-item-description">
|
||||
<?php echo esc_html(formipay_get_post_meta($access, 'details_short_description')); ?>
|
||||
</p>
|
||||
<?php } ?>
|
||||
<?php if( '' !== $filesize){ ?>
|
||||
<span class="formipay-file-size">
|
||||
<?php echo esc_html($filesize); ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<a id="formipay-download-<?php echo esc_attr($access) ?>" class="formipay-download-button formipay-submit-button" href="<?php echo esc_url($link) ?>" <?php echo $type == 'download' ? 'download' : 'target="_blank"' ?>>
|
||||
<?php echo esc_html($button_text); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
}
|
||||
|
||||
$content = '<div class="formipay-downloads">'.ob_get_contents().'</div>';
|
||||
ob_end_clean();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function page_title($title) {
|
||||
|
||||
global $wp_query;
|
||||
|
||||
if(
|
||||
is_array($wp_query->query) &&
|
||||
array_key_exists('formipay-thankyou', $wp_query->query) &&
|
||||
true === boolval($wp_query->query['formipay-thankyou'])
|
||||
) :
|
||||
|
||||
$token = explode(':::', base64_decode($wp_query->query['formipay-token']));
|
||||
$form_id = $token[0];
|
||||
$order_id = $token[1];
|
||||
|
||||
$title = 'Thankyou' . ' for your order #' . $order_id;
|
||||
|
||||
endif;
|
||||
|
||||
return $title;
|
||||
|
||||
}
|
||||
|
||||
public function render_order_details() {
|
||||
|
||||
ob_start();
|
||||
if(!empty($this->order_details)){
|
||||
?>
|
||||
<table id="order-details">
|
||||
<tbody>
|
||||
<?php
|
||||
foreach($this->order_details as $detail){
|
||||
$qty = '';
|
||||
if(isset($detail['qty'])){
|
||||
$qty = ' <i class="bi bi-x"></i> '.$detail['qty'];
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th><?php echo wp_kses_post($detail['item']) . wp_kses_post($qty); ?></th>
|
||||
<td><?php echo esc_html(formipay_price_format($detail['subtotal'], $this->form_id)); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
|
||||
<td><b><?php echo esc_html(formipay_price_format($this->order['total'], $this->form_id)); ?></b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
$content = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function render_form_submit() {
|
||||
ob_start();
|
||||
if(!empty($this->form_submit)){
|
||||
$field_config = formipay_get_post_meta($this->form_id, 'formipay_settings');
|
||||
?>
|
||||
<table id="order-submission-details">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Product', 'formipay'); ?></th>
|
||||
<td><?php echo esc_html(get_the_title($this->form_id)); ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$skip_row = array(
|
||||
'form_id', 'payment', 'order_id', 'order_status', 'grand_total', 'order_date'
|
||||
);
|
||||
foreach($this->form_submit as $field){
|
||||
// $field_label = $field_config['fields'][$field_name.'_config']['label'];
|
||||
$field_name = $field['name'];
|
||||
$field_value = $field['value'];
|
||||
if(in_array($field_name, $skip_row)){
|
||||
continue;
|
||||
}
|
||||
if(empty($field_value)){
|
||||
continue;
|
||||
}
|
||||
switch ($field_name) {
|
||||
case 'form_id':
|
||||
$field_label = esc_html__( 'Form ID', 'formipay' );
|
||||
break;
|
||||
case 'qty':
|
||||
$field_label = esc_html__( 'Quantity', 'formipay' );
|
||||
break;
|
||||
case 'coupon_code':
|
||||
$field_label = esc_html__( 'Coupon Discount', 'formipay' );
|
||||
break;
|
||||
case 'payment':
|
||||
$field_label = esc_html__( 'Payment', 'formipay' );
|
||||
break;
|
||||
case 'payment_gateway':
|
||||
$field_label = esc_html__( 'Payment Method', 'formipay' );
|
||||
// $field_value = ucwords(str_replace('_', ' ', $field_value));
|
||||
$field_value = $field_value == 'cod' ? 'Cash on Delivery' : ucwords( str_replace(['-','_'], ' ', $field_value) );
|
||||
break;
|
||||
case 'order_id':
|
||||
$field_label = esc_html__( 'Order ID', 'formipay' );
|
||||
break;
|
||||
case 'grand_total':
|
||||
$field_label = esc_html__( 'Grand Total', 'formipay' );
|
||||
$field_value = esc_html(formipay_price_format($field_value, $this->form_id));
|
||||
break;
|
||||
case 'order_status':
|
||||
$field_label = esc_html__( 'Order Status', 'formipay' );
|
||||
break;
|
||||
case 'order_date':
|
||||
$field_label = esc_html__( 'Order Date', 'formipay' );
|
||||
break;
|
||||
|
||||
default:
|
||||
// $field_label = $field_config['fields'][$field_name.'_config']['label'];
|
||||
if(is_array($field_value)){
|
||||
$field_value = $field_value['value'];
|
||||
}
|
||||
if(filter_var($field_value, FILTER_VALIDATE_EMAIL)){
|
||||
$field_value = $field_value;
|
||||
}elseif(strpos($field_value, ',') !== false){
|
||||
$values = explode(',', $field_value);
|
||||
$field_value = '';
|
||||
foreach($values as $value){
|
||||
$field_value .= '<span class="checkbox-span">'.$value.'</span> ';
|
||||
}
|
||||
}else{
|
||||
$field_value = ucwords( str_replace(['-','_'], ' ', $field_value) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th><?php echo esc_html($field_label) ?></th>
|
||||
<td><?php echo wp_kses_post($field_value) ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
$content = ob_get_contents();
|
||||
ob_get_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function get_cookie() {
|
||||
$cookie = [];
|
||||
if (!empty($_COOKIE['fp_access'])) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$raw_value = wp_unslash($_COOKIE['fp_access']);
|
||||
|
||||
// Validate before unserializing
|
||||
if (is_serialized($raw_value)) { // Use WordPress core function
|
||||
$maybe = maybe_unserialize($raw_value);
|
||||
|
||||
// Type-check and sanitize array contents
|
||||
if (is_array($maybe)) {
|
||||
$cookie = array_map('sanitize_text_field', $maybe);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
}
|
||||