ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilSoapUtils.php
Go to the documentation of this file.
1 <?php
2  /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22  */
23 
24 
33 include_once './webservice/soap/classes/class.ilSoapAdministration.php';
34 
36 {
37  function ilSoapUtils()
38  {
40  }
41 
42  function ignoreUserAbort()
43  {
44  ignore_user_abort();
45  }
46 
47  function disableSOAPCheck()
48  {
49  $this->soap_check = false;
50  }
51 
52  function sendMail($sid,$to,$cc,$bcc,$sender,$subject,$message,$attach)
53  {
54  $this->initAuth($sid);
55  $this->initIlias();
56 
57  if(!$this->__checkSession($sid))
58  {
59  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
60  }
61 
62 
63  global $ilLog;
64 
65  include_once 'Services/Mail/classes/class.ilMimeMail.php';
66 
67  $mmail = new ilMimeMail();
68  $mmail->autoCheck(false);
69  $mmail->From($sender);
70  $mmail->To(explode(',',$to));
71  $mmail->Subject($subject);
72  $mmail->Body($message);
73 
74  if($cc)
75  {
76  $mmail->Cc(explode(',',$cc));
77  }
78 
79  if($bcc)
80  {
81  $mmail->Bcc(explode(',',$bcc));
82  }
83  if($attach)
84  {
85  // mjansen: switched separator from "," to "#:#" because of mantis bug #6039
86  // for backward compatibility we have to check if the substring "#:#" exists as leading separator
87  // otherwise we should use ";"
88  if(strpos($attach, '#:#') === 0)
89  {
90  $attach = substr($attach, strlen('#:#'));
91  $attachments = explode('#:#', $attach);
92  }
93  else
94  {
95  $attachments = explode(',', $attach);
96  }
97  foreach ($attachments as $attachment)
98  {
99  $mmail->Attach($attachment);
100  }
101  }
102 
103  $mmail->Send();
104  $ilLog->write('SOAP: sendMail(): '.$to.', '.$cc.', '.$bcc);
105 
106  return true;
107  }
108 
115  public function distributeMails($sid, $a_mail_xml)
116  {
117  $this->initAuth($sid);
118  $this->initIlias();
119 
120  if(!$this->__checkSession($sid))
121  {
122  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
123  }
124 
125  include_once 'Services/Mail/classes/class.ilMail.php';
126  include_once 'webservice/soap/classes/class.ilSoapMailXmlParser.php';
127 
128  $parser = new ilSoapMailXmlParser($a_mail_xml);
129  try
130  {
131  // Check if wellformed
132  libxml_use_internal_errors(true);
133  $ok = simplexml_load_string($a_mail_xml);
134  if(!$ok)
135  {
136  foreach(libxml_get_errors() as $err)
137  {
138  $error .= ($err->message.' ');
139  }
140  return $this->__raiseError($error, 'CLIENT');
141  }
142  $parser->start();
143  }
144  catch(InvalidArgumentException $e)
145  {
146  $GLOBALS['ilLog']->write(__METHOD__.' '.$e->getMessage());
147  return $this->__raiseError($e->getMessage(),'CLIENT');
148  }
149  catch(ilSaxParserException $e)
150  {
151  $GLOBALS['ilLog']->write(__METHOD__.' '.$e->getMessage());
152  return $this->__raiseError($e->getMessage(), 'CLIENT');
153  }
154 
155  $mails = $parser->getMails();
156 
157  global $ilUser;
158 
159  foreach($mails as $mail)
160  {
161  // Prepare attachments
162  include_once './classes/class.ilFileDataMail.php';
163  $file = new ilFileDataMail($ilUser->getId());
164  foreach((array) $mail['attachments'] as $attachment)
165  {
166  // TODO: Error handling
167  $file->storeAsAttachment($attachment['name'], $attachment['content']);
168  $attachments[] = ilUtil::_sanitizeFilemame($attachment['name']);
169  }
170 
171  $mail_obj = new ilMail($ilUser->getId());
172  $mail_obj->setSaveInSentbox(true);
173  $mail_obj->saveAttachments((array) $attachments);
174  $mail_obj->sendMail(
175  implode(',',(array) $mail['to']),
176  implode(',',(array) $mail['cc']),
177  implode(',',(array) $mail['bcc']),
178  $mail['subject'],
179  implode("\n",$mail['body']),
180  (array) $attachments,
181  array($mail['type']),
182  (bool) $mail['usePlaceholders']
183  );
184 
185  // Finally unlink attachments
186  foreach((array) $attachments as $att)
187  {
188  $file->unlinkFile($att);
189  }
190  $mail_obj->savePostData(
191  $ilUser->getId(),
192  array(),
193  '',
194  '',
195  '',
196  '',
197  '',
198  '',
199  '',
200  ''
201  );
202  }
203  return true;
204  }
205 
206  function saveTempFileAsMediaObject($sid, $name, $tmp_name)
207  {
208  $this->initAuth($sid);
209  $this->initIlias();
210 
211  if(!$this->__checkSession($sid))
212  {
213  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
214  }
215 
216  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
217  return ilObjMediaObject::_saveTempFileAsMediaObject($name, $tmp_name);
218  }
219 
220  function getMobsOfObject($sid, $a_type, $a_id)
221  {
222  $this->initAuth($sid);
223  $this->initIlias();
224 
225  if(!$this->__checkSession($sid))
226  {
227  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
228  }
229 
230  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
231  return ilObjMediaObject::_getMobsOfObject($a_type, $a_id);
232  }
233 
241  public function ilCloneDependencies($sid,$copy_identifier)
242  {
243  $this->initAuth($sid);
244  $this->initIlias();
245 
246  if(!$this->__checkSession($sid))
247  {
248  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
249  }
250 
251  global $ilLog,$ilUser;
252 
253  include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
254  $cp_options = ilCopyWizardOptions::_getInstance($copy_identifier);
255 
256  // Check owner of copy procedure
257  if(!$cp_options->checkOwner($ilUser->getId()))
258  {
259  $ilLog->write(__METHOD__.': Permission check failed for user id: '.$ilUser->getId().', copy id: '.$copy_identifier);
260  return false;
261  }
262 
263  // Fetch first node
264  if(($node = $cp_options->fetchFirstDependenciesNode()) === false)
265  {
266  $cp_options->deleteAll();
267  $ilLog->write(__METHOD__.': Finished copy step 2. Copy completed');
268 
269  return true;
270  }
271 
272  // Check options of this node
273  $options = $cp_options->getOptions($node['child']);
274  $new_ref_id = 0;
275  switch($options['type'])
276  {
278  $ilLog->write(__METHOD__.': Omitting node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
279  $this->callNextDependency($sid,$cp_options);
280  break;
281 
283  $ilLog->write(__METHOD__.': Nothing to do for node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
284  $this->callNextDependency($sid,$cp_options);
285  break;
286 
288  $ilLog->write(__METHOD__.': Start cloning dependencies: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
289  $this->cloneDependencies($node,$cp_options);
290  $this->callNextDependency($sid,$cp_options);
291  break;
292 
293  default:
294  $ilLog->write(__METHOD__.': No valid action type given for node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
295  $this->callNextDependency($sid,$cp_options);
296  break;
297  }
298  return true;
299  }
300 
309  public function ilClone($sid,$copy_identifier)
310  {
311  $this->initAuth($sid);
312  $this->initIlias();
313 
314  if(!$this->__checkSession($sid))
315  {
316  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
317  }
318 
319  global $ilLog,$ilUser;
320 
321  include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
322  $cp_options = ilCopyWizardOptions::_getInstance($copy_identifier);
323 
324  // Check owner of copy procedure
325  if(!$cp_options->checkOwner($ilUser->getId()))
326  {
327  $ilLog->write(__METHOD__.': Permission check failed for user id: '.$ilUser->getId().', copy id: '.$copy_identifier);
328  return false;
329  }
330 
331 
332  // Fetch first node
333  if(($node = $cp_options->fetchFirstNode()) === false)
334  {
335  $ilLog->write(__METHOD__.': Finished copy step 1. Starting copying of object dependencies...');
336  return $this->ilCloneDependencies($sid,$copy_identifier);
337  }
338 
339  // Check options of this node
340  $options = $cp_options->getOptions($node['child']);
341 
342  $new_ref_id = 0;
343  switch($options['type'])
344  {
346  $ilLog->write(__METHOD__.': Omitting node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
347  // set mapping to zero
348  $cp_options->appendMapping($node['child'],0);
349  $this->callNextNode($sid,$cp_options);
350  break;
351 
353  $ilLog->write(__METHOD__.': Start cloning node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
354  $new_ref_id = $this->cloneNode($node,$cp_options);
355  $this->callNextNode($sid,$cp_options);
356  break;
357 
359  $ilLog->write(__METHOD__.': Start linking node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
360  $new_ref_id = $this->linkNode($node,$cp_options);
361  $this->callNextNode($sid,$cp_options);
362  break;
363 
364  default:
365  $ilLog->write(__METHOD__.': No valid action type given for node: '.$node['obj_id'].', '.$node['title'].', '.$node['type']);
366  $this->callNextNode($sid,$cp_options);
367  break;
368 
369  }
370  return $new_ref_id;
371  }
372 
379  private function callNextNode($sid,$cp_options)
380  {
381  global $ilLog;
382 
383  $cp_options->dropFirstNode();
384 
385  if($cp_options->isSOAPEnabled())
386  {
387  // Start next soap call
388  include_once 'Services/WebServices/SOAP/classes/class.ilSoapClient.php';
389  $soap_client = new ilSoapClient();
390  $soap_client->setResponseTimeout(1);
391  $soap_client->enableWSDL(true);
392  $soap_client->init();
393  $soap_client->call('ilClone',array($sid,$cp_options->getCopyId()));
394  }
395  else
396  {
397  $ilLog->write(__METHOD__.': Cannot call SOAP server');
398  $cp_options->read();
399  include_once('./webservice/soap/include/inc.soap_functions.php');
400  $res = ilSoapFunctions::ilClone($sid,$cp_options->getCopyId());
401  }
402  return true;
403  }
404 
405  private function callNextDependency($sid,$cp_options)
406  {
407  global $ilLog;
408 
409  $cp_options->dropFirstDependenciesNode();
410 
411  if($cp_options->isSOAPEnabled())
412  {
413  // Start next soap call
414  include_once 'Services/WebServices/SOAP/classes/class.ilSoapClient.php';
415  $soap_client = new ilSoapClient();
416  $soap_client->setResponseTimeout(1);
417  $soap_client->enableWSDL(true);
418  $soap_client->init();
419  $soap_client->call('ilCloneDependencies',array($sid,$cp_options->getCopyId()));
420  }
421  else
422  {
423  $ilLog->write(__METHOD__.': Cannot call SOAP server');
424  $cp_options->read();
425  include_once('./webservice/soap/include/inc.soap_functions.php');
426  $res = ilSoapFunctions::ilCloneDependencies($sid,$cp_options->getCopyId());
427  }
428  return true;
429  }
430 
438  private function cloneNode($node,$cp_options)
439  {
440  global $ilLog,$tree,$ilAccess,$rbacreview;
441 
442  #sleep(20);
443 
444  $source_id = $node['child'];
445  $parent_id = $node['parent'];
446  $options = $cp_options->getOptions($node['child']);
447  $mappings = $cp_options->getMappings();
448 
449  if(!$ilAccess->checkAccess('copy','',$node['child']))
450  {
451  $ilLog->write(__METHOD__.': No copy permission granted: '.$source_id.', '.$node['title'].', '.$node['type']);
452  return false;
453 
454  }
455  if(!isset($mappings[$parent_id]))
456  {
457  $ilLog->write(__METHOD__.': Omitting node '.$source_id.', '.$node['title'].', '.$node['type']. '. No target found.');
458  return true;
459  }
460  $target_id = $mappings[$parent_id];
461 
462  if(!$tree->isInTree($target_id))
463  {
464  $ilLog->write(__METHOD__.': Omitting node '.$source_id.', '.$node['title'].', '.$node['type']. '. Object has been deleted.');
465  return false;
466  }
467 
468  $orig = ilObjectFactory::getInstanceByRefId((int) $source_id);
469  $new_obj = $orig->cloneObject((int) $target_id,$cp_options->getCopyId());
470 
471  if(!is_object($new_obj))
472  {
473  $ilLog->write(__METHOD__.': Error copying '.$source_id.', '.$node['title'].', '.$node['type'].'. No target found.');
474  return false;
475  }
476 
477  // rbac log
478  include_once "Services/AccessControl/classes/class.ilRbacLog.php";
479  $rbac_log_roles = $rbacreview->getParentRoleIds($new_obj->getRefId(), false);
480  $rbac_log = ilRbacLog::gatherFaPa($new_obj->getRefId(), array_keys($rbac_log_roles), true);
481  ilRbacLog::add(ilRbacLog::COPY_OBJECT, $new_obj->getRefId(), $rbac_log, (int)$source_id);
482 
483  // Finally add new mapping entry
484  $cp_options->appendMapping($source_id,$new_obj->getRefId());
485  return $new_obj->getRefId();
486  }
487 
495  private function cloneDependencies($node,$cp_options)
496  {
497  global $ilLog;
498 
499  $source_id = $node['child'];
500  $mappings = $cp_options->getMappings();
501 
502  if(!isset($mappings[$source_id]))
503  {
504  $ilLog->write(__METHOD__.': Omitting node '.$source_id.', '.$node['title'].', '.$node['type']. '. No mapping found.');
505  return true;
506  }
507  $target_id = $mappings[$source_id];
508 
509  $orig = ilObjectFactory::getInstanceByRefId((int) $source_id);
510  $orig->cloneDependencies($target_id,$cp_options->getCopyId());
511  return true;
512  }
513 
521  private function linkNode($node,$cp_options)
522  {
523  global $ilLog,$ilAccess,$rbacreview;
524 
525  $source_id = $node['child'];
526  $parent_id = $node['parent'];
527  $options = $cp_options->getOptions($node['child']);
528  $mappings = $cp_options->getMappings();
529 
530  if(!$ilAccess->checkAccess('delete','',$node['child']))
531  {
532  $ilLog->write(__METHOD__.': No delete permission granted: '.$source_id.', '.$node['title'].', '.$node['type']);
533  return false;
534 
535  }
536  if(!isset($mappings[$parent_id]))
537  {
538  $ilLog->write(__METHOD__.': Omitting node '.$source_id.', '.$node['title'].', '.$node['type']. '. No target found.');
539  return true;
540  }
541  $target_id = $mappings[$parent_id];
542 
543  $orig = ilObjectFactory::getInstanceByRefId((int) $source_id);
544  $new_ref_id = $orig->createReference();
545  $orig->putInTree($target_id);
546  $orig->setPermissions($target_id);
547 
548  if(!($new_ref_id))
549  {
550  $ilLog->write(__METHOD__.': Error linking '.$source_id.', '.$node['title'].', '.$node['type'].'. No target found.');
551  return false;
552  }
553 
554  // rbac log
555  include_once "Services/AccessControl/classes/class.ilRbacLog.php";
556  $rbac_log_roles = $rbacreview->getParentRoleIds($new_ref_id, false);
557  $rbac_log = ilRbacLog::gatherFaPa($new_ref_id, array_keys($rbac_log_roles), true);
558  ilRbacLog::add(ilRbacLog::LINK_OBJECT, $new_ref_id, $rbac_log, (int)$source_id);
559 
560  // Finally add new mapping entry
561  $cp_options->appendMapping($source_id,$new_ref_id);
562  return $new_ref_id;
563  }
564 
571  static function validateXML ($xml) {
572  // validate to prevent wrong XMLs
573  $dom = @domxml_open_mem($xml, DOMXML_LOAD_VALIDATING, $error);
574  if ($error)
575  {
576  $msg = array();
577  if (is_array($error))
578  {
579  foreach ($error as $err) {
580  $msg []= "(".$err["line"].",".$err["col"]."): ".$err["errormessage"];
581  }
582  }
583  else
584  {
585  $msg[] = $error;
586  }
587  $msg = join("\n",$msg);
588  return $msg;
589  }
590  return true;
591  }
592 
593  public function handleECSTasks($sid,$a_server_id)
594  {
595  $this->initAuth($sid);
596  $this->initIlias();
597 
598  if(!$this->__checkSession($sid))
599  {
600  return $this->__raiseError($this->__getMessage(),$this->__getMessageCode());
601  }
602 
603  include_once('./Services/WebServices/ECS/classes/class.ilECSTaskScheduler.php');
604 
605  global $ilLog;
606 
607  $ilLog->write(__METHOD__.': Starting task execution...');
608  $scheduler = ilECSTaskScheduler::_getInstanceByServerId($a_server_id);
609  $scheduler->startTaskExecution();
610 
611  return true;
612  }
613 
627  {
628  $this->initAuth($sid);
629  $this->initIlias();
630 
631  // Session check not possible -> anonymous user is the trigger
632 
633  global $ilDB, $ilLog;
634 
635  $ilLog->write(__METHOD__.': Started deletion of inactive user objects with expired confirmation hash values (dual opt in) ...');
636 
637  require_once 'Services/Registration/classes/class.ilRegistrationSettings.php';
638  $oRegSettigs = new ilRegistrationSettings();
639 
640  $query = '';
641 
642  /*
643  * Fetch the current actuator user object first, because this user will try to perform very probably
644  * a new registration with the same login name in a few seconds ;-)
645  *
646  */
647  if((int)$usr_id > 0)
648  {
649  $query .= 'SELECT usr_id, create_date, reg_hash FROM usr_data '
650  . 'WHERE active = 0 '
651  . 'AND reg_hash IS NOT NULL '
652  . 'AND usr_id = '.$ilDB->quote($usr_id, 'integer').' ';
653  $query .= 'UNION ';
654  }
655 
656  $query .= 'SELECT usr_id, create_date, reg_hash FROM usr_data '
657  . 'WHERE active = 0 '
658  . 'AND reg_hash IS NOT NULL '
659  . 'AND usr_id != '.$ilDB->quote($usr_id, 'integer').' ';
660 
661  $res = $ilDB->query($query);
662 
663  $ilLog->write(__METHOD__.': '.$ilDB->numRows($res).' inactive user objects with confirmation hash values (dual opt in) found ...');
664 
665  /*
666  * mjansen: 15.12.2010:
667  * I perform the expiration check in php because of multi database support (mysql, postgresql).
668  * I did not find an oracle equivalent for mysql: UNIX_TIMESTAMP()
669  */
670 
671  $num_deleted_users = 0;
672  while($row = $ilDB->fetchAssoc($res))
673  {
674  if($row['usr_id'] == ANONYMOUS_USER_ID || $row['usr_id'] == SYSTEM_USER_ID) continue;
675  if(!strlen($row['reg_hash'])) continue;
676 
677  if((int)$oRegSettigs->getRegistrationHashLifetime() > 0 &&
678  $row['create_date'] != '' &&
679  time() - $oRegSettigs->getRegistrationHashLifetime() > strtotime($row['create_date']))
680  {
681  $user = ilObjectFactory::getInstanceByObjId($row['usr_id'], false);
682  if($user instanceof ilObjUser)
683  {
684  $ilLog->write(__METHOD__.': User '.$user->getLogin().' (obj_id: '.$user->getId().') will be deleted due to an expired registration hash ...');
685  $user->delete();
686  ++$num_deleted_users;
687  }
688  }
689  }
690 
691  $ilLog->write(__METHOD__.': '.$num_deleted_users.' inactive user objects with expired confirmation hash values (dual opt in) deleted ...');
692 
693  $ilLog->write(__METHOD__.': Finished deletion of inactive user objects with expired confirmation hash values (dual opt in) ...');
694 
695  return true;
696  }
697 }
698 ?>