Preview: glossary-import.php
Size: 5.17 KB
/var/www/candid-stg.bitkit.dk/httpdocs/wp-content/plugins/glossary-import.php
<?php
/**
* Plugin Name: Glossary CSV Importer
* Description: Imports Glossary CPT items from a CSV file (Term → title, Definition → ACF field glossary_definition).
* Version: 1.1
* Author: Your Name
*/
if (! defined('ABSPATH')) exit;
class Glossary_CSV_Importer
{
public function __construct()
{
add_action('admin_menu', array($this, 'register_menu'));
// Remove filters that strip special characters
add_action('init', array($this, 'remove_sanitization_filters'));
}
public function remove_sanitization_filters()
{
// Only remove during import - we'll add them back
// This is handled in process_import()
}
public function register_menu()
{
add_management_page(
'Glossary CSV Import',
'Glossary Import',
'manage_options',
'glossary-csv-import',
array($this, 'import_page')
);
}
public function import_page()
{
echo '<div class="wrap"><h1>Glossary CSV Import</h1>';
if (isset($_POST['submit']) && check_admin_referer('glossary_import_form')) {
$this->process_import();
}
?>
<form method="post" enctype="multipart/form-data">
<?php wp_nonce_field('glossary_import_form'); ?>
<p><label><strong>Select CSV File:</strong></label><br>
<input type="file" name="csv_file" required>
</p>
<p><input type="submit" name="submit" class="button button-primary" value="Import CSV"></p>
</form>
<?php
echo '</div>';
}
private function process_import()
{
// Temporarily remove sanitization filters
remove_filter('title_save_pre', 'wp_filter_kses');
remove_filter('content_save_pre', 'wp_filter_kses');
// force UTF-8 handling
mb_internal_encoding("UTF-8");
setlocale(LC_ALL, 'en_US.UTF-8');
if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
echo '<div class="error"><p>File upload failed.</p></div>';
return;
}
$tmp = $_FILES['csv_file']['tmp_name'];
// Read raw bytes
$csv_raw = file_get_contents($tmp);
if (!$csv_raw) {
echo '<div class="error"><p>Could not read CSV.</p></div>';
return;
}
// Remove BOM if present
$csv_raw = preg_replace('/^\xEF\xBB\xBF/', '', $csv_raw);
// Detect encoding
$encoding = mb_detect_encoding($csv_raw, ['UTF-8', 'UTF-16', 'UTF-32', 'ISO-8859-1', 'WINDOWS-1252'], true);
if (!$encoding) {
$encoding = 'UTF-8';
}
// Convert to UTF-8
if ($encoding !== 'UTF-8') {
$csv_raw = mb_convert_encoding($csv_raw, 'UTF-8', $encoding);
}
// Write clean UTF-8 csv to real temporary file
$converted = wp_tempnam('glossary.csv');
file_put_contents($converted, $csv_raw);
$handle = fopen($converted, 'r');
if (!$handle) {
echo '<div class="error"><p>Failed to open converted CSV.</p></div>';
return;
}
$imported = 0;
$row = 0;
while (($data = fgetcsv($handle, 0, ',')) !== false) {
// Skip empty or invalid rows
if (!is_array($data) || count($data) < 2) continue;
$row++;
// Skip header
if ($row === 1 && preg_match('/term/i', $data[0])) continue;
// Keep full Unicode - no sanitization
$term = trim($data[0]);
$definition = trim($data[1]);
if ($term === '') continue;
$existing = get_page_by_title($term, OBJECT, 'glossary');
if ($existing) {
$post_id = $existing->ID;
} else {
// Use wp_insert_post with special flag
$post_id = wp_insert_post([
'post_title' => sanitize_text_field($term),
'post_type' => 'glossary',
'post_status' => 'publish',
], false, false); // Third parameter: false = don't sanitize
}
if ($post_id) {
// Update ACF field directly in database to bypass filters
// update_field() can still sanitize, so use update_post_meta
update_post_meta($post_id, 'glossary_definition', $definition);
// If you need ACF's internal reference keys:
$field_object = get_field_object('glossary_definition', $post_id);
if ($field_object) {
update_post_meta($post_id, '_glossary_definition', $field_object['key']);
}
$imported++;
}
}
fclose($handle);
// Re-add filters
add_filter('title_save_pre', 'wp_filter_kses');
add_filter('content_save_pre', 'wp_filter_kses');
echo '<div class="updated"><p>Import complete. ' . $imported . ' items imported.</p></div>';
}
}
new Glossary_CSV_Importer();
Directory Contents
Dirs: 19 × Files: 4