feat(media): add local offline SVG generator option alongside Picsum Online

This commit is contained in:
idtemankampus-creator
2026-09-18 08:47:01 +07:00
parent 6159c8fd15
commit cabda4a9da
+55 -10
View File
@@ -3,7 +3,7 @@
* Plugin Name: DummyLab Dummy Post & Content Generator
* Plugin URI: https://apps.masbudi.my.id/dummylab-wp
* Description: Advanced dummy content generator for WordPress development with safety controls and bulk purge features.
* Version: 1.4.0
* Version: 1.5.0
* Author: masbudikusuma
* Author URI: https://masbudi.my.id
* Donate link: https://donate.masbudi.my.id/dummylab-wp
@@ -115,7 +115,6 @@ class DummyLab {
.dummylab-lang-btn { text-decoration: none; padding: 5px 14px; border-radius: 16px; font-size: 12px; font-weight: 600; color: #50575e; transition: all 0.2s ease; }
.dummylab-lang-btn.active { background: #2271b1; color: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.1); }
/* Modern Tabs */
.dummylab-tabs { display: flex; gap: 8px; margin-bottom: 20px; border-bottom: 2px solid #e2e8f0; }
.dummylab-tab-item { padding: 10px 18px; text-decoration: none; font-weight: 600; color: #646970; border-bottom: 2px solid transparent; margin-bottom: -2px; font-size: 14px; transition: all 0.2s ease; display: flex; align-items: center; gap: 8px; }
.dummylab-tab-item:hover { color: #2271b1; }
@@ -169,10 +168,9 @@ class DummyLab {
</div>
<div class="dummylab-wrap">
<!-- Header Banner -->
<div class="dummylab-header">
<div>
<h1>🧪 DummyLab <span style="font-size: 14px; font-weight: 400; color: #646970;">v1.4.0</span></h1>
<h1>🧪 DummyLab <span style="font-size: 14px; font-weight: 400; color: #646970;">v1.5.0</span></h1>
<p><?php echo $t['created_by']; ?> <a href="https://masbudi.my.id" target="_blank" style="text-decoration: none; font-weight: 600; color: #2271b1;">masbudikusuma</a> &bull; <a href="https://apps.masbudi.my.id/dummylab-wp" target="_blank" style="text-decoration: none; color: #2271b1;"><?php echo $t['plugin_doc']; ?></a> &bull; <a href="https://donate.masbudi.my.id/dummylab-wp" target="_blank" style="text-decoration: none; font-weight: 600; color: #b35900;">☕ <?php echo $t['link_donate']; ?></a></p>
</div>
<div class="dummylab-lang-switch">
@@ -181,7 +179,6 @@ class DummyLab {
</div>
</div>
<!-- Navigation Tabs -->
<div class="dummylab-tabs">
<a href="<?php echo esc_url(add_query_arg(['tab' => 'generator', 'ui_lang' => $ui_lang])); ?>" class="dummylab-tab-item <?php echo $current_tab === 'generator' ? 'active' : ''; ?>">
🚀 <?php echo $t['tab_generator']; ?>
@@ -294,6 +291,13 @@ class DummyLab {
</select>
</div>
<div class="dummylab-field">
<label for="image_source"><?php echo $t['lbl_image_source']; ?></label>
<select name="image_source" id="image_source">
<option value="picsum" selected><?php echo $t['opt_img_picsum']; ?></option>
<option value="local_svg"><?php echo $t['opt_img_svg']; ?></option>
</select>
</div>
<div class="dummylab-field full-width">
<label for="image_size"><?php echo $t['lbl_image_size']; ?></label>
<select name="image_size" id="image_size">
<option value="800/600"><?php echo $t['opt_img_small']; ?></option>
@@ -494,8 +498,11 @@ class DummyLab {
'opt_len_short' => 'Short (2-3 paragraphs)',
'opt_len_medium' => 'Medium (4-6 paragraphs + heading)',
'opt_len_long' => 'Long (7-10 paragraphs + heading, quote)',
'lbl_image_source' => 'Image Source Method',
'opt_img_picsum' => 'Picsum Photos (Online - High Quality Photos)',
'opt_img_svg' => 'SVG Placeholder (100% Offline & Fast)',
'lbl_image_size' => 'Featured Image Size',
'opt_use_img' => 'Include random image from Picsum Photos',
'opt_use_img' => 'Include featured image',
'opt_img_small' => 'Small (800x600)',
'opt_img_med' => 'Medium (1200x800)',
'opt_img_large' => 'Large (1600x1000)',
@@ -509,7 +516,7 @@ class DummyLab {
'guide_title' => 'Quick Usage Guide',
'guide_step1' => 'Select total count and content type (Post/Page).',
'guide_step2' => 'Choose generated text language and length.',
'guide_step3' => 'Check image box to auto-fetch thumbnails from Picsum.',
'guide_step3' => 'Choose between online photos or offline fast SVG images.',
'guide_step4' => 'Click Purge anytime to completely clean test data.',
'safety_title' => 'Development Safety',
'safety_item1' => 'All dummy posts tracked via unique metadata key.',
@@ -539,7 +546,7 @@ class DummyLab {
'msg_purged' => 'data dummy berhasil dibersihkan!',
'msg_deleted_single' => 'Item dummy berhasil dihapus.',
'loading_title' => 'Sedang membuat konten dummy...',
'loading_subtitle' => 'Mohon tunggu beberapa saat. Server sedang mengunduh gambar dan membuat data artikel.',
'loading_subtitle' => 'Mohon tunggu beberapa saat. Server sedang memproses data artikel dan gambar.',
'sec_general' => 'Pengaturan Utama',
'sec_taxonomy' => 'Taksonomi & Penulis',
'sec_content' => 'Konten & Media',
@@ -567,8 +574,11 @@ class DummyLab {
'opt_len_short' => 'Pendek (2-3 paragraf)',
'opt_len_medium' => 'Sedang (4-6 paragraf + heading)',
'opt_len_long' => 'Panjang (7-10 paragraf + heading, quote)',
'lbl_image_source' => 'Metode Sumber Gambar',
'opt_img_picsum' => 'Picsum Photos (Online - Foto Asli Realistis)',
'opt_img_svg' => 'SVG Placeholder (100% Offline & Super Cepat)',
'lbl_image_size' => 'Ukuran Gambar Unggulan',
'opt_use_img' => 'Sertakan gambar acak dari Picsum Photos',
'opt_use_img' => 'Sertakan gambar unggulan',
'opt_img_small' => 'Kecil (800x600)',
'opt_img_med' => 'Sedang (1200x800)',
'opt_img_large' => 'Besar (1600x1000)',
@@ -582,7 +592,7 @@ class DummyLab {
'guide_title' => 'Panduan Penggunaan',
'guide_step1' => 'Pilih jumlah data dan tipe konten (Post atau Halaman).',
'guide_step2' => 'Atur bahasa dan panjang artikel yang akan dihasilkan.',
'guide_step3' => 'Centang opsi gambar untuk mengunduh thumbnail dari Picsum.',
'guide_step3' => 'Pilih sumber gambar online (foto asli) atau offline (SVG instan).',
'guide_step4' => 'Gunakan tombol Purge untuk menghapus semua data pengujian.',
'safety_title' => 'Pengembangan Aman',
'safety_item1' => 'Setiap postingan dummy dilindungi metadata internal unik.',
@@ -619,6 +629,7 @@ class DummyLab {
$author_opt = isset($_POST['post_author']) ? sanitize_text_field($_POST['post_author']) : 'random';
$date_opt = isset($_POST['date_option']) ? sanitize_text_field($_POST['date_option']) : 'now';
$content_length = isset($_POST['content_length']) ? sanitize_text_field($_POST['content_length']) : 'medium';
$image_source = isset($_POST['image_source']) ? sanitize_text_field($_POST['image_source']) : 'picsum';
$use_image = isset($_POST['use_featured_image']) ? true : false;
$image_size = isset($_POST['image_size']) ? sanitize_text_field($_POST['image_size']) : '1200/800';
$add_comments = isset($_POST['add_comments']) ? true : false;
@@ -682,6 +693,39 @@ class DummyLab {
update_post_meta($post_id, $this->meta_key, '1');
if ($use_image) {
if ($image_source === 'local_svg') {
$size_parts = explode('/', $image_size);
$w = isset($size_parts[0]) ? intval($size_parts[0]) : 1200;
$h = isset($size_parts[1]) ? intval($size_parts[1]) : 800;
$colors = ['#1e293b', '#0f172a', '#1e3a8a', '#14532d', '#701a75', '#312e81', '#831843', '#7c2d12'];
$bg_color = $colors[array_rand($colors)];
$svg_content = '<svg xmlns="http://www.w3.org/2000/svg" width="' . $w . '" height="' . $h . '" viewBox="0 0 ' . $w . ' ' . $h . '">' .
'<rect width="100%" height="100%" fill="' . $bg_color . '"/>' .
'<text x="50%" y="45%" dominant-baseline="middle" text-anchor="middle" fill="#ffffff" font-size="36" font-family="sans-serif" font-weight="bold">DummyLab Placeholder</text>' .
'<text x="50%" y="55%" dominant-baseline="middle" text-anchor="middle" fill="#94a3b8" font-size="20" font-family="sans-serif">' . $w . ' x ' . $h . ' - Post #' . $post_id . '</text>' .
'</svg>';
$file_name = 'dummylab-svg-' . $post_id . '-' . rand(100, 999) . '.svg';
$upload = wp_upload_bits($file_name, null, $svg_content);
if (!$upload['error']) {
$attachment = [
'post_mime_type' => 'image/svg+xml',
'post_title' => 'DummyLab SVG ' . $post_id,
'post_content' => '',
'post_status' => 'inherit'
];
$attach_id = wp_insert_attachment($attachment, $upload['file'], $post_id);
if ($attach_id && !is_wp_error($attach_id)) {
$attach_data = wp_generate_attachment_metadata($attach_id, $upload['file']);
wp_update_attachment_metadata($attach_id, $attach_data);
set_post_thumbnail($post_id, $attach_id);
update_post_meta($attach_id, $this->meta_key, '1');
}
}
} else {
$image_url = 'https://picsum.photos/' . $image_size . '?random=' . rand(1, 9999);
$tmp = download_url($image_url);
if (!is_wp_error($tmp)) {
@@ -697,6 +741,7 @@ class DummyLab {
@unlink($tmp);
}
}
}
if ($i === 0 && $make_sticky && $post_type === 'post') {
stick_post($post_id);