ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
BasicPersistence.php
Go to the documentation of this file.
1<?php
2
4
14
16{
17
21 protected static $instance;
25 protected static $buckets = [];
41 protected static $tasks = [];
45 protected $connector = null;
46
47
48 public static function instance()
49 {
50 if (!self::$instance) {
51 self::$instance = new BasicPersistence();
52 }
53
54 return self::$instance;
55 }
56
57
63 {
64 $this->connector = $connector;
65 }
66
67
73 public function saveBucketAndItsTasks(Bucket $bucket)
74 {
75 $bucket->checkIntegrity();
76
77 $this->saveObserver($bucket);
78 }
79
80
86 public function updateBucket(Bucket $bucket)
87 {
88 $bucketContainer = new BucketContainer($this->getBucketContainerId($bucket), $this->connector);
89
90 // The basic information about the task.
91 $bucketContainer->setUserId($bucket->getUserId());
92 $bucketContainer->setState($bucket->getState());
93 $bucketContainer->setTotalNumberoftasks(count($bucket->getTask()->unfoldTask()));
94 $bucketContainer->setPercentage($bucket->getOverallPercentage());
95 $bucketContainer->setTitle($bucket->getTitle());
96 $bucketContainer->setLastHeartbeat($bucket->getLastHeartbeat());
97 $bucketContainer->setDescription($bucket->getDescription());
98 $bucketContainer->setCurrentTaskid($this->getTaskContainerId($bucket->getCurrentTask()));
99 $bucketContainer->setRootTaskid($this->getTaskContainerId($bucket->getTask()));
100
101 // Save and store the container to bucket instance.
102 $bucketContainer->update();
103 }
104
105
109 public function getBucketIdsOfUser($user_id, $order_by = "id", $order_direction = "ASC")
110 {
111 return BucketContainer::where(['user_id' => $user_id])
112 ->orderBy($order_by, $order_direction)
113 ->getArray(null, 'id');
114 }
115
116
122 public function getBucketMetaOfUser($user_id)
123 {
124 $buckets = BucketContainer::where([ 'user_id' => $user_id ])->get();
125 $bucketMetas = array_map(function (BucketContainer $bucketContainer) {
126 $bucketMeta = new BasicBucketMeta();
127
128 $bucketMeta->setUserId($bucketContainer->getUserId());
129 $bucketMeta->setState($bucketContainer->getState());
130 $bucketMeta->setTitle($bucketContainer->getTitle());
131 $bucketMeta->setDescription($bucketContainer->getDescription());
132 $bucketMeta->setOverallPercentage($bucketContainer->getPercentage());
133
134 return $bucketMeta;
135 }, $buckets);
136
137 return $bucketMetas;
138 }
139
140
145 {
146 $buckets = BucketContainer::where([ 'state' => $state ])->get();
147 $ids = array_map(function (BucketContainer $bucket_container) {
148 return $bucket_container->getId();
149 }, $buckets);
150
151 return $ids;
152 }
153
154
161 protected function saveObserver(Bucket $bucket)
162 {
163 // If the instance has a known container we use it, otherwise we create a new container.
164 if (isset($this->bucketHashToObserverContainerId[spl_object_hash($bucket)])) {
165 $bucketContainer = new BucketContainer($this->bucketHashToObserverContainerId[spl_object_hash($bucket)], $this->connector);
166 } else {
167 $bucketContainer = new BucketContainer(0, $this->connector);
168 }
169
170 // The basic information about the task.
171 $bucketContainer->setUserId($bucket->getUserId());
172 $bucketContainer->setState($bucket->getState());
173 $bucketContainer->setTitle($bucket->getTitle());
174 $bucketContainer->setDescription($bucket->getDescription());
175 $bucketContainer->setTotalNumberoftasks(count($bucket->getTask()->unfoldTask()));
176 $bucketContainer->setPercentage($bucket->getOverallPercentage());
177
178 // We want to store the bucket ID in every sub task and value. Thus we need to create an id if not available yet.
179 if (!$bucketContainer->getId()) {
180 $bucketContainer->create();
181 }
182
183 // The recursive part.
184 $this->saveTask($bucket->getTask(), $bucketContainer->getId());
185 if (!$bucket->getCurrentTask()) {
186 $bucket->setCurrentTask($bucket->getTask());
187 }
188 $bucketContainer->setCurrentTaskid($this->getTaskContainerId($bucket->getCurrentTask()));
189 $bucketContainer->setRootTaskid($this->getTaskContainerId($bucket->getTask()));
190
191 // Save and store the container to bucket instance.
192 $bucketContainer->save();
193 $this->bucketHashToObserverContainerId[spl_object_hash($bucket)] = $bucketContainer->getId();
194 }
195
196
204 protected function saveTask(Task $task, $bucketId)
205 {
206 // If the instance has a known container we use it, otherwise we create a new container.
207 if (isset($this->taskHashToTaskContainerId[spl_object_hash($task)])) {
208 $taskContainer = new TaskContainer($this->taskHashToTaskContainerId[spl_object_hash($task)], $this->connector);
209 } else {
210 $taskContainer = new TaskContainer(0, $this->connector);
211 }
212
213 // The basic information about the task.
214 $taskContainer->setType($task->getType());
215 $taskContainer->setBucketId($bucketId);
216 $reflection = new \ReflectionClass(get_class($task));
217 $taskContainer->setClassName(get_class($task));
218 $taskContainer->setClassPath($reflection->getFileName());
219
220 // Recursivly save the inputs and link them to this task.
221 foreach ($task->getInput() as $input) {
222 $this->saveValue($input, $bucketId);
223 }
224 $this->saveValueToTask($task, $taskContainer, $bucketId);
225
226 // Save and store the container to the task instance.
227 $taskContainer->save();
228 $this->taskHashToTaskContainerId[spl_object_hash($task)] = $taskContainer->getId();
229 }
230
231
240 protected function saveValueToTask(Task $task, TaskContainer $taskContainer, $bucketId)
241 {
242 // If we have previous values to task associations we delete them.
243 if ($taskContainer->getId()) {
245 $olds = ValueToTaskContainer::where([ 'task_id' => $taskContainer->getId() ])->get();
246 foreach ($olds as $old) {
247 $old->delete();
248 }
249 } else {
250 // We need a valid ID to link the inputs
251 $taskContainer->save();
252 }
253
254 // We create the new 1 to n relation.
255 foreach ($task->getInput() as $inputValue) {
256 $v = new ValueToTaskContainer(0, $this->connector);
257 $v->setTaskId($taskContainer->getId());
258 $v->setBucketId($bucketId);
259 $v->setValueId($this->getValueContainerId($inputValue));
260 $v->save();
261 }
262 }
263
264
272 protected function saveValue(Value $value, $bucketId)
273 {
274 // If we have previous values to task associations we delete them.
275 if (isset($this->valueHashToValueContainerId[spl_object_hash($value)])) {
276 $valueContainer = new ValueContainer($this->valueHashToValueContainerId[spl_object_hash($value)], $this->connector);
277 } else {
278 $valueContainer = new ValueContainer(0, $this->connector);
279 }
280
281 // Save information about the value
282 $reflection = new \ReflectionClass(get_class($value));
283 $valueContainer->setClassName(get_class($value));
284 $valueContainer->setClassPath($reflection->getFileName());
285 $valueContainer->setType($value->getType());
286 $valueContainer->setHasParenttask($value->hasParentTask());
287 $valueContainer->setBucketId($bucketId);
288 $valueContainer->setHash($value->getHash());
289 $valueContainer->setSerialized($value->serialize());
290
291 // If the value is a thunk value we also store its parent.
292 if ($value->hasParentTask()) {
293 $this->saveTask($value->getParentTask(), $bucketId);
294 $valueContainer->setParentTaskid($this->getTaskContainerId($value->getParentTask()));
295 }
296
297 // We save the container and store the instance to container association.
298 $valueContainer->save();
299 $this->valueHashToValueContainerId[spl_object_hash($value)] = $valueContainer->getId();
300 }
301
302
309 public function getBucketContainerId(Bucket $bucket)
310 {
311 if (!isset($this->bucketHashToObserverContainerId[spl_object_hash($bucket)])) {
312 throw new SerializationException("Could not resolve container id of task: "
313 . print_r($bucket, true));
314 }
315
316 return $this->bucketHashToObserverContainerId[spl_object_hash($bucket)];
317 }
318
319
326 protected function getTaskContainerId(Task $task)
327 {
328 if (!isset($this->taskHashToTaskContainerId[spl_object_hash($task)])) {
329 throw new SerializationException("Could not resolve container id of task: "
330 . print_r($task, true));
331 }
332
333 return $this->taskHashToTaskContainerId[spl_object_hash($task)];
334 }
335
336
343 protected function getValueContainerId($value)
344 {
345 if (!isset($this->valueHashToValueContainerId[spl_object_hash($value)])) {
346 throw new SerializationException("Could not resolve container id of value: "
347 . print_r($value, true));
348 }
349
350 return $this->valueHashToValueContainerId[spl_object_hash($value)];
351 }
352
353
360 public function loadBucket($bucket_id)
361 {
362 if (isset(self::$buckets[$bucket_id])) {
363 return self::$buckets[$bucket_id];
364 }
366 $bucketContainer = BucketContainer::find($bucket_id);
367 if (!$bucketContainer) {
368 throw new BucketNotFoundException("The requested bucket with container id $bucket_id could not be found in the database.");
369 }
370 $bucket = new BasicBucket();
371
372 $bucket->setUserId($bucketContainer->getUserId());
373 $bucket->setState($bucketContainer->getState());
374 $bucket->setTitle($bucketContainer->getTitle());
375 $bucket->setDescription($bucketContainer->getDescription());
376 $bucket->setOverallPercentage($bucketContainer->getPercentage());
377 $bucket->setLastHeartbeat($bucketContainer->getLastHeartbeat());
378 $bucket->setTask($this->loadTask($bucketContainer->getRootTaskid(), $bucket, $bucketContainer));
379
380 $this->bucketHashToObserverContainerId[spl_object_hash($bucket)] = $bucket_id;
381
382 return $bucket;
383 }
384
385
397 private function loadTask($taskContainerId, Bucket $bucket, BucketContainer $bucketContainer)
398 {
399 global $DIC;
400 $factory = $DIC->backgroundTasks()->taskFactory();
402 $taskContainer = TaskContainer::find($taskContainerId);
404 require_once($taskContainer->getClassPath());
406 $task = $factory->createTask($taskContainer->getClassName());
407
408 // Bugfix 0023775
409 // Added additional orderBy for the id to ensure that the items are returned in the right order.
411 $valueToTasks = ValueToTaskContainer::where([ 'task_id' => $taskContainerId ])->orderBy('task_id')->orderBy('id')->get();
412 $inputs = [];
413 foreach ($valueToTasks as $valueToTask) {
414 $inputs[] = $this->loadValue($valueToTask->getValueId(), $bucket, $bucketContainer);
415 }
416 $task->setInput($inputs);
417
418 if ($taskContainerId == $bucketContainer->getCurrentTaskid()) {
419 $bucket->setCurrentTask($task);
420 }
421
422 $this->taskHashToTaskContainerId[spl_object_hash($task)] = $taskContainerId;
423
424 return $task;
425 }
426
427
428 private function loadValue($valueContainerId, Bucket $bucket, BucketContainer $bucketContainer)
429 {
430 global $DIC;
431 $factory = $DIC->backgroundTasks()->injector();
432
434 $valueContainer = ValueContainer::find($valueContainerId);
436 require_once($valueContainer->getClassPath());
438 $value = $factory->createInstance($valueContainer->getClassName());
439
440 $value->unserialize($valueContainer->getSerialized());
441 if ($valueContainer->getHasParenttask()) {
442 $value->setParentTask($this->loadTask($valueContainer->getParentTaskid(), $bucket, $bucketContainer));
443 }
444
445 $this->valueHashToValueContainerId[spl_object_hash($value)] = $valueContainerId;
446
447 return $value;
448 }
449
450
451 public function deleteBucketById($bucket_id)
452 {
454 $buckets = BucketContainer::where([ 'id' => $bucket_id ])->get();
455 array_map(function (\ActiveRecord $item) {
456 $item->delete();
457 }, $buckets);
458
460 $tasks = TaskContainer::where([ 'bucket_id' => $bucket_id ])->get();
461 array_map(function (\ActiveRecord $item) {
462 $item->delete();
463 }, $tasks);
464
466 $values = ValueContainer::where([ 'bucket_id' => $bucket_id ])->get();
467 array_map(function (\ActiveRecord $item) {
468 $item->delete();
469 }, $values);
470
472 $valueToTasks = ValueToTaskContainer::where([ 'bucket_id' => $bucket_id ])->get();
473 array_map(function (\ActiveRecord $item) {
474 $item->delete();
475 }, $valueToTasks);
476 }
477
478
482 public function deleteBucket($bucket)
483 {
484 $id = $this->getBucketContainerId($bucket);
485 $this->deleteBucketById($id);
486 unset($this->bucketHashToObserverContainerId[spl_object_hash($bucket)]);
487 }
488
489
495 public function loadBuckets($bucket_container_id)
496 {
497 $buckets = [];
498 foreach ($bucket_container_id as $bucket_id) {
499 $buckets[] = $this->loadBucket($bucket_id);
500 }
501
502 return $buckets;
503 }
504}
$factory
Definition: metadata.php:47
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
Class ActiveRecord.
static where($where, $operator=null)
An exception for terminatinating execution or to throw for unit testing.
saveBucketAndItsTasks(Bucket $bucket)
Fully updates or creates an Observer and all its tasks into the database.
updateBucket(Bucket $bucket)
Updates only the bucket! Use this if e.g.
getBucketIdsOfUser($user_id, $order_by="id", $order_direction="ASC")
\int[] Returns an array of bucket ids for the given user Id.
getBucketIdsByState($state)
int[] Returns a list of bucket ids for the given Observer State
deleteBucket($bucket)
Delete the bucket and all its stuff.void
setConnector(\arConnector $connector)
Currently for testing only.
Class arConnector.
if(!array_key_exists('StateId', $_REQUEST)) $id
getLastHeartbeat()
When was the last time that something happened on this bucket?
deleteBucketById($bucket_id)
Deletes the Observer AND all its tasks and values.
loadBucket($bucket_container_id)
$old
global $DIC
Definition: saml.php:7