This is written in CI and using the wooapi v2. The order is always being marked as completed, instead of manual renewal. The goal is that if the post status is already manual renewal, that it will not get marked completed, but stay manual renewal. Any help greatly appreciated. Somewhat new to CI.
function complete_order($orderid) {
$consumer_key = 'xxx'; // Add your own Consumer Key here
$consumer_secret = 'xxxx'; // Add your own Consumer Secret here
$store_url = 'xxx'; // Add the home URL to the store you want to connect to here
$options = array(
'debug' => true,
'return_as_array' => false,
'validate_url' => false,
'timeout' => 30,
'ssl_verify' => false,
);
$servername = "xxx";
$username = "xxx";
$password = "xxx";
$dbname = "xxx";
$conn = new mysqli($servername, $username, $password, $dbname);
$sql ="SELECT * FROM xxxxxx WHERE ID = '$orderid'";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
$poststatus= '. $row["post_status"].';
if ($poststatus = wc-manual-renewal-re){
$client = new WC_API_Client($store_url, $consumer_key, $consumer_secret, $options);
$client->orders->update_status($orderid, 'wc-manual-renewal-re');
}else{$client = new WC_API_Client($store_url, $consumer_key, $consumer_secret, $options);
$client->orders->update_status($orderid, 'wc-completed');
}
}
}
You have a couple of mistakes/typos in your code here
if ($poststatus = wc-manual-renewal-re){
$client = new WC_API_Client($store_url, $consumer_key, $consumer_secret, $options);
$client->orders->update_status($orderid, 'wc-manual-renewal-re');
}
You are assigning = instead of comparing === which will always return true, and I guess this should be a string, not a constant: wc-manual-renewal-re
if ($poststatus === 'wc-manual-renewal-re'){
$client = new WC_API_Client($store_url, $consumer_key, $consumer_secret, $options);
$client->orders->update_status($orderid, 'wc-manual-renewal-re');
}
Related
I hope that you can help me with this one. Basically what I am doing, is adding tweets to my twitter account through api from my website administration panel.
It all works fine, BUT I cannot store the info to database because the json_decode variable that I have returns a NULL. I do not understand what is the appropriate way to get the info from twitter json.
Here is my code:
$settings = array(
'oauth_access_token' => $oauth_access_token,
'oauth_access_token_secret' => $oauth_access_token_secret,
'consumer_key' => $consumer_key,
'consumer_secret' => $consumer_secret
);
$connection = new TwitterAPIExchange($settings);
$url = 'https://api.twitter.com/1.1/statuses/update.json';
$requestMethod = "POST";
$user = $twitter_user;
$postfields = array(
'screen_name' => $user,
'status' => $twit );
$connection->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
// get the contents of the JSON file
$jsonCont = file_get_contents($connection);
//decode JSON data to PHP array
$content = json_decode($jsonCont, true);
$conn = new mysqli($server, $username, $password, $database);
$id = $content['id'];
$created = $content['created_at'];
$tweet = $content['text'];
$by = $content['user']['name'];
$sql = "INSERT INTO `twitter` (`idtwit`, `tweet`, `tweetedby`, `datet`) VALUES ('".$id."', '".$tweet."', '".$by."', '".$created."')";
$conn->query($sql);
echo "<br /><div class='alert alert-info'>New record updated successfully</div>";
$conn->close();
How to use json_decode properly with this ?!
I have also tried to wrap it around the $connection request like so, eliminating my variable, but then, it will not post to twitter anymore.
$connection->json_decode(buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest(),$assoc = TRUE);
I'm using this composer package https://github.com/basvandorst/StravaPHP
The OAUTH is working fine and its generating me the JSON with the access token and user id, etc..
But whenever I try to use other function it returns me 404 not found.
Output is this :
{"token_type":"Bearer","access_token":"077058e0c800881c72a4b10a04a520d5898d4e3e","athlete":{"id":35670467,"username":"amir_do","resource_state":2,"firstname":"Amir","lastname":"Do","city":null,"state":null,"country":null,"sex":"M","premium":false,"summit":false,"created_at":"2018-10-13T13:55:41Z","updated_at":"2018-10-13T13:56:25Z","badge_type_id":0,"profile_medium":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","profile":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","friend":null,"follower":null,"email":"goncalomaia97#gmail.com"}}
35670467
Client error: `GET https://www.strava.com/api/athletes/35670467/stats?access_token=077058e0c800881c72a4b10a04a520d5898d4e3e` resulted in a `404 Not Found` response: {"message":"Record Not Found","errors":[{"resource":"resource","field":"path","code":"invalid"}]}
And this is my current callback.php page code:
<?php
include 'vendor/autoload.php';
use Strava\API\Client;
use Strava\API\Exception;
use Strava\API\Service\REST;
session_start();
$client = new GuzzleHttp\Client();
global $connect;
require_once("configs/database.php");
$connect = new mysqli($config['database']['host'],$config['database']['user'],$config['database']['pass'],$config['database']['db']);
$code = $_GET['code'];
$state = $_GET['state'];
$scope = $_GET['scope'];
$user = $_SESSION['username'];
$check = $connect->query("SELECT * FROM users WHERE email = '$user'");
$fetch = $check->fetch_array(MYSQLI_ASSOC);
$apix = $fetch['api'];
$api_secretx = $fetch['api_secret'];
$client = new GuzzleHttp\Client();
$data = [
"client_id" => $apix,
"client_secret" => $api_secretx,
"code" => $code
];
$result = $client->post('https://www.strava.com/oauth/token', ['json' => $data]);
print "<pre>";
print_r( $result->getBody()->getContents() );
print "</pre>";
$bodyb = $result->getBody();
$varx = json_decode((string) $bodyb, true);
$token = $varx['access_token'];
$id = $varx['athlete']['id'];
$_SESSION['token'] = $token;
printf($id);
try {
// REST adapter (We use `Guzzle` in this project)
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
// Service to use (Service\Stub is also available for test purposes)
$service = new \Strava\API\Service\REST($token, $adapter);
// Receive the athlete!
$client = new Client($service);
$athlete = $client->getAthleteStats($id);
print_r($athlete);
} catch(Exception $e) {
print $e->getMessage();
}
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
Change that to this (It should be trailing) :
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3/']);
I am facing a problem while adding a new invoice line in existing invoice from Mysql database.
I have synced the invoice from quickbook to MySql. Two-way sync is working between quickbook and mysql.
The problem is when I add a new invoicline in qb_invoice_invoicline table, It does not sync with Quickbook. Following error I received in qb_invoice table. qbsql_last_errnum 320 last_error_msg
Object "64-1518123234" specified in the request cannot be found. (here 64-1518123234 is the value in qb_invoice_invoiceline.TxnLineID coulmn).If I leave this field blank then there is a parsing error when syncing.
Following is the code I am using to sync.
<?php
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', 1);
require_once dirname(__FILE__) . '/QuickBooks.php';
require_once 'Common/Constants.php';
require_once 'Common/Utility.php';
require_once 'Common/Hook.php';
if (function_exists('date_default_timezone_set'))
{
date_default_timezone_set(TIMEZONE);
}
if(!isset($_GET['companyId'])) {
trigger_error('Error! Parameter "CompanyId" missing in API.', E_USER_ERROR);
return;
}
$companyId = $_GET['companyId'];
$companyConfig = file_get_contents('config.json');
$companyData = json_decode($companyConfig, true);
if(!isset($companyData['company'][$companyId])) {
trigger_error('Error! Company detail not found in config file.', E_USER_ERROR);
return;
}
// The username and password the Web Connector will use to connect with
$username = $companyData['company'][$companyId]['web_connector_username'];
$password = $companyData['company'][$companyId]['web_connector_password'];
// get Company Database credentials
$db = $companyData['company'][$companyId];
$dsn = 'mysqli://' . $db['username'] . ':' . $db['password'] . '#' . $db['host'] . '/' . $db['db_name'];
// If the database has not been initialized, we need to initialize it (create
// schema and set up the username/password, etc.)
if (!QuickBooks_Utilities::initialized($dsn))
{
header('Content-Type: text/plain');
// It takes a really long time to build the schema...
set_time_limit(0);
$driver_options = array(
);
$init_options = array(
'quickbooks_sql_enabled' => true,
);
QuickBooks_Utilities::initialize($dsn, $driver_options, $init_options);
QuickBooks_Utilities::createUser($dsn, $username, $password);
exit;
}
$mode = QuickBooks_WebConnector_Server_SQL::MODE_READWRITE;
$conflicts = QuickBooks_WebConnector_Server_SQL::CONFLICT_LOG;
$delete = QuickBooks_WebConnector_Server_SQL::DELETE_FLAG; // Just flag it as deleted
$hook_obj = Hook::getInstance($companyId);
$hooks = array(
QuickBooks_SQL::HOOK_SQL_INSERT => array(
'preHookHandler',
array( $hook_obj, 'insertHook' ),
),
QuickBooks_SQL::HOOK_SQL_UPDATE => array(
'preHookHandler',
array( $hook_obj, 'updateHook' ),
),
);
function preHookHandler($requestID, $user, $hook, &$err, $hook_data, $callback_config)
{
return true;
}
$soap_options = array();
$handler_options = array(
'deny_concurrent_logins' => false,
'deny_reallyfast_logins' => false,
);
$driver_options = array();
$ops = array(
QUICKBOOKS_OBJECT_ACCOUNT,
QUICKBOOKS_OBJECT_SALESTAXITEM,
QUICKBOOKS_OBJECT_SALESTAXCODE,
QUICKBOOKS_OBJECT_CUSTOMER,
QUICKBOOKS_OBJECT_VENDOR,
QUICKBOOKS_OBJECT_INVENTORYITEM,
QUICKBOOKS_OBJECT_TEMPLATE,
QUICKBOOKS_OBJECT_CUSTOMERTYPE,
QUICKBOOKS_OBJECT_VENDORTYPE,
QUICKBOOKS_OBJECT_ESTIMATE,
QUICKBOOKS_OBJECT_INVOICE,
QUICKBOOKS_OBJECT_CLASS,
QUICKBOOKS_OBJECT_UNITOFMEASURESET,
QUICKBOOKS_ADD_UNITOFMEASURESET,
QUICKBOOKS_MOD_UNITOFMEASURESET,
QUICKBOOKS_QUERY_UNITOFMEASURESET,
QUICKBOOKS_IMPORT_UNITOFMEASURESET,
QUICKBOOKS_OBJECT_STANDARDTERMS,
QUICKBOOKS_OBJECT_INVENTORYITEM,
QUICKBOOKS_OBJECT_NONINVENTORYITEM,
QUICKBOOKS_OBJECT_SERVICEITEM,
QUICKBOOKS_OBJECT_SHIPMETHOD,
QUICKBOOKS_OBJECT_PAYMENTMETHOD,
QUICKBOOKS_OBJECT_TERMS,
QUICKBOOKS_OBJECT_PRICELEVEL,
QUICKBOOKS_OBJECT_ITEM,
QUICKBOOKS_ADD_SERVICEITEM,
QUICKBOOKS_MOD_SERVICEITEM,
QUICKBOOKS_QUERY_SERVICEITEM,
QUICKBOOKS_IMPORT_SERVICEITEM,
QUICKBOOKS_OBJECT_RECEIVEPAYMENT,
QUICKBOOKS_ADD_RECEIVE_PAYMENT,
QUICKBOOKS_MOD_RECEIVE_PAYMENT,
QUICKBOOKS_QUERY_RECEIVE_PAYMENT,
QUICKBOOKS_IMPORT_RECEIVE_PAYMENT,
QUICKBOOKS_DERIVE_RECEIVE_PAYMENT,
QUICKBOOKS_OBJECT_PAYMENTMETHOD,
QUICKBOOKS_OBJECT_COMPANY,
QUICKBOOKS_OBJECT_HOST,
QUICKBOOKS_OBJECT_PREFERENCES,
QUICKBOOKS_QUERY_DELETEDTRANSACTIONS,
QUICKBOOKS_OBJECT_SALESREP,
QUICKBOOKS_OBJECT_DATAEXT,
QUICKBOOKS_ADD_DATAEXT,
QUICKBOOKS_MOD_DATAEXT,
QUICKBOOKS_OBJECT_DATAEXTDEF,
QUICKBOOKS_ADD_DATAEXTDEF,
QUICKBOOKS_MOD_DATAEXTDEF
);
$ops_misc = array( // For fetching inventory levels, deleted transactions, etc.
QUICKBOOKS_DERIVE_INVENTORYLEVELS,
QUICKBOOKS_QUERY_DELETEDLISTS,
QUICKBOOKS_QUERY_DELETEDTRANSACTIONS
// 'nothing',
);
//
$sql_options = array(
'only_import' => $ops,
'only_add' => $ops,
'only_modify' => $ops,
'only_misc' => $ops_misc,
);
//
$callback_options = array();
$Server = new QuickBooks_WebConnector_Server_SQL(
$dsn,
'1 minute',
$mode,
$conflicts,
$delete,
$username,
array(),
array(),
$hooks,
QUICKBOOKS_LOG_DEVELOP,
QUICKBOOKS_SOAPSERVER_BUILTIN,
QUICKBOOKS_WSDL,
$soap_options,
$handler_options,
$driver_options,
$sql_options,
$callback_options);
$Server->handle(true, true);
To summarize the problem what value should be in (qb_invoice_invoiceline.TxnLineID) column to add a new invoiceline ?
If you are trying to just add a line, set the TxnLineID to -1 for all the new line items.
For example, if your Invoice has line items with IDs A/B/C, and you want to append another line, your mod should be something like:
...
<InvoiceLineMod><TxnLineID>A</TxnLineID><InvoiceLineMod>
<InvoiceLineMod><TxnLineID>B</TxnLineID><InvoiceLineMod>
<InvoiceLineMod><TxnLineID>C</TxnLineID><InvoiceLineMod>
<InvoiceLineMod>
<TxnLineID>-1</TxnLineID>
< ... other required values... >
<InvoiceLineMod>
...
If you wanted to delete line B, just send
<InvoiceLineMod><TxnLineID>A</TxnLineID><InvoiceLineMod>
<InvoiceLineMod><TxnLineID>C</TxnLineID><InvoiceLineMod>
I am trying to implement two way syncing with quickbook using consolibyte library. I have used consolibyte example file "example_mysql_mirror.php". It creates around 139 tables and import data from Quickbook successfully.
When I made some changes in Quickbook and MySql database, Quickbook changes reflects in MySql database but MySql dabase changes does not appear in Quickbook.
I am using QuickBook enterprise 2018 and consolibyte stable build 2.0.0.
Fallowing are the content of "example_mysql_mirror.php" file.
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
require_once dirname(__FILE__) . '/../QuickBooks.php';
if (function_exists('date_default_timezone_set'))
{
date_default_timezone_set('America/New_York');
}
$username = 'Admin';
$password = '123456';
$dsn = 'mysqli://root:#localhost/quickbooks_sql';
if (!QuickBooks_Utilities::initialized($dsn))
{
header('Content-Type: text/plain');
set_time_limit(0);
$driver_options = array(
);
$init_options = array(
'quickbooks_sql_enabled' => true,
);
QuickBooks_Utilities::initialize($dsn, $driver_options, $init_options);
QuickBooks_Utilities::createUser($dsn, $username, $password);
exit;
}
$mode = QuickBooks_WebConnector_Server_SQL::MODE_READWRITE;
$conflicts = QuickBooks_WebConnector_Server_SQL::CONFLICT_LOG;
$delete = QuickBooks_WebConnector_Server_SQL::DELETE_FLAG;
$hooks = array();
$soap_options = array();
$handler_options = array(
'deny_concurrent_logins' => false,
);
$driver_options = array();
$ops = array(
QUICKBOOKS_OBJECT_SALESTAXITEM,
QUICKBOOKS_OBJECT_SALESTAXCODE,
QUICKBOOKS_OBJECT_CUSTOMER,
QUICKBOOKS_OBJECT_VENDOR,
QUICKBOOKS_OBJECT_INVENTORYITEM,
QUICKBOOKS_OBJECT_TEMPLATE,
QUICKBOOKS_OBJECT_CUSTOMERTYPE,
QUICKBOOKS_OBJECT_VENDORTYPE,
QUICKBOOKS_OBJECT_ESTIMATE,
QUICKBOOKS_OBJECT_INVOICE,
QUICKBOOKS_OBJECT_CLASS,
QUICKBOOKS_OBJECT_INVOICE,
QUICKBOOKS_OBJECT_PAYMENTMETHOD,
QUICKBOOKS_OBJECT_COMPANY,
QUICKBOOKS_OBJECT_HOST,
QUICKBOOKS_OBJECT_PREFERENCES,
);
$ops_misc = array(
QUICKBOOKS_DERIVE_INVENTORYLEVELS,
QUICKBOOKS_QUERY_DELETEDLISTS,
QUICKBOOKS_QUERY_DELETEDTRANSACTIONS,
// 'nothing',
);
$sql_options = array(
'only_import' => $ops,
'only_add' => $ops,
'only_modify' => $ops,
'only_misc' => $ops_misc,
);
$callback_options = array();
$Server = new QuickBooks_WebConnector_Server_SQL(
$dsn,
'1 minute',
$mode,
$conflicts,
$delete,
$username,
array(),
array(),
$hooks,
QUICKBOOKS_LOG_DEVELOP,
QUICKBOOKS_SOAPSERVER_BUILTIN,
QUICKBOOKS_WSDL,
$soap_options,
$handler_options,
$driver_options,
$sql_options,
$callback_options);
$Server->handle(true, true);
If your QuickBooks computer in this time zone?
if (function_exists('date_default_timezone_set'))
{
date_default_timezone_set('America/New_York');
}
If not, fix your code so that the timezone of this code matches the timezone of QuickBooks.
I'm currently attempting to update an internal tool to handle an upgrade of our exchange servers to office 365.
I'm using the most recent version of James Armas's PHP-EWS tool. jamesiarmes/php-ews
Here is the code snippet that is inside of a function that we use to get events for a certain date range.
$email = '*email#domain*';
$password = '*password*';
$server = 'outlook.office365.com';
// Define EWS
//$ews = EWSAutodiscover::getEWS($email, $password);
$ews = new Client($server, $email, $password);
// Set init class
$request = new FindItemType();
// Use this to search only the items in the parent directory in question or use ::SOFT_DELETED
// to identify "soft deleted" items, i.e. not visible and not in the trash can.
$request->Traversal = ItemQueryTraversalType::SHALLOW;
// This identifies the set of properties to return in an item or folder response
$request->ItemShape = new ItemResponseShapeType();
$request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
// Define the timeframe to load calendar items
$request->CalendarView = new CalendarViewType();
$request->CalendarView->StartDate = $start_date;// an ISO8601 date e.g. 2012-06-12T15:18:34+03:00
$request->CalendarView->EndDate = $end_date;// an ISO8601 date later than the above
// Only look in the "calendars folder"
$request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::CALENDAR;
$request->ParentFolderIds->DistinguishedFolderId->Mailbox = new StdClass;
$request->ParentFolderIds->DistinguishedFolderId->Mailbox->EmailAddress = $email_address;
// Send request
$response = $ews->FindItem($request);
When this code is run, we get a 404 from the SOAP client:
Fatal error: Uncaught exception 'Exception' with message 'SOAP client returned status of 404.' in /*dirs*/Client.php:1650 Stack trace: #0 /*dirs*/Client.php(1633): jamesiarmes\PhpEws\Client->processResponse(NULL) #1 /*dirs*/Client.php(670): jamesiarmes\PhpEws\Client->makeRequest('FindItem', Object(jamesiarmes\PhpEws\Request\FindItemType)) #2 /*dirs*/index_dev.php(64): jamesiarmes\PhpEws\Client->FindItem(Object(jamesiarmes\PhpEws\Request\FindItemType)) #3 /*dirs*/index_dev.php(269): getEventHTML('email#domain...', '2017-07-18T02:0...', '2017-07-18T21:5...') #4 {main} thrown in /*dirs*/Client.php on line 1650
I believe that I do have the connection set up correctly, because when I alter the credentials, I do get a 401.
I have looked into this page: PHP-EWS “Soap client returned status of 404”
And I've tried the outlook.office365.com/EWS/Exchange.asmx endpoint as well, but I still get the SOAP 404.
Because of this, I thought this was enough of a separate question. (Although the more I research, the more that the REST client may be the next step)
I might be on the completely wrong track as well, so any help would be greatly appreciated!
I had a similar issue when we moved from an on-premises Exchange server to Office 365 and managed to trace the issue back to SoapClient.php under php-ntlm.
Going from the error that was thrown in your request:
Fatal error: Uncaught exception 'Exception' with message 'SOAP client returned status of 404.' .... thrown in /*dirs*/Client.php on line 1650
If we look at that line in Client.php the exception appears to come from the function that calls the aforementioned SoapClient.php script.
protected function processResponse($response)
{
// If the soap call failed then we need to throw an exception.
$code = $this->soap->getResponseCode();
if ($code != 200) {
throw new \Exception(
"SOAP client returned status of $code.",
$code
);
}
return $response;
}
I was able to resolve the issue by modifying the CURL request options in SoapClient.php (located around line 180).
Original Code:
protected function curlOptions($action, $request)
{
$options = $this->options['curlopts'] + array(
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $this->buildHeaders($action),
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_NTLM,
CURLOPT_USERPWD => $this->options['user'] . ':'
. $this->options['password'],
);
// We shouldn't allow these options to be overridden.
$options[CURLOPT_HEADER] = true;
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $request;
return $options;
}
Modified Code:
protected function curlOptions($action, $request)
{
$cOpts = array(
CURLOPT_PROXY => "my.proxy.com:8080",
CURLOPT_PROXYUSERPWD => $this->options['user'] . ':'
. $this->options['password'],
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $this->buildHeaders($action),
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_NTLM,
CURLOPT_USERPWD => $this->options['user'] . ':'
. $this->options['password'],
);
$options = $this->options['curlopts'] + $cOpts;
// We shouldn't allow these options to be overridden.
$options[CURLOPT_HEADER] = true;
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $request;
return $options;
}
I set CURLOPT_SSL_VERIFYPEER to false and also added proxy options to the request as the connection is made from inside a corporate network which requires proxy authentication to access any external sites.
In my mailing PHP script I create the client using the following code:
$server = 'outlook.office365.com';
$username = 'user#domain.com';
$password = 'myPassword';
$version = Client::VERSION_2016;
$client = new Client($server, $username, $password, $version);
Have you tried using the solution from https://github.com/jamesiarmes/php-ews/issues/196 eg change
$version = Client::VERSION_2016;
$ews = new Client($server, $email, $password,$version);
I can't make out what is wrong with your code but maybe the following helps. I'm using this script successfully to export my calendar regulary from o365.
Host and User are like this:
host = "outlook.office365.com"
username = "user#domain.com"
Script:
$start_date = new Datetime('today -1 months');
$end_date = new Datetime('today +1 months');
$timezone = 'W. Europe Standard Time';
$ini_array = parse_ini_file($credentials_ini);
$host = $ini_array['host'];
$username = $ini_array['username'];
$password = $ini_array['password'];
$version = Client::VERSION_2016;
$client = new Client($host, $username, $password, $version);
$client->setTimezone($timezone);
$request = new FindItemType();
$request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->ItemShape = new ItemResponseShapeType();
$request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
$folder_id = new DistinguishedFolderIdType();
$folder_id->Id = DistinguishedFolderIdNameType::CALENDAR;
$request->ParentFolderIds->DistinguishedFolderId[] = $folder_id;
$request->Traversal = ItemQueryTraversalType::SHALLOW;
$request->CalendarView = new CalendarViewType();
$request->CalendarView->StartDate = $start_date->format('c');
$request->CalendarView->EndDate = $end_date->format('c');
$request->ConnectionTimeout = 60;
$response = $client->FindItem($request);
$response_messages = $response->ResponseMessages->FindItemResponseMessage;
foreach ($response_messages as $response_message) {
$items = $response_message->RootFolder->Items->CalendarItem;
foreach ($items as $event){
$id = $event->ItemId->Id;
$subject = $event->Subject;
$location = $event->Location;
// ...
// do something with it
}
}