/** * Check that $value is $expected_types. */ public function checkTypes($name, $value, $expected_types) { // Convert expected type string into array $expected_types = is_string($expected_types) ? [$expected_types] : $expected_types; $validators = array_map(function ($expectedType) use($name, $value) { $validator = new \app\locker\statements\xAPIValidation(); $validator->checkTypes($name, $value, $expectedType, 'params'); return $this->jsonParam($expectedType, $value); }, $expected_types); $passes = array_filter($validators, function (\app\locker\statements\xAPIValidation $validator) { return $validator->getStatus() === 'passed'; }); if (count($passes) < 1) { \App::abort(400, sprintf("`%s` is not a %s", $name, implode(',', $expected_types))); } return $value; }
/** * @param array $statements An array of statements to create * @param array $lrs * **/ public function create($statements, $lrs, $attachments = '') { //Full tincan statement validation to make sure the statement conforms $saved_ids = array(); $site = \Site::first(); $authority = ["name" => $site->name, "mbox" => "mailto:" . $site->email, "objectType" => "Agent"]; foreach ($statements as &$statement) { //loop and amend - return on fail $verify = new \app\locker\statements\xAPIValidation(); //run full validation $return = $verify->runValidation($statement, $authority); if ($return['status'] == 'failed') { return array('success' => 'false', 'message' => $return['errors']); } else { $statement = $return['statement']; } } //now we are sure that statements are valid - loop back through and actually add them foreach ($statements as $vs) { //check to see if the statementId already has a statement in the LRS if ($result = $this->doesStatementIdExist($lrs->_id, $vs['id'], $statement)) { return array('success' => $result); } //The date stored in LRS in ISO 8601 format $current_date = DateTime::createFromFormat('U.u', microtime(true)); $current_date->setTimezone(new \DateTimeZone(\Config::get('app.timezone'))); $vs['stored'] = $current_date->format('Y-m-d\\TH:i:s.uP'); //if no timestamp, make it the same as stored if (!isset($vs['timestamp'])) { $vs['timestamp'] = $vs['stored']; } /* |------------------------------------------------------------------------------ | For now we store the latest submitted definition. @todo this will change | when we have a way to determine authority to edit. |------------------------------------------------------------------------------ */ if (isset($vs['object']['definition'])) { $this->activity->saveActivity($vs['object']['id'], $vs['object']['definition']); } /* |------------------------------------------------------------------------------ | Run through keys to make sure there are no full stops. If so, replace with | html entity &46; - this will probably only occur in extensions. |------------------------------------------------------------------------------ */ $vs = $this->replaceFullStop($vs); //Create a new statement object $new_statement = new Statement(); $new_statement->lrs = array('_id' => $lrs->_id, 'name' => $lrs->title); $new_statement->statement = $vs; //now add our MongoData timestamp (based on statement timestamp) to use with Mongo Aggregation Function $new_statement->timestamp = new \MongoDate(strtotime($vs['timestamp'])); if ($new_statement->save()) { $saved_ids[] = $new_statement->statement['id']; } else { return array('success' => 'false', 'message' => $new_statement->errors); } } //now we have saved statements, store attachments if ($attachments != '') { $this->storeAttachments($attachments, $lrs->_id); } return array('success' => true, 'ids' => $saved_ids); }