ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilECSEventQueueReader.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2006 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 include_once './Services/WebServices/ECS/classes/class.ilECSEvent.php';
25 
26 
37 {
38  const TYPE_EXPORTED = 'exported';
39  const TYPE_DIRECTORY_TREES = 'directory_trees';
40  const TYPE_CMS_COURSES = 'courses';
41  const TYPE_CMS_COURSE_MEMBERS = 'course_members';
42  const TYPE_REMOTE_COURSE = 'rcrs';
43  const TYPE_REMOTE_CATEGORY = 'rcat';
44  const TYPE_REMOTE_FILE = 'rfil';
45  const TYPE_REMOTE_GLOSSARY = 'rglo';
46  const TYPE_REMOTE_GROUP = 'rgrp';
48  const TYPE_REMOTE_WIKI = 'rwik';
49  const TYPE_REMOTE_TEST = 'rtst';
50  const TYPE_COURSE_URLS = 'course_urls';
51  const TYPE_ENROLMENT_STATUS = 'member_status';
52 
53  protected $log;
54  protected $db;
55 
56  protected $events = array();
57  protected $econtent_ids = array();
58 
64  public function __construct($a_server_id)
65  {
66  global $ilLog,$ilDB;
67 
68  include_once('Services/WebServices/ECS/classes/class.ilECSSetting.php');
69 
70  $this->settings = ilECSSetting::getInstanceByServerId($a_server_id);
71  $this->log = $ilLog;
72  $this->db = $ilDB;
73 
74  $this->read();
75  }
76 
83  protected static function getEventTypeFromObjectType($a_obj_type)
84  {
85  // currently they are the same for all resource types
86  return $a_obj_type;
87  }
88 
94  protected static function getAllEContentTypes()
95  {
96  return array(self::TYPE_REMOTE_COURSE, self::TYPE_REMOTE_CATEGORY,
97  self::TYPE_REMOTE_FILE, self::TYPE_REMOTE_GLOSSARY, self::TYPE_REMOTE_GROUP,
98  self::TYPE_REMOTE_LEARNING_MODULE, self::TYPE_REMOTE_WIKI, self::TYPE_REMOTE_TEST);
99  }
100 
109  protected static function getAllResourceIds(ilECSSetting $server, array $a_types, $a_sender_only = false)
110  {
111  include_once 'Services/WebServices/ECS/classes/class.ilRemoteObjectBase.php';
112  $list = array();
113  foreach($a_types as $type)
114  {
116  if($robj)
117  {
118  $list[$type] = $robj->getAllResourceIds($server, $a_sender_only);
119  }
120  }
121 
122  return $list;
123  }
124 
132  public static function handleImportReset(ilECSSetting $server)
133  {
134  global $ilLog;
135 
136  include_once('Services/WebServices/ECS/classes/class.ilECSConnector.php');
137  include_once('Services/WebServices/ECS/classes/class.ilECSConnectorException.php');
138 
139  try
140  {
141  include_once('./Services/WebServices/ECS/classes/class.ilECSEventQueueReader.php');
142  include_once('./Services/WebServices/ECS/classes/class.ilECSImport.php');
143  include_once('./Services/WebServices/ECS/classes/class.ilECSExport.php');
144 
145  $types = self::getAllEContentTypes();
146 
147  $event_queue = new ilECSEventQueueReader($server->getServerId());
148  $event_queue->deleteAllEContentEvents($types);
149 
150  $list = self::getAllResourceIds($server, $types);
152 
153  $GLOBALS['ilLog']->write(__METHOD__.': Imported = '.print_r($imported,true));
154  $GLOBALS['ilLog']->write(__METHOD__.': List = '.print_r($list,true));
155 
156  foreach($list as $resource_type => $link_ids)
157  {
158  if(!in_array($resource_type, ilECSUtils::getPossibleRemoteTypes()))
159  {
160  $GLOBALS['ilLog']->write(__METHOD__.': Ignoring resource type '. $resource_type);
161  continue;
162  }
163 
164 
165  foreach((array) $link_ids as $link_id)
166  {
167  if(!isset($imported[$link_id]))
168  {
169  // Add create event for not imported econtent
170  $event_queue->add(
171  $resource_type,
172  $link_id,
174  );
175  }
176  else
177  {
178  // Add update event for already existing events
179  $event_queue->add(
180  $resource_type,
181  $link_id,
183  );
184  }
185 
186  if(isset($imported[$link_id]))
187  {
188  unset($imported[$link_id]);
189  }
190  }
191  }
192 
193  if(is_array($imported))
194  {
195  // Delete event for deprecated econtent
196  include_once 'Services/WebServices/ECS/classes/class.ilECSObjectSettings.php';
197  foreach($imported as $econtent_id => $obj_id)
198  {
200  if($type)
201  {
202  $event_queue->add($type,
203  $econtent_id,
205  );
206  }
207  }
208  }
209  }
210  catch(ilECSConnectorException $e1)
211  {
212  $ilLog->write('Cannot connect to ECS server: '.$e1->getMessage());
213  throw $e1;
214  }
215  catch(ilException $e2)
216  {
217  $ilLog->write('Update failed: '.$e2->getMessage());
218  throw $e2;
219  }
220  return true;
221  }
222 
231  public static function handleExportReset(ilECSSetting $server)
232  {
233  include_once('./Services/WebServices/ECS/classes/class.ilECSExport.php');
234 
235  // Delete all export events
236  $queue = new ilECSEventQueueReader($server->getServerId());
237  $queue->deleteAllExportedEvents();
238 
239  // Read all local export info
240  $local_econtent_ids = ilECSExport::_getAllEContentIds($server->getServerId());
241 
242  $types = self::getAllEContentTypes();
243  $list = self::getAllResourceIds($server, $types, true);
244 
245 
246  // merge in one array
247  $all_remote_ids = array();
248  foreach($list as $resource_type => $remote_ids)
249  {
250  $all_remote_ids = array_merge($all_remote_ids,(array) $remote_ids);
251  }
252  $all_remote_ids = array_unique($all_remote_ids);
253 
254  $GLOBALS['ilLog']->write(__METHOD__.': Resources = ' . print_r($all_remote_ids,true));
255  $GLOBALS['ilLog']->write(__METHOD__.': Local = ' . print_r($local_econtent_ids,true));
256  foreach($local_econtent_ids as $local_econtent_id => $local_obj_id)
257  {
258  if(!in_array($local_econtent_id, $all_remote_ids))
259  {
260  // Delete this deprecated info
261  $GLOBALS['ilLog']->write(__METHOD__.': Deleting deprecated econtent id '. $local_econtent_id);
262  ilECSExport::_deleteEContentIds($server->getServerId(),array($local_econtent_id));
263 
264  }
265  }
266  return true;
267  }
268 
269 
274  public function getServer()
275  {
276  return $this->settings;
277  }
278 
279 
286  public function getEvents()
287  {
288  return $this->events ? $this->events : array();
289  }
290 
296  public function deleteAll()
297  {
298  global $ilDB;
299 
300  $query = "DELETE FROM ecs_events ".
301  'WHERE server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
302  $res = $ilDB->manipulate($query);
303  return true;
304  }
305 
312  public function deleteAllEContentEvents(array $a_types)
313  {
314  global $ilDB;
315 
316  $query = "DELETE FROM ecs_events ".
317  "WHERE ".$this->db->in("type", $a_types, "", "text").' '.
318  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
319  $res = $ilDB->manipulate($query);
320  return true;
321  }
322 
328  protected function deleteAllExportedEvents()
329  {
330  global $ilDB;
331 
332  $query = "DELETE FROM ecs_events ".
333  "WHERE type = ".$this->db->quote(self::TYPE_EXPORTED,'text').' '.
334  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
335  $res = $ilDB->manipulate($query);
336  return true;
337  }
338 
345  public function refresh()
346  {
347  try {
348  include_once('Services/WebServices/ECS/classes/class.ilECSConnector.php');
349  include_once('Services/WebServices/ECS/classes/class.ilECSConnectorException.php');
350 
351  $connector = new ilECSConnector($this->getServer());
352  while(true)
353  {
354  $res = $connector->readEventFifo(false);
355 
356  if(!count($res->getResult()))
357  {
358  return true;
359  }
360 
361  foreach($res->getResult() as $result)
362  {
363  include_once './Services/WebServices/ECS/classes/class.ilECSEvent.php';
364  $event = new ilECSEvent($result);
365 
366  $GLOBALS['ilLog']->write(__METHOD__.' ---------------------------- Handling new event ');
367  $GLOBALS['ilLog']->write(__METHOD__.print_r($event,true));
368  $GLOBALS['ilLog']->write(__METHOD__.' ---------------------------- Done! ');
369 
370  // Fill command queue
371  $this->writeEventToDB($event);
372  }
373  // Delete from fifo
374  $connector->readEventFifo(true);
375  }
376 
377  }
378  catch(ilECSConnectorException $e)
379  {
380  $GLOBALS['ilLog']->write(__METHOD__.': Cannot read event fifo. Aborting');
381  }
382  }
383 
389  public static function deleteServer($a_server_id)
390  {
391  global $ilDB;
392 
393  $query = 'DELETE FROM ecs_events '.
394  'WHERE server_id = '.$ilDB->quote($a_server_id,'integer');
395  $ilDB->manipulate($query);
396  }
397 
401  private function writeEventToDB(ilECSEvent $ev)
402  {
403  global $ilDB;
404 
405  // this should probably be moved elsewhere
406  switch($ev->getRessourceType())
407  {
408  case 'directory_trees':
410  break;
411 
412  case 'course_members':
414  break;
415 
416  case 'courses':
417  $type = self::TYPE_CMS_COURSES;
418  break;
419 
420  case 'courselinks':
421  $type = self::TYPE_REMOTE_COURSE;
422  break;
423 
424  case 'categories':
426  break;
427 
428  case 'files':
429  $type = self::TYPE_REMOTE_FILE;
430  break;
431 
432  case 'glossaries':
434  break;
435 
436  case 'groups':
437  $type = self::TYPE_REMOTE_GROUP;
438  break;
439 
440  case 'learningmodules':
442  break;
443 
444  case 'wikis':
445  $type = self::TYPE_REMOTE_WIKI;
446  break;
447 
448  case 'tests':
449  $type = self::TYPE_REMOTE_TEST;
450  break;
451 
452  case 'course_urls':
453  $type = self::TYPE_COURSE_URLS;
454  break;
455 
456  case 'member_status':
458  break;
459  }
460 
461  $query = "SELECT * FROM ecs_events ".
462  "WHERE type = ".$ilDB->quote($type,'integer')." ".
463  "AND id = ".$ilDB->quote($ev->getRessourceId(),'integer')." ".
464  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
465  $res = $ilDB->query($query);
466 
467  $event_id = 0;
468  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
469  {
470  $event_id = $row->event_id;
471  }
472 
473  if(!$event_id)
474  {
475  // No previous entry exists => perform insert
476  $query = "INSERT ecs_events (event_id,type,id,op,server_id) ".
477  "VALUES( ".
478  $ilDB->quote($ilDB->nextId('ecs_events'),'integer').','.
479  $ilDB->quote($type,'text').', '.
480  $ilDB->quote($ev->getRessourceId(),'integer').', '.
481  $ilDB->quote($ev->getStatus(),'text').', '.
482  $ilDB->quote($this->getServer()->getServerId(),'integer').' '.
483  ')';
484  $ilDB->manipulate($query);
485  return true;
486  }
487  // Do update
488  $do_update = false;
489  switch($ev->getStatus())
490  {
491  case ilECSEvent::CREATED:
492  // Do update, although impossible
493  $do_update = true;
494  break;
495 
497  $do_update = true;
498  break;
499 
500  case ilECSEvent::UPDATED:
501  // Do nothing. Old status is ok.
502  break;
503  }
504 
505  if(!$do_update)
506  {
507  return true;
508  }
509  $query = "UPDATE ecs_events ".
510  "SET op = ".$ilDB->quote($ev->getStatus(),'text')." ".
511  "WHERE event_id = ".$ilDB->quote($event_id,'integer').' '.
512  'AND type = '.$ilDB->quote($type).' '.
513  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
514  $ilDB->manipulate($query);
515  return true;
516  }
517 
524  public function shift()
525  {
526  $event = array_shift($this->events);
527  if($event == null)
528  {
529  return array();
530  }
531  else
532  {
533 
534  #$this->delete($event['event_id']);
535  return $event;
536  }
537  }
538 
539 
545  public function add($a_type,$a_id,$a_op)
546  {
547  global $ilDB;
548 
549  $next_id = $ilDB->nextId('ecs_events');
550  $query = "INSERT INTO ecs_events (event_id,type,id,op,server_id) ".
551  "VALUES (".
552  $ilDB->quote($next_id,'integer').", ".
553  $this->db->quote($a_type,'text').", ".
554  $this->db->quote($a_id,'integer').", ".
555  $this->db->quote($a_op,'text').", ".
556  $ilDB->quote($this->getServer()->getServerId(),'integer').' '.
557  ")";
558  $res = $ilDB->manipulate($query);
559 
560  $new_event['event_id'] = $next_id;
561  $new_event['type'] = $a_type;
562  $new_event['id'] = $a_id;
563  $new_event['op'] = $a_op;
564 
565  $this->events[] = $new_event;
566  $this->econtent_ids[$a_id] = $a_id;
567  return true;
568  }
569 
576  private function update($a_type,$a_id,$a_operation)
577  {
578  global $ilDB;
579 
580  $query = "UPDATE ecs_events ".
581  "SET op = ".$this->db->quote($a_operation,'text')." ".
582  "WHERE type = ".$this->db->quote($a_type,'text')." ".
583  "AND id = ".$this->db->quote($a_id,'integer')." ".
584  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
585  $res = $ilDB->manipulate($query);
586  }
587 
594  public function delete($a_event_id)
595  {
596  global $ilDB;
597 
598  $query = "DELETE FROM ecs_events ".
599  "WHERE event_id = ".$this->db->quote($a_event_id,'integer')." ".
600  'AND server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer');
601  $res = $ilDB->manipulate($query);
602  unset($this->econtent_ids[$a_event_id]);
603  return true;
604  }
605 
610  public function read()
611  {
612  global $ilDB;
613 
614  $query = "SELECT * FROM ecs_events ".
615  'WHERE server_id = '.$ilDB->quote($this->getServer()->getServerId(),'integer').' '.
616  'ORDER BY event_id';
617 
618  $res = $this->db->query($query);
619  $counter = 0;
620  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
621  {
622  $this->events[$counter]['event_id'] = $row->event_id;
623  $this->events[$counter]['type'] = $row->type;
624  $this->events[$counter]['id'] = $row->id;
625  $this->events[$counter]['op'] = $row->op;
626 
627  $this->econtent_ids[$row->event_id] = $row->event_id;
628  ++$counter;
629  }
630  return true;
631  }
632 
633  public static function deleteByServerId($a_server_id)
634  {
635  global $ilDB;
636 
637  $query = 'DELETE FROM ecs_events'.
638  ' WHERE server_id = '.$ilDB->quote($a_server_id,'integer');
639  $ilDB->manipulate($query);
640  return true;
641  }
642 }
643 ?>