StatementGenerator   F
last analyzed

Complexity

Total Complexity 64

Size/Duplication

Total Lines 586
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 64
eloc 319
c 1
b 0
f 0
dl 0
loc 586
rs 3.28

17 Methods

Rating   Name   Duplication   Size   Complexity  
B getVerb() 0 113 2
A checkError() 0 22 5
A makeEndpoint() 0 7 1
A sendRequests() 0 17 3
A createAuthority() 0 5 1
A createResult() 0 3 1
A createObject() 0 34 6
A make_request() 0 39 4
A createContext() 0 15 3
A createAccountActor() 0 5 1
A checkKey() 0 2 3
C sendRequestsOld() 0 75 14
A returnAvailableVerbs() 0 27 1
A __construct() 0 4 1
A error() 0 2 1
A createMboxActor() 0 5 1
F buildStatement() 0 64 16

How to fix   Complexity   

Complex Class

Complex classes like StatementGenerator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use StatementGenerator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ijeffro\Laralocker\Statements;
4
5
use Log;
6
use Carbon\Carbon;
7
8
class StatementGenerator {
9
10
    const LL_COURSE_EXTENSION  = 'http://learninglocker.net/extensions/course';
11
    const COMMENT_EXTENSION  = 'http://curatr3.com/define/extension/commentText';
12
    const BADGE_EXTENSION  = 'http://specification.openbadges.org/xapi/extensions/badgeassertion';
13
    const MCQ_SINGLE_EXTENSION  = 'http://curatr3.com/define/extension/single-mcq-option';
14
    const MCQ_MULTIPLE_EXTENSION  = 'http://curatr3.com/define/extension/multiple-mcq-options';
15
    const CONTRIBUTION_OBJECT  = 'http://curatr3.com/define/extension/contribution-object';
16
    const BADGE_TYPE = 'http://activitystrea.ms/schema/1.0/badge';
17
    const CATEGORY_TYPE = 'http://activitystrea.ms/schema/1.0/collection';
18
    const COLLECTION_TYPE = 'http://curatr3.com/define/type/collection';
19
    const COMMENT_TYPE = 'http://activitystrea.ms/schema/1.0/comment';
20
    const COURSE_TYPE = 'http://adlnet.gov/expapi/activities/course';
21
    const FILE_TYPE = 'http://activitystrea.ms/schema/1.0/file';
22
    const GATE_TYPE = 'http://curatr3.com/define/type/gate';
23
    const LEVEL_TYPE = 'http://curatr3.com/define/type/level';
24
    const OBJECT_TYPE = 'http://activitystrea.ms/schema/1.0/article';
25
    const ORGANISATION_TYPE = 'http://curatr3.com/define/type/organisation';
26
    const PAGE_TYPE = 'http://activitystrea.ms/schema/1.0/page';
27
    const QUESTION_TYPE = 'http://activitystrea.ms/schema/1.0/question';
28
    const RESPONSE_TYPE = 'http://curatr3.com/define/type/response';
29
    const SECTION_TYPE = 'http://activitystrea.ms/schema/1.0/collection';
30
    const TAG_TYPE = 'http://id.tincanapi.com/activitytype/tag';
31
    const TAG_TYPE_EXTENSION = 'http://curatr3.com/define/extension/tag-type';
32
33
    public $url, $statement, $endpoints, $log;
34
35
    public function __construct( $endpoints=array() ) {
36
37
      $this->log = \App::make('xapi.log');
38
      $this->endpoints = $endpoints;
39
    }
40
41
    /**
42
  * Checks a passed array has a defined key, returns a default if not set
43
  * @param array $array The array to check
44
  * @param string $key Key to check
45
  * @param type $default Default to return if key is not set
0 ignored issues
show
Bug introduced by
The type Ijeffro\Laralocker\Statements\type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
46
  * @return mixed
47
  */
48
    private static function checkKey( $array, $key, $default='' ){
49
        return (isset($array[$key]) && !empty($array[$key])) ? $array[$key] : $default;
50
    }
51
52
  /**
53
  * Creates a statement from an array, with defaults if needed
54
  * @param Array $data Holds the actor, verb and object information
55
  */
56
  public function buildStatement($data) {
57
58
    $actor      = $this->checkKey($data, 'actor');
59
    $verb       = $this->checkKey($data, 'verb',        self::getVerb('experienced') );
0 ignored issues
show
Bug introduced by
self::getVerb('experienced') of type array is incompatible with the type Ijeffro\Laralocker\Statements\type expected by parameter $default of Ijeffro\Laralocker\State...ntGenerator::checkKey(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
    $verb       = $this->checkKey($data, 'verb',        /** @scrutinizer ignore-type */ self::getVerb('experienced') );
Loading history...
60
    $object     = $this->checkKey($data, 'object');
61
    $authority  = $this->checkKey($data, 'authority', []);
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type Ijeffro\Laralocker\Statements\type expected by parameter $default of Ijeffro\Laralocker\State...ntGenerator::checkKey(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $authority  = $this->checkKey($data, 'authority', /** @scrutinizer ignore-type */ []);
Loading history...
62
    $context    = $this->checkKey($data, 'context', [] );
63
    $result     = $this->checkKey($data, 'result', [] );
64
    $timestamp  = $this->checkKey($data, 'timestamp',   Carbon::now()->format("c") );
0 ignored issues
show
Bug introduced by
Carbon\Carbon::now()->format('c') of type string is incompatible with the type Ijeffro\Laralocker\Statements\type expected by parameter $default of Ijeffro\Laralocker\State...ntGenerator::checkKey(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
    $timestamp  = $this->checkKey($data, 'timestamp',   /** @scrutinizer ignore-type */ Carbon::now()->format("c") );
Loading history...
65
66
    $this->statement = array(
67
      'actor'     => $actor,
68
      'verb'      => $verb,
69
      'object'    => $object,
70
      'timestamp' => $timestamp
71
    );
72
73
    if( isset($result) && !empty($result) ){
74
        $this->statement['result'] = $result;
75
    }
76
77
    if( isset($authority) && !empty($authority) ){
78
        $this->statement['authority'] = $authority;
79
    }
80
81
    if( isset($context) && !empty($context) ){
82
        $this->statement['context'] = $context;
83
    } else {
84
      $this->statement['context'] = $this->createContext();
85
    }
86
87
    //Add the org to the contextActivites
88
    $org = \Organisation::userCurrent();
0 ignored issues
show
Bug introduced by
The type Organisation was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
89
    if( $org ){
90
      if( !isset($this->statement['context']['contextActivities']) ){
91
        $this->statement['context']['contextActivities'] = [];
92
      }
93
94
      if( !isset($this->statement['context']['contextActivities']['grouping']) ){
95
        $this->statement['context']['contextActivities']['grouping'] = [];
96
      } elseif( !isset($this->statement['context']['contextActivities']['grouping'][0])){
97
        $val = $this->statement['context']['contextActivities']['grouping'];
98
        $this->statement['context']['contextActivities']['grouping'] = [ $val ];
99
      }
100
101
      $this->statement['context']['contextActivities']['grouping'][] = $org->tcExtension();
102
    }
103
104
    // remove context.platform if NOT an activity (xAPI 4.1.6)
105
    if (
106
        isset($this->statement['context'])
107
        && isset($this->statement['object'], $this->statement['object']['objectType'])
108
        && strtolower($this->statement['object']['objectType']) !== strtolower('activity')
109
        ) {
110
      if (isset($this->statement['context']['platform'])) {
111
        unset($this->statement['context']['platform']);
112
      }
113
      if (isset($this->statement['context']['revision'])) {
114
        unset($this->statement['context']['revision']);
115
      }
116
    }
117
118
119
    return $this->statement;
120
  }
121
122
  /**
123
  * Static method
124
  * Generates the actor part of the statement
125
  * @param string $name
126
  * @param string $email
127
  * @return array
128
  */
129
    public static function createMboxActor( $name, $email ){
130
        return array(
131
            'name'          =>  $name,
132
            'mbox'          =>  'mailto:' . $email,
133
            'objectType'    =>  'Agent'
134
        );
135
    }
136
137
    /**
138
     * Static method
139
     * Generates the actor part of the statement
140
     * @param string $name
141
     * @param string $homepage
142
     * @param string $ref
143
     * @return array
144
     */
145
    public static function createAccountActor( $name, $homepage, $ref ){
146
      return [
147
          'name'          => $name,
148
          'account'       => ['homePage' => $homepage, 'name' => $ref],
149
          'objectType'    => 'Agent'
150
      ];
151
    }
152
153
    /**
154
     * Static method
155
     * Generates the authority part of the statement
156
     * @param string $name
157
     * @param string $email
158
     * @return array
159
     */
160
    public static function createAuthority( $name, $email ){
161
        return array(
162
            'name'          =>  $name,
163
            'mbox'          =>  'mailto:' . $email,
164
            'objectType'    =>  'Agent'
165
        );
166
    }
167
168
    /**
169
     * Static method
170
     * Generates the result part of the statement
171
     * @return array
172
     */
173
    public static function createResult( $result=array() ){
174
175
        return $result;
176
177
    }
178
179
    /**
180
     * Static method
181
     * Generates the context extension part of the statement
182
     * @todo hardcoded for now
183
     * @return array
184
     */
185
    public static function createContext( $extensions = array(), $additional=null ){
186
187
        $context = array(
188
            'platform'  =>  'Curatr'
189
        );
190
191
        if( !empty($extensions) ){
192
          $context['extensions'] = $extensions;
193
        }
194
195
        if( !is_null($additional) ){
196
            $context = array_merge($context, $additional );
197
        }
198
199
        return $context;
200
201
    }
202
203
  /**
204
  * Static method
205
  * Returns a predefined verb or 'experienced' if not found
206
  * @param string $key The verb to use
207
  * @return array
208
  */
209
    public static function getVerb( $key ){
210
211
        $verbs = array();
212
213
        $available_verbs = self::returnAvailableVerbs();
214
215
        // add all official verbs
216
        foreach( $available_verbs as $v ){
217
            $verbs[$v] = array(
218
                "id"        =>  "http://adlnet.gov/expapi/verbs/{$v}",
219
                "display"   =>  array( "en-GB" =>  $v ),
220
            );
221
        }
222
223
        // Standard Verbs
224
        $verbs['commented'] = array(
225
            "id"        =>  "http://adlnet.gov/expapi/verbs/commented",
226
            "display"   =>  array(  "en-GB" =>  "commented on" )
227
        );
228
        $verbs['coached'] = array(
229
            "id"        =>  "http://learninglocker.net/verbs/coached-in",
230
            "display"   =>  array(  "en-GB" =>  "coached in" )
231
        );
232
        $verbs['mentored'] = array(
233
            "id"        =>  "http://learninglocker.net/verbs/mentored-in",
234
            "display"   =>  array(  "en-GB" =>  "mentored in" )
235
        );
236
        $verbs['observed'] = array(
237
            "id"        =>  "http://learninglocker.net/verbs/observed-in",
238
            "display"   =>  array(  "en-GB" =>  "observed in" )
239
        );
240
        $verbs['trained'] = array(
241
            "id"        =>  "http://learninglocker.net/verbs/trained-in",
242
            "display"   =>  array(  "en-GB" =>  "trained in" )
243
        );
244
        $verbs['endorsed'] = array(
245
            "id"        =>  "http://learninglocker.net/verbs/endorsed-in",
246
            "display"   =>  array(  "en-GB" =>  "endorsed in" )
247
        );
248
        $verbs['posted'] = array(
249
            "id"        =>  "http://curatr3.com/define/verb/posted",
250
            "display"   =>  array( "en-GB" =>  "posted" )
251
        );
252
        $verbs['published'] = array(
253
            "id"        =>  "http://curatr3.com/define/verb/published",
254
            "display"   =>  array( "en-GB" =>  "published" )
255
        );
256
        $verbs['read'] = array(
257
            "id"        =>  "http://curatr3.com/define/verb/read",
258
            "display"   =>  array( "en-GB" =>  "read" )
259
        );
260
        $verbs['liked'] = array(
261
            "id"        =>  "http://curatr3.com/define/verb/liked",
262
            "display"   =>  array( "en-GB" =>  "liked" )
263
        );
264
        $verbs['bookmarked'] = array(
265
            "id"        =>  "http://curatr3.com/define/verb/bookmarked",
266
            "display"   =>  array( "en-GB" =>  "bookmarked" )
267
        );
268
        $verbs['earned'] = array(
269
            "id"        =>  "http://curatr3.com/define/verb/earned",
270
            "display"   =>  array( "en-GB" =>  "earned" )
271
        );
272
        $verbs['badge_earned'] = array(
273
            "id"        =>  "http://specification.openbadges.org/xapi/verbs/earned",
274
            "display"   =>  array( "en-GB" =>  "earned" )
275
        );
276
        $verbs['login'] = array(
277
            "id"        =>  "https://brindlewaye.com/xAPITerms/verbs/loggedin/",
278
            "display"   =>  array(  "en-GB" =>  "logged in to" )
279
        );
280
        $verbs['logout'] = array(
281
            "id"        =>  "http://curatr3.com/define/verb/logout",
282
            "display"   =>  array(  "en-GB" =>  "logged out of" )
283
        );
284
        $verbs['edited'] = array(
285
            "id"        =>  "http://curatr3.com/define/verb/edited",
286
            "display"   =>  array( "en-GB" =>  "edited" )
287
        );
288
        $verbs['uploaded'] = array(
289
            "id"        =>  "http://curatr3.com/define/verb/uploaded",
290
            "display"   =>  array( "en-GB" =>  "uploaded" )
291
        );
292
        $verbs['accessed'] = array(
293
            "id"        =>  "http://activitystrea.ms/schema/1.0/access",
294
            "display"   =>  array( "en-GB" =>  "accessed" )
295
        );
296
        $verbs['voted-up'] = array(
297
            "id"        =>  "http://curatr3.com/define/verb/voted-up",
298
            "display"   =>  array(  "en-GB" =>  "voted up" )
299
        );
300
        $verbs['voted-down'] = array(
301
            "id"        =>  "http://curatr3.com/define/verb/voted-down",
302
            "display"   =>  array(  "en-GB" =>  "voted down" )
303
        );
304
        $verbs['flag-as-inappropriate'] = array(
305
            "id"        =>  "http://activitystrea.ms/schema/1.0/flag-as-inappropriate",
306
            "display"   =>  array( "en-GB" =>  "flagged as inappropriate" )
307
        );
308
        $verbs['join'] = array(
309
            "id"        =>  "http://activitystrea.ms/schema/1.0/join",
310
            "display"   =>  array( "en-GB" =>  "joined" )
311
        );
312
        $verbs['leave'] = array(
313
            "id"        =>  "http://activitystrea.ms/schema/1.0/leave",
314
            "display"   =>  array( "en-GB" =>  "left" )
315
        );
316
        $verbs['opened'] = array(
317
            "id"        =>  "http://activitystrea.ms/schema/1.0/open",
318
            "display"   =>  array( "en-GB" =>  "opened" )
319
        );
320
321
        return self::checkKey( $verbs, $key, $verbs['experienced']);
322
    }
323
324
    /**
325
     * Create the object section of statement
326
     *
327
     * @param int $id
328
     * @param string $name
329
     * @param string $description
330
     * @param array $extensions
331
     * @return array
332
     *
333
     */
334
    public static function createObject( $id, $name=null, $description=null, $type=null, $extensions = array() )
335
    {
336
        $object = array(
337
        'objectType'    => 'Activity',
338
        'id'            => $id
339
        );
340
341
        $definition = array();
342
343
        if (!empty($name)) {
344
        $definition['name'] = [
345
            'en-GB' => $name
346
        ];
347
        }
348
349
        if( !empty($description)){
350
            $definition['description'] = [
351
            'en-GB'=>$description
352
        ];
353
        }
354
355
        if( !empty($type)){
356
        $definition['type'] = $type;
357
        }
358
359
        if( !empty($extensions) ){
360
        $definition['extensions'] = $extensions;
361
        }
362
363
        if (!empty($definition)) {
364
        $object['definition'] = $definition;
365
        }
366
367
        return $object;
368
    }
369
370
371
372
  public function sendRequests() {
373
    foreach( $this->endpoints as $name => $ep ){
374
375
      $username = $ep->username;
376
      $password = $ep->key;
377
      $url = $ep->url;
378
379
      if(substr($url, -1) !== '/') {
380
        $url .= '/';
381
      }
382
383
      \Queue::push('\HT2\Queues\XAPIService', [
384
        'endpoint'  => $url,
385
        'type'      => 'basic',
386
        'username'  => $username,
387
        'password'  => $password,
388
        'statement' => $this->statement
389
      ]);
390
391
    }
392
  }
393
394
  /**
395
  * Send the request to all end points defined in the endpoints array
396
  * @return array An array of all requests sent and their responses
397
  */
398
    public function sendRequestsOld(){
399
      $error = $this->checkError();
400
      if( $error ) return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
401
402
      $results = array();
403
404
405
      foreach( $this->endpoints as $name => $ep ){
406
407
          $username = $ep->username;
408
          $password = $ep->key;
409
          $url = $ep->url;
410
          $auth = base64_encode( $username.':'.$password );
411
412
          $result = $this->make_request($auth, $url, $this->statement);
413
          $error = false;
414
          $error_type = "";
415
          $body = "";
416
417
          if( isset($result['error']) ){
418
            $error = true;
419
            $error_type = "cURL error";
420
          } else {
421
422
            $body = isset($result['body']) ? json_decode($result['body']) : "";
423
424
            if( isset($body->success) ){
425
              if( $body->success == false ){
426
                $error = true;
427
                $error_type = "LRS returned success as false";
428
              }
429
            }
430
431
            if( isset($body->error) ){
432
              if( $body->error == true ){
433
                $error = true;
434
                $error_type = "LRS returned error as true";
435
              }
436
            }
437
            if( isset($result['status']) ){
438
              $status = $result['status'];
439
440
              switch( intval($status) ){
441
                case 400:
442
                case 404:
443
                case 500:
444
                  $error = true;
445
                  $error_type = "LRS returned HTTP code ".$status;
446
                break;
447
              }
448
            }
449
          }
450
451
          if( $error ){
452
            $this->log->error( 'Statement Failed', array(
453
              'curl_result' =>  $result,
454
              'type'        =>  $error_type,
455
              'url'         =>  $ep->url,
456
              'statement'   =>  $this->statement
457
            ));
458
          } else {
459
            $this->log->info( 'Sent', array(
460
              'url'         =>  $ep->url,
461
              'statement'   =>  $this->statement
462
            ));
463
          }
464
465
          $results[$url] = $body;
466
      }
467
468
469
      return array(
470
          'statement' =>  $this->statement,
471
          'endpoints' =>  $this->endpoints,
472
          'results'   =>  $results
473
      );
474
  }
475
476
  /**
477
  * Send statement
478
  * @param string $auth The base64 basic auth info for the request
479
  * @param string $url The endpoint
480
  * @param array $statement The statement to be encoded
481
  * @return boolean/array Returns false on fail, array of details on success
0 ignored issues
show
Documentation Bug introduced by
The doc comment boolean/array at position 0 could not be parsed: Unknown type name 'boolean/array' at position 0 in boolean/array.
Loading history...
482
  */
483
  public function make_request( $auth, $url, $statement ) {
484
485
    $headers =   array(
486
      'Authorization: Basic '.$auth,
487
      'Content-Type: application/json; charset=UTF-8',
488
      'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
489
      'X-Experience-API-Version: 1.0.0'
490
    );
491
492
    if(substr($url, -1) !== '/') {
493
      $url .= '/';
494
    }
495
496
    $ch = curl_init( $url . 'statements' );
497
    curl_setopt( $ch, CURLOPT_POST, 1);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

497
    curl_setopt( /** @scrutinizer ignore-type */ $ch, CURLOPT_POST, 1);
Loading history...
498
    curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($statement) );
499
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
500
    curl_setopt( $ch, CURLOPT_HEADER, 1);
501
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
502
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers );
503
504
    if( substr($url, 0, 5) == "https" ){
505
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
506
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
507
      curl_setopt ($ch, CURLOPT_CAINFO, storage_path()."/cacert.pem");
508
    }
509
510
    $response = curl_exec( $ch );
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

510
    $response = curl_exec( /** @scrutinizer ignore-type */ $ch );
Loading history...
511
    if( $response === false ){
512
      return array('error'=>true, 'curl_error'=>curl_error($ch));
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

512
      return array('error'=>true, 'curl_error'=>curl_error(/** @scrutinizer ignore-type */ $ch));
Loading history...
513
    } else {
514
      $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

514
      $header_size = curl_getinfo(/** @scrutinizer ignore-type */ $ch, CURLINFO_HEADER_SIZE);
Loading history...
515
      $header = substr($response, 0, $header_size);
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type true; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

515
      $header = substr(/** @scrutinizer ignore-type */ $response, 0, $header_size);
Loading history...
516
      $body = substr($response, $header_size);
517
      return array(
518
        'ch'      =>  $ch,
519
        'status'  =>  curl_getinfo($ch, CURLINFO_HTTP_CODE),
520
        'header'  =>  $header,
521
        'body'    =>  $body
522
      );
523
    }
524
  }
525
526
    private function checkError(){
527
        if( empty($this->statement) ){
528
            $this->error("No data set");
529
            return true;
530
        }
531
532
        if( !isset($this->statement['actor']) ){
533
            $this->error("No actor set");
534
            return true;
535
        }
536
537
        if( !isset($this->statement['verb']) ){
538
            $this->error("No verb set");
539
            return true;
540
        }
541
542
        if( !isset($this->statement['object']) ){
543
            $this->error("No object set");
544
            return true;
545
        }
546
547
        return false;
548
    }
549
550
    private function error( $message ){
551
        $this->log->error( "Statement Generator Error: ".$message );
552
    }
553
554
    /**
555
     * We will probably move this to the db, or hook into an existing service?
556
     *
557
     **/
558
    private static function returnAvailableVerbs(){
559
        return array(
560
            'answered',
561
            'asked',
562
            'attempted',
563
            'attended',
564
            'commented',
565
            'completed',
566
            'exited',
567
            'experienced',
568
            'failed',
569
            'imported',
570
            'initialized',
571
            'interacted',
572
            'launched',
573
            'mastered',
574
            'passed',
575
            'preferred',
576
            'progressed',
577
            'registered',
578
            'responded',
579
            'resumed',
580
            'scored',
581
            'shared',
582
            'suspended',
583
            'terminated',
584
            'voided');
585
    }
586
587
    public static function makeEndpoint( $url, $username, $password ){
588
        $ep = new \stdClass;
589
        $ep->url = $url;
590
        $ep->username = $username;
591
        $ep->key = $password;
592
        $ep->basicAuth = base64_encode(sprintf('%s:%s', $username, $password));
593
        return $ep;
594
    }
595
}
596