Success returned and Subscriber.AddWithCustomFields

Hello,

I'm just beginning to work with the API and am using the PHP sample code provided.

my Subscriber.Add call worked no problem.  New subscriber showed up in the reports and tested true using Subscriber.GetIsSubscribed.

However my list has several custom fields and I need to populate some values so I tried to use Subscriber.AddWithCustomFields like so using the sample code, API key and list id etc.  Same as Add.

$now = date("Ymdhis");
$result = $cm->subscriberAddWithCustomFields(
         'ecard@nolaflash.com', 'Ecard Martin', 
          array('syncedtomachforms' => "$now"));

Script echos success but subscriber is not present in reports or via API tests.

Code reporting success is that same code provided in sample scripts.

if($result['Code'] == 0)
        echo 'Success';

So I added the debug code to both my Add and AddWithCustomFields scripts and I still can't see where the return value signifies an actual successful add.

Doing a print_r on $result yielded "".  So I checked that my FTP is putting in ascii mode and it is.  Tried echoing $result['Code'] and $result['Message'] but they appear to be empty.

So I have two questions: One is whether you can see any error my call to subscriberAddWithCustomFields?

And second, why does the demo code use $result['Code']  in thi sway if success just mean no errors?  I need to know if I actually added someone and it seems it should not report success if I have not added a subscriber.

In case anyone is interested I'll post the entirety of my debug output below my signature.

Any advice most welcome.

TIA!

David

Success

CampaignMonitor Object
(
    [url]=> http://api.createsend.com/api/api.asmx
    [soapAction] => http://api.createsend.com/api/
    [api] => myapikeyishere
    [campaign_id] => 
    [client_id] => 
    [list_id] => mylistidishere
    [method] => soap
    [curl] => 1
    [curlExists] => 1
    [debug_level] => 1
    [debug_request] => <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <Subscriber.AddWithCustomFields xmlns="http://api.createsend.com/api/">
        <ApiKey>myapikeyishere</ApiKey>
        <ListID>mylistidishere<ListID>
        <Email>ecard@nolaflash.com<Email>
        <Name>Ecard Martin<Name>

        <CustomFields>
            <SubscriberCustomField>
                <Key>syncedtomachforms<Key>
                <Value>20090722062709<Value>
            <SubscriberCustomField>
        <CustomFields>
    </Subscriber.AddWithCustomFields>
</soap:Body>

</soap:Envelope>
    [debug_response] => 
    [debug_url] => http://api.createsend.com/api/api.asmx
    [debug_info] => Array
        (
            [url]=> http://api.createsend.com/api/api.asmx
            [http_code] => 400
            [header_size] => 248
            [request_size] => 937
            [filetime] => -1
            [ssl_verify_result] => 0
            [redirect_count] => 0
            [total_time] => 0.15434
            [namelookup_time] => 0.001598
            [connect_time] => 0.078224
            [pretransfer_time] => 0.078339
            [size_upload] => 0
            [size_download] => 0
            [speed_download] => 0
            [speed_upload] => 0
            [download_content_length] => 0
            [upload_content_length] => 0
            [starttransfer_time] => 0.154213
            [redirect_time] => 0
            [headers_sent] => Array
                (
                    [0] => User-Agent: CMBase URL Handler 1.5
                    [1] => Content-Type: text/xml; charset=utf-8
                    [2] => SOAPAction: "http://api.createsend.com/api/Subscriber.AddWithCustomFields"
                )

        )

    [show_response_headers] => 0
)
jerrygarciuh, 7 years ago

I'm guessing that the server returning an HTTP Error 400 - Bad request probably has something to do with this problem.

In case it helps I am posting the entire demo code with just my key and list id removed.

Note that I replaced my timestamp with the number 1111 just in case there was an issue with a 16 digit number in the storage but it did not change the outcome.

<?php
    //Sample using the CMBase.php wrapper to call Subscriber.AddWithCustomFields from any version of PHP
    
    //Relative path to CMBase.php. This example assumes the file is in the same folder
    require_once('CMBase.php');
    
    //Your API Key. Go to http://www.campaignmonitor.com/api/required/ to see where to find this and other required keys
    
    $api_key = 'xxxx';
    $client_id = null;
    $campaign_id = null;
    $list_id = 'xxxx';        // web join form
    $cm = new CampaignMonitor( $api_key, $client_id, $campaign_id, $list_id );
    
    //Optional statement to include debugging information in the result
    $cm->debug_level = 1;
    
    //This is the actual call to the method, passing email address, name and custom fields. Custom fields should be added as an array as shown here with the Interests and Dog fields.
    //Multi-option field values are added as an array within this, as demonstrated for the Interests field.
    $now = date("Ymdhis");
    $result = $cm->subscriberAddWithCustomFields('designs@mydomain.com', 'Designs Martin', array('syncedtomachforms' => '1111'));

    
    if($result['Code'] == 0)
        echo 'Success';
    else
        echo 'Error : ' . $result['Message'];
    
    //Print out the debugging info
    print_r($cm);
?>
jerrygarciuh, 7 years ago

So I solved this.  The code CM is distributing would never have succeeded as the XML generated by the array2xml() function lacked the slash in the closing tags for all the fields it generated.

How did the author ever test this and not know???

OK, in cmBase.php you will want to replace lines 821 - 853, the array2xml() function.

All I did was add the trailing slashes.

I cannot believe this was being distributed as if it worked.  It could never have worked as it was.  It must have been untested.


function array2xml( $arr, $indent = '', $escape = true )
{
    $buff = '';
   
    foreach ( $arr as $k => $v )
    {
        if ( !is_array( $v ) )
            $buff .= "$indent<$k>" . ($escape ? utf8_encode( $v ) : $v ) . '</' . "$k>\n";
        else
        {
            /*
            Encountered a list. The primary difference between the two branches is that
            in the 'if' branch, a $k element is generated for each item in $v, whereas
            in the 'else' branch, a single $k element encapsulates $v.
            */
           
            if ( isset( $v[0] ) )
            {
                foreach ( $v as $_k => $_v )
                {
                    if ( is_array( $_v ) )
                         $buff .= "$indent<$k>\n" . array2xml( $_v, $indent . "\t", $escape ) . "$indent" . '</' . "$k>\n";
                    else
                        $buff .= "$indent<$k>" . ($escape ? utf8_encode( $_v ) : $_v ) . '</' . "$k>\n";
                }
            }
            else
                $buff .= "$indent<$k>\n" . array2xml( $v, $indent . "\t", $escape ) . "$indent" . '</' . "$k>\n";
        }
    }
   
    return $buff;
}

jamesd jamesd, 7 years ago

Hi,

I have run your code above against the PHP wrapper available from http://code.google.com/p/campaignmonitor-php/ and have been unable to reproduce the output you claim you receive above.

It appears that the only difference between the version of the array2xml() function you have provided above and the latest version in the PHP API wrapper is that your version does not utilise variable parsing in double quoted strings (http://au.php.net/manual/en/language.types.string.php#language.types.string.parsing). If that is not the case, please let us know.

This is the first instance in which someone has claimed that this aspect of the PHP API wrapper does not work as expected and I am still not able to reproduce the problem. If anyone else is able to reproduce this problem, please reply here and let us know. In the meantime, it would be helpful to know which version of the API wrapper you are using and which version of PHP you are running.

Here is the output from running your code against another list with another custom field when I use the latest version of the PHP wrapper from http://code.google.com/p/campaignmonitor-php/

SuccessCampaignMonitor Object
(
    [url]=> http://api.createsend.com/api/api.asmx
    [soapAction] => http://api.createsend.com/api/
    [api] => key
    [campaign_id] => 
    [client_id] => 
    [list_id] => xyz
    [method] => soap
    [curl] => 1
    [curlExists] => 1
    [debug_level] => 1
    [debug_request] => <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <Subscriber.AddWithCustomFields xmlns="http://api.createsend.com/api/">
        <ApiKey>key</ApiKey>
        <ListID>xyz</ListID>
        <Email>email@example.com</Email>
        <Name>Example</Name>
        <CustomFields>
            <SubscriberCustomField>
                <Key>customtest</Key>
                <Value>blah blah</Value>
            </SubscriberCustomField>
        </CustomFields>
    </Subscriber.AddWithCustomFields>
</soap:Body>
</soap:Envelope>
    [debug_response] => <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><Subscriber.AddWithCustomFieldsResponse xmlns="http://api.createsend.com/api/"><Subscriber.AddWithCustomFieldsResult><Code>0</Code><Message>Success</Message></Subscriber.AddWithCustomFieldsResult></Subscriber.AddWithCustomFieldsResponse></soap:Body></soap:Envelope>
    [debug_url] => http://api.createsend.com/api/api.asmx
    [debug_info] => Array
        (
            [url]=> http://api.createsend.com/api/api.asmx
            [content_type] => text/xml; charset=utf-8
            [http_code] => 200
            [header_size] => 291
            [request_size] => 932
            [filetime] => -1
            [ssl_verify_result] => 0
            [redirect_count] => 0
            [total_time] => 0.717
            [namelookup_time] => 0.187
            [connect_time] => 0.202
            [pretransfer_time] => 0.202
            [size_upload] => 690
            [size_download] => 483
            [speed_download] => 673
            [speed_upload] => 962
            [download_content_length] => 483
            [upload_content_length] => -1
            [starttransfer_time] => 0.717
            [redirect_time] => 0
            [headers_sent] => Array
                (
                    [0] => User-Agent: CMBase URL Handler 1.5
                    [1] => Content-Type: text/xml; charset=utf-8
                    [2] => SOAPAction: "http://api.createsend.com/api/Subscriber.AddWithCustomFields"
                )

        )

    [show_response_headers] => 0
)
jerrygarciuh, 7 years ago

Hi James,

If you look at line 907 of the current cmBase.php available at the url you supplied you will see

$buff .= "$indent<$k>\n" . array2xml( $_v, $indent . "\t", $escape ) . "$indent<$k>\n";

Lines 909 and 913 are similar.

They all contain the flaw that the closing tag <$k>  should have a slash like so </$k>

The 400 returned by the server is due to cmBase.php sending malformed XML and this problem is fixed by my code.

There are no variables enclosed in my single quotes.  There is nothing requiring interpolation in my single quotes.

And I would like to add that immediately after you replied to my post you replied to another more recent post on the same topic.

David Martin

jamesd jamesd, 7 years ago

Hi again,

This is strange because when I look at line 907 of CMBase.php  I see:

$buff .= "$indent<$k>\n" . array2xml( $_v, $indent . "\t", $escape ) . "$indent</$k>\n";

I don't know whether you're looking at the right version? Just look at the latest from trunk.

Aidy, 7 years ago

Hi

I just downloaded the latest version of the code 1.4.3 from http://code.google.com/p/campaignmonitor-php/ and had the same problem! Think the code there needs fixing.

ballvicki, 6 years ago

Hello - I am VERY new at this so it is quite possible I am making a mistake somewhere, but I am getting a success response and yet nothing gets entered onto my list. The $cm is spitting out:

Success
campaignmonitor Object ( [api] => xxxxxxxxxxxxxx [campaign_id] => [client_id] => [list_id] => xxxxxxxxxxxx [method] => soap [url]=> http://api.createsend.com/api/api.asmx [soapAction] => http://api.createsend.com/api/ [curl] => 1 [curlExists] => 1 [debug_level] => 1 [debug_request] =>   xxxxxxxxxxxxxxxxx xxxxx  xxxxx      [debug_response] => [debug_url] => http://api.createsend.com/api/api.asmx [debug_info] => Array ( [url]=> http://api.createsend.com/api/api.asmx [http_code] => 400 [header_size] => 248 [request_size] => 1022 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.254865 [namelookup_time] => 0.022193 [connect_time] => 0.136835 [pretransfer_time] => 0.136923 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => 0 [upload_content_length] => 0 [starttransfer_time] => 0.254781 [redirect_time] => 0 [headers_sent] => Array ( [0] => User-Agent: CMBase URL Handler 1.5 [1] => Content-Type: text/xml; charset=utf-8 [2] => SOAPAction: "http://api.createsend.com/api/Subscriber.AddWithCustomFields" ) ) [show_response_headers] => 0 )

My code is:

$api_key = 'xxxxxxxxxx';
        $client_id = null;
        $campaign_id = null;
        $list_id = 'xxxxxxxxxxxxxxxxx';
        $cm = new CampaignMonitor( $api_key, $client_id, $campaign_id, $list_id );
       
        //Optional statement to include debugging information in the result
        //$cm->debug_level = 1;
       
        //This is the actual call to the method, passing email address, name and custom fields. Custom fields should be added as an array as shown here with the Interests and Dog fields.
        //Multi-option field values are added as an array within this, as demonstrated for the Interests field.
       
       
        $custom['Company'][]= "$company";
        $custom['Type']= "$deltype";

        $result = $cm->subscriberAddWithCustomFields($email, $name, $custom);
   
       
        if($result['Code'] == 0)
        echo 'Success';
    else
        echo 'Error : ' . $result['Message'];
   
    //Print out the debugging info
    print_r($cm);
   

I have tried every which way / format to no avail so any advice would be greatly apreciated - the straightforward subscriberAdd works hunky dorey

Ta muchly

Vicki

ballvicki, 6 years ago

Ok I think I have fixed it too - phew!!! I changed the end <$k>\n"; to </$k>\n"; as mentioned by jerrygarciuh

I had some variables with mine so I paste my code in the hope it will help someone else as ignorant as me!!!


$company="xxxxx";
$deltype="xxxxx";
$tel="xxxxx";

$api_key = 'xxxxxxxxxxxxxx';
$client_id = null;
$campaign_id = null;
$list_id = 'xxxxxxxxxxxxxxxxx';
$cm = new CampaignMonitor( $api_key, $client_id, $campaign_id, $list_id );
           
$cm->subscriberAddWithCustomFields($email, $name, array('Company' => $company,'Type' => $deltype,'Tel' =>$tel));

Aidy, 6 years ago

Just bump this again because I think CM are meant to be in control of the php library. 

Maybe they could fix this?..

Ken Ken, 6 years ago

Hi Guys,

This is totally weird. I downloaded the latest version (campaignmonitor-php-1.4.3.zip) and couldn't find any lines where the end of the line was <$k>\n"; and needed to be changed to </$k>\n";.

Could you tell us which line number(s) the problem was? Ideally, could you go to http://code.google.com/p/campaignmonitor-php/source/browse/trunk/CMBase.php, find the line number, and post the link the line number is on? (ie. copy the link location of the link of the line number on the left hand side)

Thanks!


http://www.campaignmonitor.com
ballvicki, 6 years ago

Sorry Ken - only just seen this - will look up later today!

erikdeleon, 6 years ago

I have the same problem with this.

I'm using Subscriber.AddAndResubscribeWithCustomFields using the PHP wrapper. It's returning Success but when I look at my subscriber, the custom fields (which had information before) are now EMPTY!

I tried jerrygarciuh's method but it doesn't seem to be working.

ballvicki, did you get this working??? It's not so much that it doesn't work, but it emptied my subscriber's custom fields, which is scaring me...

erikdeleon, 6 years ago

Ok, this is very weird.

This wasn't working last night (2010-01-16) and I made sure that everything was verified before I went to bed. I think you guys had a maintenance window around 8 or 9 PM EST. API functions were running slow after that until I went to bed.

Now, when I tried my script again, IT WORKS! I have no clue what happened.

With relation to jerrygarciuh's findings, essentially he's referring to lines 497, 511, 513 and 517 in CMBase.php of version 1.4.3 of the PHP library. He's referring to the 2nd instances of <$k> on those lines and asking shouldn't they not be closing XML tags (i.e. </$k> versus <$k>). I think he's right and this should be fixed.

jamesd jamesd, 6 years ago
erikdeleon :

With relation to jerrygarciuh's findings, essentially he's referring to lines 497, 511, 513 and 517 in CMBase.php of version 1.4.3 of the PHP library. He's referring to the 2nd instances of <$k> on those lines and asking shouldn't they not be closing XML tags (i.e. </$k> versus <$k>). I think he's right and this should be fixed.

I have said this before, but I'll link to the files directly in the repository again:

http://code.google.com/p/campaignmonitor-php/source/browse/trunk/CMBase.php?r=23#497
http://code.google.com/p/campaignmonitor-php/source/browse/trunk/CMBase.php?r=23#511
http://code.google.com/p/campaignmonitor-php/source/browse/trunk/CMBase.php?r=23#513
http://code.google.com/p/campaignmonitor-php/source/browse/trunk/CMBase.php?r=23#517

I do not see any evidence for the lack of a closing slash being added in the lines cited above. The source files in the zip are also consistent with the file linked above.

The only possibilities I can think of which may be causing this alleged problem:
1. There has been an unofficial version of the code distributed somewhere, which doesn't close the xml elements correctly
2. When the code is downloaded and opened with (or copied into) a particular editor, for some reason it is being manipulated such that xml elements are not being closed correctly

Obviously both these possibilities are pretty unlikely, but that's all I can think of at the moment.

erikdeleon, 6 years ago

That is very weird indeed. In the link that you provided, the closing tags look fine.

However, in the code that I downloaded (directly linked from Campaign Monitor's Support section), the tags were not closed and I had to add them myself.

Very weird!

jamesd jamesd, 6 years ago

In an attempt to solve this, could you provide a link to the exact file that you originally used to download the PHP API wrapper?

erikdeleon, 6 years ago

Hi jamesd, I just re-downloaded it from here:

http://code.google.com/p/campaignmonitor-php/

On the right-hand column, I clicked the link (see screenshot: http://dl.dropbox.com/u/104155/cm.png)

It downloads a zip. I opened CMBase.php and it still has the error (lines 497, 511, 513 and 517).

jamesd jamesd, 6 years ago

Hi, I've just done exactly what you've done on both Mac OS X and Win7 and in both situations I see the correctly formed file.

Can you check that the CMBase.php file you download is 56558 bytes once extracted, opened and saved in the editor you are using?

If CMBase.php is not 56558 bytes (which it shouldn't be if it's missing certain characters), then your editor may be doing something strange to the file when it is opening it.

erikdeleon, 6 years ago

Hi jamesd, it's 56558... BUT!

When I open it in Dreamweaver, it seems to remove the / :
http://dl.dropbox.com/u/104155/cm-dw.png

If I open it in TextWrangler, however, it looks fine!
http://dl.dropbox.com/u/104155/cm-textwrangler.png

That is some weird #@$#$.

jamesd jamesd, 6 years ago

So, the problem is obviously with Dreamweaver, not the PHP code. I'd be interested to know whether the other guys experiencing this problem were also using Dreamweaver to edit the CMBase.php file.

I've never used Dreamweaver, will certainly never ever be using it in the future and would highly recommend against using it based on this bug which has been found.

erikdeleon, 6 years ago

Yup, the codebase seems to be correct and Dreamweaver seems to be the problem. I've been using Dreamweaver's code editor for awhile now and have never faced this problem. I think it might be important to report this to Adobe.

Thanks for your help in verifying this, jamesd. I'm also curious to see whether everyone else that were having problems were using Dreamweaver.

jamesd jamesd, 6 years ago

I've submitted a bug with Adobe using the form here: https://www.adobe.com/cfusion/mmform/index.cfm?name=wishform

jamesd jamesd, 6 years ago

And I've also committed a change to the PHP wrapper to avoid this issue occurring again for those people using Dreamweaver.

erikdeleon, 6 years ago

I see what you've done, jamesd, and it works perfectly in Dreamweaver. I just tested it by opening the latest release of CMBase.php and it didn't auto-correct it.

Join 200,000 companies around the world that use Campaign Monitor to run email marketing campaigns that deliver results for their business.

Get started for free
1-888-533-8098