Commit df0c4dbf authored by Sergej Naumenko's avatar Sergej Naumenko
Browse files

Initial commit

parents
<?php
namespace local_solving\service;
use local_solving\httpController\httpController;
class EnmeshedService {
private $apikey;
private $enmeshedurl;
private $httpcontroller;
public function __construct() {
global $CFG;
$this->apikey = $CFG->solving_enmeshed_api_key;
$this->enmeshedurl = $CFG->solving_enmeshed_url;
$this->httpcontroller = new httpController();
}
/**
* Generate a template for a user if there is no existing one
* @return mixed
* @throws \dml_exception
*/
private function enmeshed_create_template() {
global $CFG, $USER, $DB;
$serviceurl = $this->enmeshedurl . '/api/v1/RelationshipTemplates/Own';
$templatecontent = $CFG->solving_enmeshed_template_config;
$httpheader = [
'X-API-KEY: ' . $this->apikey,
"Accept: application/json",
"Content-Type: application/json",
];
$response = $this->httpcontroller->executeRequests($serviceurl, $templatecontent,
CURLOPT_POST, $httpheader);
$result = json_decode($response, JSON_PRETTY_PRINT);
$templateID = $result['result']['id'];
$dbdata = (object) [
'uid' => $USER->id,
'template_id' => $templateID,
];
$DB->insert_record('solving_enmeshed', $dbdata);
return $templateID;
}
/**
* Returns the template id for a certain user
* @return mixed
* @throws \dml_exception
*/
public function enmeshed_get_template_id() {
global $USER, $DB;
$sql = 'SELECT template_id FROM {solving_enmeshed}'
. ' WHERE uid = ?';
$result = $DB->get_record_sql($sql, [$USER->id]);
if (!empty($result)) {
return $result->template_id;
}
return $this->enmeshed_create_template();
}
/**
* Synchronize changes from a user. Used to accept the membership request after scanning the QR-Code
*/
public function enmeshed_account_sync() {
$serviceurl = $this->enmeshedurl . '/api/v1/Account/Sync';
$httpheader = [
'X-API-KEY: ' . $this->apikey,
"Accept: application/json",
"Content-Type: application/json",
];
$response = $this->httpcontroller->executeRequests($serviceurl, NULL,
CURLOPT_POST, $httpheader);
$result = json_decode($response, JSON_PRETTY_PRINT);
if (!empty($result['result']['relationships'])) {
$this->enmeshed_accept_relationship($result);
}
}
/**
* Accept the relationship and process the data
* @param $result
*/
private function enmeshed_accept_relationship($result) {
$httpheader = [
'X-API-KEY: ' . $this->apikey,
"Accept: application/json",
"Content-Type: application/json",
];
foreach ($result['result']['relationships'] as $relationship) {
if ($relationship['status'] == 'Pending') {
$changeID = $relationship['changes']['0']['id'];
$relID = $relationship['id'];
$service_url = $this->enmeshedurl . '/api/v1/Relationships/' . $relID . '/Changes/' . $changeID . '/Accept';
$postfields = '{
"content": {
"prop1": "value",
"prop2": 1
}
}';
$response = $this->httpcontroller->executePutRequest($service_url,$postfields,CURLOPT_POST,$httpheader);
$result = json_decode($response, JSON_PRETTY_PRINT);
$this->enmeshed_save_relationship($result,$relID);
}
}
}
/**
* Save the relationship from the user and wallet id
* @param $data
* @param $relID
*
* @throws \dml_exception
*/
private function enmeshed_save_relationship($data,$relID){
global $DB;
$walletId = $data['result']['peer'];
$templateID = $this->enmeshed_get_template_id();
$DB->execute("UPDATE {solving_enmeshed} SET status = 'accepted', wallet_id = :wallet_id,relation_id = :relation_id WHERE template_id = :template_id",[
"wallet_id"=>$walletId,
"relation_id"=>$relID,
"template_id"=>$templateID
]);
}
/**
* Send a request to write in the wallet
*/
public function enmeshed_write_in_wallet(){
$service_url = $this->enmeshedurl . '/api/v1/Messages';
$httpheader = [
'X-API-KEY: ' . $this->apikey,
"Accept: application/json",
"Content-Type: application/json",
];
$walletId = $this->enmeshed_get_wallet_id();
$postfields = '{
"content" : {
"@type": "RequestMail",
"to": ["' . $walletId . '"],
"cc": [],
"subject": "Du bist nun bei der IVS registriert",
"body": "Hi Anne,<br /><br />Attached please find your personal bonus card id. You can share this id to our partners to benefit of attractive discounts.<br /><br />Best Regards!<br />Your Team",
"requests": [
{
"@type": "AttributesChangeRequest",
"attributes": [
{
"@type": "Attribute",
"name": "Social.video",
"value": "experte",
"validFrom": "2022-10-01"
}
],
"applyTo": "' . $walletId . '",
"reason": "Your bonus card id to share and benefit of discounts."
}
]
},
"recipients": ["' . $walletId . '"]
}
';
$response = $this->httpcontroller->executeRequests($service_url,$postfields,CURLOPT_POST,$httpheader);
}
/**
* Returns the wallet id for the current user
* @return null
* @throws \dml_exception
*/
public function enmeshed_get_wallet_id(){
global $USER, $DB;
$sql = 'SELECT wallet_id FROM {solving_enmeshed}'
. ' WHERE uid = ?';
$result = $DB->get_record_sql($sql, [$USER->id]);
if (!empty($result)) {
return $result->wallet_id;
}
return NULL;
}
/**
* Generate the QR-Code for scanning
* @return bool|string
* @throws \dml_exception
*/
public function enmeshed_generate_qr_code(){
global $USER;
$templateToken = $this->enmeshed_get_template_id();
$service_url = $this->enmeshedurl . '/api/v1/RelationshipTemplates/Own/' . $templateToken . '/Token';
$httpheader = [
'X-API-KEY: ' . $this->apikey,
"Accept: image/png",
"Content-Type: image/png",
];
$postfields = [
'expiresAt' => '2022-12-09T21:21:40.309Z',
'ephemeral' => TRUE
];
return $this->httpcontroller->executeRequests($service_url,$postfields,CURLOPT_POST,$httpheader);
}
}
\ No newline at end of file
<?xml version="1.0"?>
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="https://www.mathplan.de/moses/xsd/default"
targetNamespace="https://www.mathplan.de/moses/xsd/default"
elementFormDefault="qualified">
<!-- ======================================================================= -->
<!-- Grundstruktur -->
<!-- ======================================================================= -->
<xs:element name="import" type="MImport" ></xs:element>
<xs:complexType name="MImport">
<xs:sequence>
<xs:element name="list" type="MList" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MList">
<xs:choice>
<!-- ******************** BIRD-Spezifika ******************** -->
<xs:element name="bird_academy" type="MBirdAcademy" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="bird_program" type="MBirdProgram" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="bird_module" type="MBirdModule" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="bird_course" type="MBirdCourse" minOccurs="0" maxOccurs="unbounded" />
</xs:choice>
<xs:attribute name="type" type="MType" use="required"/>
<xs:attribute name="context" type="MContext"/>
<xs:attribute name="mode" type="MMode" />
<xs:attribute name="semesterFilter" type="xs:string" />
<xs:attribute name="order" type="ordertype" default="1000"/>
</xs:complexType>
<xs:simpleType name="ordertype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]*"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MContext" final="restriction">
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9]+"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MMode" final="restriction">
<xs:restriction base="xs:string">
<xs:enumeration value="add" />
<xs:enumeration value="sync" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MId">
<xs:restriction base="xs:string">
<!-- Keine Pipe-Zeichen und keine führenden/nachgestellten Whitespaces -->
<xs:pattern value="[^\s|]|[^\s|][^|]*[^\s|]" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MType" final="restriction">
<xs:restriction base="xs:string">
<xs:enumeration value="bird_academy" />
<xs:enumeration value="bird_program" />
<xs:enumeration value="bird_module" />
<xs:enumeration value="bird_course" />
</xs:restriction>
</xs:simpleType>
<!-- ======================================================================= -->
<!-- Basistypen -->
<!-- ======================================================================= -->
<xs:complexType name="MBaseEntity">
<xs:sequence>
<xs:element name="ignore" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="ignoreIfSet" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="id" type="MId" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="MNamedEntity">
<xs:complexContent>
<xs:extension base="MBaseEntity">
<xs:sequence>
<xs:element name="name" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="MBirdAcademy">
<xs:complexContent>
<xs:extension base="MNamedEntity">
<xs:sequence>
<xs:element name="kurzname" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="MBirdProgram">
<xs:complexContent>
<xs:extension base="MNamedEntity">
<xs:sequence>
<xs:element name="academyId" type="MId" />
<xs:element name="degreeName" type="xs:string" />
<xs:element name="startOfProgram" minOccurs="0" type="xs:string" />
<xs:element name="typeOfStudies" minOccurs="0" type="xs:string" />
<xs:element name="periodOfStudy" minOccurs="0" type="xs:integer" />
<xs:element name="focusOfStudy" minOccurs="0" type="xs:string" />
<xs:element name="languageOfStudy" minOccurs="0" type="xs:string" />
<xs:element name="locationOfStudy" minOccurs="0" type="xs:string" />
<xs:element name="restrictedApplication" minOccurs="0" type="xs:boolean" />
<xs:element name="applicationRequirements" minOccurs="0" type="xs:string" />
<xs:element name="birdModuleId" type="MId" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="birdCourseId" type="MId" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="MBirdModule">
<xs:complexContent>
<xs:extension base="MNamedEntity">
<xs:sequence>
<xs:element name="academyId" type="MId" />
<xs:element name="examtitle" minOccurs="0" type="xs:string" />
<xs:element name="subjectExamtitle" minOccurs="0" type="xs:string" />
<xs:element name="duration" minOccurs="0" type="xs:integer" />
<xs:element name="credits" minOccurs="0" type="xs:integer" />
<xs:element name="workload" minOccurs="0" type="xs:string" />
<xs:element name="requirements" minOccurs="0" type="xs:string" />
<xs:element name="learningOutcomes" minOccurs="0" type="xs:string" />
<xs:element name="recommendedKnowledge" minOccurs="0" type="xs:string" />
<xs:element name="moduleContent" minOccurs="0" type="xs:string" />
<xs:element name="formOfWork" minOccurs="0" type="xs:string" />
<xs:element name="birdCourseId" type="MId" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="MBirdCourse">
<xs:complexContent>
<xs:extension base="MNamedEntity">
<xs:sequence>
<xs:element name="academyId" type="MId" />
<xs:element name="lectureType" type="xs:string" />
<xs:element name="sws" minOccurs="0" type="xs:integer" />
<xs:element name="department" minOccurs="0" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
<?php
namespace local_solving\httpController;
class httpController {
/**
* Sends a Get or POST Request to the enmeshed server
* @param $url
* @param $postfields
* @param $posttype
* @param $headers
*
* @return bool|string
*/
public function executeRequests($url,$postfields,$posttype,$headers){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, $posttype, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
return curl_exec($curl);
}
/**
* Sends a put request to the enmeshed server
* @param $url
* @param $postfields
* @param $posttype
* @param $headers
*
* @return bool|string
*/
public function executePutRequest($url,$postfields,$posttype,$headers){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, $posttype, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_BINARYTRANSFER, TRUE);
return curl_exec($curl);
}
}
\ No newline at end of file
<?php
// Replace ivs with the name of your module and remove this line.
require_once('../../config.php');
global $USER, $DB, $CFG;
$token = get_bearer_token();
$solving_bearer_token = $CFG->solving_bearer_token;
if ($token != $solving_bearer_token) {
header('HTTP/1.1 403 Forbidden');
print ("invalid token :(");
exit;
}
$bird_courses = '';
$courses = get_courses();
$template = '<bird_course>
<id>:id</id>
<name>:title</name>
<academyId>IVS</academyId>
<lectureType>Kurs</lectureType>
</bird_course>';
foreach ($courses as $courseId => $course) {
$course = get_course($courseId);
$vars = array(
':id' => $courseId,
':title' => $course->fullname,
);
$bird_courses .= strtr($template, $vars);
}
$xml = '<import xmlns="https://www.mathplan.de/moses/xsd/default" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<list type="bird_academy">
<bird_academy>
<id>Test</id>
<name>Volkoshochschule Template</name>
<kurzname>VHS Hogwarts</kurzname>
</bird_academy>
</list>
<list type="bird_course">
' . $bird_courses . '
</list>
</import>';
### Validation
$xmlDoc= new DOMDocument();
$xmlDoc->loadXML($xml); // Or load if filename required
if (!$xmlDoc->schemaValidate('bird.xsd')) // Or schemaValidateSource if string used.
{
header('HTTP/1.1 409 Conflict');
print ("The XML content was invalid against the specified schema");
exit;
}
header('Content-Type: application/xml');
print $xml;
exit;
/**
* @return mixed|null
*/
function get_bearer_token() {
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
} else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} else if (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
//print_r($requestHeaders);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
return null;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment