5 * Copyright 2011, Olivier Berger & Institut Telecom
6 * Copyright 2021, Franck Villaume - TrivialDev
8 * This program was developped in the frame of the COCLICO project
9 * (http://www.coclico-project.org/) with financial support of the Paris
12 * This file is part of FusionForge. FusionForge is free software;
13 * you can redistribute it and/or modify it under the terms of the
14 * GNU General Public License as published by the Free Software
15 * Foundation; either version 2 of the Licence, or (at your option)
18 * FusionForge is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 require_once 'common/include/rdfutils.php';
30 class doaprdfPlugin extends Plugin {
31 function __construct($id=0) {
32 parent::__construct($id) ;
33 $this->name = "doaprdf";
34 $this->text = _("DoaPRDF!"); // To show in the tabs, use...
36 _("This plugin provides DOAP RDF documents for projects on /projects URLs
37 with content-negotiation (application/rdf+xml).");
38 $this->_addHook("script_accepted_types");
39 $this->_addHook("content_negociated_project_home");
40 $this->_addHook("alt_representations");
45 * Declares itself as accepting RDF XML on /projects/...
46 * @param unknown_type $params
48 function script_accepted_types (&$params) {
49 $script = $params['script'];
50 if ($script == 'project_home') {
51 $params['accepted_types'][] = 'application/rdf+xml';
52 $params['accepted_types'][] = 'text/turtle';
56 function doapNameSpaces() {
57 // Construct an ARC2_Resource containing the project's RDF (DOAP) description
59 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
60 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
61 'doap' => 'http://usefulinc.com/ns/doap#',
62 'dcterms' => 'http://purl.org/dc/terms/'
67 function getProjectResourceIndex($group_id, &$ns, $detailed = false) {
69 // connect to FusionForge internals
70 $project = group_get_object($group_id);
71 $projectname = $project->getUnixName();
72 $project_shortdesc = $project->getPublicName();
73 $project_description = $project->getDescription();
75 if (forge_get_config('use_project_tags')) {
76 $tags_list = $project->getTags();
83 $res = ARC2::getResource($conf);
84 $res->setURI(util_make_url_g($projectname, $group_id).'#project');
86 // $res->setRel('rdf:type', 'doap:Project');
87 rdfutils_setPropToUri($res, 'rdf:type', 'doap:Project');
89 $res->setProp('doap:name', $projectname);
90 $res->setProp('doap:shortdesc', $project_shortdesc);
91 if($project_description) {
92 $res->setProp('doap:description', $project_description);
94 $homepages = array(util_make_url_g($projectname, $group_id));
95 $project_homepage = $project->getHomePage();
96 if(!in_array($project_homepage, $homepages)) {
97 $homepages[] = $project_homepage;
99 $res->setProp('doap:homepage', $homepages);
102 $tags = explode(', ',$tags_list);
103 $res->setProp('dcterms:subject', $tags);
106 // Now, we need to collect complementary RDF descriptiosn of the project via other plugins
107 // invoke the 'project_rdf_metadata' hook so as to complement the RDF description
108 $hook_params = array();
109 $hook_params['prefixes'] = array();
110 foreach($ns as $prefix => $url) {
111 $hook_params['prefixes'][$url] = $prefix;
113 $hook_params['group'] = $group_id;
114 // pass the resource in case it could be useful (read-only in principle)
115 $hook_params['in_Resource'] = $res;
116 $hook_params['out_Resources'] = array();
118 $hook_params['details'] = 'full';
121 $hook_params['details'] = 'minimal';
123 plugin_hook_by_reference('project_rdf_metadata', $hook_params);
125 // add new prefixes to the list
126 foreach($hook_params['prefixes'] as $url => $prefix) {
127 if (!isset($ns[$prefix])) {
132 // merge the two sets of triples
133 $merged_index = $res->index;
134 foreach($hook_params['out_Resources'] as $out_res) {
135 $merged_index = ARC2::getMergedIndex($merged_index, $out_res->index);
138 return $merged_index;
142 * Outputs project's DOAP profile
143 * @param unknown_type $params
145 function content_negociated_project_home (&$params) {
146 $projectname = $params['groupname'];
147 $accept = $params['accept'];
148 $group_id = $params['group_id'];
150 if($accept == 'application/rdf+xml' || $accept == 'text/turtle') {
152 // We will return RDF+XML
153 $params['content_type'] = $accept;
155 $ns = $this->doapNameSpaces();
157 $merged_index = $this->getProjectResourceIndex($group_id, $ns, $detailed = true);
161 'serializer_type_nodes' => true
164 if($accept == 'application/rdf+xml') {
165 $ser = ARC2::getRDFXMLSerializer($conf);
169 $ser = ARC2::getTurtleSerializer($conf);
171 /* Serialize a resource index */
172 $doc = $ser->getSerializedIndex($merged_index);
174 $params['content'] = $doc . "\n";
179 * Declares a link to itself in the link+meta HTML headers
180 * @param unknown_type $params
182 function alt_representations (&$params) {
183 $script_name = $params['script_name'];
184 $php_self = $params['php_self'];
185 // really trigger only for real projects descriptions, not for the projects index
186 if ( ($script_name == '/projects') && (($php_self != '/projects') && ($php_self != '/projects/')) ) {
187 $params['return'][] = '<link rel="alternate" type="application/rdf+xml" title="DOAP RDF Data" href=""/>';
188 $params['return'][] = '<link rel="alternate" type="test/turtle" title="DOAP RDF Data" href=""/>';
196 // c-file-style: "bsd"