├── .config_blank.json ├── .gitignore ├── .styleci.yml ├── LICENSE ├── README.md ├── authorise-application.php ├── composer.json ├── factories └── ContactFactory.php ├── helpers └── GoogleHelper.php ├── objects └── Contact.php ├── redirect-handler.php ├── test.php └── test_individual.php /.config_blank.json: -------------------------------------------------------------------------------- 1 | { 2 | "clientID": "", 3 | "clientSecret": "", 4 | "redirectUri": "", 5 | "developerKey": "", 6 | "refreshToken": "" 7 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Composer and vendor files 2 | composer.lock 3 | vendor/ 4 | 5 | # Config.json file changes should be ignored to prevent private API access keys being uploaded to Git 6 | .config.json 7 | 8 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | disabled: 2 | - short_array_syntax -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Rapid Web Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP Google Contacts v3 API 2 | 3 | [![Packagist](https://img.shields.io/packagist/dt/rapidwebltd/php-google-contacts-v3-api.svg)](https://packagist.org/packages/rapidwebltd/php-google-contacts-v3-api/stats) 4 | 5 | PHP library for the Google Contacts API (v3) 6 | 7 | **💡 NOTE: If you're starting a new project, we strongly recommend using our [PHP Google People API](https://github.com/rapidwebltd/php-google-people-api) package instead. It is more capable than this package and uses a newer API which will probably be supported for longer.** 8 | 9 | ## Installation & Dependencies 10 | 11 | This package and its dependencies can be installed using `composer`. 12 | 13 | Just run `composer require rapidwebltd/php-google-contacts-v3-api`. 14 | 15 | ## Setup 16 | 17 | 1. Install required dependencies. See the 'Dependencies' section above. 18 | 2. Copy or rename `.config_blank.json` to `.config.json`. Note the dot (`.`) at the beginning of the file name. 19 | 3. Fill in the `clientID`, `clientSecret` and `redirectUri` in `.config.json`. 20 | * Note that `redirectUri` should be configure to point towards the `redirect-handler.php` file. 21 | * The `clientID` and `clientSecret` can be found in the Google Developers console at https://console.developers.google.com/ under 'APIs & auth' -> 'Credentials', after enabling the Contacts API. 22 | 4. Go to `authorise-application.php` in a web browser. This should give you a URL to authorise your application for Google Contacts. 23 | 5. Go to the authorisation URL provided by the previous step. 24 | 6. Accept the permissions requested on the page displayed. You should then be redirected back to the `redirect-handler.php` file. 25 | 7. The page generated by the `redirect-handler.php` file should then present you with a refresh token. Copy this into your `.config.json`. 26 | 8. Setup is done! 27 | 28 | ## Usage 29 | 30 | After the library has been installed and the setup and account association steps have been completed, you can make use of the library. 31 | 32 | If your framework does not do this for you, remember to include the require the `vendor/autoload.php` file on any pages you wish to make use of this library on. 33 | 34 | ### Retrieving Google Contacts 35 | 36 | The following code will retrieve all contacts from the associated Google account. 37 | 38 | ```php 39 | $contacts = rapidweb\googlecontacts\factories\ContactFactory::getAll(); 40 | 41 | var_dump($contacts); 42 | ``` 43 | 44 | The `ContactFactory::getAll()` method will return an array of `Contact` objects. The contact's details will be available as public member variables of these objects. 45 | 46 | The `selfURL` contained within each `Contact` object is the unique reference to this particular contact. If you need to retrieve a specific contact in the future, you will need to store this `selfURL`. 47 | 48 | To retrieve a specific contact (by its selfURL), use the following code. 49 | 50 | ```php 51 | $selfURL = "..."; 52 | 53 | $contact = rapidweb\googlecontacts\factories\ContactFactory::getBySelfURL($selfURL); 54 | 55 | var_dump($contact); 56 | ``` 57 | 58 | This `ContactFactory::getBySelfURL` method will return a single `Contact` object. 59 | 60 | Google Contact properties are accessed as follows. 61 | 62 | ```php 63 | $selfURL = "..."; 64 | 65 | $contact = rapidweb\googlecontacts\factories\ContactFactory::getBySelfURL($selfURL); 66 | 67 | echo $contact->name; 68 | echo $contact->phoneNumber; 69 | echo $contact->email; 70 | echo $contact->content; 71 | ``` 72 | 73 | ### Updating existing Google Contacts 74 | 75 | The updating of Google Contacts using this library is done in a very object orientated manner. 76 | 77 | You must first retrieve a `Contact` object using one of the methods mentioned previously. You can then modify the contact object's public member variables. To save these changes back to the Google Contacts service, you then pass the modified object to the `ContactFactory::submitUpdates($contact)` method. 78 | 79 | The following code demonstrates in full retrieving a contact, modifying it and submitting the updates. 80 | 81 | ```php 82 | $selfURL = "..."; 83 | 84 | $contact = rapidweb\googlecontacts\factories\ContactFactory::getBySelfURL($selfURL); 85 | 86 | var_dump($contact); 87 | 88 | $contact->name = 'Test'; 89 | $contact->phoneNumber = '07812363789'; 90 | $contact->email = 'test@example.com'; 91 | $contact->content = 'Note for example'; 92 | 93 | $contactAfterUpdate = rapidweb\googlecontacts\factories\ContactFactory::submitUpdates($contact); 94 | 95 | var_dump($contactAfterUpdate); 96 | ``` 97 | 98 | ### Creating new Google Contacts 99 | 100 | Creating a new Google Contact is very easy. Simply call the `ContactFactory::create($name, $phoneNumber, $emailAddress)` method, passing through appropriate parameters. This method will return the created contact as a `Contact` object including its newly assigned `selfURL`. 101 | 102 | ```php 103 | $name = "Frodo Baggins"; 104 | $phoneNumber = "06439111222"; 105 | $emailAddress = "frodo@example.com"; 106 | $note = "Note for example"; 107 | 108 | $newContact = rapidweb\googlecontacts\factories\ContactFactory::create($name, $phoneNumber, $emailAddress, $note); 109 | ``` 110 | 111 | ### Config file override 112 | 113 | Each method has optional argument for config file override. It is useful when you want to use work with multiple Google accounts at the same time. 114 | 115 | ```php 116 | $customConfig = (object) array( 117 | 'clientID' => '', 118 | 'clientSecret' => '', 119 | 'redirectUri' => '', 120 | 'developerKey' => '', 121 | 'refreshToken' => '' 122 | ); 123 | 124 | $contacts = ContactFactory::getAll($customConfig); 125 | ``` 126 | 127 | You have to define all variables as the original config is completely ignored. To be more precise, it doesn't have to exist at all. 128 | 129 | 130 | ## Examples 131 | 132 | Take a look at the following files for basic examples of how to retrieve contacts. They can also be used to ensure you have currently associated your Google account with the library. 133 | 134 | * test.php 135 | * test_individual.php 136 | -------------------------------------------------------------------------------- /authorise-application.php: -------------------------------------------------------------------------------- 1 | =5.2.1", 10 | "google/apiclient": ">=1.1.4 <2.0.0" 11 | }, 12 | "autoload": { 13 | "psr-4": { 14 | "rapidweb\\googlecontacts\\": "." 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /factories/ContactFactory.php: -------------------------------------------------------------------------------- 1 | getAuth()->authenticatedRequest($req); 17 | 18 | $response = $val->getResponseBody(); 19 | 20 | $xmlContacts = simplexml_load_string($response); 21 | $xmlContacts->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); 22 | 23 | $contactsArray = array(); 24 | 25 | foreach ($xmlContacts->entry as $xmlContactsEntry) { 26 | $contactDetails = array(); 27 | 28 | $contactDetails['id'] = (string) $xmlContactsEntry->id; 29 | $contactDetails['name'] = (string) $xmlContactsEntry->title; 30 | $contactDetails['content'] = (string) $xmlContactsEntry->content; 31 | 32 | foreach ($xmlContactsEntry->children() as $key => $value) { 33 | $attributes = $value->attributes(); 34 | 35 | if ($key == 'link') { 36 | if ($attributes['rel'] == 'edit') { 37 | $contactDetails['editURL'] = (string) $attributes['href']; 38 | } elseif ($attributes['rel'] == 'self') { 39 | $contactDetails['selfURL'] = (string) $attributes['href']; 40 | } elseif ($attributes['rel'] == 'http://schemas.google.com/contacts/2008/rel#edit-photo') { 41 | $contactDetails['photoURL'] = (string) $attributes['href']; 42 | } 43 | } 44 | } 45 | 46 | $contactGDNodes = $xmlContactsEntry->children('http://schemas.google.com/g/2005'); 47 | foreach ($contactGDNodes as $key => $value) { 48 | switch ($key) { 49 | case 'organization': 50 | $contactDetails[$key]['orgName'] = (string) $value->orgName; 51 | $contactDetails[$key]['orgTitle'] = (string) $value->orgTitle; 52 | break; 53 | case 'email': 54 | $attributes = $value->attributes(); 55 | $emailadress = (string) $attributes['address']; 56 | $emailtype = substr(strstr($attributes['rel'], '#'), 1); 57 | $contactDetails[$key][] = ['type' => $emailtype, 'email' => $emailadress]; 58 | break; 59 | case 'phoneNumber': 60 | $attributes = $value->attributes(); 61 | //$uri = (string) $attributes['uri']; 62 | $type = substr(strstr($attributes['rel'], '#'), 1); 63 | //$e164 = substr(strstr($uri, ':'), 1); 64 | $contactDetails[$key][] = ['type' => $type, 'number' => $value->__toString()]; 65 | break; 66 | default: 67 | $contactDetails[$key] = (string) $value; 68 | break; 69 | } 70 | } 71 | 72 | $contactsArray[] = new Contact($contactDetails); 73 | } 74 | 75 | return $contactsArray; 76 | } 77 | 78 | public static function getBySelfURL($selfURL, $customConfig = NULL) 79 | { 80 | $client = GoogleHelper::getClient($customConfig); 81 | 82 | $req = new \Google_Http_Request($selfURL); 83 | 84 | $val = $client->getAuth()->authenticatedRequest($req); 85 | 86 | $response = $val->getResponseBody(); 87 | 88 | $xmlContact = simplexml_load_string($response); 89 | $xmlContact->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); 90 | 91 | $xmlContactsEntry = $xmlContact; 92 | 93 | $contactDetails = array(); 94 | 95 | $contactDetails['id'] = (string) $xmlContactsEntry->id; 96 | $contactDetails['name'] = (string) $xmlContactsEntry->title; 97 | $contactDetails['content'] = (string) $xmlContactsEntry->content; 98 | 99 | foreach ($xmlContactsEntry->children() as $key => $value) { 100 | $attributes = $value->attributes(); 101 | 102 | if ($key == 'link') { 103 | if ($attributes['rel'] == 'edit') { 104 | $contactDetails['editURL'] = (string) $attributes['href']; 105 | } elseif ($attributes['rel'] == 'self') { 106 | $contactDetails['selfURL'] = (string) $attributes['href']; 107 | } elseif ($attributes['rel'] == 'http://schemas.google.com/contacts/2008/rel#edit-photo') { 108 | $contactDetails['photoURL'] = (string) $attributes['href']; 109 | } 110 | } 111 | } 112 | 113 | $contactGDNodes = $xmlContactsEntry->children('http://schemas.google.com/g/2005'); 114 | foreach ($contactGDNodes as $key => $value) { 115 | switch ($key) { 116 | case 'organization': 117 | $contactDetails[$key]['orgName'] = (string) $value->orgName; 118 | $contactDetails[$key]['orgTitle'] = (string) $value->orgTitle; 119 | break; 120 | case 'email': 121 | $attributes = $value->attributes(); 122 | $emailadress = (string) $attributes['address']; 123 | $emailtype = substr(strstr($attributes['rel'], '#'), 1); 124 | $contactDetails[$key][] = ['type' => $emailtype, 'email' => $emailadress]; 125 | break; 126 | case 'phoneNumber': 127 | $attributes = $value->attributes(); 128 | $uri = (string) $attributes['uri']; 129 | $type = substr(strstr($attributes['rel'], '#'), 1); 130 | $e164 = substr(strstr($uri, ':'), 1); 131 | $contactDetails[$key][] = ['type' => $type, 'number' => $e164]; 132 | break; 133 | default: 134 | $contactDetails[$key] = (string) $value; 135 | break; 136 | } 137 | } 138 | 139 | return new Contact($contactDetails); 140 | } 141 | 142 | public static function submitUpdates(Contact $updatedContact, $customConfig = NULL) 143 | { 144 | $client = GoogleHelper::getClient($customConfig); 145 | 146 | $req = new \Google_Http_Request($updatedContact->selfURL); 147 | 148 | $val = $client->getAuth()->authenticatedRequest($req); 149 | 150 | $response = $val->getResponseBody(); 151 | 152 | $xmlContact = simplexml_load_string($response); 153 | $xmlContact->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); 154 | 155 | $xmlContactsEntry = $xmlContact; 156 | 157 | $xmlContactsEntry->title = $updatedContact->name; 158 | 159 | $contactGDNodes = $xmlContactsEntry->children('http://schemas.google.com/g/2005'); 160 | 161 | foreach ($contactGDNodes as $key => $value) { 162 | $attributes = $value->attributes(); 163 | 164 | if ($key == 'email') { 165 | $attributes['address'] = $updatedContact->email; 166 | } else { 167 | $xmlContactsEntry->$key = $updatedContact->$key; 168 | $attributes['uri'] = ''; 169 | } 170 | } 171 | 172 | $updatedXML = $xmlContactsEntry->asXML(); 173 | 174 | $req = new \Google_Http_Request($updatedContact->editURL); 175 | $req->setRequestHeaders(array('content-type' => 'application/atom+xml; charset=UTF-8; type=feed')); 176 | $req->setRequestMethod('PUT'); 177 | $req->setPostBody($updatedXML); 178 | 179 | $val = $client->getAuth()->authenticatedRequest($req); 180 | 181 | $response = $val->getResponseBody(); 182 | 183 | $xmlContact = simplexml_load_string($response); 184 | $xmlContact->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); 185 | 186 | $xmlContactsEntry = $xmlContact; 187 | 188 | $contactDetails = array(); 189 | 190 | $contactDetails['id'] = (string) $xmlContactsEntry->id; 191 | $contactDetails['name'] = (string) $xmlContactsEntry->title; 192 | $contactDetails['content'] = (string) $xmlContactsEntry->content; 193 | 194 | foreach ($xmlContactsEntry->children() as $key => $value) { 195 | $attributes = $value->attributes(); 196 | 197 | if ($key == 'link') { 198 | if ($attributes['rel'] == 'edit') { 199 | $contactDetails['editURL'] = (string) $attributes['href']; 200 | } elseif ($attributes['rel'] == 'self') { 201 | $contactDetails['selfURL'] = (string) $attributes['href']; 202 | } 203 | } 204 | } 205 | 206 | $contactGDNodes = $xmlContactsEntry->children('http://schemas.google.com/g/2005'); 207 | 208 | foreach ($contactGDNodes as $key => $value) { 209 | $attributes = $value->attributes(); 210 | 211 | if ($key == 'email') { 212 | $contactDetails[$key] = (string) $attributes['address']; 213 | } else { 214 | $contactDetails[$key] = (string) $value; 215 | } 216 | } 217 | 218 | return new Contact($contactDetails); 219 | } 220 | 221 | public static function create($name, $phoneNumber, $emailAddress, $note, $customConfig = NULL) 222 | { 223 | $doc = new \DOMDocument(); 224 | $doc->formatOutput = true; 225 | $entry = $doc->createElement('atom:entry'); 226 | $entry->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:atom', 'http://www.w3.org/2005/Atom'); 227 | $entry->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gd', 'http://schemas.google.com/g/2005'); 228 | $entry->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gd', 'http://schemas.google.com/g/2005'); 229 | $doc->appendChild($entry); 230 | 231 | $title = $doc->createElement('title', $name); 232 | $entry->appendChild($title); 233 | 234 | $email = $doc->createElement('gd:email'); 235 | $email->setAttribute('rel', 'http://schemas.google.com/g/2005#work'); 236 | $email->setAttribute('address', $emailAddress); 237 | $entry->appendChild($email); 238 | 239 | $contact = $doc->createElement('gd:phoneNumber', $phoneNumber); 240 | $contact->setAttribute('rel', 'http://schemas.google.com/g/2005#work'); 241 | $entry->appendChild($contact); 242 | 243 | $note = $doc->createElement('atom:content', $note); 244 | $note->setAttribute('rel', 'http://schemas.google.com/g/2005#kind'); 245 | $entry->appendChild($note); 246 | 247 | $xmlToSend = $doc->saveXML(); 248 | 249 | $client = GoogleHelper::getClient($customConfig); 250 | 251 | $req = new \Google_Http_Request('https://www.google.com/m8/feeds/contacts/default/full'); 252 | $req->setRequestHeaders(array('content-type' => 'application/atom+xml; charset=UTF-8; type=feed')); 253 | $req->setRequestMethod('POST'); 254 | $req->setPostBody($xmlToSend); 255 | 256 | $val = $client->getAuth()->authenticatedRequest($req); 257 | 258 | $response = $val->getResponseBody(); 259 | 260 | $xmlContact = simplexml_load_string($response); 261 | $xmlContact->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005'); 262 | 263 | $xmlContactsEntry = $xmlContact; 264 | 265 | $contactDetails = array(); 266 | 267 | $contactDetails['id'] = (string) $xmlContactsEntry->id; 268 | $contactDetails['name'] = (string) $xmlContactsEntry->title; 269 | 270 | foreach ($xmlContactsEntry->children() as $key => $value) { 271 | $attributes = $value->attributes(); 272 | 273 | if ($key == 'link') { 274 | if ($attributes['rel'] == 'edit') { 275 | $contactDetails['editURL'] = (string) $attributes['href']; 276 | } elseif ($attributes['rel'] == 'self') { 277 | $contactDetails['selfURL'] = (string) $attributes['href']; 278 | } 279 | } 280 | } 281 | 282 | $contactGDNodes = $xmlContactsEntry->children('http://schemas.google.com/g/2005'); 283 | 284 | foreach ($contactGDNodes as $key => $value) { 285 | $attributes = $value->attributes(); 286 | 287 | if ($key == 'email') { 288 | $contactDetails[$key] = (string) $attributes['address']; 289 | } else { 290 | $contactDetails[$key] = (string) $value; 291 | } 292 | } 293 | 294 | return new Contact($contactDetails); 295 | } 296 | 297 | public static function delete(Contact $toDelete, $customConfig = NULL) 298 | { 299 | $client = GoogleHelper::getClient($customConfig); 300 | 301 | $req = new \Google_Http_Request($toDelete->editURL); 302 | $req->setRequestHeaders(array('content-type' => 'application/atom+xml; charset=UTF-8; type=feed')); 303 | $req->setRequestMethod('DELETE'); 304 | 305 | $client->getAuth()->authenticatedRequest($req); 306 | } 307 | 308 | public static function getPhoto($photoURL, $customConfig = NULL) 309 | { 310 | $client = GoogleHelper::getClient($customConfig); 311 | $req = new \Google_Http_Request($photoURL); 312 | $req->setRequestMethod('GET'); 313 | $val = $client->getAuth()->authenticatedRequest($req); 314 | $response = $val->getResponseBody(); 315 | return $response; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /helpers/GoogleHelper.php: -------------------------------------------------------------------------------- 1 | clientID = $clientID; 18 | self::$_config->clientSecret = $clientSecret; 19 | self::$_config->redirectUri = $redirectUri; 20 | self::$_config->developerKey = $developerKey; 21 | self::$_config->refreshToken = $refreshToken; 22 | } 23 | 24 | private static function loadConfig($customConfig = NULL) 25 | { 26 | self::$_config = $customConfig; 27 | if (NULL === self::$_config) { 28 | $configPath = __DIR__.'/../../../../.config.json'; 29 | if(!file_exists($configPath)) throw new \Exception('Not found config.json'); 30 | $contents = file_get_contents($configPath); 31 | self::$_config = json_decode($contents); 32 | } 33 | 34 | return self::$_config; 35 | } 36 | 37 | public static function getClient($customConfig = NULL) 38 | { 39 | $config = self::loadConfig($customConfig); 40 | 41 | $client = new \Google_Client(); 42 | 43 | $client->setApplicationName('Rapid Web Google Contacts API'); 44 | 45 | $client->setScopes(array(/* 46 | 'https://apps-apis.google.com/a/feeds/groups/', 47 | 'https://www.googleapis.com/auth/userinfo.email', 48 | 'https://apps-apis.google.com/a/feeds/alias/', 49 | 'https://apps-apis.google.com/a/feeds/user/',*/ 50 | 'https://www.google.com/m8/feeds/', 51 | /*'https://www.google.com/m8/feeds/user/',*/ 52 | )); 53 | 54 | $client->setClientId($config->clientID); 55 | $client->setClientSecret($config->clientSecret); 56 | $client->setRedirectUri($config->redirectUri); 57 | $client->setAccessType('offline'); 58 | $client->setApprovalPrompt('force'); 59 | $client->setDeveloperKey($config->developerKey); 60 | 61 | if (isset($config->refreshToken) && $config->refreshToken) { 62 | $client->refreshToken($config->refreshToken); 63 | } 64 | 65 | return $client; 66 | } 67 | 68 | public static function getAuthUrl(\Google_Client $client) 69 | { 70 | return $client->createAuthUrl(); 71 | } 72 | 73 | public static function authenticate(\Google_Client $client, $code) 74 | { 75 | $client->authenticate($code); 76 | } 77 | 78 | public static function getAccessToken(\Google_Client $client) 79 | { 80 | return json_decode($client->getAccessToken()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /objects/Contact.php: -------------------------------------------------------------------------------- 1 | $value) { 10 | $this->$key = $value; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /redirect-handler.php: -------------------------------------------------------------------------------- 1 | refresh_token)) { 24 | echo 'Google did not respond with a refresh token. You can still use the Google Contacts API, but you may to re-authorise your application in the future. '; 25 | 26 | echo 'Access token response:'; 27 | 28 | var_dump($accessToken); 29 | } else { 30 | echo 'Refresh token is: '.$accessToken->refresh_token.' - Please add this to the config file.'; 31 | } 32 | -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | name = 'Test'; 16 | $contact->phoneNumber = '07812363789'; 17 | $contact->email = 'test@example.com'; 18 | $contact->content = 'Note for example'; 19 | 20 | $contactAfterUpdate = ContactFactory::submitUpdates($contact); 21 | 22 | var_dump($contactAfterUpdate); 23 | --------------------------------------------------------------------------------