Skip to content

Commit

Permalink
Merge pull request #90 from thybag/develop
Browse files Browse the repository at this point in the history
Roll to master
  • Loading branch information
thybag committed Nov 25, 2015
2 parents 523f26d + 0dcc9ed commit 5732be7
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 74 deletions.
2 changes: 1 addition & 1 deletion License.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 Carl Saggs
Copyright (c) 2015 Carl Saggs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion SharePointAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* Simple PHP API for reading/writing and modifying SharePoint list items.
*
* @version 0.6.2
* @version 0.6.4
* @licence MIT License
* @source: http://github.com/thybag/PHP-SharePoint-Lists-API
*
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "thybag/php-sharepoint-lists-api",
"version": "0.6.2",
"version": "0.6.4",
"type": "library",
"description": "A simple PHP API to make working with SharePoint lists easy.",
"homepage": "https://github.com/thybag/PHP-SharePoint-Lists-API",
Expand Down
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,9 @@ If you are attempting to store a value in a "lookup" data type but for some reas

If you are getting this error it normally means that php_openssl (needed to curl https urls) is not enabled on your webserver. With many local websevers (such as XAMPP) you can simply open your php.ini file and uncomment the php_openssl line (ie. remove the ; before it).

Note: If you are using SharePoint Online and having SSL errors, please pull the latest version which has changed from SSL v3 to TLS for sharepoint online connections -

Add this line to your `composer.json` file.

"thybag/php-sharepoint-lists-api": "dev-develop"

23 changes: 18 additions & 5 deletions src/Thybag/Auth/SharePointOnlineAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ public function __doRequest($request, $location, $action, $version, $one_way = f
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_COOKIE, $this->authCookies);

// Connection requires CURLOPT_SSLVERSION set to 3
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_SSLVERSION, 3);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);

// Useful for debugging
Expand Down Expand Up @@ -91,16 +89,32 @@ protected function configureAuthCookies($location) {
// Send request and grab returned xml
$result = $this->authCurl("https://login.microsoftonline.com/extSTS.srf", $xml);


// Extract security token from XML
$xml = new \DOMDocument();
$xml->loadXML($result);
$xpath = new \DOMXPath($xml);

// Register SOAPFault namespace for error checking
$xpath->registerNamespace('psf', "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault");

// Try to detect authentication errors
$errors = $xpath->query("//psf:internalerror");
if($errors->length > 0){
$info = $errors->item(0)->childNodes;
throw new \Exception($info->item(1)->nodeValue, $info->item(0)->nodeValue);
}

$nodelist = $xpath->query("//wsse:BinarySecurityToken");
foreach ($nodelist as $n){
$token = $n->nodeValue;
break;
}

if(!isset($token)){
throw new \Exception("Unable to extract token from authentiction request");
}

// Send token to SharePoint online in order to gain authentication cookies
$result = $this->authCurl($endpoint."/_forms/default.aspx?wa=wsignin1.0", $token, true);

Expand Down Expand Up @@ -129,7 +143,6 @@ protected function extractAuthCookies($result){
$authCookies[] = $loop[1];
}
}
unset($authCookies[0]); // No need for first cookie

// Extract cookie name & payload and format in to cURL compatible string
foreach($authCookies as $payload){
Expand Down Expand Up @@ -166,7 +179,7 @@ protected function authCurl($url, $payload, $header = false){
curl_setopt($ch,CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

Expand Down Expand Up @@ -226,4 +239,4 @@ protected function generateSecurityToken($username, $password, $endpoint) {
</s:Envelope>
TOKEN;
}
}
}
3 changes: 1 addition & 2 deletions src/Thybag/Auth/SoapClientAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ public function __doRequest($request, $location, $action, $version, $one_way = 0
'User-Agent: PHP-SOAP',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "' . $action . '"',
'Content-Length: ' . strlen($request),
'Expect: 100-continue',
'Connection: Keep-Alive'
);
Expand All @@ -105,7 +104,7 @@ public function __doRequest($request, $location, $action, $version, $one_way = 0

curl_setopt($ch, CURLOPT_USERPWD, $this->Username . ':' . $this->Password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_SSLVERSION, 3);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

Expand Down
33 changes: 28 additions & 5 deletions src/Thybag/Auth/StreamWrapperHttpAuth.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
<?php
namespace Thybag\Auth;
/**
* SoapClientAuth for accessing Web Services protected by HTTP authentication
* Author: tc
* Last Modified: 04/08/2011
* Update: 14/03/2012 - Fixed issue with CURLAUTH_ANY not authenticating to NTLM servers
* Download from: http://tcsoftware.net/blog/
*
* Copyright (C) 2011 tc software (http://tcsoftware.net)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* Class streamWrapperHttpAuth
* @author tc
* @copyright Copyright (C) 2011 tc software
*
* @package Thybag\Auth
*/
Expand Down Expand Up @@ -98,7 +122,6 @@ protected function postRequest($path, $authType = CURLAUTH_ANY) {
);
}

curl_setopt($this->curlHandle, CURLOPT_SSLVERSION, 3);
curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->curlHandle, CURLOPT_SSL_VERIFYHOST, 2);

Expand All @@ -109,7 +132,7 @@ protected function postRequest($path, $authType = CURLAUTH_ANY) {
return $response;
}
else {
throw new Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
throw new \Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
}
}
else {
Expand All @@ -118,15 +141,15 @@ protected function postRequest($path, $authType = CURLAUTH_ANY) {
return $this->postRequest($path, CURLAUTH_NTLM);
}
else {
throw new Exception ('Access Denied', 401);
throw new \Exception ('Access Denied', 401);
}
}
else {
if (curl_errno($this->curlHandle) != 0) {
throw new Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
throw new \Exception(curl_error($this->curlHandle), curl_errno($this->curlHandle));
}
else {
throw new Exception('Error', $info['http_code']);
throw new \Exception('Error', $info['http_code']);
}
}
}
Expand Down
24 changes: 21 additions & 3 deletions src/Thybag/Service/QueryObjectService.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class QueryObjectService {
*/
private $fields = array();

/**
* CAML Options for query
*/
private $options = NULL;

/**
* Construct
* Setup new query Object
Expand Down Expand Up @@ -135,6 +140,18 @@ public function using ($view) {
return $this;
}

/**
* Options
* Specify view to use when returning data.
*
* @param String $options "XML string of query options."
* @return Ref to self
*/
public function options($options){
$this->options = $options;
return $this;
}

/**
* Sort
* Specify order data should be returned in.
Expand Down Expand Up @@ -182,14 +199,15 @@ public function all_columns($exclude_hidden = true){ return $this->all_fields($e
/**
* get
* Runs the specified query and returns a usable result.
* @return Array: SharePoint List Data
*
* @return Array: SharePoint List Data
*/
public function get () {
public function get ($options = NULL) {

// String = view, array = specific fields
$view = (sizeof($this->fields) === 0) ? $this->view : $this->fields;

return $this->api->read($this->list_name, $this->limit, $this, $view);
return $this->api->read($this->list_name, $this->limit, $this, $view, NULL, $this->options);
}

/**
Expand Down
99 changes: 43 additions & 56 deletions src/Thybag/SharePointAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Simple PHP API for reading/writing and modifying SharePoint list items.
*
* @author Carl Saggs
* @version 0.6.2
* @version 0.6.4
* @licence MIT License
* @source: http://github.com/thybag/PHP-SharePoint-Lists-API
*
Expand Down Expand Up @@ -136,9 +136,10 @@ class SharePointAPI {
* @param string $spUsername User account to authenticate with. (Must have read/write/edit permissions to given Lists)
* @param string $spPassword Password to use with authenticating account.
* @param string $spWsdl WSDL file for this set of lists ( sharepoint.url/subsite/_vti_bin/Lists.asmx?WSDL )
* @param Whether to authenticate with NTLM
* @param string $mode Authenticaton method to use (Defaults to basic auth, also supports SPONLINE & NTLM)
* @param array $options Options for SoapClient
*/
public function __construct ($spUsername, $spPassword, $spWsdl, $mode = 'STANDARD') {
public function __construct ($spUsername, $spPassword, $spWsdl, $mode = 'STANDARD', $options = array()) {
// Check if required class is found
assert(class_exists('SoapClient'));

Expand All @@ -148,10 +149,9 @@ public function __construct ($spUsername, $spPassword, $spWsdl, $mode = 'STANDAR
$this->spWsdl = $spWsdl;

/*
* General options
* NOTE: You can set all these parameters, see class ExampleSharePointAPI for an example)
* defaults
*/
$options = array(
$defaultOptions = array(
'trace' => $this->soap_trace,
'exceptions' => $this->soap_exceptions,
'keep_alive' => $this->soap_keep_alive,
Expand All @@ -160,6 +160,8 @@ public function __construct ($spUsername, $spPassword, $spWsdl, $mode = 'STANDAR
'compression' => $this->soap_compression,
'encoding' => $this->internal_encoding,
);
// $options will overwrite defaults if provided
$options = array_merge($defaultOptions, $options);

// Is login set?
if (!empty($this->spUsername)) {
Expand Down Expand Up @@ -639,6 +641,36 @@ public function addAttachment ($list_name, $list_item_id, $file_name) {
return true;
}

/**
* deleteAttachment
* Remove an attachment from a SharePoint list item
*
* @param $list_name Name of list
* @param $list_item_id ID of record item is attached to
* @param $url
*/
public function deleteAttachment ($list_name, $list_item_id, $url) {
// Wrap in CAML
$CAML = '
<DeleteAttachment xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>' . $list_name . '</listName>
<listItemID>' . $list_item_id . '</listItemID>
<url>' . $url . '</url>
</DeleteAttachment>';

$xmlvar = new \SoapVar($CAML, XSD_ANYXML);

// Attempt to run operation
try {
$this->soapClient->DeleteAttachment($xmlvar);
} catch (\SoapFault $fault) {
$this->onError($fault);
}

// Return true on success
return true;
}

/**
* getAttachment
* Return an attachment from a SharePoint list item
Expand Down Expand Up @@ -835,12 +867,12 @@ public function getSortFromValue ($value) {
$value = strtolower($value);

// Default is descending
$sort = 'false';
$sort = 'FALSE';

// Is value set to allow ascending sorting?
if ($value == 'asc' || $value == 'true' || $value == 'ascending') {
// Sort ascending
$sort = 'true';
$sort = 'TRUE';
}

// Return it
Expand Down Expand Up @@ -1085,61 +1117,16 @@ public function getFieldVersions ($list, $id, $field) {
}
public function getColumnVersions ($list, $id, $field) { return $this->getFieldVersions($list, $id, $field); }

/**
* getItemVersions
* Get previous versions of an item
*
* @param $list Name or GUID of list
* @param $id ID of item to find versions for
* @return array | object
*/
public function getItemVersions ($list, $id, $exclude_hidden = true) {
$fields = $this->readListMeta($list, $exclude_hidden);

// Parse results
$results = array();
// Format data in to array or object
foreach ($fields as $counter => $field) {
// Modified always returns an error
if($field['name'] == 'Modified') { continue; }

// Get all the fields
$field_versions = $this->getFieldVersions($list, $id, $field['name']);

// Get the versions for each field
if(sizeof($field_versions) !== 0) {
foreach($field_versions as $key => $value) {
if($this->lower_case_indexs) {
$results[$key][strtolower($field['name'])] = $value[strtolower($field['name'])];
} else {
$results[$key][$field['name']] = $value[$field['name']];
}
}
//Make object if needed
if ($this->returnType === 1) settype($results[$counter], "object");
}
}

// Add error array if stuff goes wrong.
if (!isset($results)) $results = array('warning' => 'No data returned.');

return $results;
}

/**
* getVersions
* Get previous versions of an item or field
* Get previous versions of a field
*
* @param $list Name or GUID of list
* @param $id ID of item to find versions for
* @param $field optional name of column to get versions for
* @return array | object
*/
public function getVersions ($list, $id, $field = null, $exclude_hidden = true) {
if($field === null) {
return $this->getItemVersions($list, $id, $exclude_hidden);
} else {
return $this->getFieldVersions($list, $id, $field);
}
public function getVersions ($list, $id, $field = null) {
return $this->getFieldVersions($list, $id, $field);
}
}

0 comments on commit 5732be7

Please sign in to comment.