PHPackages                             comicrelief/smartfocus - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. comicrelief/smartfocus

ActiveLibrary

comicrelief/smartfocus
======================

SmartFocus API

1.2.0(9y ago)02.8kMITPHPPHP &gt;=5.3.0

Since Oct 16Pushed 8y ago8 watchersCompare

[ Source](https://github.com/comicrelief/smartfocus)[ Packagist](https://packagist.org/packages/comicrelief/smartfocus)[ RSS](/packages/comicrelief-smartfocus/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependencies (1)Versions (10)Used By (0)

PHP SmartFocus API
==================

[](#php-smartfocus-api)

[![](https://camo.githubusercontent.com/c1c7a904d54bbf82f7d342d57bbb0a56d1885f2d6016301aabffe07f266189b4/68747470733a2f2f7261772e6769746875622e636f6d2f657374696e612f736d617274666f6375732f6d61737465722f73665f6c6f676f2e706e67)](https://camo.githubusercontent.com/c1c7a904d54bbf82f7d342d57bbb0a56d1885f2d6016301aabffe07f266189b4/68747470733a2f2f7261772e6769746875622e636f6d2f657374696e612f736d617274666f6375732f6d61737465722f73665f6c6f676f2e706e67)

This is a PHP library for SmartFocus API.

This library provides access to SmartFocus (previously known as EmailVision) [Campaign Commander's APIs](https://help-developer.smartfocus.com/#Home.htm%3FTocPath%3D_____1). It was designed with flexibility in mind, with fully decoupled components, so it would be easy for developer to inject and use his own components where appropriate.

Requirements
------------

[](#requirements)

- PHP 5.3+
- curl
- libxml

Install
-------

[](#install)

```
composer require estina/smartfocus

```

### Usage

[](#usage)

Interacting with API can be trimmed down to these basic steps:

- open the connection and extract security token from the XML response
- call the API method(s) using token and other required parameters
- close the connection

Please, check the \[examples\] (#api-examples) below.

HTTP transport to the actual REST interface is implemented in Api\\Http\\CurlClient class. It's possible to use different class object as long as it implements a very simple Api\\Http\\ClientInterface.

#### Supported APIs and Methods

[](#supported-apis-and-methods)

- [Member REST](#member-rest) - individual subscription management
- [Batch Member REST](#batch-member-rest) - batch subscription management
- [Notification REST](#notification-rest) - notification (email sending) service

##### Member REST

[](#member-rest)

- openConnection($server, $login, $password, $key)
- closeConnection($token)
- \[insertMemberByEmailAddress($token, $email)\] (#memberinsertmemberbyemailaddresstoken-email)
- insertMember($token, $xml)
- updateMember($token, $xml)
- \[insertOrUpdateMember($token, $xml)\] (#memberinsertorupdatemembertoken-xml)
- updateMemberByEmailAddress($token, $email, $field, $value)
- getMemberJobStatus($token, $jobId)
- getMemberByEmail($token, $email)
- getMemberByCellphone($token, $cellphone)
- getMemberById($token, $memberId)
- getMembersByPage($token, $page)
- getMembersByCriteria($token, $xml)
- getMemberTableColumnNames($token)
- unsubscribeMemberByEmail($token, $email)
- unsubscribeMemberByCellphone($token, $cellphone)
- unsubscribeMemberById($token, $memberId)
- unsubscribeMemberByValue($token, $xml)
- resubscribeMemberByEmail($token, $email)
- resubscribeMemberByCellphone($token, $cellphone)
- resubscribeMemberById($token, $memberId)

##### Batch Member REST

[](#batch-member-rest)

- openConnection($server, $login, $password, $key)
- closeConnection($token)
- buildInsertXml($filepath, $dateformat = 'yyyy-MM-dd', $dedup = true)
- insert($token, $xml)
- buildUpdateXml($filepath, $dateformat = 'yyyy-MM-dd')
- update($token, $xml)
- getLastUpload($token)
- getUploadStatus($token, $uploadId)
- getUploads($token, $page, $pageSize = 1000, $sort = null, $status = null, $source = null)
- getLogFile($token, $uploadId)
- getBadFile($token, $uploadId)

##### Notification REST

[](#notification-rest)

- \[send($email, $encrypt, $notificationId, $random, $dyn, $senddate, $uidkey, $stype)\] (#notificationsendemail-encrypt-notificationid-random-dyn-senddate-uidkey-stype)
- buildTransactionalRequestObject($recipientEmail, $encryptId, $randomId, $dyn, $content, $enableTracking, $additionalParams)
- post(SimpleXMLElement $xmlRequestObject)

### API Examples

[](#api-examples)

#### Member::insertMemberByEmailAddress($token, $email)

[](#memberinsertmemberbyemailaddresstoken-email)

```
// cURL client for communication with API
use Estina\SmartFocus\Api\Http\CurlClient;
// Member REST API class
use Estina\SmartFocus\Api\Rest\Member;
// helper for XML parsing (optional)
use Estina\SmartFocus\Api\Util\RestResponseParser;

// initialize object, injecting the cURL client
$api = new Member(new CurlClient());

// open the connection, XML is returned, containing token or error description
$xmlResponse = $api->openConnection(
    'server hostname',
    'your login name',
    'your password',
    'your API key'
);

if ($xmlResponse) {
    // extract token from XML
    $parser = new RestResponseParser();
    $token = $parser->getResult($xmlResponse);

    if ($token) {

        // call the API method and fetch the response
        $insertResponse = $api->insertMemberByEmailAddress(
            $token,
            'email@example.com'
        );

        // close the connection
        $api->closeConnection($token);
    }
}
```

#### Member::insertOrUpdateMember($token, $xml)

[](#memberinsertorupdatemembertoken-xml)

```
// cURL client for communication with API
use Estina\SmartFocus\Api\Http\CurlClient;
// Member REST API class
use Estina\SmartFocus\Api\Rest\Member;
// helper for XML parsing (optional)
use Estina\SmartFocus\Api\Util\RestResponseParser;

// initialize object, injecting the cURL client
$api = new Member(new CurlClient());

// open the connection, XML is returned, containing token or error description
$xmlResponse = $api->openConnection(
    'server hostname',
    'your login name',
    'your password',
    'your API key'
);

if ($xmlResponse) {
    // extract token from XML
    $parser = new RestResponseParser();
    $token = $parser->getResult($xmlResponse);

    if ($token) {

        /*
         * Let's build request's XML body with data
         *
         * :
         *      Multiple sets of criteria can be combined to identify the member, e.g.
         *      EMAIL:johnsmith@smartfocus.com|LASTNAME:Smith
         *
         * :
         *      envelope containing the list of fields to be updated and their values
         *
         * :
         *      The entry envelope containing the field to update and its value.
         *
         * :
         *      The field that will be updated.
         *
         * :
         *      The value with which to update the field.
         */
        $xml =
            '

                EMAIL:%s

                        FIRSTNAME
                        %s

                        LASTNAME
                        %s

            ';

        // inject values into XML
        $xml = sprintf($xml, 'email@example.com', 'John', 'Smith');

        // call the API method and fetch the response
        $insertResponse = $api->insertOrUpdateMember($token, $xml);
        // close the connection
        $api->closeConnection($token);
    }
}
```

#### Notification::send($email, $encrypt, $notificationId, $random, $dyn, $senddate, $uidkey, $stype)

[](#notificationsendemail-encrypt-notificationid-random-dyn-senddate-uidkey-stype)

```
// cURL client for communication with API
use Estina\SmartFocus\Api\Http\CurlClient;
// Member REST API class
use Estina\SmartFocus\Api\Rest\Notification;

// initialize object, injecting the cURL client
$api = new Notification(new CurlClient());

$response = $api->send(
    'email@example.com',             // Recipient
    'abcdefg',                       // Encrypt value provided in the interface
    '132456',                        // ID of the Template
    '123456789',                     // Random value provided for the template
    'firstname:John|lastname:Smith', // Dynamic parameters as a string
    'YYYY-MM-DD HH:MM:SS',           // optional, The time you wish to send
    'email',                         // Now *REQUIRED* - the key you wish to update, normally email
    'NOTHING'                        // optional, The type of synchronization
);
```

### Notification::post(SimpleXMLElement $xmlRequestObject)

[](#notificationpostsimplexmlelement-xmlrequestobject)

```
// cURL client for communication with API
use Estina\SmartFocus\Api\Http\CurlClient;
// Member REST API class
use Estina\SmartFocus\Api\Rest\Notification;

// initialize object, injecting the cURL client
$api = new Notification(new CurlClient());

$recipientEmail = 'email@example.com';
$encryptId = 'abcdefg';
$randomId = '132456';

$additionalParams = [
    'senddate'      => 'YYYY-MM-DDTHH:MM:SS', // 'T' between date & time
    'uidkey'        => 'email',
    'synchrotype'   => 'NOTHING'
];

// Optional: Dynamic parameters as an array
$dyn = [
    'firstname' => 'John',
    'lastname' => 'Smith'
];

$content = [
    'click here please',
    'good stuff is available here'
];

// Tracking enabled for the links passed in the content blocks.
$enableTracking = true;

// Build request object.
$xmlRequestObject = $api->buildTransactionalRequestObject(
    $recipientEmail,
    $encryptId,
    $randomId,
    $dyn,
    $content,
    $enableTracking,
    $additionalParams
);

// Make the request.
$response = $api->post($xmlRequestObject);
```

Troubleshooting
---------------

[](#troubleshooting)

If you get the response with the following status codes:

- UPDATE\_MEMBER\_FAILED
- ISTUPD\_MEMBER\_FAILED

Check the following:

- XML input body is formatted correctly
- There are no spaces, newlines or other invalid symbols inside the tag, it should look like:

```
EMAIL:email@example.com
```

Unit test
---------

[](#unit-test)

```
composer test

```

More information
----------------

[](#more-information)

SmartFocus documentation is available in the "doc" folder. Also, more detailed descriptions of all functions and their parameters are available in the source code.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 60% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~142 days

Recently: every ~175 days

Total

6

Last Release

3514d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f06b1798977e196e99c5d0b7f408c2c3a13cf09c0df2cf93841b6e1b73124b16?d=identicon)[adamclark-dev](/maintainers/adamclark-dev)

---

Top Contributors

[![forceedge01](https://avatars.githubusercontent.com/u/1619816?v=4)](https://github.com/forceedge01 "forceedge01 (3 commits)")[![NoelLH](https://avatars.githubusercontent.com/u/3274454?v=4)](https://github.com/NoelLH "NoelLH (1 commits)")[![Saphyel](https://avatars.githubusercontent.com/u/5764721?v=4)](https://github.com/Saphyel "Saphyel (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/comicrelief-smartfocus/health.svg)

```
[![Health](https://phpackages.com/badges/comicrelief-smartfocus/health.svg)](https://phpackages.com/packages/comicrelief-smartfocus)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
