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 25 namespace core_badges\external; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 use core\external\exporter; 30 use 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 */ 39 class 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 // Having mixed $data is causing some issues. As this class is treating $data as an object everywhere, it can be converted 49 // to object at this point, to avoid errors and get the expected behaviour always. 50 // $data is an array when this class is a request exporter in backpack_api_mapping, but it is an object when this is 51 // used as a response exporter. 52 $data = (object) $data; 53 54 $pick = $this->pick_related(); 55 foreach ($pick as $one) { 56 $isarray = false; 57 // Allow [] to mean an array of values. 58 if (substr($one, -2) === '[]') { 59 $one = substr($one, 0, -2); 60 $isarray = true; 61 } 62 $prefixed = 'related_' . $one; 63 if (property_exists($data, $one) && !array_key_exists($one, $related)) { 64 if ($isarray) { 65 $newrelated = []; 66 foreach ($data->$one as $item) { 67 $newrelated[] = (object) $item; 68 } 69 $related[$one] = $newrelated; 70 } else { 71 $related[$one] = (object) $data->$one; 72 } 73 unset($data->$one); 74 } else if (property_exists($data, $prefixed) && !array_key_exists($one, $related)) { 75 if ($isarray) { 76 $newrelated = []; 77 foreach ($data->$prefixed as $item) { 78 $newrelated[] = (object) $item; 79 } 80 $related[$one] = $newrelated; 81 } else { 82 $related[$one] = (object) $data->$prefixed; 83 } 84 unset($data->$prefixed); 85 } else if (!array_key_exists($one, $related)) { 86 $related[$one] = null; 87 } 88 } 89 parent::__construct($data, $related); 90 } 91 92 /** 93 * List properties passed in $data that should be moved to $related in the constructor. 94 * 95 * @return array A list of properties to move from $data to $related. 96 */ 97 public static function pick_related() { 98 return ['alignment[]', 'criteria']; 99 } 100 101 /** 102 * Map data from a request response to the internal structure. 103 * 104 * @param stdClass $data The remote data. 105 * @param string $apiversion The backpack version used to communicate remotely. 106 * @return stdClass 107 */ 108 public static function map_external_data($data, $apiversion) { 109 $mapped = new \stdClass(); 110 if (isset($data->entityType)) { 111 $mapped->type = $data->entityType; 112 } else { 113 $mapped->type = $data->type; 114 } 115 if (isset($data->entityId)) { 116 $mapped->id = $data->entityId; 117 } else { 118 $mapped->id = $data->id; 119 } 120 $mapped->name = $data->name; 121 $mapped->image = $data->image; 122 $mapped->issuer = $data->issuer; 123 $mapped->description = $data->description; 124 if (isset($data->openBadgeId)) { 125 $mapped->hostedUrl = $data->openBadgeId; 126 } else { 127 $mapped->hostedUrl = $data->id; 128 } 129 130 return $mapped; 131 } 132 133 /** 134 * Return the list of properties. 135 * 136 * @return array 137 */ 138 protected static function define_properties() { 139 return [ 140 'type' => [ 141 'type' => PARAM_ALPHA, 142 'description' => 'BadgeClass', 143 ], 144 'id' => [ 145 'type' => PARAM_RAW, 146 'description' => 'Unique identifier for this badgeclass', 147 ], 148 'issuer' => [ 149 'type' => PARAM_RAW, 150 'description' => 'Unique identifier for this badgeclass', 151 'optional' => true, 152 ], 153 'name' => [ 154 'type' => PARAM_TEXT, 155 'description' => 'Name of the badgeclass', 156 ], 157 'image' => [ 158 'type' => PARAM_URL, 159 'description' => 'URL to the image.', 160 ], 161 'description' => [ 162 'type' => PARAM_TEXT, 163 'description' => 'Description of the badge class.', 164 ], 165 'hostedUrl' => [ 166 'type' => PARAM_RAW, 167 'description' => 'Identifier of the open badge for this assertion', 168 'optional' => true, 169 ], 170 ]; 171 } 172 173 /** 174 * Returns a list of objects that are related. 175 * 176 * @return array 177 */ 178 protected static function define_related() { 179 return array( 180 'context' => 'context', 181 'alignment' => 'stdClass[]?', 182 'criteria' => 'stdClass?', 183 ); 184 } 185 186 /** 187 * Return the list of additional properties. 188 * 189 * @return array 190 */ 191 protected static function define_other_properties() { 192 return array( 193 'alignment' => array( 194 'type' => alignment_exporter::read_properties_definition(), 195 'optional' => true, 196 'multiple' => true 197 ), 198 'criteriaUrl' => array( 199 'type' => PARAM_URL, 200 'optional' => true 201 ), 202 'criteriaNarrative' => array( 203 'type' => PARAM_TEXT, 204 'optional' => true 205 ) 206 ); 207 } 208 209 /** 210 * We map from related data passed as data to this exporter to clean exportable values. 211 * 212 * @param renderer_base $output 213 * @return array 214 */ 215 protected function get_other_values(renderer_base $output) { 216 global $DB; 217 $result = []; 218 219 if (array_key_exists('alignment', $this->related) && $this->related['alignment'] !== null) { 220 $alignment = []; 221 foreach ($this->related['alignment'] as $alignment) { 222 $exporter = new alignment_exporter($alignment, $this->related); 223 $alignments[] = $exporter->export($output); 224 } 225 $result['alignment'] = $alignments; 226 } 227 if (array_key_exists('criteria', $this->related) && $this->related['criteria'] !== null) { 228 if (property_exists($this->related['criteria'], 'id') && $this->related['criteria']->id !== null) { 229 $result['criteriaUrl'] = $this->related['criteria']->id; 230 } 231 if (property_exists($this->related['criteria'], 'narrative') && $this->related['criteria']->narrative !== null) { 232 $result['criteriaNarrative'] = $this->related['criteria']->narrative; 233 } 234 } 235 236 return $result; 237 } 238 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body