Unable to add MX and TXT records to zone using php api library

I seem to be unable to pass MX and TXT records to Cloudflare using the PHP Cloudflare API library.

I am able to add all A, AAAA and CNAME records:

$records = [
    // A Records
    ['type' => 'A', 'name' => 'cpanel', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'cpcalendars', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'cpcontacts', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => '@', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => true, 'ttl' => 1],

    ['type' => 'A', 'name' => 'ftp', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'mail', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'webdisk', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'webmail', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'webserver', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    ['type' => 'A', 'name' => 'whm', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    // AAAA Records
    ['type' => 'AAAA', 'name' => '@', 'content' => '2a02:4780:c:5d::1', 'proxiable' => true, 'proxied' => true, 'ttl' => 1],

    // CNAME Records
    ['type' => 'CNAME', 'name' => 'www', 'content' => '@', 'ttl' => 1],

    // MX RECORDS AND TXT RECORDS

    ['type' => 'MX', 'name' => $domain, 'content' => 'mail.' . $domain, 'ttl' => 1, 'priority' => 5],
    
    ['type' => 'TXT', 'name' => '_dmarc.'  $domain, 'content' => '"v=DMARC1; p=none; rua=mailto:dmarc-reports@'  $domain . '"', 'ttl' => 1],
    ['type' => 'TXT', 'name' => '@', 'content' => '"v=spf1 +mx +a +ip4:62.72.33.133 ~all"', 'ttl' => 1],
    
    ['type' => 'TXT', 'name' => 'default._domainkey', 'content' => '"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuCL8Y2QwKwmp2Gv2qgON4ZoWY6iedl1apZ1yfs2JQAfB9UIJ7SsMDgHpc/9kfAmF7jen5RXpbGSSX+EfihG2qlRoypRjUM9t4tmteRTx4Bidy2ssQn3uUW57k7TwT+XGXvJC3ndU9x88KvZgMJCqNy1sJoBIkXD83kCZITwfUJhxhL30mMKW+NsgYKgX2e" "4jCYUPAZpPrAol2h4qNtCFNiNsjXb3uGIGMckTdZrBitHjZJDnFtZijDJNkoAiq2a/8Sy1HPEQgnkUy5MXp6pOZe0/RYVCordvjU9jDe/44JNmQL426qF+3wzWdUOiz5IY30i+1IUHBW3NFna9qYInQIDAQAB;"', 'ttl' => 1]


];

This is the rest of my code

<?php

require_once __DIR__ . '/vendor/autoload.php';

use PreviewTechs\cPanelWHM\WHM\Accounts;
use PreviewTechs\cPanelWHM\WHMClient;
use PreviewTechs\cPanelWHM\Entity\Account;
use Cloudflare\API\Auth\APIKey;
use Cloudflare\API\Adapter\Guzzle;
use Cloudflare\API\Endpoints\DNS;
use Cloudflare\API\Endpoints\Zones;


// Hook into Elementor form submission
add_action('elementor_pro/forms/new_record', function ($record, $ajax_handler) {
    // Ensure this is the correct form
    $form_name = $record->get_form_settings('form_name');
    if ('REGISTER' !== $form_name) {
        return; // Replace with your actual form name
    }

    // Get submitted data
    $raw_fields = $record->get('fields');
    $fields = [];
    foreach ($raw_fields as $id => $field) {
        $fields[$id] = $field['value'];
    }

    // Call the function to handle WHM account creation
    handle_whm_account_creation($fields);
}, 10, 2);

// Function to handle WHM account creation
function handle_whm_account_creation($fields) {
    // Debugging: Log received fields
    error_log('Received fields: ' . print_r($fields, true));

    // Extract necessary fields
    $domain = sanitize_text_field($fields['domene'] ?? '');
    $username = sanitize_text_field($fields['brukernavn'] ?? '');
    $password = sanitize_text_field($fields['passord'] ?? '');
    $plan = 'User'; // Replace with the actual plan name

    // Debugging: Log extracted values
    error_log("Domain: $domain, Username: $username, Password: $password");

    // Create an Account object
    $account = new Account();
    $account->setUser($username);
    $account->setDomain($domain);
    $account->setPassword($password);
    $account->setPlanName($plan);

    // WHM Credentials
    $whmUsername = "root";
    $apiToken = WHM_API_TOKEN;
    $whmServer = "webserver.driftbedrift.no";

    // Initialize WHM Client
    $whmClient = new WHMClient($whmUsername, $apiToken, $whmServer, 2087);
    $accounts = new Accounts($whmClient);

    // Additional options, if any
    $options = [];

    // Create account using the library
    try {
        $createAccountResponse = $accounts->create($account, $options);
        error_log('WHM account created successfully: ' . print_r($createAccountResponse, true));

        // After WHM account creation, update DNS records in Cloudflare
        update_dns_records_cloudflare($domain);
    } catch (Exception $e) {
        error_log('Error creating WHM account: ' . $e->getMessage());
    }
}

function update_dns_records_cloudflare($domain) {
    // Cloudflare credentials
    $cloudflareEmail = CLOUDFLARE_EMAIL;
    $cloudflareApiKey = CLOUDFLARE_API_TOKEN;

    // Initialize Cloudflare API
    $key = new APIKey($cloudflareEmail, $cloudflareApiKey);
    $adapter = new Guzzle($key);
    $zones = new Zones($adapter);

    // Create DNS zone
    try {
        $zoneCreationResponse = $zones->addZone($domain);
        
        // Log the entire response for debugging
        error_log('Cloudflare DNS zone creation response: ' . print_r($zoneCreationResponse, true));
        // Assuming the zone creation response has a 'result' array
        if (isset($zoneCreationResponse->id)) {
            $cloudflareZoneID = $zoneCreationResponse->id;
            error_log('Cloudflare Zone ID: ' . $cloudflareZoneID);
            // Proceed with DNS record updates using the retrieved zone ID
            update_dns_zone_records($adapter, $cloudflareZoneID, $domain);
        } else {
            throw new Exception('Failed to retrieve Cloudflare zone ID');
        }
    } catch (Exception $e) {
        error_log('Error in Cloudflare zone creation or DNS update: ' . $e->getMessage());
    }
}



// Function to update DNS zone records
function update_dns_zone_records($adapter, $cloudflareZoneID, $domain) {
    if ($cloudflareZoneID === null) {
        error_log('Cloudflare zone ID is null.');
        return;
    }
    $dns = new DNS($adapter);

    // Define the DNS records to create
$records = [
    // A Records
    ['type' => 'A', 'name' => 'cpanel', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'cpcalendars', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'cpcontacts', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => '@', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => true, 'ttl' => 1],
    ['type' => 'A', 'name' => 'ftp', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'mail', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'webdisk', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'webmail', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'webserver', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],
    ['type' => 'A', 'name' => 'whm', 'content' => '62.72.33.133', 'proxiable' => true, 'proxied' => false, 'ttl' => 1],

    // AAAA Records
    ['type' => 'AAAA', 'name' => '@', 'content' => '2a02:4780:c:5d::1', 'proxiable' => true, 'proxied' => true, 'ttl' => 1],

    // CNAME Records
    ['type' => 'CNAME', 'name' => 'www', 'content' => '@', 'ttl' => 1],
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // ADD MX RECORDS AND TXT RECORDS
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ['type' => 'MX', 'name' => $domain, 'content' => 'mail.' . $domain, 'ttl' => 1, 'priority' => 5],
    
    ['type' => 'TXT', 'name' => '_dmarc.'  $domain, 'content' => '"v=DMARC1; p=none; rua=mailto:dmarc-reports@'  $domain . '"', 'ttl' => 1],
    ['type' => 'TXT', 'name' => '@', 'content' => '"v=spf1 +mx +a +ip4:62.72.33.133 ~all"', 'ttl' => 1],
    
    ['type' => 'TXT', 'name' => 'default._domainkey', 'content' => '"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuCL8Y2QwKwmp2Gv2qgON4ZoWY6iedl1apZ1yfs2JQAfB9UIJ7SsMDgHpc/9kfAmF7jen5RXpbGSSX+EfihG2qlRoypRjUM9t4tmteRTx4Bidy2ssQn3uUW57k7TwT+XGXvJC3ndU9x88KvZgMJCqNy1sJoBIkXD83kCZITwfUJhxhL30mMKW+NsgYKgX2e" "4jCYUPAZpPrAol2h4qNtCFNiNsjXb3uGIGMckTdZrBitHjZJDnFtZijDJNkoAiq2a/8Sy1HPEQgnkUy5MXp6pOZe0/RYVCordvjU9jDe/44JNmQL426qF+3wzWdUOiz5IY30i+1IUHBW3NFna9qYInQIDAQAB;"', 'ttl' => 1]


];

    
    
    


    // Create each DNS record
    foreach ($records as $record) {
        try {
            $dns->addRecord($cloudflareZoneID, $record['type'], $record['name'], $record['content'], $record['ttl']);
            error_log("Cloudflare DNS record created: Type {$record['type']}, Name {$record['name']}");
        } catch (Exception $e) {
            error_log("Error creating Cloudflare DNS record: " . $e->getMessage());
        }
    }
}

Wonder if there might be something deprecated for cPanel, but cannot tell for sure. I’d have to dug for that information a bit more and get back to you.

Hopefully, the Cloudflare API didn’t change in the meantime, which would result in some error you’d get while trying to execute the request :thinking:

WordPress right? What kind of an error message you get?

Do you have to use the … hm, just wondering if you could temporary just modify it in a bit different way, therefrom for testing purpose, execute and add a single TXT record via Elementor form submission via the PHP cURL for the zone, without using the PHP library for the Cloudflare v4 API? :thinking:

EDIT: Aha, you’re using PHP / guzzle … Are you actually trying to add a new (non-existing TXT and/or MX), or rather update the existing ones? :thinking:

And your API token permissions are correct?

Just what come to my mind, since using cPanel/WHM, you might be able to load a BIND file from it and directly import the DNS? Just wondering …

The script is meant to create a cpanel account, create a DNS zone in Cloudflare, and then update the DNS records for this zone to the prespecified list of records.

There seems not to be an issue with the apis, they are working perfectly up until i pass MX and TXT records into it

My whm/cpanel api is operating quite independently from my cloudflare API. I am collecting information from an elementor form where a visitor sends in information regarding their domain, and set a username and password for their cpanel account. The domain is used to create a new DNS Zone on my Cloudflare account. After the zone is created, the script fetches the zone id, and passes a set of DNS records to the zone, so that this is correctly pointed to my server.

I am able to update the A-recrods, AAAA-records and CNAME-records (they have been created and i can see them in my cloudflare dashboard for the zone); however, the script gets stuck on the MX and TXT records (these are not being created + they produce an error when passing them trough the API). It could be the case that there is a syntactical error in my code, and that the ‘@’ Cloudflare uses to identify the domain is messing up something when passed with strings (Usure of this though).

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.