├── .gitignore
├── README.md
├── bootstrap.php
├── composer.json
├── phpunit.xml
├── src
├── Exception.php
├── Exception
│ ├── CurlException.php
│ ├── DomainException.php
│ ├── ForbiddenCustomFieldNameException.php
│ ├── InvalidEmailException.php
│ ├── InvalidURLException.php
│ ├── LogicException.php
│ ├── RuntimeException.php
│ └── UnexpectedValueException.php
├── Model
│ ├── Campaign.php
│ ├── EmailBody.php
│ └── Sender.php
├── Response
│ └── SubscriptionStatus.php
├── Sendy.php
└── autoload.php
└── tests
├── SendyPHP
└── Response
│ └── SubscriptionStatusTest.php
└── TestBootstrap.php
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | .idea/
3 | vendor
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP sendy client
2 | PHP interface for Sendy api ([http://sendy.co/](http://sendy.co/?ref=q5mRD "Sendy - Send newsletters, 100x cheaper via Amazon SES")) with full support Sendy API ([http://sendy.co/api](http://sendy.co/api?ref=q5mRD "Sendy - API documentation"))
3 |
4 | # Installation
5 | ## Using composer
6 | Simply add new require jiririedl/php-sendy
to your composer.json
.
7 | ```json
8 | "require": {
9 | "jiririedl/php-sendy" : ">=1.0.0"
10 | }
11 | ```
12 | and update in console
13 | ```sh
14 | composer update
15 | ```
16 | ## Using autoload (alternative dirty way)
17 | If you don't use Composer (for some reasons) you can download and include library bootstrap into your project manually.
18 | This wil add spl_autoload for SendyPHP namespace.
19 | ```php
20 | $phpSendyPath = ''; // here you can fill something like 'vendor/SendyPHP'
21 | require_once($phpSendyPath.'/bootstrap.php');
22 | ```
23 | ## Using autoload method (alternative dirty dirty way)
24 | If you have your own solution of class autoloading, there is prepared autload function in /src/autoload.php
.
25 | Calling ```\SendyPHP\autoload($className)``` includes requested class from SendyPHP
namespace or returns FALSE
26 |
27 | # Usage
28 | Create instance of \SendyPHP\Sendy
with URL of your Sendy installation and API key.
29 | Your API key is located in sendy - login as Admin and go to "Settings" (/settings) - your key is located in right side under topic "Your API key" beware of white spaces!
30 | ```php
31 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
32 | ```
33 | Some request doesn't need API key for work (f.e. subscribe() or unsubscribe()) so setting api key is optional.
34 | You can also set api key by using setApiKey() method or redefine sendy URL by setURL().
35 |
36 | ## Methods
37 |
38 | ### Sendy API Requests
39 | All requests uses curl library for calling Sendy API.
40 | If you have installed library by using Composer, curl was checked automatically,
41 | otherwise you can check this in your phpinfo, or just try to call some method from curl (http://php.net/manual/en/ref.curl.php).
42 |
43 | #### Subscribe
44 | This method adds a new subscriber to a list.
45 | You can also use this method to update an existing subscriber.
46 | ```php
47 | bool subscribe($listID, $email, $name = NULL, array $customFields = array(), &$statusMessage = NULL)
48 | ```
49 | ##### Parameters
50 | * $listID - the list id you want to subscribe a user to. This encrypted & hashed id can be found under View all lists section named ID
51 | * $email - user's email
52 | * $name - optional -user's name is optional
53 | * $customFields - optional - associative array of custom fields and their values f.e. array('salutation'=>'Mr.','userLevel'=>'VIP+')
54 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
55 |
56 | ##### Example
57 | ```php
58 | try{
59 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
60 |
61 | $statusMessage = '';
62 | $status = $sendy->subscribe('myHashedListID','newsubscribers@email.com','John Doe',$statusMessage);
63 |
64 | if($status)
65 | echo "Yeah! New subscriber successfully added";
66 | else
67 | echo "Ops! Sendy API responds a problem with adding subscriber - Sendy PHP message :".$statusMessage;
68 |
69 | }catch (\SendyPHP\Exception $e)
70 | {
71 | echo "Ops! An exception raised: ".$e;
72 | }
73 | ```
74 | ##### Exceptions
75 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
76 | * \SendyPHP\Exception\InvalidEmailException
is thrown if email address is not valid
77 | * \SendyPHP\Exception\DomainException
is thrown if $listID is empty
78 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
79 |
80 | ##### Return values
81 | Returns TRUE on success or FALSE on failure.
82 |
83 | #### UnSubscribe
84 | This method unsubscribes a user from a list.
85 | ```php
86 | bool unsubscribe($listID, $email,&$statusMessage = NULL)
87 | ```
88 | ##### Parameters
89 | * $listID - the list id you want to unsubscribe a user from. This encrypted & hashed id can be found under View all lists section named ID
90 | * $email - user's email
91 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
92 |
93 | ##### Example
94 | ```php
95 | try{
96 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
97 |
98 | $statusMessage = '';
99 | $status = $sendy->unsubscribe('myHashedListID','newsubscribers@email.com',$statusMessage);
100 |
101 | if($status)
102 | echo "Subscriber successfully removed from list";
103 | else
104 | echo "Ops! Sendy API responds a problem with unsubscribing - Sendy PHP message :".$statusMessage;
105 |
106 | }catch (\SendyPHP\Exception $e)
107 | {
108 | echo "Ops! An exception raised: ".$e;
109 | }
110 | ```
111 | ##### Exceptions
112 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
113 | * \SendyPHP\Exception\InvalidEmailException
is thrown if email address is not valid
114 | * \SendyPHP\Exception\DomainException
is thrown if $listID is empty
115 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
116 |
117 | ##### Return values
118 | Returns TRUE on success or FALSE on failure.
119 |
120 | #### Delete
121 | This method deletes a subscriber off a list (only supported in Sendy version 2.1.1.4 and above).
122 | ```php
123 | bool delete($listID, $email,&$statusMessage = NULL)
124 | ```
125 | ##### Parameters
126 | * $listID - the list id you want to delete a user from. This encrypted & hashed id can be found under View all lists section named ID
127 | * $email - user's email
128 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
129 |
130 | ##### Example
131 | ```php
132 | try{
133 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
134 |
135 | $statusMessage = '';
136 | $status = $sendy->delete('myHashedListID','newsubscribers@email.com',$statusMessage);
137 |
138 | if($status)
139 | echo "Subscriber successfully deleted from list";
140 | else
141 | echo "Ops! Sendy API responds a problem with deleting - Sendy PHP message :".$statusMessage;
142 |
143 | }catch (\SendyPHP\Exception $e)
144 | {
145 | echo "Ops! An exception raised: ".$e;
146 | }
147 | ```
148 | ##### Exceptions
149 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
150 | * \SendyPHP\Exception\InvalidEmailException
is thrown if email address is not valid
151 | * \SendyPHP\Exception\DomainException
is thrown if $listID is empty
152 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
153 |
154 | ##### Return values
155 | Returns TRUE on success or FALSE on failure.
156 |
157 | #### Get active subscriber count
158 | This method gets the total active subscriber count.
159 | ```php
160 | number|false getActiveSubscriberCount($listID, &$statusMessage = NULL)
161 | ```
162 | ##### Parameters
163 | * $listID - the list id you want to subscribe a user to. This encrypted & hashed id can be found under View all lists section named ID
164 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
165 |
166 | ##### Example
167 | ```php
168 | try{
169 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
170 |
171 | $statusMessage = '';
172 | $subscribersCount = $sendy->getActiveSubscriberCount('myHashedListID',$statusMessage);
173 |
174 | if($subscribersCount!==false)
175 | echo "In this list is $subscribersCount active subscribers";
176 | else
177 | echo "Ops! Sendy API responds a problem with getting active subscribers count - Sendy PHP message :".$statusMessage;
178 |
179 | }catch (\SendyPHP\Exception $e)
180 | {
181 | echo "Ops! An exception raised: ".$e;
182 | }
183 | ```
184 | ##### Exceptions
185 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
186 | * \SendyPHP\Exception\DomainException
is thrown if $listID is empty
187 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
188 |
189 | ##### Return values
190 | Returns number of active subscribers or FALSE on failure.
191 |
192 | #### Get subscribtion status
193 | This method gets the current status of a subscriber (eg. subscribed, unsubscribed, bounced, complained).
194 | ```php
195 | \SendyPHP\Response\SubscriptionStatus getSubscriptionStatus($listID, $email)
196 | ```
197 | ##### Parameters
198 | * $listID - the list id you want to subscribe a user to. This encrypted & hashed id can be found under View all lists section named ID
199 | * $email - user's email
200 |
201 | ##### Example
202 | ```php
203 | try{
204 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
205 |
206 | $subscriptionStatus = $sendy->getSubscriptionStatus('myHashedListID','mysubscribers@email.com');
207 |
208 | if($subscriptionStatus->success())
209 | {
210 | switch(true)
211 | {
212 | case $subscriptionStatus->isSubscribed():
213 | echo "Subscribed";
214 | break;
215 | case $subscriptionStatus->isUnSubscribed():
216 | echo "Unsubscribed";
217 | break;
218 | case $subscriptionStatus->isComplained():
219 | echo "Complained";
220 | break;
221 | case $subscriptionStatus->isUnconfirmed():
222 | echo "Unconfirmed";
223 | break;
224 | case $subscriptionStatus->isHardBounced():
225 | echo "Hard Bounced";
226 | break;
227 | case $subscriptionStatus->isSoftBounced():
228 | echo "Soft bounced";
229 | break;
230 | }
231 | }
232 | else
233 | echo "Ops! Sendy API responds a problem with getting subscribtion status - Sendy PHP message :".$subscriptionStatus->getRawResponse();
234 |
235 | }catch (\SendyPHP\Exception $e)
236 | {
237 | echo "Ops! An exception raised: ".$e;
238 | }
239 | ```
240 | ##### Exceptions
241 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
242 | * \SendyPHP\Exception\DomainException
is thrown if $listID is empty
243 | * \SendyPHP\Exception\InvalidEmailException
is thrown if email address is not valid
244 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
245 |
246 | ##### Return values
247 | \SendyPHP\Response\SubscriptionStatus
248 | returned object has many of usable methods (see phpdoc) f.e. by calling success() are you able to check if API returns some subscribers status.
249 |
250 | #### Create campaign
251 | Creates draft of campaign
252 | ```php
253 | bool createCampaign($brandID, Model\Campaign $campaign, &$statusMessage = NULL)
254 | ```
255 | ##### Parameters
256 | * $brandID - Brand IDs can be found under 'Brands' page named ID
257 | * $campaign <\SendyPHP\Model\Campaign> - configured campaign
258 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
259 |
260 | ##### Example
261 | ```php
262 | try{
263 | $sender = new \SendyPHP\Model\Sender('From name','from-adrress@mydomain.com','reply-address@mydomain.com');
264 | $emailBody = new \SendyPHP\Model\EmailBody('HTML body of my newsletter
', 'Plaintext body of my newsletter');
265 | $campaign = new \SendyPHP\Model\Campaign($sender,'My first great newsletter!',$emailBody);
266 | $brandID = 1; // here fill your brand ID
267 |
268 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
269 |
270 | $statusMessage = '';
271 | $status = $sendy->createCampaign($brandID,$campaign,$statusMessage);
272 |
273 | if($status)
274 | {
275 | echo "Campaign successfully created";
276 | }
277 | else
278 | echo "Ops! Sendy API responds a problem with creating campaign - Sendy PHP message :".$statusMessage;
279 |
280 | }catch (\SendyPHP\Exception $e)
281 | {
282 | echo "Ops! An exception raised: ".$e;
283 | }
284 | ```
285 | ##### Exceptions
286 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
287 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
288 |
289 | ##### Return values
290 | Returns TRUE on success or FALSE on failure.
291 |
292 | #### Send campaign
293 | Creates draft and automatically sends campaign
294 | ```php
295 | bool sendCampaign(array $listIDs, Model\Campaign $campaign, &$statusMessage = NULL)
296 | ```
297 | ##### Parameters
298 | * $listIDs - The encrypted & hashed ids can be found under View all lists section named ID.
299 | * $campaign <\SendyPHP\Model\Campaign> - configured campaign
300 | * $statusMessage - optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
301 |
302 | ##### Example
303 | ```php
304 | try{
305 | $sender = new \SendyPHP\Model\Sender('From name','from-adrress@mydomain.com','reply-address@mydomain.com');
306 | $emailBody = new \SendyPHP\Model\EmailBody('HTML body of my newsletter
', 'Plaintext body of my newsletter');
307 | $campaign = new \SendyPHP\Model\Campaign($sender,'My first great newsletter!',$emailBody);
308 | $listIDs = array(1); // here fill your list IDs
309 |
310 | $sendy = new \SendyPHP\Sendy('http://mysendyinstalation.mydomain','myAPIKey');
311 |
312 | $statusMessage = '';
313 | $status = $sendy->sendCampaign($listIDs,$campaign,$statusMessage);
314 |
315 | if($status)
316 | {
317 | echo "Campaign successfully created and now sending";
318 | }
319 | else
320 | echo "Ops! Sendy API responds a problem with creating and sending campaign - Sendy PHP message :".$statusMessage;
321 |
322 | }catch (\SendyPHP\Exception $e)
323 | {
324 | echo "Ops! An exception raised: ".$e;
325 | }
326 | ```
327 | ##### Exceptions
328 | All exceptions are extended from \SendyPHP\Exception
so you can easily catch just this parent class
329 | * \SendyPHP\Exception\CurlException
is thrown if cURL library could not handle your request
330 | * \SendyPHP\Exception\DomainException
is thrown if $listIDs array is empty
331 |
332 | ##### Return values
333 | Returns TRUE on success or FALSE on failure.
334 |
335 | ### Other methods
336 | #### Set cURL option
337 | Sets cURL option
338 | You can set cURL options f.e. CURLOPT_SSL_VERIFYPEER
or CURLOPT_SSL_VERIFYHOST
339 | some parameters (\CURLOPT_RETURNTRANSFER
, \CURLOPT_POST
, \CURLOPT_POSTFIELDS
) are used, if you try to set one of these exception is thrown.
340 | See http://php.net/manual/en/function.curl-setopt.php for more informations.
341 | ```php
342 | void setCurlOption($option, $value)
343 | ```
344 | ##### Parameters
345 | * $option - use \CURLOPT_
* constant
346 | * $value mixed
347 |
348 | ##### Exceptions
349 | \SendyPHP\Exception\UnexpectedValueException
is thrown if you try to set one of predefined options (\CURLOPT_RETURNTRANSFER
, \CURLOPT_POST
and \CURLOPT_POSTFIELDS
).
350 |
351 | #### Clear cURL option
352 | Sets cURL option
353 | Clears user defined cURL options
354 | ```php
355 | void clearCurlOptions()
356 | ```
357 |
358 | #### Set URL
359 | Sets sendy installation URL
360 | Clears user defined cURL options
361 | ```php
362 | void setURL($URL)
363 | ```
364 | ##### Exceptions
365 | \SendyPHP\Exception\InvalidURLException
is thrown if URL is invalid.
366 |
367 | #### Set API key
368 | Sets api key
369 | ```php
370 | void setApiKey($apiKey)
371 | ```
372 | ##### Parameters
373 | * $apiKey - sendy API key - your API key is available in sendy Settings
374 |
375 | ##### Exceptions
376 | \SendyPHP\Exception\DomainException
is thrown if API key is not string.
377 |
--------------------------------------------------------------------------------
/bootstrap.php:
--------------------------------------------------------------------------------
1 | =1.0.0" to your composer.json for obtaining last stable release
11 | * @link https://getcomposer.org/doc/00-intro.md#declaring-dependencies
12 | * @link https://packagist.org/packages/jiririedl/php-sendy
13 | *
14 | * @author Jiri Riedl
15 | * @package SendyPHP
16 | */
17 |
18 | require_once(__DIR__.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'autoload.php');
19 |
20 | \spl_autoload_register('\\SendyPHP\\autoload');
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jiririedl/php-sendy",
3 | "description": "PHP class for using sendy API",
4 | "keywords": ["sendy","api","php"],
5 | "homepage": "https://github.com/jiririedl/php-sendy",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Jiri Riedl",
10 | "email": "riedl@dcommunity.org",
11 | "homepage": "http://www.riedl.in",
12 | "role": "Local genius"
13 | }
14 | ],
15 | "require": {
16 | "php": ">=5.3.0",
17 | "lib-curl": "*"
18 | },
19 | "autoload": {
20 | "psr-4": {"SendyPHP\\": "src/"}
21 | }
22 | }
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tests
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Exception.php:
--------------------------------------------------------------------------------
1 | _buildMessage($message),$code,$previous);
23 | }
24 | /**
25 | * Builds Exception message text
26 | *
27 | * @param string $message
28 | * @param resource|null $resource
29 | * @return string
30 | */
31 | protected function _buildMessage($message, $resource = NULL)
32 | {
33 | $message = 'cURL '.$message;
34 | if(!is_null($resource))
35 | {
36 | $message.= ' cURL error: ['.curl_errno($resource).'] '.curl_error($resource);
37 | }
38 | return $message;
39 | }
40 | }
--------------------------------------------------------------------------------
/src/Exception/DomainException.php:
--------------------------------------------------------------------------------
1 | _buildMessage($customFieldName), $code, $previous);
22 | }
23 | /**
24 | * Builds Exception message text
25 | *
26 | * @param mixed $customFieldName
27 | * @return string
28 | */
29 | protected function _buildMessage($customFieldName)
30 | {
31 | $message = 'Forbidden custom field name detected ';
32 | if(is_string($customFieldName))
33 | $message.= ' - [.'.$customFieldName.'.] - this field name is reserved.';
34 | else
35 | $message.= ' - '.gettype($customFieldName).' given ['.var_export($customFieldName,1).'], string expected.';
36 | return $message;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Exception/InvalidEmailException.php:
--------------------------------------------------------------------------------
1 | _buildMessage($email), $code, $previous);
22 | }
23 | /**
24 | * Builds Exception message text
25 | *
26 | * @param mixed $email
27 | * @return string
28 | */
29 | protected function _buildMessage($email)
30 | {
31 | $message = 'Valid e-mail address expected ';
32 | if(is_string($email))
33 | $message.= ' - invalid e-mail given [.'.$email.'.]';
34 | else
35 | $message.= ' - '.gettype($email).' given ['.var_export($email,1).']';
36 | return $message;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Exception/InvalidURLException.php:
--------------------------------------------------------------------------------
1 | _buildMessage($URL), $code, $previous);
22 | }
23 | /**
24 | * Builds Exception message text
25 | *
26 | * @param mixed $URL
27 | * @return string
28 | */
29 | protected function _buildMessage($URL)
30 | {
31 | $message = 'Valid URL expected ';
32 | if(is_string($URL))
33 | $message.= ' - invalid URL given [.'.$URL.'.]';
34 | else
35 | $message.= ' - '.gettype($URL).' given ['.var_export($URL,1).']';
36 | return $message;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Exception/LogicException.php:
--------------------------------------------------------------------------------
1 |
7 | * @package SendyPHP
8 | */
9 | class Campaign
10 | {
11 | /**
12 | * Sender settings
13 | * @var Sender
14 | */
15 | protected $_sender = NULL;
16 | /**
17 | * Email subject
18 | * @var string
19 | */
20 | protected $_subject = NULL;
21 | /**
22 | * Email body
23 | * @var EmailBody
24 | */
25 | protected $_emailBody = NULL;
26 |
27 | /**
28 | * Sendy campaign settings
29 | *
30 | * @param Sender $sender Sender settings
31 | * @param string|null $subject email subject
32 | * @param EmailBody $emailBody Email body variants
33 | *
34 | * @throws \SendyPHP\Exception\DomainException
35 | */
36 | public function __construct(Sender $sender = NULL, $subject = NULL, EmailBody $emailBody = NULL)
37 | {
38 | if(!is_null($sender))
39 | $this->setSenderSettings($sender);
40 |
41 | if(!is_null($subject))
42 | $this->setSubject($subject);
43 |
44 | if(!is_null($emailBody))
45 | $this->setEmailBodyVariants($emailBody);
46 | }
47 | /**
48 | * Sets e-mail body
49 | *
50 | * @param string $html
51 | * @param string|null $plainText
52 | * @throws \SendyPHP\Exception\DomainException
53 | */
54 | public function setEmailBody($html, $plainText = NULL)
55 | {
56 | $this->setEmailBodyVariants(new EmailBody($html,$plainText));
57 | }
58 | /**
59 | * Sets e-mail body variants
60 | *
61 | * @param EmailBody $emailBody
62 | */
63 | public function setEmailBodyVariants(EmailBody $emailBody)
64 | {
65 | $this->_emailBody = $emailBody;
66 | }
67 | /**
68 | * Returns e-mail body
69 | *
70 | * @return EmailBody
71 | */
72 | public function getEmailBody()
73 | {
74 | return $this->_emailBody;
75 | }
76 | /**
77 | * Sets sender settings
78 | *
79 | * @param string $fromName 'From name' of your campaign
80 | * @param string $fromAddress 'From email' of your campaign
81 | * @param string $replyAddress 'Reply to' of your campaign
82 | * @throws \SendyPHP\Exception\DomainException
83 | */
84 | public function setSender($fromName, $fromAddress, $replyAddress)
85 | {
86 | $this->setSenderSettings(new Sender($fromName, $fromAddress, $replyAddress));
87 | }
88 | /**
89 | * Sets sender settings
90 | *
91 | * @param Sender $sender
92 | */
93 | public function setSenderSettings(Sender $sender)
94 | {
95 | $this->_sender = $sender;
96 | }
97 | /**
98 | * Returns Sender settings
99 | *
100 | * @return Sender
101 | */
102 | public function getSender()
103 | {
104 | return $this->_sender;
105 | }
106 | /**
107 | * Sets e-mail subject
108 | *
109 | * @param string $subject
110 | * @throws \SendyPHP\Exception\DomainException
111 | */
112 | public function setSubject($subject)
113 | {
114 | if(strlen($subject) == 0)
115 | throw new \SendyPHP\Exception\DomainException('Email subject can not be empty');
116 |
117 | $this->_subject = $subject;
118 | }
119 | /**
120 | * Returns e-mail subject
121 | *
122 | * @return string
123 | */
124 | public function getSubject()
125 | {
126 | return $this->_subject;
127 | }
128 | }
--------------------------------------------------------------------------------
/src/Model/EmailBody.php:
--------------------------------------------------------------------------------
1 |
7 | * @package SendyPHP
8 | */
9 | class EmailBody
10 | {
11 | /**
12 | * HTML email code
13 | * @var string
14 | */
15 | protected $_html = NULL;
16 | /**
17 | * Plain text version of e-mail
18 | * @var string|null
19 | */
20 | protected $_plainText = NULL;
21 |
22 | /**
23 | * Email body
24 | *
25 | * @param string $html the 'HTML version' of your e-mail
26 | * @param string|null $plainText the 'Plain text version' of your e-mail (optional)
27 | *
28 | * @throws \SendyPHP\Exception\DomainException
29 | */
30 | public function __construct($html, $plainText = NULL)
31 | {
32 | $this->setHtml($html);
33 |
34 | if(!is_null($plainText))
35 | $this->setPlainText($plainText);
36 | }
37 | /**
38 | * Sets HTML email code
39 | *
40 | * @param string $html
41 | * @throws \SendyPHP\Exception\DomainException
42 | */
43 | public function setHtml($html)
44 | {
45 | if(strlen($html) == 0)
46 | throw new \SendyPHP\Exception\DomainException('HTML email code can not be empty');
47 |
48 | $this->_html = $html;
49 | }
50 | /**
51 | * Returns HTML email code
52 | *
53 | * @return string
54 | */
55 | public function getHtml()
56 | {
57 | return $this->_html;
58 | }
59 | /**
60 | * Sets plain text version of e-mail
61 | *
62 | * @param string $plainText
63 | * @throws \SendyPHP\Exception\DomainException
64 | */
65 | public function setPlainText($plainText)
66 | {
67 | if(strlen($plainText) == 0)
68 | throw new \SendyPHP\Exception\DomainException('Plain text version of e-mai can not be empty - you can disable plaintext version by calling removePlainText().');
69 |
70 | $this->_plainText = $plainText;
71 | }
72 | /**
73 | * Remove plaintext version
74 | */
75 | public function removePlainText()
76 | {
77 | $this->_plainText = NULL;
78 | }
79 | /**
80 | * Returns plain text version of e-mail
81 | *
82 | * NULL is returned, if no plain text version is set
83 | *
84 | * @return null|string
85 | */
86 | public function getPlainText()
87 | {
88 | return $this->_plainText;
89 | }
90 |
91 | }
--------------------------------------------------------------------------------
/src/Model/Sender.php:
--------------------------------------------------------------------------------
1 |
8 | * @package SendyPHP
9 | */
10 | class Sender
11 | {
12 | /**
13 | * "From name" of your campaign
14 | * @var string
15 | */
16 | protected $_name = NULL;
17 | /**
18 | * "From email" of your campaign
19 | * @var string
20 | */
21 | protected $_address = NULL;
22 | /**
23 | * "Reply to" of your campaign
24 | * @var string
25 | */
26 | protected $_replyAddress = NULL;
27 |
28 | /**
29 | * Sender settings
30 | *
31 | * @param string $fromName 'From name' of your campaign
32 | * @param string $fromAddress 'From email' of your campaign
33 | * @param string $replyAddress 'Reply to' of your campaign
34 | * @throws \SendyPHP\Exception\DomainException
35 | * @throws \SendyPHP\Exception\InvalidEmailException
36 | */
37 | public function __construct($fromName, $fromAddress, $replyAddress)
38 | {
39 | $this->setName($fromName);
40 | $this->setAddress($fromAddress);
41 | $this->setReplyAddress($replyAddress);
42 | }
43 | /**
44 | * Sets "From" e-mail address
45 | *
46 | * @param string $address
47 | * @throws \SendyPHP\Exception\InvalidEmailException
48 | * @uses \SendyPHP\Sendy::isEmailValid()
49 | */
50 | public function setAddress($address)
51 | {
52 | if(!Sendy::isEmailValid($address))
53 | throw new \SendyPHP\Exception\InvalidEmailException($address);
54 |
55 | $this->_address = $address;
56 | }
57 | /**
58 | * Returns "From" e-mail address
59 | * @return string
60 | */
61 | public function getAddress()
62 | {
63 | return $this->_address;
64 | }
65 | /**
66 | * Sets From name
67 | *
68 | * @param string $name
69 | * @throws \SendyPHP\Exception\DomainException
70 | */
71 | public function setName($name)
72 | {
73 | if(strlen($name) == 0)
74 | throw new \SendyPHP\Exception\DomainException('From name have to longer than zero');
75 |
76 | $this->_name = $name;
77 | }
78 | /**
79 | * Returns From name
80 | *
81 | * @return string
82 | */
83 | public function getName()
84 | {
85 | return $this->_name;
86 | }
87 | /**
88 | * Sets reply e-mail address
89 | *
90 | * @param string $replyAddress
91 | * @throws \SendyPHP\Exception\InvalidEmailException
92 | * @uses \SendyPHP\Sendy::isEmailValid()
93 | */
94 | public function setReplyAddress($replyAddress)
95 | {
96 | if(!Sendy::isEmailValid($replyAddress))
97 | throw new \SendyPHP\Exception\InvalidEmailException($replyAddress);
98 |
99 | $this->_replyAddress = $replyAddress;
100 | }
101 | /**
102 | * Returns reply e-mail address
103 | *
104 | * @return string
105 | */
106 | public function getReplyAddress()
107 | {
108 | return $this->_replyAddress;
109 | }
110 | }
--------------------------------------------------------------------------------
/src/Response/SubscriptionStatus.php:
--------------------------------------------------------------------------------
1 |
9 | * @package SendyPHP
10 | */
11 | class SubscriptionStatus
12 | {
13 | /**
14 | * Subscribed text response from API
15 | * @link http://sendy.co/api
16 | */
17 | const RESPONSE_SUBSCRIBED = 'Subscribed';
18 | /**
19 | * Unsubscribed text response from API
20 | * @link http://sendy.co/api
21 | */
22 | const RESPONSE_UNSUBSCRIBED = 'Unsubscribed';
23 | /**
24 | * Unconfirmed text response from API
25 | * @link http://sendy.co/api
26 | */
27 | const RESPONSE_UNCONFIRMED = 'Unconfirmed';
28 | /**
29 | * Bounced text response from API - this usually means hard bounces
30 | * @link http://sendy.co/api
31 | */
32 | const RESPONSE_BOUNCED = 'Bounced';
33 | /**
34 | * Soft bounced text response from API
35 | * @link http://sendy.co/api
36 | */
37 | const RESPONSE_SOFT_BOUNCED = 'Soft bounced';
38 | /**
39 | * Complained text response from API
40 | * @link http://sendy.co/api
41 | */
42 | const RESPONSE_COMPLAINED = 'Complained';
43 |
44 | /**
45 | * RAW sendy response
46 | * @var string
47 | */
48 | protected $_rawResponse = NULL;
49 |
50 | /**
51 | * Subscription status
52 | *
53 | * @param string $rawResponse
54 | */
55 | public function __construct($rawResponse)
56 | {
57 | $this->_rawResponse = $rawResponse;
58 | }
59 | /**
60 | * Returns TRUE if user is subscribed
61 | *
62 | * @return bool
63 | */
64 | public function isSubscribed()
65 | {
66 | return ($this->getRawResponse() == self::RESPONSE_SUBSCRIBED);
67 | }
68 | /**
69 | * Returns true if user is unsubscribed
70 | *
71 | * @return bool
72 | */
73 | public function isUnSubscribed()
74 | {
75 | return ($this->getRawResponse() == self::RESPONSE_UNSUBSCRIBED);
76 | }
77 | /**
78 | * Returns true if user is unconfirmed
79 | *
80 | * @return bool
81 | */
82 | public function isUnconfirmed()
83 | {
84 | return ($this->getRawResponse() == self::RESPONSE_UNCONFIRMED);
85 | }
86 | /**
87 | * Returns true if user is bounced
88 | *
89 | * The email is rejected by the recipient's ISP or rejected by Amazon SES because the email address is on the Amazon SES suppression list.
90 | * For ISP bounces, Amazon SES reports only hard bounces and soft bounces that will no longer be retried by Amazon SES.
91 | * In these cases, your recipient did not receive your email message, and Amazon SES will not try to resend it.
92 | * Bounce notifications are available through email and Amazon SNS.
93 | * You are notified of out-of-the-office (OOTO) messages through the same method as bounces, although they don't count toward your bounce statistics.
94 | *
95 | * You can also call isHardBounced() or isSoftBounced()
96 | *
97 | * @see http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notifications.html
98 | * @return bool
99 | */
100 | public function isBounced()
101 | {
102 | return ($this->isSoftBounced() || $this->isHardBounced());
103 | }
104 | /**
105 | * Returns TRUE if user id hard bounced
106 | *
107 | * A hard bounce indicates a persistent delivery failure (e.g., mailbox does not exist).
108 | * In other words, your recipient did not receive your email message, and your server will not try to resend it.
109 | *
110 | * @return bool
111 | */
112 | public function isHardBounced()
113 | {
114 | return ($this->getRawResponse() == self::RESPONSE_BOUNCED);
115 | }
116 | /**
117 | * Returns true if user is soft bounced
118 | *
119 | * Unlike a hard bounce, a soft bounce is not a permanent failure or rejection (e.g., mailbox full).
120 | * Many email systems (including Amazon SES) will automatically try to resend a message that has generated a soft bounce over a period of time until the message either delivers or the system will no longer retry the delivery and in turn generates a hard bounce.
121 | *
122 | * @return bool
123 | */
124 | public function isSoftBounced()
125 | {
126 | return ($this->getRawResponse() == self::RESPONSE_SOFT_BOUNCED);
127 | }
128 | /**
129 | * Returns true if user is complained
130 | *
131 | * The email is accepted by the ISP and delivered to the recipient, but the recipient does not want the email and clicks a button such as "Mark as spam."
132 | * If Amazon SES has a feedback loop set up with the ISP, Amazon SES will send you a complaint notification.
133 | * Complaint notifications are available through email and Amazon SNS.
134 | *
135 | * @return bool
136 | */
137 | public function isComplained()
138 | {
139 | return ($this->getRawResponse() == self::RESPONSE_COMPLAINED);
140 | }
141 | /**
142 | * Returns TRUE if request successfully obtains status
143 | *
144 | * if FALSE you can get error message by calling getRawResponse()
145 | * @return bool
146 | */
147 | public function success()
148 | {
149 | return ($this->isSubscribed() || $this->isUnSubscribed() || $this->isUnconfirmed() || $this->isBounced() || $this->isSoftBounced() || $this->isComplained());
150 | }
151 | /**
152 | * Returns TRUE if request obtaining status failed
153 | *
154 | * If TRUE you can get error message by calling getRawMessage()
155 | * @return bool
156 | */
157 | public function failed()
158 | {
159 | return !$this->success();
160 | }
161 | /**
162 | * Returns raw response (plaintext api response)
163 | *
164 | * @see http://sendy.co/api section "subscription status":"response"
165 | * @return string
166 | */
167 | public function getRawResponse()
168 | {
169 | return $this->_rawResponse;
170 | }
171 | }
--------------------------------------------------------------------------------
/src/Sendy.php:
--------------------------------------------------------------------------------
1 |
7 | * @package SendyPHP
8 | */
9 | class Sendy
10 | {
11 | /**
12 | * Subscribe API URI
13 | */
14 | CONST URI_SUBSCRIBE = 'subscribe';
15 | /**
16 | * Unsubscribe API URI
17 | */
18 | CONST URI_UNSUBSCRIBE = 'unsubscribe';
19 | /**
20 | * Delete subscriber API URL
21 | */
22 | CONST URI_DELETE_SUBSCRIBER = 'api/subscribers/delete.php';
23 | /**
24 | * Subscribtion status API URI
25 | */
26 | CONST URI_SUBSCRIPTION_STATUS = 'api/subscribers/subscription-status.php';
27 | /**
28 | * Active subscibers API URI
29 | */
30 | CONST URI_ACTIVE_SUBSCRIBER_COUNT = 'api/subscribers/active-subscriber-count.php';
31 | /**
32 | * Create campaign API URI
33 | */
34 | CONST URI_CAMPAIGN = 'api/campaigns/create.php';
35 | /**
36 | * Sendy installation URL
37 | * @var string|NULL
38 | */
39 | protected $_URL = NULL;
40 | /**
41 | * Api key
42 | * @var string|null
43 | */
44 | protected $_apiKey = NULL;
45 | /**
46 | * Additional cUrL options
47 | * @var array
48 | */
49 | protected $_cURLOption = array();
50 |
51 | /**
52 | * PHP interface for Sendy api
53 | *
54 | * @param string $URL sendy installation URL
55 | * @param string|null $apiKey your API key is available in sendy Settings - api key is required almost for all requests
56 | * @throws Exception\InvalidURLException
57 | * @throws Exception\DomainException
58 | */
59 | public function __construct($URL, $apiKey = NULL)
60 | {
61 | $this->setURL($URL);
62 |
63 | if(!is_null($apiKey))
64 | $this->setApiKey($apiKey);
65 | }
66 | /**
67 | * This method adds a new subscriber to a list.
68 | *
69 | * You can also use this method to update an existing subscriber.
70 | * On another note, you can also embed a subscribe form on your website using Sendy's subscribe form HTML code.
71 | * Visit View all lists, select your desired list then click 'Subscribe form' at the top of the page.
72 | *
73 | * @param string $listID the list id you want to subscribe a user to. This encrypted & hashed id can be found under View all lists section named ID
74 | * @param string $email user's email
75 | * @param string|null $name user's name is optional
76 | * @param array $customFields associative array of custom fields and their values f.e. array('salutation'=>'Mr.','userLevel'=>'VIP+')
77 | * @param string|null $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
78 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\InvalidEmailException|\SendyPHP\Exception\DomainException|\SendyPHP\Exception\CurlException]
79 | * @return bool
80 | */
81 | public function subscribe($listID, $email, $name = NULL, array $customFields = array(), &$statusMessage = NULL)
82 | {
83 | if(strlen($listID) == 0)
84 | throw new Exception\DomainException('List ID can not be empty');
85 | if(!self::isEmailValid($email))
86 | throw new Exception\InvalidEmailException($email);
87 |
88 | $request = array( 'api_key'=>$this->_getApiKey(),
89 | 'email'=>$email,
90 | 'list'=>$listID,
91 | 'boolean' => 'true');
92 | if(!is_null($name))
93 | $request['name'] = $name;
94 |
95 | foreach ($customFields as $fieldName=>$value)
96 | {
97 | if(array_key_exists($fieldName,$request))
98 | throw new Exception\ForbiddenCustomFieldNameException($fieldName);
99 | else
100 | $request[$fieldName] = $value;
101 | }
102 |
103 | $response = $this->_callSendy(self::URI_SUBSCRIBE,$request);
104 | if(!in_array($response,array(true,'true','1')))
105 | {
106 | $statusMessage = $response;
107 | return false;
108 | }
109 | else
110 | {
111 | $statusMessage = 'Success';
112 | return true;
113 | }
114 | }
115 | /**
116 | * This method unsubscribes a user from a list.
117 | *
118 | * @param string $listID the list id you want to unsubscribe a user from. This encrypted & hashed id can be found under View all lists section named ID
119 | * @param string $email user's email
120 | * @param string|null $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
121 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\InvalidEmailException|\SendyPHP\Exception\DomainException|\SendyPHP\Exception\CurlException]
122 | * @return bool
123 | */
124 | public function unsubscribe($listID, $email,&$statusMessage = NULL)
125 | {
126 | if(strlen($listID) == 0)
127 | throw new Exception\DomainException('List ID can not be empty');
128 | if(!self::isEmailValid($email))
129 | throw new Exception\InvalidEmailException($email);
130 |
131 | $request = array( 'api_key'=>$this->_getApiKey(),
132 | 'email'=>$email,
133 | 'list'=>$listID,
134 | 'boolean' => 'true');
135 |
136 | $response = $this->_callSendy(self::URI_UNSUBSCRIBE,$request);
137 | if(!in_array($response,array(true,'true','1')))
138 | {
139 | $statusMessage = $response;
140 | return false;
141 | }
142 | else
143 | {
144 | $statusMessage = 'Success';
145 | return true;
146 | }
147 | }
148 |
149 | /**
150 | * This method deletes a user from a list.
151 | *
152 | * @param string $listID the list id you want to delete a user from. This encrypted & hashed id can be found under View all lists section named ID
153 | * @param string $email user's email
154 | * @param string|null $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
155 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\InvalidEmailException|\SendyPHP\Exception\DomainException|\SendyPHP\Exception\CurlException]
156 | * @return bool
157 | */
158 | public function delete($listID, $email,&$statusMessage = NULL)
159 | {
160 | if(strlen($listID) == 0)
161 | throw new Exception\DomainException('List ID can not be empty');
162 | if(!self::isEmailValid($email))
163 | throw new Exception\InvalidEmailException($email);
164 |
165 | $request = array( 'api_key'=>$this->_getApiKey(),
166 | 'email'=>$email,
167 | 'list_id'=>$listID);
168 |
169 | $response = $this->_callSendy(self::URI_DELETE_SUBSCRIBER,$request);
170 | if(!in_array($response,array(true,'true','1')))
171 | {
172 | $statusMessage = $response;
173 | return false;
174 | }
175 | else
176 | {
177 | $statusMessage = 'Success';
178 | return true;
179 | }
180 | }
181 | /**
182 | * This method gets the current status of a subscriber (eg. subscribed, unsubscribed, bounced, complained).
183 | *
184 | * @param string $listID
185 | * @param string $email
186 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\DomainException|\SendyPHP\Exception\InvalidEmailException|\SendyPHP\Exception\CurlException]
187 | * @return \SendyPHP\Response\SubscriptionStatus
188 | */
189 | public function getSubscriptionStatus($listID, $email)
190 | {
191 | if(strlen($listID) == 0)
192 | throw new Exception\DomainException('List ID can not be empty');
193 | if(!self::isEmailValid($email))
194 | throw new Exception\InvalidEmailException($email);
195 |
196 | $request = array( 'api_key'=>$this->_getApiKey(),
197 | 'list_id'=>$listID,
198 | 'email' => $email);
199 |
200 | $response = $this->_callSendy(self::URI_SUBSCRIPTION_STATUS,$request);
201 | return new Response\SubscriptionStatus($response);
202 | }
203 | /**
204 | * This method gets the total active subscriber count.
205 | *
206 | * @param string $listID the id of the list you want to get the active subscriber count. This encrypted id can be found under View all lists section named ID
207 | * @param string|null $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
208 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\DomainException|\SendyPHP\Exception\CurlException]
209 | * @return number|false
210 | */
211 | public function getActiveSubscriberCount($listID, &$statusMessage = NULL)
212 | {
213 | if(strlen($listID) == 0)
214 | throw new Exception\DomainException('List ID can not be empty');
215 |
216 | $request = array( 'api_key'=>$this->_getApiKey(),
217 | 'list_id'=>$listID);
218 |
219 | $response = $this->_callSendy(self::URI_ACTIVE_SUBSCRIBER_COUNT,$request);
220 |
221 | if(!is_numeric($response))
222 | {
223 | $statusMessage = $response;
224 | return false;
225 | }
226 | else
227 | {
228 | $statusMessage = 'Success';
229 | return intval($response);
230 | }
231 | }
232 | /**
233 | * Creates draft of campaign
234 | *
235 | * @param string $brandID Brand IDs can be found under 'Brands' page named ID
236 | * @param Model\Campaign $campaign configured campaign
237 | * @param string|NULL $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
238 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\CurlException]
239 | * @return bool
240 | */
241 | public function createCampaign($brandID, Model\Campaign $campaign, &$statusMessage = NULL)
242 | {
243 | $request = array( 'api_key'=>$this->_getApiKey(),
244 | 'from_name'=>$campaign->getSender()->getName(),
245 | 'from_email'=>$campaign->getSender()->getAddress(),
246 | 'reply_to'=>$campaign->getSender()->getReplyAddress(),
247 | 'subject'=>$campaign->getSubject(),
248 | 'html_text'=>$campaign->getEmailBody()->getHtml(),
249 | 'brand_id'=>$brandID,
250 | 'send_campaign'=>0);
251 |
252 | $plainText = $campaign->getEmailBody()->getPlainText();
253 | if(!is_null($plainText))
254 | $request['plain_text'] = $plainText;
255 |
256 | $response = $this->_callSendy(self::URI_CAMPAIGN,$request);
257 | $statusMessage = $response;
258 | if($response == 'Campaign created')
259 | return true;
260 | else
261 | return false;
262 | }
263 | /**
264 | * Creates draft and automatically sends campaign
265 | *
266 | * @param array $listIDs The encrypted & hashed ids can be found under View all lists section named ID.
267 | * @param Model\Campaign $campaign configured campaign
268 | * @param string|NULL $statusMessage optional - here will be returned status message f.e. if you get FALSE again, and again, here you can find why
269 | * @throws \SendyPHP\Exception [\SendyPHP\Exception\CurlException|\SendyPHP\Exception\DomainException]
270 | * @return bool
271 | */
272 | public function sendCampaign(array $listIDs, Model\Campaign $campaign, &$statusMessage = NULL)
273 | {
274 | if(count($listIDs) == 0)
275 | throw new Exception\DomainException('List IDs can not be empty');
276 |
277 | $request = array( 'api_key'=>$this->_getApiKey(),
278 | 'from_name'=>$campaign->getSender()->getName(),
279 | 'from_email'=>$campaign->getSender()->getAddress(),
280 | 'reply_to'=>$campaign->getSender()->getReplyAddress(),
281 | 'subject'=>$campaign->getSubject(),
282 | 'html_text'=>$campaign->getEmailBody()->getHtml(),
283 | 'list_ids'=>implode(',',$listIDs),
284 | 'send_campaign'=>1);
285 |
286 | $plainText = $campaign->getEmailBody()->getPlainText();
287 | if(!is_null($plainText))
288 | $request['plain_text'] = $plainText;
289 |
290 | $response = $this->_callSendy(self::URI_CAMPAIGN,$request);
291 | $statusMessage = $response;
292 | if($response == 'Campaign created and now sending')
293 | return true;
294 | else
295 | return false;
296 | }
297 | /**
298 | * Sets sendy installation URL
299 | *
300 | * @param string $URL
301 | * @throws \SendyPHP\Exception\InvalidURLException
302 | */
303 | public function setURL($URL)
304 | {
305 | if(!self::isURLValid($URL))
306 | throw new Exception\InvalidURLException($URL);
307 |
308 | $this->_URL = $URL;
309 | }
310 | /**
311 | * Sets api key
312 | *
313 | * your API key is available in sendy Settings
314 | *
315 | * @param string $apiKey
316 | * @throws \SendyPHP\Exception\DomainException
317 | */
318 | public function setApiKey($apiKey)
319 | {
320 | if(!is_string($apiKey))
321 | throw new Exception\DomainException('Api key have to be string '.gettype($apiKey).' given');
322 |
323 | $this->_apiKey = $apiKey;
324 | }
325 | /**
326 | * Sets cURL option
327 | *
328 | * You can set cURL options f.e. CURLOPT_SSL_VERIFYPEER or CURLOPT_SSL_VERIFYHOST
329 | * some parameters (\CURLOPT_RETURNTRANSFER,\CURLOPT_POST,\CURLOPT_POSTFIELDS) are used, if you try to set one of these exception is thrown
330 | *
331 | * @param number $option use \CURLOPT_* constant
332 | * @param mixed $value
333 | * @throws \SendyPHP\Exception\UnexpectedValueException
334 | * @see http://php.net/manual/en/function.curl-setopt.php
335 | */
336 | public function setCurlOption($option, $value)
337 | {
338 | // reserved options check
339 | if(in_array($option,array(\CURLOPT_RETURNTRANSFER,\CURLOPT_POST,\CURLOPT_POSTFIELDS)))
340 | throw new Exception\UnexpectedValueException('cURL option ['.$option.'] is reserved and can not be changed');
341 |
342 | $this->_cURLOption[$option] = $value;
343 | }
344 | /**
345 | * Clears user defined cURL options
346 | */
347 | public function clearCurlOptions()
348 | {
349 | $this->_cURLOption = array();
350 | }
351 | /**
352 | * Checks URL validity
353 | *
354 | * returns TRUE if given URL is valid
355 | *
356 | * @param mixed $url
357 | * @return bool
358 | */
359 | public static function isURLValid($url)
360 | {
361 | return (filter_var($url,\FILTER_VALIDATE_URL)!==false);
362 | }
363 | /**
364 | * Checks Email validity
365 | *
366 | * returns TRUE if given e-mail address is valid
367 | *
368 | * @param mixed $email
369 | * @return bool
370 | */
371 | public static function isEmailValid($email)
372 | {
373 | return (filter_var($email,\FILTER_VALIDATE_EMAIL)!==false);
374 | }
375 | /**
376 | * Returns URL
377 | *
378 | * if no no URL is defined throws an exception
379 | *
380 | * @throws Exception\UnexpectedValueException
381 | * @return string
382 | */
383 | protected function _getURL()
384 | {
385 | if(is_null($this->_URL))
386 | throw new Exception\UnexpectedValueException('There is no Sendy URL defined - use setURL() first');
387 |
388 | return $this->_URL;
389 | }
390 | /**
391 | * Returns API key
392 | *
393 | * @return string
394 | * @throws Exception\UnexpectedValueException
395 | */
396 | protected function _getApiKey()
397 | {
398 | if(is_null($this->_apiKey))
399 | throw new Exception\UnexpectedValueException('There is no Sendy Api Key defined - use setAPIKey() first');
400 |
401 | return $this->_apiKey;
402 | }
403 | /**
404 | * Returns user specified cURL options
405 | *
406 | * @return array
407 | */
408 | protected function _getCurlOptions()
409 | {
410 | return $this->_cURLOption;
411 | }
412 | /**
413 | * Call sendy api
414 | *
415 | * @param string $URI
416 | * @param array $params
417 | * @throws Exception\CurlException
418 | * @return string
419 | */
420 | protected function _callSendy($URI, array $params)
421 | {
422 | $url = $this->_getURL() .'/'. $URI;
423 | $resource = curl_init($url);
424 |
425 | if($resource === false)
426 | throw new Exception\CurlException('initialization failed. URL: '.$url);
427 |
428 | $postData = http_build_query($params);
429 |
430 | $curlOptions = $this->_getCurlOptions();
431 |
432 | $curlOptions[\CURLOPT_RETURNTRANSFER] = 1;
433 | $curlOptions[\CURLOPT_POST] = 1;
434 | $curlOptions[\CURLOPT_POSTFIELDS] = $postData;
435 |
436 | foreach($curlOptions as $option=>$value)
437 | {
438 | if(!curl_setopt($resource, $option, $value))
439 | throw new Exception\CurlException('option setting failed. Option: ['.$option.'] , value ['.$value.'])',$resource);
440 | }
441 |
442 | $result = curl_exec($resource);
443 | if($result === false)
444 | throw new Exception\CurlException('exec failed',$resource);
445 |
446 | curl_close($resource);
447 |
448 | return $result;
449 | }
450 | }
451 |
--------------------------------------------------------------------------------
/src/autoload.php:
--------------------------------------------------------------------------------
1 | assertTrue($response->success());
20 | $this->assertFalse($response->failed());
21 | }
22 | /**
23 | * @test
24 | * @dataProvider failedResponseProvider
25 | * @param string $rawResponse
26 | */
27 | public function testFailed($rawResponse)
28 | {
29 | $response = new \SendyPHP\Response\SubscriptionStatus($rawResponse);
30 | $this->assertFalse($response->success());
31 | $this->assertTrue($response->failed());
32 | }
33 | /**
34 | * @test
35 | */
36 | public function testSubscribed()
37 | {
38 | $response = new \SendyPHP\Response\SubscriptionStatus('Subscribed');
39 | $this->assertTrue($response->success());
40 | $this->assertFalse($response->failed());
41 | $this->assertTrue($response->isSubscribed());
42 | $this->assertFalse($response->isBounced());
43 | $this->assertFalse($response->isSoftBounced());
44 | $this->assertFalse($response->isHardBounced());
45 | $this->assertFalse($response->isUnconfirmed());
46 | $this->assertFalse($response->isUnSubscribed());
47 | $this->assertFalse($response->isComplained());
48 | }
49 | /**
50 | * @test
51 | */
52 | public function testUnSubscribed()
53 | {
54 | $response = new \SendyPHP\Response\SubscriptionStatus('Unsubscribed');
55 | $this->assertTrue($response->success());
56 | $this->assertFalse($response->failed());
57 | $this->assertFalse($response->isSubscribed());
58 | $this->assertFalse($response->isBounced());
59 | $this->assertFalse($response->isSoftBounced());
60 | $this->assertFalse($response->isHardBounced());
61 | $this->assertFalse($response->isUnconfirmed());
62 | $this->assertTrue($response->isUnSubscribed());
63 | $this->assertFalse($response->isComplained());
64 | }
65 | /**
66 | * @test
67 | */
68 | public function testUnconfirmed()
69 | {
70 | $response = new \SendyPHP\Response\SubscriptionStatus('Unconfirmed');
71 | $this->assertTrue($response->success());
72 | $this->assertFalse($response->failed());
73 | $this->assertFalse($response->isSubscribed());
74 | $this->assertFalse($response->isBounced());
75 | $this->assertFalse($response->isSoftBounced());
76 | $this->assertFalse($response->isHardBounced());
77 | $this->assertTrue($response->isUnconfirmed());
78 | $this->assertFalse($response->isUnSubscribed());
79 | $this->assertFalse($response->isComplained());
80 | }
81 | /**
82 | * @test
83 | */
84 | public function testBounced()
85 | {
86 | $response = new \SendyPHP\Response\SubscriptionStatus('Bounced');
87 | $this->assertTrue($response->success());
88 | $this->assertFalse($response->failed());
89 | $this->assertFalse($response->isSubscribed());
90 | $this->assertTrue($response->isBounced());
91 | $this->assertFalse($response->isSoftBounced());
92 | $this->assertTrue($response->isHardBounced());
93 | $this->assertFalse($response->isUnconfirmed());
94 | $this->assertFalse($response->isUnSubscribed());
95 | $this->assertFalse($response->isComplained());
96 | }
97 | /**
98 | * @test
99 | */
100 | public function testSoftBounced()
101 | {
102 | $response = new \SendyPHP\Response\SubscriptionStatus('Soft bounced');
103 | $this->assertTrue($response->success());
104 | $this->assertFalse($response->failed());
105 | $this->assertFalse($response->isSubscribed());
106 | $this->assertTrue($response->isBounced());
107 | $this->assertTrue($response->isSoftBounced());
108 | $this->assertFalse($response->isHardBounced());
109 | $this->assertFalse($response->isUnconfirmed());
110 | $this->assertFalse($response->isUnSubscribed());
111 | $this->assertFalse($response->isComplained());
112 | }
113 | /**
114 | * @test
115 | */
116 | public function testComplained()
117 | {
118 | $response = new \SendyPHP\Response\SubscriptionStatus('Complained');
119 | $this->assertTrue($response->success());
120 | $this->assertFalse($response->failed());
121 | $this->assertFalse($response->isSubscribed());
122 | $this->assertFalse($response->isBounced());
123 | $this->assertFalse($response->isSoftBounced());
124 | $this->assertFalse($response->isHardBounced());
125 | $this->assertFalse($response->isUnconfirmed());
126 | $this->assertFalse($response->isUnSubscribed());
127 | $this->assertTrue($response->isComplained());
128 | }
129 | /**
130 | * @test
131 | * @dataProvider badResponseProvider
132 | * @param mixed $response
133 | */
134 | public function testBadResponse($response)
135 | {
136 | $response = new \SendyPHP\Response\SubscriptionStatus($response);
137 | $this->assertFalse($response->success());
138 | $this->assertTrue($response->failed());
139 | $this->assertFalse($response->isSubscribed());
140 | $this->assertFalse($response->isBounced());
141 | $this->assertFalse($response->isSoftBounced());
142 | $this->assertFalse($response->isHardBounced());
143 | $this->assertFalse($response->isUnconfirmed());
144 | $this->assertFalse($response->isUnSubscribed());
145 | $this->assertFalse($response->isComplained());
146 | }
147 | /**
148 | * Dataprovider for success responses
149 | *
150 | * Includes all success responses from documentation
151 | * @link http://sendy.co/api section ["Subscription status" > "Response" > "Error"]
152 | * @return array
153 | */
154 | public static function successResponseProvider()
155 | {
156 | return array(array('Subscribed'),array('Unsubscribed'),array('Unconfirmed'),array('Bounced'),array('Soft bounced'),array('Complained'));
157 | }
158 | /**
159 | * Dataprovider for error responses
160 | *
161 | * Includes all error responses from documentation
162 | * @link http://sendy.co/api section ["Subscription status" > "Response" > "Error"]
163 | * @return array
164 | */
165 | public static function failedResponseProvider()
166 | {
167 | return array(array('No data passed'),array('API key not passed'),array('Email not passed'),array('List ID not passed'),array('Email does not exist in list'));
168 | }
169 | /**
170 | * Dataprovider for bad responses
171 | *
172 | * @return array
173 | */
174 | public static function badResponseProvider()
175 | {
176 | return array(array(NULL),array(''),array(-1),array(1));
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/tests/TestBootstrap.php:
--------------------------------------------------------------------------------
1 |