Skip to content

Commit 03ebdb2

Browse files
authored
Merge pull request #5 from wpfresher/feature/templates
Add Templates List Table
2 parents fbefb48 + ff83bda commit 03ebdb2

16 files changed

Lines changed: 1274 additions & 418 deletions

.assets/css/admin.scss

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,53 @@
1-
#aimg-form{
2-
.preview-image{
3-
width: 600px;
4-
max-width: 98%;
5-
height: auto;
6-
border: 1px solid #cccccc;
7-
padding: 5px;
8-
background: #ffffff;
1+
.aimg-wrap{
2+
.columns {
3+
display: flex;
4+
gap: 20px;
5+
6+
.column {
7+
width: 100%;
8+
}
9+
10+
.column-left {
11+
width: 60%;
12+
}
13+
14+
.column-right {
15+
width: 40%;
16+
}
917
}
1018

19+
@media (max-width: 768px) {
20+
.columns {
21+
flex-direction: column;
22+
23+
.column-left, .column-right {
24+
width: 100%;
25+
}
26+
}
27+
}
28+
}
29+
// Card style.
30+
.aicw-card{
31+
background: #FFFFFF;
32+
border: 1px solid #DDDDDD;
33+
margin-bottom: 1.25rem;
34+
&__title{
35+
margin: 0;
36+
}
37+
&__header{
38+
padding: 10px 20px;
39+
border-bottom: 1px solid #DDDDDD;
40+
}
41+
&__body{
42+
padding: 10px 20px;
43+
}
44+
&__footer{
45+
padding: 10px 20px;
46+
}
47+
}
48+
49+
// Form styles.
50+
#aimg-form{
1151
@media (max-width: 768px) {
1252
.form-table, .form-table thead, .form-table tbody, .form-table th, .form-table td, .form-table tr {
1353
display: block;
@@ -21,6 +61,19 @@
2161
}
2262
}
2363

64+
// Preview image styles.
65+
.preview-image{
66+
border: 1px solid #cccccc;
67+
padding: 5px;
68+
background: #ffffff;
69+
70+
img{
71+
width: 100%;
72+
height: auto;
73+
}
74+
}
75+
76+
// Overlay images styles.
2477
.aimg-overlay-images{
2578
h4{
2679
margin: 0 0 10px;

.assets/js/admin.js

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Image Generator Admin JS
33
* https://beautifulplugins.com/
44
*
5-
* Copyright (c) 2025 BeautifulPlugins
5+
* Copyright (c) 2026 BeautifulPlugins
66
* Licensed under the GPLv2+ license.
77
*/
88
jQuery(function ($) {
@@ -62,36 +62,29 @@ jQuery(function ($) {
6262
});
6363
});
6464

65-
// Send the data to the server via AJAX
66-
$.ajax({
67-
url: aimg_object.ajax_url,
68-
type: 'POST',
69-
data: {
70-
action: 'aimg_save_overlay_images',
71-
overlay_images: overlayImages,
72-
nonce: aimg_object.nonce
73-
},
74-
success: function (response) {
75-
if (response.success) {
76-
// Loop through overlayImages and append only new ones.
77-
$.each(overlayImages, function (index, image) {
78-
if (existingImageIds.indexOf(image.id) === -1) {
79-
var container = $('<div class="aimg-overlay-images__item" data-id="' + image.id + '"></div>');
80-
container.append('<img src="' + image.url + '" alt="' + image.title + '" style="width:60px;height:60px;" />');
81-
container.append('<input type="hidden" name="aimg_overlay_image_ids[]" value="' + image.id + '">');
82-
container.append('<button type="button" class="remove-overlay button button-secondary">X</button>');
83-
84-
$('#overlay-image-list').append(container);
85-
}
86-
});
87-
} else {
88-
alert(response.data.message || 'Failed to save images.');
89-
}
90-
},
91-
error: function () {
92-
alert('An error occurred while uploading images.');
65+
// Loop through overlayImages and append only new ones.
66+
$.each(overlayImages, function (index, image) {
67+
if (existingImageIds.indexOf(image.id) === -1) {
68+
var container = $('<div class="aimg-overlay-images__item" data-id="' + image.id + '"></div>');
69+
container.append('<img src="' + image.url + '" alt="' + image.title + '" style="width:60px;height:60px;" />');
70+
container.append('<input type="hidden" name="aimg_overlay_image_ids[]" value="' + image.id + '">');
71+
container.append('<button type="button" class="remove-overlay button button-secondary">X</button>');
72+
73+
$('#overlay-image-list').append(container);
74+
}
75+
});
76+
77+
// Update the hidden input as araay of images ids only.
78+
var currentIds = $('#overlay_images').val();
79+
var overlayImageIds = currentIds ? JSON.parse(currentIds) : [];
80+
$.each(overlayImages, function (index, image) {
81+
if (overlayImageIds.indexOf(image.id) === -1) {
82+
overlayImageIds.push(image.id);
9383
}
9484
});
85+
86+
// Save the updated IDs back to the hidden input.
87+
$('#overlay_images').val(JSON.stringify(overlayImageIds));
9588
});
9689

9790
mediaUploader.open();
@@ -103,26 +96,19 @@ jQuery(function ($) {
10396
var $item = $(this).closest('.aimg-overlay-images__item');
10497
var imageId = $item.data('id');
10598

106-
// Send AJAX request to remove the image from the server.
107-
$.ajax({
108-
url: aimg_object.ajax_url,
109-
type: 'POST',
110-
data: {
111-
action: 'aimg_remove_overlay_image',
112-
image_id: imageId,
113-
nonce: aimg_object.nonce
114-
},
115-
success: function (response) {
116-
if (response.success) {
117-
$item.remove();
118-
} else {
119-
alert(response.data.message || 'Failed to remove image.');
120-
}
121-
},
122-
error: function () {
123-
alert('An error occurred while removing the image.');
124-
}
125-
});
99+
// Update the hidden input by removing the image ID.
100+
var currentIds = $('#overlay_images').val();
101+
var overlayImageIds = currentIds ? JSON.parse(currentIds) : [];
102+
var index = overlayImageIds.indexOf(imageId);
103+
if (index !== -1) {
104+
overlayImageIds.splice(index, 1);
105+
}
106+
107+
// Save the updated IDs back to the hidden input.
108+
$('#overlay_images').val(JSON.stringify(overlayImageIds));
109+
110+
// Remove the item from the UI immediately.
111+
$item.remove();
126112
}
127113
};
128114

includes/Admin/Actions.php

Lines changed: 68 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,122 +18,97 @@ class Actions {
1818
* @since 1.0.0
1919
*/
2020
public function __construct() {
21-
add_action( 'admin_post_aimg_artificial_image_generator', array( $this, 'save_artificial_image_generator_settings' ) );
22-
add_action( 'wp_ajax_aimg_save_overlay_images', array( $this, 'save_overlay_images' ) );
23-
add_action( 'wp_ajax_aimg_remove_overlay_image', array( $this, 'remove_overlay_image' ) );
21+
add_action( 'admin_post_aimg_update_template', array( __CLASS__, 'update_template' ) );
2422
}
2523

2624
/**
27-
* Save auto image generator settings.
25+
* Add product tabs data.
2826
*
2927
* @since 1.0.0
28+
* @return void
3029
*/
31-
public function save_artificial_image_generator_settings() {
32-
check_admin_referer( 'aimg_artificial_image_generator' );
30+
public static function update_template() {
31+
check_admin_referer( 'aimg_update_template' );
3332
$referer = wp_get_referer();
3433

3534
if ( ! current_user_can( 'manage_options' ) ) {
36-
artificial_image_generator()->flash_notice( esc_html__( 'You do not have permission to perform this action.', 'artificial-image-generator' ), 'error' );
35+
artificial_image_generator()->flash_notice( __( 'You do not have permission to process this action', 'artificial-image-generator' ), 'error' );
3736
wp_safe_redirect( $referer );
38-
exit();
37+
exit;
3938
}
4039

41-
$bg_colors = isset( $_POST['bg_colors'] ) ? sanitize_text_field( wp_unslash( $_POST['bg_colors'] ) ) : '';
42-
$width = isset( $_POST['width'] ) ? absint( $_POST['width'] ) : 1200;
43-
$height = isset( $_POST['height'] ) ? absint( $_POST['height'] ) : 800;
44-
$title_font_size = isset( $_POST['title_font_size'] ) ? absint( $_POST['title_font_size'] ) : 40;
45-
$is_overlay_image = isset( $_POST['is_overlay_image'] ) ? 'yes' : 'no';
46-
$overlay_position = isset( $_POST['overlay_position'] ) ? sanitize_text_field( wp_unslash( $_POST['overlay_position'] ) ) : 'center-center';
40+
$template_id = isset( $_POST['template_id'] ) ? absint( wp_unslash( $_POST['template_id'] ) ) : 0;
41+
$title = isset( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : '';
42+
$status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : 'publish';
4743

48-
update_option( 'aimg_bg_colors', $bg_colors );
49-
update_option( 'aimg_width', $width );
50-
update_option( 'aimg_height', $height );
51-
update_option( 'aimg_title_font_size', $title_font_size );
52-
update_option( 'aimg_is_overlay_image', $is_overlay_image );
53-
update_option( 'aimg_overlay_position', $overlay_position );
54-
55-
// Generate the thumbnail image if the settings are saved.
56-
$colors = empty( $bg_colors ) ? '#e74c3c,#2ecc71,#9b59b6' : $bg_colors;
57-
$overlay_images = get_option( 'aimg_overlay_images', array() );
58-
$preview_image_url = aimg_generate_preview( 'Dynamic Post Title Will be Available Here', $colors, $width, $height, $overlay_images );
59-
60-
// Save the preview image URL in the options.
61-
update_option( 'aimg_preview_image_url', $preview_image_url );
62-
63-
artificial_image_generator()->flash_notice( esc_html__( 'Settings saved successfully.', 'artificial-image-generator' ), 'success' );
64-
wp_safe_redirect( $referer );
65-
exit();
66-
}
67-
68-
/**
69-
* Save overlay images via AJAX.
70-
*
71-
* @since 1.0.0
72-
*/
73-
public function save_overlay_images() {
74-
check_ajax_referer( 'aimg_nonce', 'nonce' );
75-
76-
if ( ! current_user_can( 'manage_options' ) ) {
77-
wp_send_json_error( __( 'You do not have permission to perform this action.', 'artificial-image-generator' ) );
44+
if ( empty( $title ) ) {
45+
artificial_image_generator()->flash_notice( __( 'The title field is required.', 'artificial-image-generator' ), 'error' );
46+
wp_safe_redirect( $referer );
47+
exit;
7848
}
7949

80-
$images = isset( $_POST['overlay_images'] ) ? map_deep( wp_unslash( $_POST['overlay_images'] ), 'sanitize_text_field' ) : array();
81-
82-
// Check if overlay images are set and is an array. Then check the images id and save them and send a success response with the ids.
83-
if ( is_array( $images ) && ! empty( $images ) ) {
84-
$image_ids = array_map(
85-
function ( $image ) {
86-
return absint( $image['id'] ?? 0 );
87-
},
88-
$images
89-
);
90-
91-
// Get the existing overlay images from the database.
92-
$existing_image_ids = get_option( 'aimg_overlay_images', array() );
93-
94-
// Merge existing and new image IDs, ensuring uniqueness.
95-
$image_ids = array_unique( array_merge( $existing_image_ids, $image_ids ) );
96-
97-
// Update the option with the new image IDs.
98-
update_option( 'aimg_overlay_images', $image_ids );
99-
100-
wp_send_json_success(
101-
array( 'message' => __( 'Overlay images saved successfully.', 'artificial-image-generator' ) )
102-
);
50+
// Create or Update Product Tab.
51+
$post_args = array(
52+
'post_type' => 'aimg_template',
53+
'post_title' => wp_strip_all_tags( $title ),
54+
'post_name' => sanitize_title( $title ),
55+
'post_content' => '',
56+
'post_status' => $status,
57+
);
58+
59+
if ( $template_id ) {
60+
$post_args['ID'] = $template_id;
10361
}
10462

105-
wp_send_json_error( __( 'No overlay images provided.', 'artificial-image-generator' ) );
106-
}
63+
// Create or update the post.
64+
$post = wp_insert_post( $post_args );
10765

108-
/**
109-
* Remove an overlay image via AJAX.
110-
*
111-
* @since 1.0.0
112-
*/
113-
public function remove_overlay_image() {
114-
check_ajax_referer( 'aimg_nonce', 'nonce' );
115-
116-
if ( ! current_user_can( 'manage_options' ) ) {
117-
wp_send_json_error( __( 'You do not have permission to perform this action.', 'artificial-image-generator' ) );
66+
if ( is_wp_error( $post ) ) {
67+
artificial_image_generator()->flash_notice( $post->get_error_message(), 'error' );
68+
wp_safe_redirect( $referer );
69+
exit;
11870
}
11971

120-
$image_id = isset( $_POST['image_id'] ) ? absint( $_POST['image_id'] ) : null;
121-
122-
if ( $image_id ) {
123-
$existing_images = get_option( 'aimg_overlay_images', array() );
72+
// Save meta fields.
73+
$bg_colors = isset( $_POST['bg_colors'] ) ? sanitize_text_field( wp_unslash( $_POST['bg_colors'] ) ) : '';
74+
$width = isset( $_POST['width'] ) ? absint( $_POST['width'] ) : 1200;
75+
$height = isset( $_POST['height'] ) ? absint( $_POST['height'] ) : 800;
76+
$title_font_size = isset( $_POST['title_font_size'] ) ? absint( $_POST['title_font_size'] ) : 40;
77+
$is_overlay_image = isset( $_POST['is_overlay_image'] ) ? 'yes' : 'no';
78+
$overlay_images = isset( $_POST['overlay_images'] ) ? sanitize_text_field( wp_unslash( $_POST['overlay_images'] ) ) : '';
79+
$overlay_position = isset( $_POST['overlay_position'] ) ? sanitize_text_field( wp_unslash( $_POST['overlay_position'] ) ) : 'center-center';
12480

125-
if ( in_array( $image_id, $existing_images, true ) ) {
126-
$existing_images = array_diff( $existing_images, array( $image_id ) );
127-
update_option( 'aimg_overlay_images', $existing_images );
81+
update_post_meta( $post, '_aimg_bg_colors', $bg_colors );
82+
update_post_meta( $post, '_aimg_width', $width );
83+
update_post_meta( $post, '_aimg_height', $height );
84+
update_post_meta( $post, '_aimg_title_font_size', $title_font_size );
85+
update_post_meta( $post, '_aimg_is_overlay_image', $is_overlay_image );
86+
update_post_meta( $post, '_aimg_overlay_images', $overlay_images );
87+
update_post_meta( $post, '_aimg_overlay_position', $overlay_position );
88+
89+
// Generate the thumbnail image if the settings are saved successfully.
90+
if ( $post ) {
91+
$colors = empty( $bg_colors ) ? '#e74c3c,#2ecc71,#9b59b6' : $bg_colors;
92+
$overlay_images = 'yes' === $is_overlay_image ? json_decode( $overlay_images ) : array();
93+
$preview_image_url = aimg_generate_preview( $post, $colors, $width, $height, $overlay_images );
94+
95+
// Update the preview image URL as post meta.
96+
update_post_meta( $post, '_aimg_preview_image_url', $preview_image_url );
97+
}
12898

129-
wp_send_json_success(
130-
array( 'message' => __( 'Overlay image removed successfully.', 'artificial-image-generator' ) )
131-
);
132-
} else {
133-
wp_send_json_error( __( 'Overlay image not found.', 'artificial-image-generator' ) );
134-
}
99+
// Flash success message and redirect.
100+
if ( $template_id ) {
101+
artificial_image_generator()->flash_notice( __( 'Image template updated successfully.', 'artificial-image-generator' ) );
102+
} else {
103+
artificial_image_generator()->flash_notice( __( 'Image template added successfully.', 'artificial-image-generator' ) );
135104
}
136105

137-
wp_send_json_error( __( 'Invalid overlay image ID.', 'artificial-image-generator' ) );
106+
$referer = add_query_arg(
107+
array( 'edit' => absint( $post ) ),
108+
remove_query_arg( 'add', $referer )
109+
);
110+
111+
wp_safe_redirect( $referer );
112+
exit;
138113
}
139114
}

0 commit comments

Comments
 (0)