Skip to content

Instantly share code, notes, and snippets.

@jslegers
Last active October 28, 2022 12:48
Show Gist options
  • Save jslegers/b2965bad99ad299741dc to your computer and use it in GitHub Desktop.
Save jslegers/b2965bad99ad299741dc to your computer and use it in GitHub Desktop.
A pretty basic but effective class that can be used to do CRUD operations on Microsoft Dynamics NAV's Odata service for the customer entity
<?php
// A pretty basic but effective class that can be used for doing CRUD operations on Microsoft Dynamics NAV's Odata services
error_reporting(E_ALL);
ini_set("display_errors", 1);
class http_request {
protected $_handle = NULL;
protected $_credentials = '';
protected $_url = '';
protected $_service = '';
protected $_company = '';
protected $_suffix = '';
protected $_requestType = '';
protected $_header = [
'Connection: Keep-Alive',
'Accept: application/json',
'Content-Type: application/json; charset=utf-8',
'DataServiceVersion: 3.0',
'MaxDataServiceVersion: 3.0',
'Prefer: return-content',
"Accept: */*"
];
protected function _ifMatch($header, $etag) {
array_push($header, 'If-Match: W/"\'' . $etag . '\'"');
return $header;
}
protected function _setData($data) {
if (!empty($data)) {
if (count($data) === 1) {
if (is_array($data[0])) {
$this->_suffix = $this->_buildSuffix(NULL, $data[0]);
} else {
$this->_suffix = $this->_buildSuffix($data[0], NULL);
}
} else {
$this->_suffix = $this->_buildSuffix($data[0], $data[1]);
}
} else {
$this->_suffix = $this->_buildSuffix(NULL, NULL);
}
}
protected function _buildCompanySuffix() {
if ($this->_company === NULL) {
return '';
}
return 'Company(\'' . $this->_company . '\')/';
}
protected function _buildIDSuffix($id = NULL) {
if ($id === NULL) {
return '';
}
return '(\'' . $id . '\')';
}
protected function _buildQuerySuffix($fields = NULL) {
if ($fields === NULL) {
return '';
}
if ($this->_requestType === 'GET') {
$this->setOption('postfields', '');
return '?' . urldecode(http_build_query(['$select' => implode(',', $fields)]));
} elseif ($this->_requestType === 'DELETE') {
$this->setOption('postfields', '');
return '';
} else {
$this->setOption('postfields', json_encode($fields));
return '';
}
}
protected function _buildSuffix($id, $q) {
return $this->_buildCompanySuffix() . $this->_service . $this->_buildIDSuffix($id) . $this->_buildQuerySuffix($q);
}
protected function _setRequestType($requestType, $data) {
$this->_requestType = $requestType;
$this->_suffix = '';
$this->_setData($data);
switch ($requestType) {
case 'GET':
case 'POST':
$this->setOptions([
'customrequest' => $requestType,
'post' => ($requestType === 'POST'),
'url' => $this->_url . $this->_suffix,
'httpheader' => $this->_header
]);
break;
case 'PATCH':
case 'DELETE':
$this->setOptions([
'customrequest' => $requestType,
'post' => true,
'url' => $this->_url . $this->_suffix,
'httpheader' => $this->_ifMatch($this->_header, $data[1]["ETag"])
]);
break;
default:
// DO NOTHING YET
}
}
protected function _initService($provider = [], $options = []) {
if(!is_array($provider)) {
$provider = json_decode(file_get_contents($provider), true);
}
if (isset($provider['url']) && $provider['url'] !== '') {
$this->setProvider($provider['url']);
}
if (isset($provider['credentials']) && $provider['credentials'] !== '') {
$this->setCredentials($provider['credentials']);
}
if (isset($options['service']) && $options['service'] !== '') {
$this->setService($options['service']);
}
if (isset($options['company']) && $options['company'] !== '') {
$this->setCompany($options['company']);
}
$this->_handle = curl_init();
$this->setOptions([
'returntransfer' => true,
'userpwd' => $this->_credentials
]);
}
protected function _send() {
return json_decode(curl_exec($this->_handle), TRUE);
}
public static function factory($provider = [], $options = []) {
return new static($provider, $options);
}
public function __construct($provider = [], $options = []) {
$this->_initService($provider, $options);
}
public function create($data) {
$this->_setRequestType('POST', [$data]);
return $this->_send();
}
public function read() {
$this->_setRequestType('GET', func_get_args());
return $this->_send();
}
public function update($id, $data) {
$olddata = $this->read($id, ['No', 'ETag']);
$data['No'] = $olddata['No'];
$data['ETag'] = $olddata['ETag'];
$this->_setRequestType('PATCH', [$id, $data]);
return $this->_send();
}
public function delete($id) {
$olddata = $this->read($id, ['No', 'ETag']);
$this->_setRequestType('DELETE', [$id, $olddata]);
return $this->_send();
}
public function setProvider($url) {
$this->_url = $url;
}
public function setCredentials($credentials = '') {
$this->_credentials = $credentials;
}
public function setService($service = '') {
$this->_service = $service;
}
public function setCompany($company = '') {
$this->_company = $company;
}
public function setOption($key, $value) {
curl_setopt($this->_handle, constant("CURLOPT_" . strtoupper($key)), $value);
return $this;
}
public function setOptions($options) {
foreach ($options as $key => $value) {
$this->setOption($key, $value);
}
return $this;
}
public function __destruct() {
// Close handle
curl_close($this->_handle);
}
}
/* HOW TO USE : */
/* ------------ */
/* Create an instance */
$service = http_request::factory([
"url" => "https://<Server>:<WebServicePort>/<ServerInstance>/OData/",
"credentials" => "username:password"
], [
'company' => 'My company',
'service' => 'customer'
]);
/* GET a list of customers */
echo json_encode($service->read(), JSON_PRETTY_PRINT);
/* READ the values for customer 14 */
echo json_encode($service->read(14), JSON_PRETTY_PRINT);
/* CREATE a new customer */
echo json_encode($service->create([
"Name" => "A test customer",
"Address" => "Times Square",
...
]), JSON_PRETTY_PRINT);
/* UPDATE the customer with ID 15 */
echo json_encode($service->update(13, [
"Name" => "PX Automatics",
"Phone_No" => "+32 56 48 88 68",
]), JSON_PRETTY_PRINT);
/* DELETE the customer with ID 15 */
echo json_encode($service->delete(15), JSON_PRETTY_PRINT);
@jslegers
Copy link
Author

jslegers commented Mar 9, 2016

Herebelow is an overview of how to do the same, using plain cURL requests...


Read

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'https://<Server>:<WebServicePort>/<ServerInstance>/OData/Company(\'<CompanyName>\')/customer(\'1\')'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_POST, false);  

curl_setopt($ch, CURLOPT_USERPWD, 'username:password');   
curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',          
        'Content-Type: application/json; charset=utf-8',
]);   

$response = json_decode(curl_exec($ch), TRUE);
echo json_encode($response, JSON_PRETTY_PRINT);
// Close handle
curl_close($ch);

Write

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'https://<Server>:<WebServicePort>/<ServerInstance>/OData/Company(\'<CompanyName>\')/customer'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_POST, true);  

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "Name" => "This is a test customer",
    ...
]));

curl_setopt($ch, CURLOPT_USERPWD, 'username:password');   
curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',          
        'Content-Type: application/json; charset=utf-8',
]);   

$response = json_decode(curl_exec($ch), TRUE);
echo json_encode($response, JSON_PRETTY_PRINT);
curl_close($ch);

Update

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'https://<Server>:<WebServicePort>/<ServerInstance>/OData/Company(\'<CompanyName>\')/customer(\'1\')'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_POST, true);  
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "Name" => "This is a test customer",
    ...
]));

curl_setopt($ch, CURLOPT_USERPWD, 'username:password');   
curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',          
        'Content-Type: application/json; charset=utf-8',
        'If-Match: W/"\'' .  $etag . '\'"',
        // You can get your etag value by doing a get request first
        // In the class hereabove, you don't need to worry about this, as the class takes care of this
]);   

$response = json_decode(curl_exec($ch), TRUE);
echo json_encode($response, JSON_PRETTY_PRINT);
curl_close($ch);

Delete

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'https://<Server>:<WebServicePort>/<ServerInstance>/OData/Company(\'<CompanyName>\')/customer(\'1\')'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_POST, true);  
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

curl_setopt($ch, CURLOPT_USERPWD, 'username:password');   
curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',          
        'Content-Type: application/json; charset=utf-8',
        'If-Match: W/"\'' .  $etag . '\'"',
        // You can get your etag value by doing a get request first
        // In the class hereabove, you don't need to worry about this, as the class takes care of this
]);   

$response = json_decode(curl_exec($ch), TRUE);
echo json_encode($response, JSON_PRETTY_PRINT);
curl_close($ch);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment