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