ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilCmiXapiStatementsReportLinkBuilder.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5
16{
20 protected function buildPipeline() : array
21 {
22 $pipeline = array();
23
24 $pipeline[] = $this->buildFilterStage();
25
26 $pipeline[] = $this->buildOrderingStage();
27
28 $pipeline[] = array('$facet' => array(
29 'stage1' => array(
30 array('$group' => array('_id' => null, 'count' => array('$sum' => 1) ))
31 ),
32 'stage2' => $this->buildLimitStage()
33 ));
34
35 $pipeline[] = array('$unwind' => '$stage1');
36
37 $pipeline[] = array('$project' => array(
38 'maxcount' => '$stage1.count',
39 'statements' => '$stage2.statement'
40 ));
41
43 //$log->debug("aggregation pipeline:\n" . json_encode($pipeline, JSON_PRETTY_PRINT));
44
45 return $pipeline;
46 }
47
48 protected function buildLimitStage()
49 {
50 $stage = array(
51 array('$skip' => (int) $this->filter->getOffset())
52 );
53
54 if ($this->filter->getLimit()) {
55 $stage[] = array('$limit' => (int) $this->filter->getLimit());
56 }
57 return $stage;
58 }
59
60 protected function buildFilterStage()
61 {
62 $cmi5_extensions_query = false;
63
64 $stage = array();
65 $stage['statement.object.objectType'] = 'Activity';
66 $stage['statement.actor.objectType'] = 'Agent';
67 if ($this->filter->getVerb()) {
68 $stage['statement.verb.id'] = $this->filter->getVerb();
69 }
70
71 if ($this->filter->getStartDate() || $this->filter->getEndDate()) {
72 $stage['statement.timestamp'] = array();
73
74 if ($this->filter->getStartDate()) {
75 $stage['statement.timestamp']['$gt'] = $this->filter->getStartDate()->toXapiTimestamp();
76 }
77
78 if ($this->filter->getEndDate()) {
79 $stage['statement.timestamp']['$lt'] = $this->filter->getEndDate()->toXapiTimestamp();
80 }
81 }
82
83 $obj = $this->getObj();
84 $activityId = array();
85
86 if ($cmi5_extensions_query == true && $obj->getContentType() == ilObjCmiXapi::CONT_TYPE_CMI5 && !$obj->isMixedContentType()) {
87 // https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/cmi5_spec.md#963-extensions
88 $activityId['statement.context.extensions.https://ilias&46;de/cmi5/activityid'] = $obj->getActivityId();
89 } else {
90 // for case-insensive: '$regex' => '(?i)^' . preg_quote($this->filter->getActivityId()) . ''
91 $activityQuery = [
92 '$regex' => '^' . preg_quote($this->filter->getActivityId()) . ''
93 ];
94 $activityId['$or'] = [];
95 // ToDo : restriction to exact activityId?
96 // query existing activityId in grouping? we have not enough control over acticityId in xapi statements
97 // another way put the obj_id into a generated registration, but we are not sure that content will put this into statement context
98 // $activityId['$or'][] = ['statement.object.id' => "{$this->filter->getActivityId()}"];
99 $activityId['$or'][] = ['statement.object.id' => $activityQuery];
100 $activityId['$or'][] = ['statement.context.contextActivities.parent.id' => $activityQuery];
101 $activityId['$or'][] = ['statement.context.contextActivities.grouping.id' => $activityQuery];
102 }
103
104 $actor = array();
105
106 // mixed
107 if ($obj instanceof ilObjCmiXapi && $obj->isMixedContentType()) {
108 if ($this->filter->getActor()) {
109 // could be registration query but so what...
110 foreach (ilCmiXapiUser::getUserIdents($this->getObjId(), $this->filter->getActor()->getUsrId()) as $usrIdent) {
111 $actor['$or'][] = ['statement.actor.mbox' => "mailto:{$usrIdent}"]; // older statements
112 $actor['$or'][] = ['statement.actor.account.name' => "{$usrIdent}"];
113 }
114 // not launched yet?
115 if (count($actor) == 0) {
116 $actor['$or'][] = ['statement.actor.mbox' => "mailto:{$this->filter->getActor()->getUsrIdent()}"]; // older statements
117 $actor['$or'][] = ['statement.actor.account.name' => "{$this->filter->getActor()->getUsrIdent()}"];
118 }
119 } else {
120 $actor['$or'] = [];
121 foreach (ilCmiXapiUser::getUsersForObject($this->getObjId()) as $cmixUser) {
122 $actor['$or'][] = ['statement.actor.mbox' => "mailto:{$cmixUser->getUsrIdent()}"];
123 $actor['$or'][] = ['statement.actor.account.name' => "{$cmixUser->getUsrIdent()}"];
124 }
125 }
126 } elseif ($obj instanceof ilObjCmiXapi && $obj->getContentType() == ilObjCmiXapi::CONT_TYPE_CMI5) {
127 if ($this->filter->getActor()) {
128 $cmixUser = $this->filter->getActor();
129 $actor['statement.context.registration'] = $cmixUser->getRegistration();
130 }
131 } else {
132 if ($this->filter->getActor()) {
133 foreach (ilCmiXapiUser::getUserIdents($this->getObjId(), $this->filter->getActor()->getUsrId()) as $usrIdent) {
134 $actor['$or'][] = ['statement.actor.mbox' => "mailto:{$usrIdent}"];
135 }
136 // not launched yet?
137 if (count($actor) == 0) {
138 $actor['statement.actor.mbox'] = $this->filter->getActor()->getUsrIdent();
139 }
140 }
146 else {
147 $actor['$or'] = [];
148 foreach (ilCmiXapiUser::getUsersForObject($this->getObjId()) as $cmixUser) {
149 $actor['$or'][] = ['statement.actor.mbox' => "mailto:{$cmixUser->getUsrIdent()}"];
150 }
151 }
152 }
153 $stage['$and'] = [];
154 $stage['$and'][] = $activityId;
155 if (count($actor) > 0) {
156 $stage['$and'][] = $actor;
157 }
158 return array('$match' => $stage);
159 }
160
161 protected function buildOrderingStage()
162 {
163 $obj = $this->getObj();
164 $actor = '';
165 if ($obj instanceof ilObjLTIConsumer) {
166 if ($obj->getProvider()->getPrivacyName() != ilObjCmiXapi::PRIVACY_NAME_NONE) {
167 $actor = 'statement.actor.name';
168 }
169 } else {
170 if ($obj->getPrivacyName() != ilObjCmiXapi::PRIVACY_NAME_NONE) {
171 $actor = 'statement.actor.name';
172 } else {
173 if ($obj->getContentType() == ilObjCmiXapi::CONT_TYPE_CMI5) {
174 if ($obj->getPublisherId() == '') { // old
175 $actor = 'statement.actor.mbox';
176 } else {
177 $actor = 'statement.actor.account.name';
178 }
179 } else {
180 $actor = 'statement.actor.mbox';
181 }
182 }
183 }
184 switch ($this->filter->getOrderField()) {
185 case 'object': // definition/description are displayed in the Table if not empty => sorting not alphabetical on displayed fields
186 $field = 'statement.object.id';
187 break;
188
189 case 'verb':
190 $field = 'statement.verb.id';
191 break;
192
193 case 'actor':
194 $field = $actor;
195 break;
196
197 case 'date':
198 default:
199 $field = 'statement.timestamp';
200 break;
201 }
202
203 $orderingFields = array(
204 $field => $this->filter->getOrderDirection() == 'desc' ? -1 : 1
205 );
206
207 return array('$sort' => $orderingFields);
208 }
209}
An exception for terminatinating execution or to throw for unit testing.
static getUsersForObject($objId, $asUsrId=false)
static getUserIdents($objId, $usrId)
static getLogger($a_component_id)
Get component logger.
filter()
Definition: filter.php:2
$log
Definition: result.php:15