Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
sharepoint_common.inc
1 <?php
17 /*
18 * Sharepoint Package Library public static functions
19 *
20 * This file contains global public static functions that are useful throughout the Sharepoint module
21 *
22 *
23 * @author Huan Nguyen <hnguyen@squiz.net>
24 * @version $Revision: 1.11 $
25 * @package MySource_Matrix_Packages
26 * @subpackage sharepoint
27 */
28 
29 
31 {
32 
33 
40  public static function addAttachment($connection, $list_id, $list_item_id, $file_name, $base64Binary)
41  {
42  $list_wsdl = self::getWSDLLocation('lists', $connection['url']);
43  try {
44  $client = new SoapClient($list_wsdl, $connection['authentication']);
45  $input_param = Array (
46  'listName' => $list_id,
47  'listItemID' => $list_item_id,
48  'fileName' => basename($file_name),
49  'attachment' => $base64Binary,
50  );
51  $response = $client->AddAttachment($input_param);
52  $upload_result = $response->AddAttachmentResult;
53  if (basename($upload_result) == basename($file_name)) {
54  return TRUE;
55  }//end if
56  } catch (SoapFault $sf) {
57  $detail = '';
58  if (isset($sf->detail)) $detail = $sf->detail;
59  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
60  }//end try catch()
61 
62  return FALSE;
63 
64  }//end addAttachment()
65 
66 
73  public static function checkOutFile($page_url, $last_modified='')
74  {
75  try {
76  $client = new SoapClient(WSDL, $authen);
77  $input_param = Array (
78  'pageUrl' => $page_url,
79  'checkoutToLocal' => TRUE,
80  'lastmodified' => $last_modified, //20 Jun 1982 12:00:00 GMT
81  );
82  $response = $client->CheckOutFile($input_param);
83  $response_xml = simplexml_load_string($response->GetPermissionCollectionResult->any);
84 
85  } catch (SoapFault $sf) {
86  $detail = '';
87  if (isset($sf->detail)) $detail = $sf->detail;
88  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
89  }//end try catch()
90 
91  }//end checkOutFile()
92 
93 
100  public static function getWSDLLocation($service_name, $url_root)
101  {
102  $services_list = self::getServiceLocation();
103  $clean_service_name = str_replace(' ', '_', strtolower($service_name));
104 
105  if (isset($services_list[$clean_service_name]))
106  return $url_root.$services_list[$clean_service_name].'?WSDL';
107  else
108  return NULL;
109 
110  }//end getWSDLLocation
111 
112 
119  private static function getServiceLocation()
120  {
121  $services_list = Array (
122  'administration' => '/_vti_adm/admin.asmx',
123  'alerts' => '/_vti_bin/alerts.asmx',
124  'document_workspace' => '/_vti_bin/dws.asmx',
125  'form' => '/_vti_bin/forms.asmx',
126  'imaging' => '/_vti_bin/imaging.asmx',
127  'list_data_retrieval' => '/_vti_bin/dspsts.asmx',
128  'lists' => '/_vti_bin/lists.asmx',
129  'meeting' => '/_vti_bin/meeting.asmx',
130  'permissions' => '/_vti_bin/permissions.asmx',
131  'site_data' => '/_vti_bin/sitedata.asmx',
132  'site' => '/_vti_bin/sites.asmx',
133  'usergroup' => '/_vti_bin/usergroup.asmx',
134  'versions' => '/_vti_bin/versions.asmx',
135  'web_part_pages' => '/_vti_bin/webpartpages.asmx',
136  'webs' => '/_vti_bin/webs.asmx',
137  );
138 
139  return $services_list;
140 
141  }//end getServiceLocation()
142 
143 
152  public static function getUserInfo($user_name='administrator')
153  {
154 
155  try {
156  $client = new SoapClient(WSDL_USRGRP, $authen);
157  $input_param = Array (
158  'userLoginName' => $user_name,
159  );
160  $response = $client->GetUserInfo($input_param);
161  $response_xml = simplexml_load_string($response->GetPermissionCollectionResult->any);
162 
163  } catch (SoapFault $sf) {
164  $detail = '';
165  if (isset($sf->detail)) $detail = $sf->detail;
166  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
167  }//end try catch()
168 
169  }//end getUserInfo()
170 
171 
180  public static function getPermissionCollection($list_name)
181  {
182  try {
183  $client = new SoapClient(WSDL_PERM, $authen);
184  $input_param = Array (
185  'objectName' => $list_name,
186  'objectType' => 'List',
187  );
188  $response = $client->GetPermissionCollection($input_param);
189  $response_xml = simplexml_load_string($response->GetPermissionCollectionResult->any);
190 
191  } catch (SoapFault $sf) {
192  $detail = '';
193  if (isset($sf->detail)) $detail = $sf->detail;
194  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
195  }//end try catch()
196 
197  }//end getPermissionCollection()
198 
199 
208  public static function deleteList($list_name)
209  {
210  global $authen;
211  try {
212  $client = new SoapClient(WSDL, $authen);
213  $input_param = Array (
214  'listName' => $list_name,
215  );
216  $response = $client->DeleteList($input_param);
217  } catch (SoapFault $sf) {
218  $detail = '';
219  if (isset($sf->detail)) $detail = $sf->detail;
220  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
221  }//end try catch
222 
223  }//end deleteList()
224 
225 
236  public static function addList($list_name, $description='', $templateID='100')
237  {
238  global $authen;
239  try {
240  $client = new SoapClient(WSDL, $authen);
241  $input_param = Array (
242  'listName' => $list_name,
243  'description' => $description,
244  'templateID' => $templateID,
245  );
246  $response = $client->AddList($input_param);
247  } catch (SoapFault $sf) {
248  $detail = '';
249  if (isset($sf->detail)) $detail = $sf->detail;
250  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
251  }//end try catch
252 
253  }//end addList()
254 
255 
265  private static function getTemplateId($template_name='')
266  {
267  $template_ids = Array (
268  'announcements' => '104',
269  'contacts' => '105',
270  'custom_list' => '100',
271  'custom_list_in_datasheet_view' => '120',
272  'dataSources' => '110',
273  'discussion_board' => '108',
274  'document_library' => '101',
275  'events' => '106',
276  'form_library' => '115',
277  'issues' => '1100',
278  'links' => '103',
279  'picture_library' => '109',
280  'survey' => '102',
281  'tasks' => '107',
282  );
283 
284  if (!empty($template_name)) {
285  return $template_ids[$template_name];
286  } else {
287  return $template_ids;
288  }//end else
289 
290  }//end getTemplateId()
291 
292 
304  public static function getList($connection, $list_id)
305  {
306  $list_wsdl = self::getWSDLLocation('lists', $connection['url']);
307  try {
308  $client = new SoapClient($list_wsdl, $connection['authentication']);
309  $input_param = Array (
310  'listName' => $list_id,
311  );
312  $response = $client->getList($input_param);
313 
314  } catch (SoapFault $sf) {
315  $detail = '';
316  if (isset($sf->detail)) $detail = $sf->detail;
317  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
318  return '';
319  }//end try catch()
320 
321  return $response;
322 
323  }//end getList()
324 
325 
337  public static function getListAvailableFields($connection, $list_id, $all=FALSE, $get_field_info=FALSE)
338  {
339  $response = self::getList($connection, $list_id);
340 
341  $available_fields = Array();
342  $field_info = Array();
343  if (!empty($response)) {
344  $xml = simplexml_load_string($response->GetListResult->any);
345  if (!empty($xml)) {
346  foreach ($xml->Fields->children() as $field) {
347  $read_only = (string) $field['ReadOnly'];
348  if ($read_only == 'TRUE' && $all == FALSE) continue;
349 
350  if (!$get_field_info) {
351  $field_xml = $field->asXML();
352  $pattern = '/(<Field Type[^>]*>)/s';
353  $matches = Array();
354  preg_match($pattern, $field_xml, $matches);
355  if (isset($matches[0]) && !empty($matches[0])) {
356  $available_fields[(string) $field['Name']] = (string) $field['DisplayName'];
357  } else {
358  $available_fields[(string) $field['Name']] = (string) $field['DisplayName'];
359  }
360  } else {
361  foreach ($field->attributes() as $attr_name => $attr_val) {
362  $field_info[(string) $field['Name']][$attr_name] = (string) $attr_val;
363  }//end if
364  }//end else
365  }//end foreach
366  }//end if
367  }//end if
368 
369  if ($get_field_info) {
370  return $field_info;
371  } else {
372  asort($available_fields);
373  return $available_fields;
374  }//end else
375 
376  }//end getListAvailableFields()
377 
378 
388  public static function deleteListItem($list_id, $list_item_id)
389  {
390 
391  try {
392  $client = new SoapClient(WSDL, $authen);
393  $update_xml = '
394 <Batch OnError="Continue" PreCalc="TRUE"
395 ListVersion="0" >
396  <Method ID="1" Cmd="Delete">
397  <Field Name="ID">'.$list_item_id.'</Field>
398  </Method>
399 </Batch>
400 ';
401  $input_param = Array (
402  'listName' => $list_id,
403  'updates' => Array (
404  'any' => $update_xml,
405  ),
406  );
407  $response = $client->UpdateListItems($input_param);
408 
409  } catch (SoapFault $sf) {
410  $detail = '';
411  if (isset($sf->detail)) $detail = $sf->detail;
412  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
413  }//end try catch
414 
415  }//end deleteListItem()
416 
417 
428  public static function addListItem($connection, $list_id, $sharepoint_fields)
429  {
430 
431  $list_wsdl = self::getWSDLLocation('lists', $connection['url']);
432  try {
433  $client = new SoapClient($list_wsdl, $connection['authentication']);
434  $fs = $client->__getFunctions();
435 
436  $inner_xml = '';
437  foreach ($sharepoint_fields as $field_id => $value) {
438  if (!empty($value)) {
439  $inner_xml .= '<Field Name="'.$field_id.'">'.$value.'</Field>';
440  }//end if
441  }//end foreach
442 
443  $request_xml = '<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0" ><Method ID="1" Cmd="New">'.$inner_xml.'</Method></Batch>';
444 
445  $input_param = Array (
446  'listName' => $list_id,
447  'updates' => Array (
448  'any' => $request_xml,
449  ),
450  );
451 
452  $response = '';
453  $response = $client->UpdateListItems($input_param);
454 
455  } catch (SoapFault $sf) {
456  $detail = '';
457  if (isset($sf->detail)) $detail = $sf->detail;
458  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
459 
460  }//end try catch
461 
462  $xml = simplexml_load_string($response->UpdateListItemsResult->any);
463  $error_code = (string) $xml->Result->ErrorCode;
464 
465  if ($error_code == '0x00000000') {
466  $items_xml = $xml->Result;
467  // zz is used for the namespace z in the xml
468  $items_xml->registerXPathNamespace('zz', '#RowsetSchema');
469  $zresults = $items_xml->xpath('//zz:row');
470 
471  $ows_ID = (int) $zresults[0]['ows_ID'];
472  return $ows_ID;
473  } else {
474  $res_msg = 'Error Code '.$error_code .' - '.(string) $xml->Result->ErrorText;
475  return $res_msg;
476  }//end else
477 
478  return TRUE;
479 
480  }//end addListItems()
481 
482 
493  private static function constructXMLQuery($search_query, $search_logic, $field_info)
494  {
495  // Refer to MS CAML Query schema @ http://msdn.microsoft.com/en-us/library/ms467521.aspx
496 
497  $query_str = '';
498  $operators = Array (
499  '<' => 'Lt',
500  '<=' => 'Leq',
501  '>' => 'Gt',
502  '>=' => 'Geq',
503  '=' => 'Eq',
504  '!=' => 'Neq',
505  'Contains' => 'Contains',
506  'BeginsWith' => 'BeginsWith',
507  'IsNotNull' => 'IsNotNull',
508  'IsNull' => 'IsNull',
509  );
510 
511  $search_query_temp = Array();
512 
513  foreach ($search_query as $index => $field_crit_info) {
514  $field_name = key($field_crit_info);
515  $crit_info = $field_crit_info[$field_name];
516  $op = $operators[$crit_info['operator']];
517  $val = $crit_info['value'];
518  $type = $field_info[$field_name]['Type'];
519 
520  $query_str = '<'.$op.'><FieldRef Name="'.$field_name.'" /><Value Type="'.$type.'">'.$val.'</Value></'.$op.'>';
521  $search_query_temp[] = $query_str;
522  }//end if
523 
524  $query_strings = self::recursiveXMLConstruct($search_query_temp, $search_logic);
525  $built_query_string = array_pop($search_query_temp);
526 
527  $final_query_str = "<Query><Where>".$built_query_string."</Where></Query>";
528 
529  return $final_query_str;
530 
531  }//end constructXMLQuery()
532 
533 
543  private static function recursiveXMLConstruct(&$search_query, $search_logic)
544  {
545  /* Ok, a bit confusing here, but we want to add an logic (AND/ OR) to a pair of conditions, if we have an
546  * uneven number of conditions, say 3, we would need to have something like
547  * <AND>
548  * <AND><ConditionA><ConditionB></AND>
549  * <ConditionC>
550  * </AND>
551  * If it is even then it's simpler
552  * <AND>
553  * <AND><ConditionA><ConditionB></AND>
554  * <AND><ConditionC><ConditionD></AND>
555  * </AND>
556  */
557  $temp_array = Array();
558  for (reset($search_query); NULL !== ($k = key($search_query)); next($search_query)) {
559  $current_element = $search_query[$k];
560  if (!empty($current_element)) {
561  $next_element = next($search_query);
562  if (!empty($next_element)) {
563  $search_clause = '<'.$search_logic.'>'.$current_element.$next_element.'</'.$search_logic.'>';
564  $temp_array[] = $search_clause;
565  } else {
566  $search_clause = $current_element;
567  $temp_array[] = $search_clause;
568  }//end else
569  }//end if
570  }//end for
571  $search_query = $temp_array;
572  if (count($search_query) >= 2) {
573  self::recursiveXMLConstruct($search_query, $search_logic);
574  }//end if
575 
576  }//end recursiveXMLConstruct
577 
578 
588  public static function getListItems($connection, $list_id, $search_query=Array(), $search_logic='And', $row_limit='', $download_file=FALSE, $bridge_info="")
589  {
590  $result = Array();
591  $list_wsdl = self::getWSDLLocation('lists', $connection['url']);
592  try {
593  $client = new SoapClient($list_wsdl, $connection['authentication']);
594 
595  $ndViewFields = " <viewFields>
596  <FieldRef Name='Field1'/><FieldRef Name='Field2'/>
597  </viewFields>";
598 
599  $param = Array (
600  'listName' => $list_id,
601  'viewName' => '',
602  'rowLimit' => $row_limit,
603  );
604  $ndQueryOptions = ' <QueryOptions>
605  <IncludeAttachmentUrls>TRUE</IncludeAttachmentUrls>
606  </QueryOptions>';
607 
608  $param['queryOptions'] = Array (
609  'any' => $ndQueryOptions,
610  );
611 
612  if (!empty($search_query)) {
613  $field_info = self::getListAvailableFields($connection, $list_id, TRUE, TRUE);
614  $query = self::constructXMLQuery($search_query, $search_logic, $field_info);
615  $param['query'] = Array (
616  'any' => $query,
617  );
618 
619  }//end if
620 
621  $items = $client->GetListItems($param);
622  $all_items = $items->GetListItemsResult->any;
623 
624  $items_xml = simplexml_load_string($all_items);
625  $namespaces = $items_xml->getDocNamespaces();
626  $items_xml->registerXPathNamespace('zz', '#RowsetSchema');
627  $zresults = $items_xml->xpath('//zz:row');
628 
629  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
630  foreach ($zresults as $zresult) {
631  $ows_ID = (string) $zresult['ows_ID'];
632  foreach ($zresult->attributes() as $attr_name => $attr_val) {
633  $attr_val = str_replace($ows_ID.';#', '', $attr_val);
634  if ($attr_name == 'ows_Attachments') {
635  $attr_val = str_replace(';#', '', $attr_val);
636  }//end
637  $result[$ows_ID][$attr_name] = (string) $attr_val;
638  }//end foreach
639 
640  //url encode the spaces in file url
641  if(isset($result[$ows_ID]['ows_FileRef']))
642  $result[$ows_ID]['ows_FileRef'] = str_replace(' ', '%20', $result[$ows_ID]['ows_FileRef']);
643  if(isset($result[$ows_ID]['ows_Attachments']))
644  $result[$ows_ID]['ows_Attachments'] = str_replace(' ', '%20', $result[$ows_ID]['ows_Attachments']);
645 
646 
647  $url_bits = parse_url($connection['url']);
648  $base_url = $url_bits['scheme'].'://'.$url_bits['host'];
649  if (isset($url_bits['port']) && !empty($url_bits['port'])) $base_url = $base_url.':'.$url_bits['port'];
650  $remote_download_url = $base_url.'/'.$result[$ows_ID]['ows_FileRef'];
651 
652  // If files needs to served locally
653  if ($download_file) {
654  $data_path = $bridge_info['data_path'].'/'.$list_id.'/';
655  if (create_directory($data_path)) {
656  self::downloadFiles(Array($remote_download_url), $data_path, $connection['authentication']);
657  $result[$ows_ID]['download_url'] = $bridge_info['url'].'?file_uri='.$list_id.'/'.basename($result[$ows_ID]['ows_FileRef']);
658  } else {
659  trigger_error('Unable to download the file to directory: '.$data_path, E_USER_WARNING);
660  $result[$ows_ID]['download_url'] = '';
661  }
662  } else {
663  $result[$ows_ID]['download_url'] = $remote_download_url;
664  }
665 
666  // Also download the file attachment to local
667  if ($download_file && isset($result[$ows_ID]['ows_Attachments']) && $result[$ows_ID]['ows_Attachments']) {
668  $data_path = $bridge_info['data_path'].'/'.$list_id.'/';
669  if (create_directory($data_path)) {
670  self::downloadFiles(Array($result[$ows_ID]['ows_Attachments']), $data_path, $connection['authentication']);
671  $result[$ows_ID]['ows_Attachments'] = $bridge_info['url'].'?file_uri='.$list_id.'/'.basename($result[$ows_ID]['ows_Attachments']);
672  } else {
673  trigger_error('Unable to download the file attachment to directory: '.$data_path, E_USER_WARNING);
674  $result[$ows_ID]['ows_Attachments'] = '';
675  }
676  }
677 
678  }//end foreach
679 
680  } catch (SoapFault $sf) {
681  $detail = '';
682  if (isset($sf->detail)) $detail = $sf->detail;
683  trigger_error($sf->getMessage().'.'.$detail, E_USER_WARNING);
684  }//end try catch
685 
686  return $result;
687 
688  }//end getListItems()
689 
690 
697  public static function getListCollections($connection, $custom_list_only=FALSE)
698  {
699  $lists = Array();
700  $list_wsdl = self::getWSDLLocation('lists', $connection['url']);
701  try {
702  $client = new SoapClient($list_wsdl, $connection['authentication']);
703  $collections = $client->GetListCollection();
704 
705  $all_lists = $collections->GetListCollectionResult->any;
706  $result = simplexml_load_string($all_lists);
707 
708  foreach ($result->children() as $list) {
709  $list_id = (string) $list ['ID'];
710  if ($custom_list_only && (string) $list['ServerTemplate'] != '100') {
711  continue;
712  }//end if
713  foreach ($list->attributes() as $name => $value) {
714  $lists[$list_id][$name] = (string) $value;
715  }//end foreach
716 
717  }//end foreach
718  } catch (SoapFault $sf) {
719  $detail = '';
720  if (isset($sf->detail)) $detail = $sf->detail;
721  }//end try catch
722 
723  return $lists;
724 
725  }//end getListCollections()
726 
727 
737  public static function getListNames($connection, $all_list_details=Array())
738  {
739  if (empty($all_list_details)) {
740  $all_list_details = self::getListCollections($connection);
741  }//end if
742  $list_names = Array();
743 
744  foreach ($all_list_details as $list_id => $list_info) {
745  $list_names[$list_id] = $list_info['Title'];
746  }//end if
747 
748  return $list_names;
749 
750  }//end getListNames()
751 
752 
763  private static function downloadFiles($urls, $save_path, $auth)
764  {
765  $mh = curl_multi_init();
766  foreach ($urls as $i => $url) {
767  $final_path = $save_path.urldecode(basename($url));
768  $conn[$i] = curl_init($url);
769  $fp[$i] = fopen($final_path, "w");
770  curl_setopt($conn[$i], CURLOPT_FILE, $fp[$i]);
771  curl_setopt($conn[$i], CURLOPT_HEADER ,0);
772  curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
773  curl_setopt($conn[$i], CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
774  if (isset($auth['login']) && isset($auth['password']))
775  curl_setopt($conn[$i], CURLOPT_USERPWD, $auth['login'].':'.$auth['password']);
776  curl_multi_add_handle($mh,$conn[$i]);
777  }//end foreach
778 
779  do {
780  $n = curl_multi_exec($mh, $active);
781  }//end do
782  while ($active);
783  foreach ($urls as $i => $url) {
784  if (isset($conn[$i]) && isset($fp[$i])) {
785  curl_multi_remove_handle($mh, $conn[$i]);
786  curl_close($conn[$i]);
787  fclose($fp[$i]);
788  }//end if
789  }//end foreach
790  curl_multi_close($mh);
791 
792  }//end downloadFiles()
793 
794 
803  public static function test_sharepoint_connection($connection, $silent=FALSE)
804  {
805  try {
806  $client = new SoapClient(self::getWSDLLocation('lists', $connection['url']), $connection['authentication']);
807  $fns = $client->__getFunctions();
808 
809  if (!empty($fns)) {
810  $all_lists = Sharepoint_Common::getListCollections($connection);
811  if (empty($all_lists)) return FALSE;
812  return TRUE;
813  } else {
814  return FALSE;
815  }//end else
816 
817  } catch (SoapFault $e) {
818  if (!$silent) {
819  echo $e->getMessage().'<br />';
820  }//end if
821  return FALSE;
822  }//end if
823 
824  }//end test_trim_connection()
825 
826 
827 
828 }//end class