In this post I would like to introduce you to a SharePoint client for PHP available on GitHub. The library provides a SharePoint Online (SPO) client for PHP applications. It allows you to performs CRUD operations on SharePoint data using an SharePoint 2013 REST/OData based API.
API
PHP:cURL library is used to make HTTP requests to performs CRUD operations on SharePoint data using SharePoint 2013 REST API.
Getting started
A first example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$username = 'username@tenant.onmicrosoft.com'; | |
$password = 'password'; | |
$url = "https://tenant.sharepoint.com/"; | |
try { | |
$authCtx = new AuthenticationContext($Url); | |
$authCtx->acquireTokenForUser($username,$password); | |
$ctx = new ClientContext($Url,$authCtx); | |
printTasks($ctx); | |
} | |
catch (Exception $e) { | |
echo 'Authentication failed: ', $e->getMessage(), "\n"; | |
} | |
function printTasks(ClientContext $ctx){ | |
$listTitle = 'Tasks'; | |
$web = $ctx->getWeb(); | |
$list = $web->getLists()->getByTitle($listTitle); | |
$items = $list->getItems(); | |
$ctx->load($items); | |
$ctx->executeQuery(); | |
foreach( $items->getData() as $item ) { | |
print "Task: '{$item->Title}'\r\n"; | |
} | |
} | |
?> |
Key points:
- SPOClient class represents a REST Service client for the specified SharePoint Online (SPO) site
- The signIn method performs a claims-based authentication. You can find more details about remote authentication in Remote authentication in SharePoint Online post.
The following examples demonstrates how to perform the remaining CRUD operations on SharePoint list data.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once 'SPOClient.php'; | |
$username = 'username@tenant.onmicrosoft.com'; | |
$password = 'password'; | |
$url = "https://tenant.sharepoint.com/"; | |
$client = new SPOClient($url); | |
$client->signIn($username,$password); | |
//Get Tasks list | |
$listTitle = 'Tasks'; | |
$list = $client->getList($listTitle); | |
//Create a Task item | |
$itemProperties = array('Title' => 'Order Approval', 'Body' => 'Order approval task'); | |
$taskItem = $list->addItem($itemProperties); | |
print "Task '{$taskItem->Title}' has been created succesfully.\r\n"; | |
$itemId = $taskItem->Id; | |
//Update a Task item | |
$itemProperties = array('PercentComplete' => 1); | |
$list->updateItem($itemId,$itemProperties); | |
//Delete a Task item | |
$list->deleteItem($itemId); | |
?> |
List data generator
And finally one more example that demonstrates how to populate Contacts list in SharePoint. For generating fake data we will utilize Faker PHP library, below is provided the complete example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once __DIR__ . '/../../Faker/src/autoload.php'; //Faker library (https://github.com/fzaninotto/Faker) | |
require_once 'SPOClient.php'; | |
$username = 'username@tenant.onmicrosoft.com'; | |
$password = 'password'; | |
$url = "https://tenant.sharepoint.com/"; | |
generateContacts($url,$username,$password); | |
function generateContacts($url,$username,$password){ | |
$client = new SPOClient($url); | |
$client->signIn($username,$password); | |
$list = $client->getList('Contacts'); | |
$contactsCount = 120; | |
for($i = 0; $i < $contactsCount; $i++){ | |
$contactEntry = createContactEntry(); | |
$item = $list->addItem($contactEntry); | |
print "Contact '{$item->Title}' has been created succesfully.\r\n"; | |
} | |
} | |
function createContactEntry() | |
{ | |
$contactCard = Faker\Factory::create(); | |
return array('Title' => $contactCard->username, | |
'FullName' => $contactCard->name, | |
'Email' => $contactCard->email, | |
'Company' => $contactCard->company, | |
'WorkPhone' => $contactCard->phoneNumber, | |
'WorkAddress' => $contactCard->streetAddress, | |
'WorkCity' => $contactCard->city, | |
'WorkZip' => $contactCard->postcode, | |
'WorkCountry' => $contactCard->country, | |
'WebPage' => array ('Url' => $contactCard->url) | |
); | |
} | |
?> |
Summary
The library currently supports CRUD operations against SharePoint list data. But since SharePoint 2013 REST covers a much broader set of API, the library could be extended.
Hopefully this helps you get started how you can interact with a SharePoint Online site from a remote Web application written in PHP!
I have a problem with connecting with Sharepoint online sites. I tried this on 2 implementations and the message is:
Authentication failed: Unknown SSL protocol error in connection to dr4xt0r.sharepoint.com:443
As I can see certificate is standard microsoft certificate for *.sharepoint.com
Also is there any workaround for Organizational implementations of SharePoint online “Direct login to WLID is not allowed for this federated namespace”
same problem: Authentication failed: Unknown SSL protocol error in connection to energonindustries.sharepoint.com:443
SP online now uses SSLv3, add ‘ curl_setopt($ch,CURLOPT_SSLVERSION, 3);’ parameter to the function ‘Request’ and ‘submitToken’ did solve this issue for me.
can you elaborate on this a bit?
what are the Request and submitToken functions?
where can I add curl_setopt?
All I can see in this examples is this:
$client = new SPOClient($url);
$client->signIn($username,$password);
does curl_init expects sharepoint url?
Sure, my bad, i forgot to mention you can find these functions in SPOClient.php. This should be bundled with the examples.
curl init does not expect the url afaik.
I can send you my version if that helps.
Great. I found it and everything works fine.
Thanks a lot
@tomboeckx Thank you for your tip, I added curl_setopt($ch,CURLOPT_SSLVERSION, 3); and it was working up until this week.
Now I get “Unknown SSL protocol error in connection to login.microsoftonline.com:443″ even tough I’m targeting *.sharepoint.com. If I remove the version option it seems to pass the log in, but then after some timeout I get ” Unknown SSL protocol error in connection to *.sharepoint.com:443″.
I noticed that login.microsoftonline.com has a new certificate since Monday.
Is there a way to workaround this?
@Zoltan, i can confirm everything i still working fine in my application. I did check my sourcecode though, and I am not using the SSLVERSION 3 option in my tokenrequest function: perhaps that is your problem.
private function requestToken($username, $password) {
$samlRequest = $this->buildSamlRequest($username, $password, $this->url);
$ch = curl_init();
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_URL,self::$stsUrl);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$samlRequest);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if($result === false) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
return $this->processToken($result);
}
If this does not solve your problem, i can send you my whole sourcecode, there’s no big secrets in it, allthough i did kind of “massacre” the original example to fit my purpose 🙂
Hello @tomboeckx
What is buildSamlRequest? I’m also trying to do my GET request using POST (reason is I guess GetItems method works only with POST) . I guess this code will solve my problems.
@tomboeckx, thank you for your reply!
I removed SSLVERSION from requestToken() and left it in request() and submitToken(), it’s working now 🙂
@tomboeckx, I have another question, what is the proper way to send a CSV file to SharePoint? With my implementation it always encodes the content in JSON, in a lazy way (strips reserved chars instead of escaping them). For now I have to manually fix the files, which quite time consuming.
@Zoltan, i need some more details, what exactly are you trying to accomplish, how are you sending the file to sharepoint etc. you may contact me @twitter @tomboeckx, send PM, so we dont polute this topic further 😉
I am having the same difficulty that Drasko submitted… but adding the curl_setopt for the CURLOPT_SSLVERSION has not helped.
Oddly, when this only happens when I use the URL of “https://login.microsoftonline.com”, and not when I use the “http://subdomain.sharepoint.com” domain.
— ERROR MSG —
Fatal error: Uncaught exception ‘Exception’ with message ‘Unknown SSL protocol error in connection to login.microsoftonline.com:443 ‘ in /Users/Shared/Projects/sharepoint/lib/phpSPO/SPOClient.php:168
Does anyone have anymore pointers?
I should also add that when I use the sharepoint.com domain for the URL, the cookie comes back empty so $FedAuth and $rtFa are not set.
NVM – speaking out-loud sometimes brings back one’s sensibility. I was calling into http and not https for the sharepoint domain… so silly!
Today I started getting this error “error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number”
I read that Office365 is no longer supporting SSL3 and TLS1.0 instead
http://blogs.office.com/2014/10/29/protecting-ssl-3-0-vulnerability/
Anyone has got a fix?
Today I started getting this error “error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number”
I read that Office365 is no longer supporting SSL3 and TLS1.0 instead
http://blogs.office.com/2014/10/29/protecting-ssl-3-0-vulnerability/
Anyone has got a fix?
Pardon for doublepost.
It works now after changing CURLOPT_SSLVERSION from 3 to 1 which is apparently TLSv1.
I had the same problem, thanks for the tip. 🙂
Hello,
Thank you for your work.
When I run the code with the good creds …
try {
$client = new SPOClient($url);
$client->signIn($username,$password);
echo ‘You have authenticated successfully\n’;
}
catch (Exception $e) {
echo ‘Connection failed: ‘, $e->getMessage(), “\n”;
}
…
I receive invariably the following message after a while:
Fatal error: Maximum execution time of 30 seconds exceeded
Could anybody help me on this?
Regards.
Claude
My previous message is no longer needed, I just had ton configure my php.ini to solve this.
Now I encounter another issue:
Authentication failed: Unknown SSL protocol error in connection to abcdwxyz-my.sharepoint.com:443
I modified CURLOPT_SSLVERSION == 1 and 3 too.
No changes.
Some ideas for me?
Regards.
Claude
.. I played with:
curl_setopt($ch, CURLOPT_SSLVERSION ,1); //I tried 1/3
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
… but no changes…
I put
curl_setopt($ch, CURLOPT_SSLVERSION,3);
in
private function submitToken($token) {}
private function requestToken($username, $password) {}
but still teh prob…
Ok now, I’ve had to add
curl_setopt($ch, CURLOPT_SSLVERSION,1);
everywhere was used curl. At 3 places.
Hope this can help other peaple.
Regards.
Claude
How was your URL? https or http, and then xxx://your-site.sharepoint.com? I get authenticated correctly if I type in http, but can’t use any of the features, whilst getting unknown SSL protocol error using https.
Did you do anything else except change sslversion to 1 on all 3 curl-fields?
Thanks
Hello,
Could it be possible to have the piece of code for uploading a file to the sharepoint 365 once teh connection is ok?
Regards.
Claude
I tried something like:
$listTitle = ‘Documents’;
$list = $client->getList($listTitle);
$list->Files->Add(‘toto.txt’,$data,true);
but…not effective…
ok transfer file. If somebody wants it I put it here :
public function requestGoFile() //csi
{
//$data = array_key_exists(‘data’, $options) ? json_encode($options[‘data’]) : ”;
$data =””;
$options = array();
$file = ‘C:\mylog.log’;
if(file_exists($file)) {
//echo ‘file exists’;
}else{
//echo ‘file existe pas’;
}
//die();
$content = file_get_contents($file);
var_dump($content);
$url = ‘https://abcdwxyz-my.sharepoint.com/personal/nsi_abcdwxyz_onmicrosoft_com/Documents/mylog.txt’;
$options[‘url’] = $url;
$headers = array(
‘Accept: application/json; odata=verbose’,
//’Content-type: application/json; odata=verbose’,
‘Content-type: multipart/form-data”‘,
‘Cookie: FedAuth=’ . $this->FedAuth . ‘; rtFa=’ . $this->rtFa,
‘Content-length:’ . strlen($content)
);
// Include If-Match header if etag is specified
if (array_key_exists(‘etag’, $options)) {
$headers[] = ‘If-Match: ‘ . $options[‘etag’];
}
// Include X-RequestDigest header if formdigest is specified
if (array_key_exists(‘formdigest’, $options)) {
$headers[] = ‘X-RequestDigest: ‘ . $options[‘formdigest’];
}
// Include X-Http-Method header if xhttpmethod is specified
if (array_key_exists(‘xhttpmethod’, $options)) {
$headers[] = ‘X-Http-Method: ‘ . $options[‘xhttpmethod’];
}
$ch = curl_init();
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch,CURLOPT_URL,$options[‘url’]);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “PUT”);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_SSLVERSION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if($result === false) {
throw new Exception(curl_error($ch));
}else{
//var_dump($result);
}
curl_close($ch);
return json_decode($result);
}
Regards.
Claude
How could I get back the id of the new doc uploaded?
Thx for any help.
Claude
Hi Claude, would you please be able to help me with uploading a file to sharepoint using phpSPO library?
Hello,
I’m stucked with the impossibility to get back the id after having uploaded a file into a library to sharepoint 365
Any help on this?
Regards.
Claude
Could anybody help me to find a way of sending metadata with the upload file using SPOClient ?
Regards.
Claude
The Name of the document uploaded is empty when I read the list afterwards with:
…
$items = $list->getItems();
foreach( $items as $item ) {
var_dump($item);
//print “Task: ‘{$item->Id}’\r\n”;
}
…
[“Title”]=> NULL
The name is not catchable too.
A solutino could be to be able to inject metadata when uploading the file, but I cannot find the way to do it.
Some help will be apreciated.
Regards.
Claude
It seem the ‘updateItem’ do not work for Libraries of documents…
This all of a sudden stopped working on an Ubuntu 13.10 server. I tested on a 14.04 installation and it does not work either. I have tried changing the SSL_VERSION to 3 to 1 to no avail.
It does work on Bluehost and a MAMP installation with no issue.
Anyone have any suggestions on what to try?
On the MAMP installation, I can log the activity and see this:
SSL connection using AES256-SHA
Never get that on Ubuntu.
I have resolved the issue by adding two lines in the request function and the submitToken function after the line curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
// ADDED TO FIX UBUNTU SERVER
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt($ch,CURLOPT_SSL_CIPHER_LIST, ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK’);
// END ADDED TO FIX UBUNTU SERVER
Thank you, David!
Hello, I managed to stumble upon the same error most other people did as well, the unknown SSL protocol error.
Now I’m not certain what the premises are, for instance, do I have to connect from an SSL site for this to work? Are there common errors occured to Ubuntu operating systems? I’ve tried all of the posted solutions on this blog, but nothing seems to work properly.
Thanks!
I’m having the same issue
I am getting this error. Can anyone help me out to solve this. Need on urgent basis.
“Authentication failed: The specified member name is either invalid or empty.”
When I attempt to sinin function as below
require_once (‘SPOClient.php’);
$url = “http://my share-point url”;
$username = ‘username’;
$password = ‘pass’;
try {
$client = new SPOClient($url);
$client->signIn($username,$password);
echo ‘You have been authenticated successfully\n’;
}
catch (Exception $e) {
echo ‘Authentication failed: ‘, $e->getMessage(), “\n”;
}
Hi,
I have a PHP from facing form on a public facing website, which any user can access. i want the values from this form to be saved in SharePoint list. I was wondering how secure is this method. I obviously do not want SharePoint data to be exposed using the credentails that I provide.
As secure as any other call to sharepoint 2013 REST API. The SPOclient.php library will first get a security token from your sharepoint online using CURL (with SSL) before any other rest calls can be made.
You never pass any plain text credentials, but this matter is subject to all other security implications (SSL is not that solid nowadays ;^-) ). Of course there is also the side of securing your PHP application so it cannot be abused, but thats a different matter.
Hi,
I have two questions:
How I build a SAML request?
How I submit a SAML token request to Microsoft Online Security Token Service??
have done list insert acton in the list ?but i also to add attachment functionality?is any suggesttion
I’m having trouble uploading a file. Here’s my script that I’ve created from among your examples. At the end is the Settings.php file as well.
getWeb()->getLists();
$ctx->load($lists);
$ctx->executeQuery();
foreach($lists->getData() as $l) {
if ($listTitle == $l->Title) {
$list = $l;
print “List ‘{$list->Title}’ has been found\r\n”;
break;
}
}
if(is_null($list)) {
$info = new ListCreationInformation($listTitle);
$info->BaseTemplate = 101;
$list = $ctx->getWeb()->getLists()->add($info);
$ctx->executeQuery();
print “List ‘{$list->Title}’ has been created\r\n”;
}
return $list;
}
function uploadFiles($localPath,\SharePoint\PHP\Client\SPList $targetList){
$ctx = $targetList->getContext();
$searchPrefix = $localPath . ‘*.*’;
foreach(glob($searchPrefix) as $filename) {
$fileCreationInformation = array(
‘Content’ => file_get_contents($filename),
‘Url’ => basename($filename)
);
$uploadFile = $targetList->getRootFolder()->getFiles()->add($fileCreationInformation);
$ctx->executeQuery();
print “File {$uploadFile->Name} has been uploaded\r\n”;
}
}
try {
/* @var $authCtx NtlmAuthenticationContext */
$authCtx = new AuthenticationContext($Settings[‘Url’]);
$authCtx->acquireTokenForUser($Settings[‘UserName’],$Settings[‘Password’]);
echo ‘You have been authenticated successfully\n’;
$ctx = new SharePoint\PHP\Client\ClientContext($Settings[‘Url’],$authCtx);
$localPath = “/home/occ/output/changes-CAB-Report.csv”;
$targetLibraryTitle = “Weekly_CAB_report”;
$list = ensureList($ctx,$targetLibraryTitle);
uploadFiles($localPath,$list);
}
catch (Exception $e) {
echo ‘Authentication failed: ‘, $e->getMessage(), “\n”;
}
?>
Settings.php file is:
“https://vertexna.sharepoint.com/sites/IT/Service%20Delivery/NAInfraTechOffice/NA%20ITO%20StoreFront/Forms/AllItems.aspx”,
‘Password’ => “*******”,
‘UserName’ => “jason.stein@vertexgroup.com”
);
Error I’m getting (or not getting) is:
You have been authenticated successfully\nPHP Notice: Trying to get property of non-object in /home/occ/phpSPO/phpSPO/src/runtime/ContextWebInformation.php on line 14
PHP Notice: Trying to get property of non-object in /home/occ/phpSPO/phpSPO/src/runtime/ContextWebInformation.php on line 14
PHP Warning: Invalid argument supplied for foreach() in /home/occ/phpSPO/phpSPO/src/runtime/ContextWebInformation.php on line 14
List ” has been created