Tegnap egész sok mindennel kísérleteztem, majd eszembe jutott, hogy szerettem volna már egy ideje saját adatokat menteni a WordPress blog-omba, de sose volt elég időm, kedvem újra elővenni a PHP-t, és belekezdeni a fejlesztésbe. Szóval most, hogy van AI meg Gemini, megkértem, hogy csináljon egy alap plugin-t. Semmi extra, egy egyszerű CRUD, ahol a create, update, delete az admin felületen keresztül történik, a read pedig short code-ként kirakható bárhová.
Azt azért látom, hogy ahhoz, ami a végső célom lenne, be kell húznom egy IDE-t, és abban prompt-olva a fejlesztést, de szerintem ez így elsőre nem tűnik rossznak.
Az eredmény ez lett:
| Név | URL | Típus |
|---|
A generált kód pedig így néz ki:
<?php
/**
* Plugin Name: Custom Items Manager
* Description: CRUD bővítmény egyedi táblával, admin authentikációval és publikus szűrhető UI-val (Név, URL, Típus).
* Version: 1.0
* Author: Developer
*/
if (!defined('ABSPATH')) {
exit;
}
class CustomItemsManager {
private $table_name;
public function __construct() {
global $wpdb;
$this->table_name =$wpdb->prefix . 'custom_items';
// Telepítéskor adatbázis tábla létrehozása
register_activation_hook(__FILE__, array($this, 'activate'));
// Admin menü létrehozása
add_action('admin_menu', array($this, 'add_admin_menu'));
// Shortcode a publikus felülethez
add_shortcode('custom_items_list', array($this, 'render_public_ui'));
// AJAX keresés végpontok (publikus és bejelentkezett felhasználóknak is)
add_action('wp_ajax_filter_custom_items', array($this, 'ajax_filter_items'));
add_action('wp_ajax_nopriv_filter_custom_items', array($this, 'ajax_filter_items'));
}
// Adatbázis tábla létrehozása
public function activate() {
global $wpdb;
$charset_collate =$wpdb->get_charset_collate();
$sql = "CREATE TABLE {$this->table_name} ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, url VARCHAR(255) NOT NULL, type VARCHAR(100) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) )$charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
// Admin menü regisztrációja
public function add_admin_menu() {
add_menu_page(
'Elemek Kezelése',
'Elemek Kezelése',
'manage_options', // Csak adminisztrátorok érhetik el
'custom-items-manager',
array($this, 'render_admin_page'),
'dashicons-database',
20
);
}
// ADMIN UI: Create, Read, Update, Delete
public function render_admin_page() {
if (!current_user_can('manage_options')) {
wp_die(__('Nincs jogosultságod az oldal megtekintéséhez.'));
}
global $wpdb;
$message = '';
// TÖRLÉS (Delete)
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
$id = intval($_GET['id']);
check_admin_referer('delete_item_' . $id);
$wpdb->delete($this->table_name, array('id' => $id));$message = '<div class="updated"><p>Elem sikeresen törölve.</p></div>';
}
// MENTÉS / MÓDOSÍTÁS (Create / Update)
if (isset($_POST['submit_item'])) {
check_admin_referer('custom_item_form_nonce');
$id = isset($_POST['item_id']) ? intval($_POST['item_id']) : 0;
$name = sanitize_text_field($_POST['name']);
$url = esc_url_raw($_POST['url']);
$type = sanitize_text_field($_POST['type']);
if (!empty($name) && !empty($url) && !empty($type)) {
if ($id > 0) { // Update$wpdb->update($this->table_name, array('name' =>$name, 'url' => $url, 'type' =>$type), array('id' => $id));$message = '<div class="updated"><p>Elem frissítve!</p></div>';
} else {
// Create
$wpdb->insert($this->table_name, array('name' => $name, 'url' =>$url, 'type' => $type));$message = '<div class="updated"><p>Új elem hozzáadva!</p></div>';
}
} else {
$message = '<div class="error"><p>Minden mező kitöltése kötelező!</p></div>';
}
}
// Szerkesztendő elem lekérése, ha van
$edit_item = null;
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
$edit_item =$wpdb->get_row($wpdb->prepare("SELECT * FROM {$this->table_name} WHERE id = %d", intval($_GET['id'])));
}
// Összes elem lekérdezése az admin listához
$items = $wpdb->get_results("SELECT * FROM {$this->table_name} ORDER BY id DESC");
?>
<div class="wrap">
<h1>Elemek Kezelése (Admin CRUD)</h1>
<?php echo $message; ?>
<!-- CRUD Űrlap (Create/Update) -->
<h2><?php echo $edit_item ? 'Elem Szerkesztése' : 'Új Elem Hozzáadása'; ?></h2>
<form method="post" style="background:#fff; padding:15px; border:1px solid #ccc; max-width:500px; margin-bottom:20px;">
<?php wp_nonce_field('custom_item_form_nonce'); ?>
<input type="hidden" name="item_id" value="<?php echo $edit_item ? $edit_item->id : 0; ?>">
<p>
<label>Név:</label><br>
<input type="text" name="name" value="<?php echo $edit_item ? esc_attr($edit_item->name) : ''; ?>" required style="width:100%;">
</p>
<p>
<label>URL:</label><br>
<input type="url" name="url" value="<?php echo $edit_item ? esc_attr($edit_item->url) : ''; ?>" required style="width:100%;">
</p>
<p>
<label>Típus:</label><br>
<input type="text" name="type" value="<?php echo $edit_item ? esc_attr($edit_item->type) : ''; ?>" placeholder="pl. Blog, Bővítmény, Dokumentáció" required style="width:100%;">
</p>
<p>
<input type="submit" name="submit_item" class="button button-primary" value="<?php echo $edit_item ? 'Frissítés' : 'Mentés'; ?>">
<?php if ($edit_item): ?>
<a href="?page=custom-items-manager" class="button">Mégse</a>
<?php endif; ?>
</p>
</form>
<!-- Admin Lista (Read) -->
<h2>Létező Elemek</h2>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>ID</th>
<th>Név</th>
<th>URL</th>
<th>Típus</th>
<th>Műveletek</th>
</tr>
</thead>
<tbody>
<?php if ($items): foreach ($items as$item): ?>
<tr>
<td><?php echo $item->id; ?></td>
<td><strong><?php echo esc_html($item->name); ?></strong></td>
<td><a href="<?php echo esc_url($item->url); ?>" target="_blank"><?php echo esc_html($item->url); ?></a></td>
<td><?php echo esc_html($item->type); ?></td>
<td>
<a href="?page=custom-items-manager&action=edit&id=<?php echo $item->id; ?>" class="button button-small">Szerkesztés</a>
<a href="<?php echo wp_nonce_url('?page=custom-items-manager&action=delete&id=' . $item->id, 'delete_item_' .$item->id); ?>" class="button button-small button-link-delete" onclick="return confirm('Biztosan törlöd?');">Törlés</a>
</td>
</tr>
<?php endforeach; else: ?>
<tr><td colspan="5">Nincs megjeleníthető elem.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php
}
// PUBLIKUS UI: Shortcode kimenet és szűrő felület
public function render_public_ui() {
ob_start();
?>
<div id="custom-items-public-container" style="max-width:800px; margin: 0 auto;">
<!-- Szűrő Mezők -->
<div style="display:flex; gap:10px; margin-bottom:20px; flex-wrap:wrap;">
<input type="text" id="filter-name" placeholder="Szűrés név alapján..." style="flex:1; padding:8px;">
<input type="text" id="filter-url" placeholder="Szűrés URL alapján..." style="flex:1; padding:8px;">
<input type="text" id="filter-type" placeholder="Szűrés típus alapján..." style="flex:1; padding:8px;">
</div>
<!-- Eredmények Táblázata -->
<table style="width:100%; border-collapse:collapse; text-align:left;">
<thead>
<tr style="background:#f4f4f4; border-bottom:2px solid #ddd;">
<th style="padding:10px;">Név</th>
<th style="padding:10px;">URL</th>
<th style="padding:10px;">Típus</th>
</tr>
</thead>
<tbody id="custom-items-results">
<!-- AJAX tölti fel -->
</tbody>
</table>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const nameInput = document.getElementById('filter-name');
const urlInput = document.getElementById('filter-url');
const typeInput = document.getElementById('filter-type');
const resultsBody = document.getElementById('custom-items-results');
function fetchItems() {
const params = new URLSearchParams({
action: 'filter_custom_items',
name: nameInput.value,
url: urlInput.value,
type: typeInput.value
});
fetch('<?php echo admin_url('admin-ajax.php'); ?>?' + params.toString())
.then(response => response.json())
.then(data => {
resultsBody.innerHTML = '';
if (data.length > 0) {
data.forEach(item => {
const row = `
<tr style="border-bottom:1px solid #eee;">
<td style="padding:10px;"><strong>${escapeHtml(item.name)}</strong></td>
<td style="padding:10px;"><a href="${escapeHtml(item.url)}" target="_blank" rel="noopener">${escapeHtml(item.url)}</a></td>
<td style="padding:10px;">${escapeHtml(item.type)}</td>
</tr>`;
resultsBody.innerHTML += row;
});
} else {
resultsBody.innerHTML = '<tr><td colspan="3" style="padding:10px;">Nincs a szűrésnek megfelelő találat.</td></tr>';
}
});
}
function escapeHtml(text) {
return text.replace(/[&<>"']/g, function(m) {
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[m];
});
}
// Eseményfigyelők a dinamikus kereséshez
nameInput.addEventListener('input', fetchItems);
urlInput.addEventListener('input', fetchItems);
typeInput.addEventListener('input', fetchItems);
// Első betöltés
fetchItems();
});
</script>
<?php
return ob_get_clean();
}
// AJAX Szűrés Lekérdezése
public function ajax_filter_items() {
global $wpdb;
$name = isset($_GET['name']) ? sanitize_text_field($_GET['name']) : '';
$url = isset($_GET['url']) ? sanitize_text_field($_GET['url']) : '';$type = isset($_GET['type']) ? sanitize_text_field($_GET['type']) : '';
$query = "SELECT name, url, type FROM {$this->table_name} WHERE 1=1";
$args = array();
if (!empty($name)) {$query .= " AND name LIKE %s";
$args[] = '%' . $wpdb->esc_like($name) . '%';
}
if (!empty($url)) {$query .= " AND url LIKE %s";
$args[] = '%' . $wpdb->esc_like($url) . '%';
}
if (!empty($type)) {$query .= " AND type LIKE %s";
$args[] = '%' . $wpdb->esc_like($type) . '%';
}
$query .= " ORDER BY name ASC";
if (!empty($args)) {$results = $wpdb->get_results($wpdb->prepare($query,$args));
} else {
$results = $wpdb->get_results($query);
}
wp_send_json($results);
}
}
new CustomItemsManager();
Vélemény, hozzászólás?
Hozzászólás küldéséhez be kell jelentkezni.