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 * This file contains a class definition for the Tool Consumer Profile resource
19 *
20 * @package    ltiservice_profile
21 * @copyright  2014 Vital Source Technologies http://vitalsource.com
22 * @author     Stephen Vickers
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26
27namespace ltiservice_profile\local\resources;
28
29use \mod_lti\local\ltiservice\service_base;
30
31defined('MOODLE_INTERNAL') || die();
32
33/**
34 * A resource implementing the Tool Consumer Profile.
35 *
36 * @package    ltiservice_profile
37 * @since      Moodle 2.8
38 * @copyright  2014 Vital Source Technologies http://vitalsource.com
39 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class profile extends \mod_lti\local\ltiservice\resource_base {
42
43    /**
44     * Class constructor.
45     *
46     * @param service_base $service Service instance
47     */
48    public function __construct($service) {
49
50        parent::__construct($service);
51        $this->id = 'ToolConsumerProfile';
52        $this->template = '/profile/{tool_proxy_id}';
53        $this->variables[] = 'ToolConsumerProfile.url';
54        $this->formats[] = 'application/vnd.ims.lti.v2.toolconsumerprofile+json';
55        $this->methods[] = 'GET';
56
57    }
58
59    /**
60     * Get the path for this resource.
61     *
62     * @return string
63     */
64    public function get_path() {
65
66        $path = $this->template;
67        $toolproxy = $this->get_service()->get_tool_proxy();
68        if (!empty($toolproxy)) {
69            $path = str_replace('{tool_proxy_id}', $toolproxy->guid, $path);
70        }
71
72        return $path;
73
74    }
75
76    /**
77     * Execute the request for this resource.
78     *
79     * @param \mod_lti\local\ltiservice\response $response  Response object for this request.
80     */
81    public function execute($response) {
82        global $CFG;
83
84        $version = service_base::LTI_VERSION2P0;
85        $params = $this->parse_template();
86        if (optional_param('lti_version', service_base::LTI_VERSION2P0, PARAM_ALPHANUMEXT) != $version) {
87            $ok = false;
88            $response->set_code(400);
89        } else {
90            $toolproxy = lti_get_tool_proxy_from_guid($params['tool_proxy_id']);
91            $ok = $toolproxy !== false;
92        }
93        if ($ok) {
94            $this->get_service()->set_tool_proxy($toolproxy);
95            $response->set_content_type($this->formats[0]);
96
97            $servicepath = $this->get_service()->get_service_path();
98            $id = $servicepath . $this->get_path();
99            $now = date('Y-m-d\TH:iO');
100            $capabilityofferedarr = explode("\n", $toolproxy->capabilityoffered);
101            $serviceofferedarr = explode("\n", $toolproxy->serviceoffered);
102            $serviceoffered = '';
103            $sep = '';
104            $services = \core_component::get_plugin_list('ltiservice');
105            foreach ($services as $name => $location) {
106                if (in_array($name, $serviceofferedarr)) {
107                    $classname = "\\ltiservice_{$name}\\local\\service\\{$name}";
108                    /** @var service_base $service */
109                    $service = new $classname();
110                    $service->set_tool_proxy($toolproxy);
111                    $resources = $service->get_resources();
112                    foreach ($resources as $resource) {
113                        $formats = implode("\", \"", $resource->get_formats());
114                        $methods = implode("\", \"", $resource->get_methods());
115                        $capabilityofferedarr = array_merge($capabilityofferedarr, $resource->get_variables());
116                        $template = $resource->get_path();
117                        if (!empty($template)) {
118                            $path = $servicepath . preg_replace('/[\(\)]/', '', $template);
119                        } else {
120                            $path = $resource->get_endpoint();
121                        }
122                        $serviceoffered .= <<< EOD
123{$sep}
124    {
125      "@type":"{$resource->get_type()}",
126      "@id":"tcp:{$resource->get_id()}",
127      "endpoint":"{$path}",
128      "format":["{$formats}"],
129      "action":["{$methods}"]
130    }
131EOD;
132                        $sep = ',';
133                    }
134                }
135            }
136            $capabilityoffered = implode("\",\n    \"", $capabilityofferedarr);
137            if (strlen($capabilityoffered) > 0) {
138                $capabilityoffered = "\n    \"{$capabilityoffered}\"";
139            }
140            $urlparts = parse_url($CFG->wwwroot);
141            $orgid = $urlparts['host'];
142            $name = 'Moodle';
143            $code = 'moodle';
144            $vendorname = 'Moodle.org';
145            $vendorcode = 'mdl';
146            $prodversion = strval($CFG->version);
147            if (!empty($CFG->mod_lti_institution_name)) {
148                $consumername = $CFG->mod_lti_institution_name;
149                $consumerdesc = '';
150            } else {
151                $consumername = get_site()->fullname;
152                $consumerdesc = strip_tags(get_site()->summary);
153            }
154            $profile = <<< EOD
155{
156  "@context":[
157    "http://purl.imsglobal.org/ctx/lti/v2/ToolConsumerProfile",
158    {
159      "tcp":"{$id}#"
160    }
161  ],
162  "@type":"ToolConsumerProfile",
163  "@id":"{$id}",
164  "lti_version":"{$version}",
165  "guid":"{$toolproxy->guid}",
166  "product_instance":{
167    "guid":"{$orgid}",
168    "product_info":{
169      "product_name":{
170        "default_value":"{$name}",
171        "key":"product.name"
172      },
173      "product_version":"{$prodversion}",
174      "product_family":{
175        "code":"{$code}",
176        "vendor":{
177          "code":"{$vendorcode}",
178          "vendor_name":{
179            "default_value":"{$vendorname}",
180            "key":"product.vendor.name"
181          },
182          "timestamp":"{$now}"
183        }
184      }
185    },
186    "service_owner":{
187      "@id":"ServiceOwner",
188      "service_owner_name":{
189        "default_value":"{$consumername}",
190        "key":"service_owner.name"
191      },
192      "description":{
193        "default_value":"{$consumerdesc}",
194        "key":"service_owner.description"
195      }
196    }
197  },
198  "capability_offered":[{$capabilityoffered}
199  ],
200  "service_offered":[{$serviceoffered}
201  ]
202}
203EOD;
204            $response->set_body($profile);
205
206        }
207    }
208
209    /**
210     * Parse a value for custom parameter substitution variables.
211     *
212     * @param string $value String to be parsed
213     *
214     * @return string
215     */
216    public function parse_value($value) {
217        if (!empty($this->get_service()->get_tool_proxy()) && (strpos($value, '$ToolConsumerProfile.url') !== false)) {
218            $value = str_replace('$ToolConsumerProfile.url', $this->get_endpoint(), $value);
219        }
220        return $value;
221
222    }
223
224}
225