Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
35 posts Page 3 of 4
Yes, the original intention was to have the sign-up forms take you to a dedicated newsletter template in both error and success cases. Nevertheless, there isn't anything that prevents us from processing the sign-up attempt on the submitting page. If you simply abstract all of the cms:form code into a snippet and embed that wherever you need a sign-up form, there will be no redirection performed. Also, don't forget to add the PHP statement for MailChimp.php wherever it may be utilized.
I keep getting the same error and not sure where I am going wrong.

Code: Select all
Fatal error: Class 'Drewm\MailChimp' not found in /var/www/vhosts/XXX.com/httpdocs/cms/tags.php(2823) : eval()'d code on line 2


newsletter.php file:

Code: Select all
<?php require_once( 'cms/cms.php' ); ?>
<?php require_once( 'MailChimp.php' ); ?>

<cms:template title='Newsletter'>
    <cms:editable label='MailChimp API Key' name='mc_api_key' required='1' type='text'/>
    <cms:editable label='MailChimp List ID' name='mc_list_id' required='1' type='text'/>
</cms:template>



<?php COUCH::invoke(); ?>


Newsletter snippet for embedding in footer:

Code: Select all
<?php require_once( 'MailChimp.php' ); ?>
<cms:form method='post' name="newsletter_form" id="newsletter_form" accept-charset="utf-8" anchor='1'>
    <cms:if k_success>
        <cms:php>
            $MailChimp = new \Drewm\MailChimp('<cms:show mc_api_key/>');

            $result = $MailChimp->call('lists/subscribe', array(
                'id'    => '<cms:show mc_list_id/>',
                'email' => array('email' => '<cms:show frm_email/>')
            ));

            if (isset($result['email'])) {
                echo "<div class=\"success\" id=\"message-news\">Please check your inbox for a confirmation email.</div>";
            } else if (isset($result['status']) &&
                       $result['status'] === 'error' &&
                       $result['name'] !== 'List_AlreadySubscribed') {
                echo "<div class=\"error\"><strong>" . $result['name'] . " (" . $result['code'] . "):</strong> " . $result['error'] . "</div>";
            } else {
                echo "<div class=\"error\">An unknown error was encountered. Please try again later or contact us.</div>";
            }
        </cms:php>
    <cms:else/>
        <cms:if k_error>
            <div class="error" id="error_news">Please enter a valid email address.</div>
        </cms:if>
      <cms:input type="text" name="news_name" id="news_name" placeholder="Your Name" />
        <cms:input name='email' placeholder='Email Address' required='1' type='text' validator='email'/>
        <input type="submit" value="Subscribe to Newsletter"  class="btn btn-default btn-rounded" >
    </cms:if>
</cms:form>
Hi,

I suggest you use an absolute path to the mailchimp file using K_COUCH_DIR or K_SITE_DIR
e.g. if the file is in your site's root, use this -
Code: Select all
<?php require_once( K_SITE_DIR.'MailChimp.php' ); ?>

if it is within a sub-folder named 'some-folder' in the site's root, use this -
Code: Select all
<?php require_once( K_SITE_DIR.'some-folder/MailChimp.php' ); ?>

if it is in 'couch' folder, use this -
Code: Select all
<?php require_once( K_COUCH_DIR.'MailChimp.php' ); ?>

Does this help?
Unfortunately it didn't. I have the MailChimp.php in the root so I tried the first one without luck. When I click on submit I still see this error:

Code: Select all
Fatal error: Class 'Drewm\MailChimp' not found in /var/www/vhosts/footsurgeon.com/httpdocs/cms/tags.php(2823) : eval()'d code on line 2


Also when I changed this line in the newsletter snippet from

Code: Select all
<cms:php>
            $MailChimp = new \Drewm\MailChimp('<cms:show mc_api_key/>');


Code: Select all
<cms:php>
            $MailChimp = new /Drewm/MailChimp('<cms:show mc_api_key/>');


The form didn't redirect and displayed the same error on the page.
Backslash ("\") is correct for namespaces.

I doubt that <cms:show mc_api_key/> and <cms:show mc_list_id/> are actually outputting anything in your case as there is no indication that these values are being retrieved from the correct template. Use <cms:get_custom_field 'mc_api_key' masterpage='newsletter.php'/> and <cms:get_custom_field 'mc_list_id' masterpage='newsletter.php'/> instead.

PHP such as <?php require_once( 'MailChimp.php' ); ?> cannot be directly used in snippets. Furthermore, it doesn't look like it is needed in newsletter.php either as no newsletter form points to that template. It would probably be easiest to just place require_once( K_SITE_DIR . 'MailChimp.php' ); in your cms/addons/kfunctions.php file since the form always points to the very page where it is present.
Worked perfectly! Thanks cheesypoof
It seems the above error
Code: Select all
Fatal error: Class 'Drewm\MailChimp' not found in /cms/tags.php(2866) : eval()'d code on line 2

is occuring on my most recent installation of this integration. Here is a copy of newsletter.php:

Code: Select all
<?php require_once( 'admin/cms.php' ); ?>
<?php require_once( 'MailChimp.php' ); ?>

<cms:template title='Newsletter' order='23'>
    <cms:editable label='MailChimp API Key' name='mc_api_key' required='1' type='text'/>
    <cms:editable label='MailChimp List ID' name='mc_list_id' required='1' type='text'/>
</cms:template>

<cms:form method='post' name='subscribe'>
    <cms:if k_success>
<cms:check_spam email=frm_email />
        <cms:php>
            $MailChimp = new \Drewm\MailChimp('<cms:show mc_api_key/>');

            $result = $MailChimp->call('lists/subscribe', array(
                'id'    => '<cms:show mc_list_id/>',
                'email' => array('email' => '<cms:show frm_email/>')
            ));

            if (isset($result['email'])) {
                echo "<div class=\"success\">Please check your inbox for a confirmation email.</div>";
            } else if (isset($result['status']) &&
                       $result['status'] === 'error' &&
                       $result['name'] !== 'List_AlreadySubscribed') {
                echo "<div class=\"error\"><strong>" . $result['name'] . " (" . $result['code'] . "):</strong> " . $result['error'] . "</div>";
            } else {
                echo "<div class=\"error\">An unknown error was encountered. Please try again later or contact us.</div>";
            }
        </cms:php>
    <cms:else/>
        <cms:if k_error>
            <div class="notice">Please enter a valid email address.</div>
        </cms:if>

        <cms:input name='email' placeholder='Email Address' required='1' type='text' validator='email'/>
        <input type="submit" value="Subscribe to Newsletter">
    </cms:if>
</cms:form>

<?php COUCH::invoke(); ?>


The api key and ID have both been correctly inserted in the admin panel, though the error seems to rather indicate that it isn't finding the MailChimp.php file at all (The file is in the sites root).
I have also tried including the file with
Code: Select all
<?php require_once( K_SITE_DIR.'MailChimp.php' ); ?>


Any ideas what the problem is or how to fix?
Image
the error seems to rather indicate that it isn't finding the MailChimp.php file at all
Not quite true. Had that been the case, <?php require_once( 'MailChimp.php' ); ?> would have balked first.

The error suggests that PHP is unable to find the *class* named 'Drewm\MailChimp' at the following line -
$MailChimp = new \Drewm\MailChimp('<cms:show mc_api_key/>');

Please check MailChimp.php file to see how this class is indeed name-spaced with 'Drewm'.
Indeed it is:

Code: Select all
<?php
namespace DrewM\MailChimp;
/**
* Super-simple, minimum abstraction MailChimp API v3 wrapper
* MailChimp API v3: http://developer.mailchimp.com
* This wrapper: https://github.com/drewm/mailchimp-api
*
* @author Drew McLellan <drew.mclellan@gmail.com>
* @version 2.0.8
*/
class MailChimp
{
    private $api_key;
    private $api_endpoint  = 'https://<dc>.api.mailchimp.com/3.0';
   
    /*  SSL Verification
        Read before disabling:
        http://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/
    */
    public  $verify_ssl    = true;
    private $last_error    = '';
    private $last_response = array();
    /**
     * Create a new instance
     * @param string $api_key Your MailChimp API key
     */
    public function __construct($api_key)
    {
        $this->api_key = $api_key;
        list(, $datacentre)  = explode('-', $this->api_key);
        $this->api_endpoint  = str_replace('<dc>', $datacentre, $this->api_endpoint);
        $this->last_response = array('headers'=>null, 'body'=>null);
    }
    /**
     * Convert an email address into a 'subscriber hash' for identifying the subscriber in a method URL
     * @param   string  $email  The subscriber's email address
     * @return  string          Hashed version of the input
     */
    public function subscriberHash($email)
    {
        return md5(strtolower($email));
    }
    /**
     * Get the last error returned by either the network transport, or by the API.
     * If something didn't work, this should contain the string describing the problem.
     * @return  array|false  describing the error
     */
    public function getLastError()
    {
        if ($this->last_error) return $this->last_error;
        return false;
    }
    /**
     * Get an array containing the HTTP headers and the body of the API response.
     * @return array  Assoc array with keys 'headers' and 'body'
     */
    public function getLastResponse()
    {
        return $this->last_response;
    }
   
    /**
     * Make an HTTP DELETE request - for deleting data
     * @param   string        URL of the API request method
     * @param   array         Assoc array of arguments (if any)
     * @param   int           Timeout limit for request in seconds
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function delete($method, $args=array(), $timeout=10)
    {
        return $this->makeRequest('delete', $method, $args, $timeout);
    }
    /**
     * Make an HTTP GET request - for retrieving data
     * @param   string        URL of the API request method
     * @param   array         Assoc array of arguments (usually your data)
     * @param   int           Timeout limit for request in seconds
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function get($method, $args=array(), $timeout=10)
    {
        return $this->makeRequest('get', $method, $args, $timeout);
    }
    /**
     * Make an HTTP PATCH request - for performing partial updates
     * @param   string        URL of the API request method
     * @param   array         Assoc array of arguments (usually your data)
     * @param   int           Timeout limit for request in seconds
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function patch($method, $args=array(), $timeout=10)
    {
        return $this->makeRequest('patch', $method, $args, $timeout);
    }
    /**
     * Make an HTTP POST request - for creating and updating items
     * @param   string        URL of the API request method
     * @param   array         Assoc array of arguments (usually your data)
     * @param   int           Timeout limit for request in seconds
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function post($method, $args=array(), $timeout=10)
    {
        return $this->makeRequest('post', $method, $args, $timeout);
    }
    /**
     * Make an HTTP PUT request - for creating new items
     * @param   string        URL of the API request method
     * @param   array         Assoc array of arguments (usually your data)
     * @param   int           Timeout limit for request in seconds
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function put($method, $args=array(), $timeout=10)
    {
        return $this->makeRequest('put', $method, $args, $timeout);
    }
    /**
     * Performs the underlying HTTP request. Not very exciting
     * @param  string $http_verb   The HTTP verb to use: get, post, put, patch, delete
     * @param  string $method       The API method to be called
     * @param  array  $args         Assoc array of parameters to be passed
     * @return array|false          Assoc array of decoded result
     */
    private function makeRequest($http_verb, $method, $args=array(), $timeout=10)
    {
        if (!function_exists('curl_init') || !function_exists('curl_setopt')) {
            throw new \Exception("cURL support is required, but can't be found.");
        }
        $url = $this->api_endpoint.'/'.$method;
        $this->last_error    = '';
        $response            = array('headers'=>null, 'body'=>null);
        $this->last_response = $response;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/vnd.api+json',
                                                    'Content-Type: application/vnd.api+json',
                                                    'Authorization: apikey '.$this->api_key));
        curl_setopt($ch, CURLOPT_USERAGENT, 'DrewM/MailChimp-API/3.0 (github.com/drewm/mailchimp-api)');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ch, CURLOPT_ENCODING, '');
        switch($http_verb) {
            case 'post':
                curl_setopt($ch, CURLOPT_POST, true);
                $this->attachRequestPayload($ch, $args);
                break;
            case 'get':
                $query = http_build_query($args);
                curl_setopt($ch, CURLOPT_URL, $url.'?'.$query);
                break;
            case 'delete':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
            case 'patch':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
                $this->attachRequestPayload($ch, $args);
                break;
           
            case 'put':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
                $this->attachRequestPayload($ch, $args);
                break;
        }
        $response['body']    = curl_exec($ch);
        $response['headers'] = curl_getinfo($ch);
       
        if ($response['body'] === false) {
            $this->last_error = curl_error($ch);
        }
       
        curl_close($ch);
        return $this->formatResponse($response);
    }
    /**
     * Encode the data and attach it to the request
     * @param   resource    cURL session handle, used by reference
     * @param   array       Assoc array of data to attach
     */
    private function attachRequestPayload(&$ch, $data)
    {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    }
    private function formatResponse($response)
    {
        $this->last_response = $response;
        if (!empty($response['body'])) {
            $d = json_decode($response['body'], true);
           
            if (isset($d['status']) && $d['status']!='200' && isset($d['detail'])) {
                $this->last_error = sprintf('%d: %s', $d['status'], $d['detail']);
            }
           
            return $d;
        }
        return false;
    }
}
Image
The API script referenced in this case appears to have made some breaking changes. Could you try 'DrewM' instead of 'Drewm'?
35 posts Page 3 of 4
cron