• Basisthema
  • Tweede menu item
    • Sub menu item
Inloggen
Home » Van csv bestand via PHP post_types aanmaken en ACF velden vullen

Van csv bestand via PHP post_types aanmaken en ACF velden vullen

Van csv bestand via PHP post_types aanmaken en ACF velden vullen

PHP Code

php
if (get_current_user_id() === 1) : 
	/**
     * Import EQA Opleidingen from CSV into CPT 'eqa-opleiding'
     * Usage: put this in a one-off mu-plugin, a WP-CLI command, or run in a secure admin context.
     */

    if ( ! defined('ABSPATH') ) { exit; }

    // === CONFIG ===

    $fileloc = dirname(__DIR__, 1);
    $csvFile = $fileloc . '/pe-opleidingen.csv'; // adjust path
    $post_type = 'pe-opleiding';
    $taxonomy  = 'pe-type'; // ACF taxonomy attached to this post_type

    // Map logical field names to ACF field KEYS (recommended).
    // TODO: replace field_XXXXXXXX with your actual ACF field keys.
    $acf_keys = [
        'systeemid'         => 'systeemid', // number
        'opleidingskenmerk' => 'opleidingskenmerk', // text
        'link'              => 'link', // link
        'toegekend'         => 'pe_of_eqa_toegekend_op', // date
        'geldig'            => 'pe_of_eqa_geldig_tot', // date
        'opleidingsvorm'    => 'opleidingsvorm', // wysiwyg
        'opl_omschrijving'  => 'opl_omschrijving', // wysiwyg
        'peuren'            => 'pe_uren', // number
        'duurdagen'         => 'duur_dagen', // number
        'kosten'            => 'kosten', // number
        'startdata'         => 'startdata', // wysiwyg
        // taxonomy is handled via wp_set_object_terms()
    ];

    // === HELPERS ===
    /**
     * Try to detect delimiter based on header line.
     */
    function detect_delimiter($line) {
        $candidates = [",", ";", "\t", "|"];
        $counts = [];
        foreach ($candidates as $d) {
            $counts[$d] = substr_count($line, $d);
        }
        arsort($counts);
        return key($counts);
    }

    /**
     * Normalize header labels to canonical keys.
     */
    function normalize_header($label) {
        $label = trim(mb_strtolower($label));
        // allow small variations/spaces
        $label = preg_replace('/\s+/', '', $label);
        return $label;
    }

    /**
     * Parse a date string into ACF Date Picker format 'Ymd'.
     * Returns null if cannot parse or empty.
     */
    function to_acf_date($value) {
        $value = trim((string)$value);
        if ($value === '') return null;

        // Try common formats
        $formats = ['Y-m-d', 'd-m-Y', 'd/m/Y', 'Y/m/d', 'd.m.Y', 'Ymd'];
        foreach ($formats as $fmt) {
            $dt = DateTimeImmutable::createFromFormat($fmt, $value);
            if ($dt instanceof DateTimeImmutable) {
                return $dt->format('Ymd');
            }
        }

        // Last resort: strtotime
        $ts = strtotime($value);
        if ($ts !== false) {
            return date('Ymd', $ts);
        }

        return null;
    }

    /**
     * Read the first line safely (handling BOM).
     */
    function fopen_no_bom($path) {
        $h = fopen($path, 'r');
        if (! $h) return false;
        // Remove UTF-8 BOM if present
        $bom = fread($h, 3);
        if ($bom !== "\xEF\xBB\xBF") {
            // Not a BOM; rewind to start
            rewind($h);
        }
        return $h;
    }

    /**
     * Find existing post by unique meta 'systeemid'.
     */
    function find_post_by_systeemid($systeemid, $post_type) {
        $q = new WP_Query([
            'post_type'      => $post_type,
            'posts_per_page' => 1,
            'post_status'    => 'any',
            'meta_query'     => [
                [
                    'key'   => 'systeemid',
                    'value' => $systeemid,
                ],
            ],
            'fields'         => 'ids',
            'no_found_rows'  => true,
        ]);
        return $q->have_posts() ? (int)$q->posts[0] : 0;
    }

    // === RUN ===
    if (! file_exists($csvFile)) {
        wp_die('CSV not found at: ' . esc_html($csvFile));
    }

    $handle = fopen_no_bom($csvFile);
    if ($handle === false) {
        wp_die('Unable to open CSV.');
    }

    // Peek first line to detect delimiter
    $firstLine = fgets($handle);


    if ($firstLine === false) {
        fclose($handle);
        wp_die('CSV is empty.');
    }
    $delimiter = detect_delimiter($firstLine);

    // Build header from first line
    $headerRaw = str_getcsv($firstLine, $delimiter);
    $headerMap = [];
    foreach ($headerRaw as $i => $label) {
        $count++;
        $norm = normalize_header($label);
        $headerMap[$i] = $norm;
    }

    // Expected canonical keys (normalized):
    $required = ['systeemid','naam','opleidingskenmerk','link','toegekend','geldig','petype', 'opleidingsvorm', 'opl_omschrijving', 'peuren', 'duurdagen', 'kosten', 'startdata'];
    $missing  = array_diff($required, $headerMap);
    if ($missing) {
        // Try to be forgiving if your header used small differences like "systeemidnaam" earlier:
        // If you for some reason have combined headers, adjust here or ensure the CSV header matches the list above.
        // For now, enforce correctness:
        fclose($handle);
        wp_die('CSV header missing columns: ' . implode(', ', $missing));
    }

    $created = 0;
    $updated = 0;

    // Iterate rows
    while (($row = fgetcsv($handle, 0, $delimiter)) !== false) {
        if (count($row) === 1 && trim($row[0]) === '') {
            continue; // skip empty lines
        }

        $item = [];
        foreach ($row as $i => $value) {
            $key = $headerMap[$i] ?? 'col_'.$i;
            $item[$key] = is_string($value) ? trim($value) : $value;
        }

        // Basic validation
        if (($item['naam'] ?? '') === '') {
            continue; // skip rows without a title
        }

        $systeemid = $item['systeemid'] ?? '';
        $existing_id = $systeemid !== '' ? find_post_by_systeemid($systeemid, $post_type) : 0;

        $postarr = [
            'post_type'   => $post_type,
            'post_title'  => $item['naam'],
            'post_status' => 'publish',
        ];

        if ($existing_id) {
            $postarr['ID'] = $existing_id;
            $post_id = wp_update_post($postarr, true);
        } else {
            $post_id = wp_insert_post($postarr, true);
        }

        if (is_wp_error($post_id)) {
            error_log('Failed to save post for systeemid '.$systeemid.': '.$post_id->get_error_message());
            continue;
        }

        // === ACF fields ===
        // Number: systeemid


        // === ACF fields — TEXT ===
        if (isset($item['opleidingsvorm'])) {
            update_field($acf_keys['opleidingsvorm'], sanitize_text_field($item['opleidingsvorm']), $post_id);
        }
        if (isset($item['opleidingskenmerk'])) {
            update_field($acf_keys['opleidingskenmerk'], sanitize_text_field($item['opleidingskenmerk']), $post_id);
        }

        // === ACF fields — WYSIWYG ===
        foreach (['opl_omschrijving','startdata'] as $wysiwygKey) {
            if (array_key_exists($wysiwygKey, $item)) {
                $val = is_string($item[$wysiwygKey]) ? trim($item[$wysiwygKey]) : $item[$wysiwygKey];
                if ($val !== '' && $val !== null) {
                    update_field($acf_keys[$wysiwygKey], $val, $post_id);
                }
            }
        }

        // Numbers: peuren, duurdagen, kosten
        foreach (['systeemid','peuren','duurdagen','kosten'] as $numKey) {
            if (!empty($item[$numKey])) {
                update_field($acf_keys[$numKey], (float) $item[$numKey], $post_id);
            }
        }

        // Link: expects array(url, title, target)
        if (!empty($item['link'])) {
            $linkArr = [
                'url'    => esc_url_raw($item['link']),
                'title'  => $item['naam'],    // or a static label like "Bekijk"
                'target' => '_blank',         // adjust if you use same window
            ];
            update_field($acf_keys['link'], $linkArr, $post_id);
        }

        // Dates: to ACF date format 'Ymd'
        foreach (['toegekend','geldig','verlengd'] as $dateKey) {
            $val = isset($item[$dateKey]) ? to_acf_date($item[$dateKey]) : null;
            if ($val) {
                update_field($acf_keys[$dateKey], $val, $post_id);
            } else {
                // Optional: clear if empty
                // update_field($acf_keys[$dateKey], null, $post_id);
            }
        }

        // Taxonomy: niveau (can be multiple; split by comma if present)
        if (!empty($item['petype'])) {
            $termsRaw = array_map('trim', preg_split('/[,|;]+/', $item['petype']));
            $termsRaw = array_filter($termsRaw, fn($t) => $t !== '');
            if ($termsRaw) {
                // Ensure terms exist; create as needed
                $term_ids = [];
                foreach ($termsRaw as $termName) {
                    $existing = term_exists($termName, $taxonomy);
                    if ($existing === 0 || $existing === null) {
                        $created_term = wp_insert_term($termName, $taxonomy);
                        if (!is_wp_error($created_term)) {
                            $term_ids[] = (int)$created_term['term_id'];
                        }
                    } elseif (is_array($existing) && isset($existing['term_id'])) {
                        $term_ids[] = (int)$existing['term_id'];
                    }
                }
                if ($term_ids) {
                    wp_set_object_terms($post_id, $term_ids, $taxonomy, false);
                }
            }
        }

        if ($existing_id) { $updated++; } else { $created++; }
    }

    fclose($handle);

    printf(
        "Done. Created: %d, Updated: %d\n",
        $created,
        $updated
    );
endif;
Bekijk Snippet

Door Gladior

  • Facebook
  • Linkedin
  • Mail
  • Instagram

Contact

service@gladior.com

Overige informatie

Basisthema voor WordPress