Skip to content
This repository has been archived by the owner on Sep 28, 2020. It is now read-only.

Commit

Permalink
Merge pull request #4 from cjcox17/master
Browse files Browse the repository at this point in the history
Use laravel Cache driver in place of file and redis code
  • Loading branch information
Chris-Pratt-Clystnet authored Jul 9, 2018
2 parents 9902962 + 5678372 commit f359f9f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 109 deletions.
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ Use the Vtiger webservice (REST) API from within Laravel for the following opera
- Retrieve
- Update
- Delete
- Search
- Query
- Describe

See [Third Party App Integration (REST APIs)](http://community.vtiger.com/help/vtigercrm/developers/third-party-app-integration.html)
See [Third Party App Integration (REST APIs)](http://community.vtiger.com/help/vtigercrm/developers/third-party-app-integration.html)

## Installation, Configuration and Usage

Expand Down Expand Up @@ -46,15 +47,13 @@ See [Third Party App Integration (REST APIs)](http://community.vtiger.com/help/v
- In your application, edit *config/vtiger.php* and replace the following array values
- Set the url to the https://{DOMAIN_NAME}/webservice.php
- Set the username and accesskey with your CRM username and access key.
- Set the session drive to either file or reddis
- Set persistconnection to false if you want a fresh login with each request

|key |value |
|-----------------|-------------------------------------|
|url |http://www.example.com/webservice.php|
|username |API |
|accesskey |irGsy9HB0YOZdEA |
|sessiondriver |file |
|persistconnection|true |
|max_retries |10 |

Expand All @@ -70,7 +69,7 @@ use Vtiger;

#### Create

To insert a record into the CRM, first create an array of data to insert. Don't forget the added the id of the `assigned_user_id` (i.e. '4x12') otherwise the insert will fail as `assigned_user_id` is a mandatory field.
To insert a record into the CRM, first create an array of data to insert. Don't forget the added the id of the `assigned_user_id` (i.e. '4x12') otherwise the insert will fail as `assigned_user_id` is a mandatory field.
```php
$data = array(
'assigned_user_id' => '',
Expand Down Expand Up @@ -122,6 +121,26 @@ $obj = Vtiger::retrieve($id);
var_dump($obj);
```

#### Search

This function is a sql query builder wrapped around the query function. Accepts instance of laravels QueryBuilder.
```php
$query = DB::table('Leads')->select('id', 'firstname', 'lastname')->where('firstname', 'John');

$obj = Vtiger::search('Leads', $query);

//loop over result
foreach($obj->result as $result) {
// do something
}
```

By default the function will quote but not escape your inputs, if you wish for your data to not be quoted, set the 3rd paramater to false like so:
```php
$obj = Vtiger::search('Leads', $query, false);
```

Also keep in mind that Victiger has several limitations on it's sql query capabilities. You can not use conditional grouping i.e "where (firstname = 'John' AND 'lastname = 'Doe') OR (firstname = 'Jane' AND lastname = 'Smith') will fail.
#### Query

To use the [Query Operation](http://community.vtiger.com/help/vtigercrm/developers/third-party-app-integration.html#query-operation), you first need to create a SQL query.
Expand Down
1 change: 0 additions & 1 deletion src/Config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
'url' => 'path/to/vtiger/webservice.php',
'username' => '',
'accesskey' => '',
'sessiondriver' => 'file', //reddis or file
'persistconnection' => true,
'max_retries' => 10
];
166 changes: 62 additions & 104 deletions src/Vtiger.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
use InvalidArgumentException;
use Mockery\CountValidator\Exception;
use Psr\Http\Message\ResponseInterface;
use \Illuminate\Contracts\Filesystem\FileNotFoundException;
use Storage;
use Config;
use Redis;
use Cache;
use DB;

/**
* Laravel wrapper for the VTgier API
Expand All @@ -20,7 +18,6 @@
*/
class Vtiger
{

/** @var VtigerErrorElement[] */
private $vTigerErrors;

Expand All @@ -33,9 +30,6 @@ class Vtiger
/** @var string */
protected $accessKey;

/** @var string */
protected $sessionDriver;

/** @var string */
protected $persistConnection;

Expand All @@ -56,7 +50,6 @@ public function __construct()
$this->url = Config::get('vtiger.url');
$this->username = Config::get('vtiger.username');
$this->accessKey = Config::get('vtiger.accesskey');
$this->sessionDriver = Config::get('vtiger.sessiondriver');
$this->persistConnection = Config::get('vtiger.persistconnection');
$this->maxRetries = Config::get('vtiger.max_retries');

Expand All @@ -65,22 +58,21 @@ public function __construct()
1 => new VtigerErrorElement('API request did not complete correctly - Response code: ', 1),
2 => new VtigerErrorElement('Success property not set on VTiger response', 2),
3 => new VtigerErrorElement('Error property not set on VTiger response when success is false', 3),
4 => new VtigerErrorElement('Session driver type of ' . $this->sessionDriver . ' is not supported', 4),
5 => new VtigerErrorElement('Could not complete login request within ' . $this->maxRetries . ' tries', 5),
4 => new VtigerErrorElement('There are no search fields in the array', 4),
5 => new VtigerErrorElement('Could not complete login request within ' . $this->maxRetries . ' tries', 5),
6 => new VtigerErrorElement(
'Could not complete get token request within ' . $this->maxRetries . ' tries',
6
),
7 => new VtigerErrorElement('Guzzle ran into problems - ', 7),
8 => new VtigerErrorElement('Redis problem - ', 8),
8 => new VtigerErrorElement('Laravel Cache problem', 8),
];

try {
$this->guzzleClient = new Client(['http_errors' => false, 'verify' => false]); //GuzzleHttp\Client
} catch (InvalidArgumentException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}

}

/**
Expand Down Expand Up @@ -109,34 +101,13 @@ public function connection($url, $username, $accessKey)
*/
protected function sessionId()
{
// Check the session file exists
switch ($this->sessionDriver) {
case "file":
if (Storage::disk('local')->exists('session.json')) {
try {
$sessionData = json_decode(Storage::disk('local')->get('session.json'));
} catch (FileNotFoundException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
}
break;
case "redis":
$sessionData = json_decode(Redis::get('clystnet_vtiger'));

if (!$sessionData) {
throw VtigerError::init($this->vTigerErrors, 8, 'Could not get the session data from index clystnet_vtiger');
}
break;
default:
throw new VtigerError("Session driver type of " . $this->sessionDriver . " is not supported", 4);
}
// Get the sessionData from the cache
$sessionData = json_decode(Cache::get('clystnet_vtiger'));

if (isset($sessionData)) {
if (
isset($sessionData) &&
if (isset($sessionData) &&
property_exists($sessionData, 'expireTime') &&
property_exists($sessionData, 'token')
) {
property_exists($sessionData, 'token')) {
if ($sessionData->expireTime < time() || empty($sessionData->token)) {
$sessionData = $this->storeSession();
}
Expand Down Expand Up @@ -195,25 +166,17 @@ protected function login($sessionData)
} while (!isset($loginResult->success) && $tryCounter <= $this->maxRetries);

if ($tryCounter >= $this->maxRetries) {
throw new VtigerError("Could not complete login request within " . $this->maxRetries . " tries", 5);
throw new VtigerError('Could not complete login request within ' . $this->maxRetries . ' tries', 5);
}

// If api login failed
if ($response->getStatusCode() !== 200 || !$loginResult->success) {
if (!$loginResult->success) {
if ($loginResult->error->code == "INVALID_USER_CREDENTIALS" || $loginResult->error->code == "INVALID_SESSIONID") {
if ($this->sessionDriver == 'file') {
if (Storage::disk('local')->exists('session.json')) {
try {
Storage::disk('local')->delete('session.json');
} catch (FileNotFoundException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
}
} elseif ($this->sessionDriver == 'redis') {
if (Redis::del('clystnet_vtiger') < 1) {
throw VtigerError::init($this->vTigerErrors, 8, 'Nothing to delete for index clystnet_vtiger');
}
if ($loginResult->error->code == 'INVALID_USER_CREDENTIALS' || $loginResult->error->code == 'INVALID_SESSIONID') {
if (!Cache::has('clystnet_vtiger')) {
throw VtigerError::init($this->vTigerErrors, 8, 'Nothing to delete for index clystnet_vtiger');
} else {
Cache::forget('clystnet_vtiger');
}
} else {
$this->_processResult($response);
Expand All @@ -225,26 +188,12 @@ protected function login($sessionData)
// login ok so get sessionid and update our session
$sessionId = $loginResult->result->sessionName;

switch ($this->sessionDriver) {
case "file":
if (Storage::disk('local')->exists('session.json')) {
try {
$json = json_decode(Storage::disk('local')->get('session.json'));
$json->sessionid = $sessionId;
Storage::disk('local')->put('session.json', json_encode($json));
} catch (FileNotFoundException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
}
break;
case "redis":
Redis::incr('loggedin');
$json = json_decode(Redis::get('clystnet_vtiger'));
$json->sessionid = $sessionId;
Redis::set('clystnet_vtiger', json_encode($json));
break;
default:
throw new VtigerError("Session driver type of " . $this->sessionDriver . " is not supported", 4);
if (Cache::has('clystnet_vtiger')) {
$json = json_decode(Cache::pull('clystnet_vtiger'));
$json->sessionid = $sessionId;
Cache::forever('clystnet_vtiger', json_encode($json));
} else {
throw VtigerError::init($this->vTigerErrors, 8, 'There is no key for index clystnet_vtiger.');
}
}

Expand All @@ -262,19 +211,7 @@ protected function storeSession()
$updated = $this->getToken();

$output = (object)$updated;
if ($this->sessionDriver == 'file') {
try {
Storage::disk('local')->put('session.json', json_encode($output));
} catch (FileNotFoundException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
} elseif ($this->sessionDriver == 'redis') {
$setResult = Redis::set('clystnet_vtiger', json_encode($output));

if (!$setResult) {
throw VtigerError::init($this->vTigerErrors, 8, 'Could not set the session data in index clystnet_vtiger');
}
}
$cacheResult = Cache::forever('clystnet_vtiger', json_encode($output));

return $output;
}
Expand Down Expand Up @@ -305,17 +242,17 @@ protected function getToken()
} while (!isset($this->_processResponse($response)->success) && $tryCounter <= $this->maxRetries);

if ($tryCounter >= $this->maxRetries) {
throw new VtigerError("Could not complete get token request within " . $this->maxRetries . " tries", 6);
throw new VtigerError('Could not complete get token request within ' . $this->maxRetries . ' tries', 6);
}

// decode the response
$challenge = $this->_processResult($response);

// Everything ok so create a token from response
$output = array(
$output = [
'token' => $challenge->result->token,
'expireTime' => $challenge->result->expireTime,
);
];

return $output;
}
Expand All @@ -337,12 +274,15 @@ protected function close($sessionId)
try {
// send a request to close current connection
$response = $this->guzzleClient->request(
'POST', $this->url, [
'query' => [
'operation' => 'logout',
'sessionName' => $sessionId
'POST',
$this->url,
[
'query' => [
'operation' => 'logout',
'sessionName' => $sessionId
]
]
]);
);
} catch (GuzzleException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
Expand Down Expand Up @@ -380,6 +320,23 @@ public function query($query)
return $this->_processResult($response);
}

public function search($query, $quote = true)
{
$bindings = $query->getBindings();
$queryString = $query->toSQL();

foreach ($bindings as $binding) {
if ($quote) {
$queryString = preg_replace('/\?/', DB::connection()->getPdo()->quote($binding), $queryString, 1);
} else {
$queryString = preg_replace('/\?/', $binding, $queryString, 1);
}
}
$queryString = str_replace('`', '', $queryString) . ';';

return $this->query($queryString);
}

/**
* Retreive a record from the VTiger API
* Format of id must be {moudler_code}x{item_id}, e.g 4x12
Expand All @@ -402,7 +359,7 @@ public function retrieve($id)
'id' => $id
]
]);
} catch (GuzzleException $e) {
} catch (GuzzleException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}

Expand Down Expand Up @@ -444,7 +401,7 @@ public function create($elem, $data)
'elementType' => $elem
]
]);
} catch (GuzzleException $e) {
} catch (GuzzleException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}

Expand Down Expand Up @@ -476,7 +433,7 @@ public function update($object)
'element' => json_encode($object),
]
]);
} catch (GuzzleException $e) {
} catch (GuzzleException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}

Expand Down Expand Up @@ -531,13 +488,16 @@ public function describe($elementType)
try {
// send a request to describe a module (which returns a list of available fields) for a Vtiger module
$response = $this->guzzleClient->request(
'GET', $this->url, [
'query' => [
'operation' => 'describe',
'sessionName' => $sessionId,
'elementType' => $elementType
'GET',
$this->url,
[
'query' => [
'operation' => 'describe',
'sessionName' => $sessionId,
'elementType' => $elementType
]
]
]);
);
} catch (GuzzleException $e) {
throw VtigerError::init($this->vTigerErrors, 7, $e->getMessage());
}
Expand Down Expand Up @@ -618,8 +578,6 @@ protected function _processResponseError($processedData)
if (!isset($processedData->error)) {
throw VtigerError::init($this->vTigerErrors, 3);
}

throw VtigerError::init($this->vTigerErrors, 0, $processedData->error->message);
}

}

0 comments on commit f359f9f

Please sign in to comment.