MDL-63262 badges: Add badgr.io
[moodle.git] / badges / classes / external / badgeclass_exporter.php
CommitLineData
aae219ac
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Contains class for displaying a badgeclass.
19 *
20 * @package core_badges
21 * @copyright 2019 Damyon Wiese
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace core_badges\external;
26
27defined('MOODLE_INTERNAL') || die();
28
29use core\external\exporter;
30use renderer_base;
31
32/**
33 * Class for displaying a badge competency.
34 *
35 * @package core_badges
36 * @copyright 2019 Damyon Wiese
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 */
39class badgeclass_exporter extends exporter {
40
41 /**
42 * Constructor - saves the persistent object, and the related objects.
43 *
44 * @param mixed $data - Either an stdClass or an array of values.
45 * @param array $related - An optional list of pre-loaded objects related to this object.
46 */
47 public function __construct($data, $related = array()) {
48 $pick = $this->pick_related();
49 foreach ($pick as $one) {
50 $isarray = false;
51 // Allow [] to mean an array of values.
52 if (substr($one, -2) === '[]') {
53 $one = substr($one, 0, -2);
54 $isarray = true;
55 }
56 $prefixed = 'related_' . $one;
57 if (array_key_exists($one, $data) && !array_key_exists($one, $related)) {
58 if ($isarray) {
59 $newrelated = [];
60 foreach ($data[$one] as $item) {
61 $newrelated[] = (object) $item;
62 }
63 $related[$one] = $newrelated;
64 } else {
65 $related[$one] = (object) $data[$one];
66 }
67 unset($data[$one]);
68 } else if (array_key_exists($prefixed, $data) && !array_key_exists($one, $related)) {
69 if ($isarray) {
70 $newrelated = [];
71 foreach ($data[$prefixed] as $item) {
72 $newrelated[] = (object) $item;
73 }
74 $related[$one] = $newrelated;
75 } else {
76 $related[$one] = (object) $data[$prefixed];
77 }
78 unset($data[$prefixed]);
79 } else if (!array_key_exists($one, $related)) {
80 $related[$one] = null;
81 }
82 }
83 parent::__construct($data, $related);
84 }
85
86 /**
87 * List properties passed in $data that should be moved to $related in the constructor.
88 *
89 * @return array A list of properties to move from $data to $related.
90 */
91 public static function pick_related() {
92 return ['alignments[]', 'criteria'];
93 }
94
95 /**
96 * Map data from a request response to the internal structure.
97 *
98 * @param stdClass $data The remote data.
99 * @param string $apiversion The backpack version used to communicate remotely.
100 * @return stdClass
101 */
102 public static function map_external_data($data, $apiversion) {
103 $mapped = new \stdClass();
104 if (isset($data->entityType)) {
105 $mapped->type = $data->entityType;
106 } else {
107 $mapped->type = $data->type;
108 }
109 if (isset($data->entityId)) {
110 $mapped->id = $data->entityId;
111 } else {
112 $mapped->id = $data->id;
113 }
114 $mapped->name = $data->name;
115 $mapped->image = $data->image;
116 $mapped->issuer = $data->issuer;
117 $mapped->description = $data->description;
118 if (isset($data->openBadgeId)) {
119 $mapped->hostedUrl = $data->openBadgeId;
120 }
121
122 return $mapped;
123 }
124
125 /**
126 * Return the list of properties.
127 *
128 * @return array
129 */
130 protected static function define_properties() {
131 return [
132 'type' => [
133 'type' => PARAM_ALPHA,
134 'description' => 'BadgeClass',
135 ],
136 'id' => [
137 'type' => PARAM_RAW,
138 'description' => 'Unique identifier for this badgeclass',
139 ],
140 'issuer' => [
141 'type' => PARAM_RAW,
142 'description' => 'Unique identifier for this badgeclass',
143 'optional' => true,
144 ],
145 'name' => [
146 'type' => PARAM_TEXT,
147 'description' => 'Name of the badgeclass',
148 ],
149 'image' => [
150 'type' => PARAM_URL,
151 'description' => 'URL to the image.',
152 ],
153 'description' => [
154 'type' => PARAM_TEXT,
155 'description' => 'Description of the badge class.',
156 ],
157 'hostedUrl' => [
158 'type' => PARAM_RAW,
159 'description' => 'Identifier of the open badge for this assertion',
160 'optional' => true,
161 ],
162 ];
163 }
164
165 /**
166 * Returns a list of objects that are related.
167 *
168 * @return array
169 */
170 protected static function define_related() {
171 return array(
172 'context' => 'context',
173 'alignments' => 'stdClass[]?',
174 'criteria' => 'stdClass?',
175 );
176 }
177
178 /**
179 * Return the list of additional properties.
180 *
181 * @return array
182 */
183 protected static function define_other_properties() {
184 return array(
185 'alignments' => array(
186 'type' => alignment_exporter::read_properties_definition(),
187 'optional' => true,
188 'multiple' => true
189 ),
190 'criteriaUrl' => array(
191 'type' => PARAM_URL,
192 'optional' => true
193 ),
194 'criteriaNarrative' => array(
195 'type' => PARAM_TEXT,
196 'optional' => true
197 )
198 );
199 }
200
201 /**
202 * We map from related data passed as data to this exporter to clean exportable values.
203 */
204 protected function get_other_values(renderer_base $output) {
205 global $DB;
206 $result = [];
207
208 if (array_key_exists('alignments', $this->related) && $this->related['alignments'] !== null) {
209 $alignments = [];
210 foreach ($this->related['alignments'] as $alignment) {
211 $exporter = new alignment_exporter($alignment, $this->related);
212 $alignments[] = $exporter->export($output);
213 }
214 $result['alignments'] = $alignments;
215 }
216 if (array_key_exists('criteria', $this->related) && $this->related['criteria'] !== null) {
217 if (property_exists($this->related['criteria'], 'id') && $this->related['criteria']->id !== null) {
218 $result['criteriaUrl'] = $this->related['criteria']->id;
219 }
220 if (property_exists($this->related['criteria'], 'narrative') && $this->related['criteria']->narrative !== null) {
221 $result['criteriaNarrative'] = $this->related['criteria']->narrative;
222 }
223 }
224
225 return $result;
226 }
227}