Update the version info of structOntology.
[project/construct.git] / conStruct.module
CommitLineData
c7843b5a
FG
1<?php
2
c7843b5a 3
acd06abd
JP
4/*! @defgroup ConStructModule conStruct Drupal Module */
5//@{
c7843b5a 6
acd06abd
JP
7/*! @file conStruct.module
8 @brief Main conStruct module file.
9 @details This file includes all the other PHP files needed to run this Drupal module.
95d4bd32 10
acd06abd 11 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 12
acd06abd
JP
13 \n\n\n
14 */
04899e7f
FG
15
16
acd06abd
JP
17// Include the utilities function used by the hooks and tools
18include_once("framework/utilities.php");
c7843b5a 19
acd06abd
JP
20// Loading needed global variables
21global $base_url;
c7843b5a 22
0ee9948c 23ini_set("memory_limit","64M");
95d4bd32 24
acd06abd
JP
25// Enable global WSF debug information
26//$_GET['wsf_debug'] = 1;
95d4bd32 27/*
acd06abd 28 global $user;
95d4bd32 29
acd06abd
JP
30 if($user->uid == 1)
31 {
95d4bd32 32 ini_set("display_errors", "On");
acd06abd
JP
33 $_GET['wsf_debug'] = 1;
34 error_reporting(E_ALL);
35 }
36*/
84735e19 37// cache_clear_all('variables', 'cache');
acd06abd
JP
38
39/*!@brief Main Drupal hook procedure
95d4bd32 40 @details This hook is the first one called by Drupal when one of the module's page is accessed.
acd06abd
JP
41 We use this hook to:
42 \li Get the URI that has been accessed by the user
43 \li Trigger the conStruct tool related to this URI by calling its main procedure.
44
45 \n
46
47 @return A string containing the HTML page description generated by the conStruct tool
48
49 @author Frederick Giasson, Structured Dynamics LLC.
50
51 \n\n\n
52*/
53
54function conStruct_main()
55{
56 global $base_url;
57
58 cache_clear_all('variables', 'cache');
59
60 drupal_set_html_head("<link type=\"text/css\" rel=\"stylesheet\" media=\"all\" href=\"/drupal/"
61 . drupal_get_path('module', "conStruct") . "/css/style.css\" />");
62
63
64 // Get the extension of the URI requested to Drupal.
65 $uri = $_GET['q'];
66
67 if (stripos($uri, "conStruct/settings/cache") !== FALSE)
68 {
69 return conStruct_cache();
70 }
71
72 return (t("Check conStruct tools in the right sidebar"));
73}
74
75
76/*! @brief Define menu items and page callbacks.
95d4bd32
FG
77 @details This hook enables modules to register paths, which determines whose requests are to be handled.
78 Depending on the type of registration requested by each path, a link is placed in the the navigation
acd06abd
JP
79 block and/or an item appears in the menu administration page (q=admin/menu).
80
81 \n
95d4bd32
FG
82
83
84 @return An array of menu items. Each menu item has a key corresponding to the Drupal path being registered.
acd06abd 85 The item is an associative array.
95d4bd32 86
acd06abd 87 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 88
acd06abd 89 @see http://api.drupal.org/api/function/hook_block
95d4bd32 90
acd06abd
JP
91 \n\n\n
92*/
93function conStruct_menu()
94{
95 $items = array();
96
97 // Registration of the conStruct module settings page path
98 $items['admin/settings/conStruct'] = array(
ed1d180f
FG
99 'title' => t('conStruct Settings'),
100 'description' => t('Basic settings for a conStruct instance'),
acd06abd
JP
101 'page callback' => 'drupal_get_form',
102 'page arguments' => array('conStruct_admin'),
103 'access arguments' => array('access administration pages'),
104 'type' => MENU_NORMAL_ITEM
105 );
106
107 // Access settings menu
108 $items['admin/settings/conStruct/access'] = array(
109 'title' => t('Access Settings'),
110 'description' => t('Access settings for node functions'),
111 'page callback' => 'drupal_get_form',
112 'page arguments' => array('conStruct_access_settings'),
113 'access arguments' => array('access administration pages'),
114 'type' => MENU_NORMAL_ITEM
115 );
116
2884fa16 117 // Registration of the main conStruct module page path
acd06abd
JP
118 $items['conStruct'] = array(
119 'page callback' => 'conStruct_main',
120 'access callback' => 'conStruct_access_callback',
121 'type' => MENU_CALLBACK
122 );
123
124 return $items;
125}
126
8267a408
FG
127function conStruct_form_alter(&$form, $form_state, $form_id)
128{
129 if ($form_id == "dataset_node_form")
130 {
131 $form['#after_build'] = array('_conStruct_form_afterbuild');
132 }
133}
134
135function _conStruct_form_afterbuild($form, &$form_state)
136{
137 // Change the field_wsf field of the Dataset type to add all the possible, registered, structWSF network addresses.
138 if(isset($form["field_wsf"]))
139 {
140 $wsfAddresses = array();
141 $wsfRegistry = variable_get("WSF-Registry", array());
142
143 foreach($wsfRegistry as $s => $wsfs)
144 {
145 // get domain
146 preg_match("/^(http:\/\/)?([^\/]+)/i", $wsfs, $domain_only);
147 $host = $domain_only[2];
148
149 $wsfAddresses[$host] = $host;
150 }
151
152 $form['field_wsf']['value']['#options'] = $wsfAddresses;
153 }
154
155 return $form;
156}
157
acd06abd 158/*! @brief Declare a block or set of blocks.
95d4bd32 159 @details Any module can export a block (or blocks) to be displayed by defining the _block hook. This hook
acd06abd
JP
160 is called by theme.inc to display a block, and also by block.module to procure the list of available blocks.
161
95d4bd32
FG
162 The functions mymodule_display_block_1 and 2, as used in the example, should of course be defined
163 somewhere in your module and return the content you want to display to your users. If the "content"
acd06abd
JP
164 element is empty, no block will be displayed even if "subject" is present.
165
166 After completing your blocks, do not forget to enable them in the block admin menu.
167
168 \n
95d4bd32
FG
169
170 @param[in] $op What kind of information to retrieve about the block or blocks. Possible values:
171 @li 'list': A list of all blocks defined by the module.
172 @li 'configure': Configuration form for the block.
173 @li 'save': Save the configuration options.
174 @li 'view': Process the block when enabled in a region in order to view its contents.
175
acd06abd 176 @param[in] $delta Which block to return (not applicable if $op is 'list'). Although it is most commonly an integer starting at 0, this is not mandatory. For instance, aggregator.module uses string values for $delta.
95d4bd32 177
acd06abd 178 @param[in] $edit If $op is 'save', the submitted form data from the configuration form.
95d4bd32 179
acd06abd 180 @return If $op is 'list': An array of block descriptions. Each block description is an associative array.
95d4bd32 181
acd06abd 182 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 183
acd06abd 184 @see http://api.drupal.org/api/function/hook_block
95d4bd32 185
acd06abd
JP
186 \n\n\n
187*/
188function conStruct_block($op = 'list', $delta = 0, $edit = array())
189{
190 global $base_url;
191
192 // The $op parameter determines what piece of information is being requested.
193 switch ($op)
194 {
195 case 'list':
196
197 // If $op is "list", we just need to return a list of block descriptions.
198 // This is used to provide a list of possible blocks to the administrator,
199 // end users will not see these descriptions.
200 $blocks[0]['info'] = t('conStruct Settings');
201 return $blocks;
202
203 case 'configure':
204 // If $op is "configure", we need to provide the administrator with a
205 // configuration form. The $delta parameter tells us which block is being
206 // configured. In this example, we'll allow the administrator to customize
207 // the text of the first block.
208 $form = array();
209 if ($delta == 0)
210 {
211 // All we need to provide is a text field, Drupal will take care of
212 // the other block configuration options and the save button.
213 $form['block_example_string'] = array(
214 '#type' => 'textfield',
215 '#title' => t('Block contents'),
216 '#size' => 100,
217 '#description' => t('This string will appear in the conStruct Tools menu'),
218 '#default_value' => variable_get('conStruct_string', t(''))
219 );
220 }
221
222 return $form;
223
224 case 'save':
225
226 // If $op is "save", we need to save settings from the configuration form.
227 // Since the first block is the only one that allows configuration, we
228 // need to check $delta to make sure we only save it.
229 if ($delta == 0)
230 {
231 // Have Drupal save the string to the database.
232 variable_set('conStruct_string', $edit['conStruct_string']);
233 }
234 return;
235
236 case 'view':
237
238 default:
239
240 // If $op is "view", then we need to generate the block for display
241 // purposes. The $delta parameter tells us which block is being requested.
242 switch ($delta)
243 {
244 case 0:
245 // The subject is displayed at the top of the block. Note that it
246 // should be passed through t() for translation.
247 $block['subject'] = t('conStruct Tools');
248 // The content of the block is typically generated by calling a custom
249 // function.
250 $block['content'] = conStruct_contents(1);
251 break;
252 }
253 return $block;
254 }
255}
256
257/*! @brief Display the conStruct side-bar menu items
258 @details This function is called to generate the HTML of the tool lists being displayed in the side-bar.
259
260 \n
95d4bd32 261
acd06abd 262 @return A string where the HTML menus have been defined.
95d4bd32 263
acd06abd 264 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 265
acd06abd
JP
266 \n\n\n
267*/
268function conStruct_contents($which_block)
269{
270 global $base_url;
271 global $user;
272
273 if ($which_block == 1)
274 {
275 // Modules would typically perform some database queries to fetch the
276 // content for their blocks. Here, we'll just use the variable set in the
277 // block configuration or, if none has set, a default value.
278
279 $localPath = $base_url . "/" . drupal_get_path("module", "conStruct") . "/imgs/";
280
281 $menuItems = "";
282
ed1d180f
FG
283 // For a specific user
284 if (user_access('administer conStruct'))
285 {
286 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
287 . "/admin/settings/conStruct/\">" . t("Settings") . "</a><br />";
288 }
289
acd06abd
JP
290 if (user_access('access conStruct') && $user->uid)
291 {
292 /*! note: this procedure can have performence issue with big structWSF instances (big datasets). */
b8254782 293 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
acd06abd
JP
294 . "/admin/settings/conStruct/access/\">Access Settings</a><br />";
295 }
ed1d180f
FG
296
297 if (user_access('access conStruct') && $user->uid && module_exists("structOntology"))
acd06abd 298 {
ed1d180f 299 /*! note: this procedure can have performence issue with big structWSF instances (big datasets). */
b8254782 300 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
ed1d180f
FG
301 . "/admin/settings/conStruct/structOntology/\">Ontology Settings</a><br />";
302 }
303
304 if (user_access('access conStruct') && $user->uid && module_exists("structScones"))
305 {
306 /*! note: this procedure can have performence issue with big structWSF instances (big datasets). */
307 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
308 . "/admin/settings/conStruct/scones/\">Scones Settings</a><br />";
acd06abd
JP
309 }
310
311 return variable_get('conStruct_string', t($menuItems));
312 }
313}
314
315
316/*! @brief Define user permissions.
95d4bd32 317 @details This hook can supply permissions that the module defines, so that they can be selected on the user
acd06abd
JP
318 permissions page and used to restrict access to actions the module performs.
319
320 The permissions in the array do not need to be wrapped with the function t(), since the string extractor
321 takes care of extracting permission names defined in the perm hook for translation.
322
323 Permissions are checked using user_access().
324
325 \n
95d4bd32
FG
326
327 @note Currently only two kind of users exist: (1) "access" and (2) "administer". However, we expect to have more
acd06abd 328 kind of users in the future for different node maintenance purposes
95d4bd32
FG
329
330 @note Once new permissions are created, the node administrator has to set their permissions in the setting panel
acd06abd 331 of the node
95d4bd32 332
acd06abd 333 @return An array of permissions strings.
95d4bd32 334
acd06abd 335 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 336
acd06abd 337 @see http://api.drupal.org/api/function/hook_perm
95d4bd32 338
acd06abd
JP
339 \n\n\n
340*/
341function conStruct_perm()
342{
343 return array(
344 'access conStruct',
345 'administer conStruct'
346 );
347}
348
349
350/*! @brief Define access restrictions.
351 @details This hook allows node modules to limit access to the node types they define.
95d4bd32
FG
352 The administrative account (user ID #1) always passes any access check, so this hook is not called in that case. If this
353 hook is not defined for a node type, all access checks will fail, so only the administrator will be able to see content of that
354 type. However, users with the "administer nodes" permission may always view and edit content through the
acd06abd
JP
355 administrative interface.
356
357 \n
95d4bd32 358
acd06abd
JP
359 @warning The access hook is not yet implemented
360
95d4bd32 361 @param[in] $op The operation to be performed. Possible values:
acd06abd
JP
362 @li "create"
363 @li "delete"
364 @li "update"
365 @li "view
95d4bd32
FG
366 @param[in] $node The node on which the operation is to be performed, or, if it does not yet exist, the type of node to be created.
367
368 @param[in] $account A user object representing the user for whom the operation is to be performed.
369
acd06abd 370 @return TRUE if the operation is to be allowed; FALSE if the operation is to be denied; NULL to not override the settings in the node_access table, or access control modules.
95d4bd32 371
acd06abd 372 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 373
acd06abd 374 @todo Implementing the access hook properly
95d4bd32 375
acd06abd 376 @see http://api.drupal.org/api/function/hook_access
95d4bd32 377
acd06abd
JP
378 \n\n\n
379*/
380
381function conStruct_access($op, $node, $account)
382{
383 return TRUE;
384}
c7843b5a
FG
385
386/*! @brief Access callback for the conStruct_main() page
387
acd06abd 388 \n
95d4bd32 389
acd06abd
JP
390 @warning The access hook callback function is not yet implemented
391
392 @return TRUE if the operation is to be allowed; FALSE if the operation is to be denied; NULL to not override the settings in the node_access table, or access control modules.
95d4bd32 393
acd06abd 394 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 395
acd06abd 396 @todo Implementing the callback function for the access hook
95d4bd32 397
acd06abd 398 @see http://api.drupal.org/api/function/hook_access
95d4bd32 399
acd06abd 400 \n\n\n
c7843b5a
FG
401*/
402
acd06abd
JP
403function conStruct_access_callback()
404{
405 return TRUE;
406}
407
c7843b5a 408/*! @brief Create the settings form
95d4bd32 409 @details This procedure is called to create the settings form displayed to the administrator
acd06abd
JP
410 when the settings page of the conStruct module is accessed
411
412 \n
95d4bd32 413
acd06abd
JP
414 @note This procedure has been registered to Drupal in the conStruct_menu() procedure.
415
416 @return A form object where all the settings have been defined.
95d4bd32 417
acd06abd 418 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 419
acd06abd
JP
420 @see http://drupal.org/node/206761
421 @see http://drupal.org/node/37775
95d4bd32 422
acd06abd 423 \n\n\n
c7843b5a 424*/
acd06abd
JP
425function conStruct_admin()
426{
427 global $base_url;
428
429 // Nomalization of the URL of the node. Here we remove the "www" to normalize it.
430 $normalized_base_url = str_replace("www.", "", $base_url);
431
432 $graph = variable_get('conStruct_UrisDomain', str_replace("http://", "", get_domain($normalized_base_url)));
433
434 // Creation of the settings form
435 $form['conStruct_UrisDomain'] = array(
436 '#type' => 'textfield',
437 '#title' => t('Domain name used to resolve resources URIs'),
438 '#default_value' => $graph,
439 '#size' => 60,
440 '#maxlength' => 1024,
441 '#description' => t(
442 "Each resource create, imported and updated on this system can be resolved on the Web. A conStruct website can have one or multiple domain names that can be used to access the resources indexed in the system. To make sure everything resolves to the same URIs, we have to set the canonical domain name used to create, and resolve, the resources identifiers."),
443 '#required' => TRUE
444 );
04899e7f
FG
445
446 $form['conStruct_enableAutomaticIpChangeOnLogin'] = array(
447 '#type' => 'checkbox',
448 '#title' => t('Automatic users IP Change on login'),
449 '#description' => t(
450 "This option let you turn on/off the feature that automatically update the IP of the users if they change
451 computer. This option is turned off by default. In that case, users have to change it manually using the
452 'access settings' page."),
453 '#default_value' => variable_get('conStruct_enableAutomaticIpChangeOnLogin', 0),
454 );
acd06abd
JP
455
456 return system_settings_form($form);
457}
c7843b5a
FG
458
459
460/*! @brief Validate the settings form
acd06abd
JP
461 @details This procedure validate the fields filled by the administrator
462
463 \n
95d4bd32 464
acd06abd
JP
465 @note This procedure is called by Drupal Core each time a setting is saved.
466
467 @param[in] $form is the form ID of the passed form
468 @param[out] $form_state are the form values which you may perform validation on
469
470 @return Nothing is successful. Returns a form error with the error message if the validation failed.
95d4bd32 471
acd06abd 472 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 473
acd06abd
JP
474 @see http://drupal.org/node/206761
475 @see http://drupal.org/node/37775
95d4bd32 476
acd06abd 477 \n\n\n
c7843b5a 478*/
acd06abd
JP
479function conStruct_admin_validate($form, &$form_state)
480{
481 // Get the current graph URI parameter
482 $uri = $form_state['values']['conStruct_UrisDomain'];
483
484 // If the URI is lesser tan 16 characters, return an error
485 if (strlen($uri) <= 8)
486 {
487 form_set_error('conStruct_UrisDomain', t('The URI of the base graph should have at least 8 characters'));
488 }
489 else{
490 // Perform special handling of that URI
491 }
492}
493
494
c7843b5a 495/*! @brief Access settings
acd06abd 496 \n
95d4bd32 497
acd06abd
JP
498 @note This procedure has been registered to Drupal in the conStruct_menu() procedure.
499
500 @return A form object where all the settings have been defined.
501
95d4bd32 502
acd06abd 503 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 504
acd06abd
JP
505 @see http://drupal.org/node/206761
506 @see http://drupal.org/node/37775
95d4bd32 507
acd06abd 508 \n\n\n
c7843b5a 509*/
acd06abd
JP
510function conStruct_access_settings()
511{
512 global $base_url;
513 global $user;
514
515 // Creation of the settings form
516 $form["conStruct_AccessUser" . $user->uid] = array(
517 '#type' => 'textfield',
518 '#title' => t('The IP address you will use to query the web services related to this node. (you current IP: '
519 . $_SERVER['REMOTE_ADDR'] . ')'),
520 '#default_value' => variable_get("conStruct_AccessUser" . $user->uid, ""),
521 '#size' => 60,
522 '#maxlength' => 1024,
523 '#description' => t(
524 "Each node user can be bound with a IP address. This IP address is the address that can be used to query any web services, and datasets, available to that user."),
525 '#required' => FALSE
04899e7f 526 );
acd06abd
JP
527
528 return system_settings_form($form);
529}
530
531
c7843b5a 532/*! @brief Validate access settings
acd06abd 533 \n
95d4bd32 534
acd06abd
JP
535 @param[in] $form Form to validate
536 @param[out] $form_state
95d4bd32 537
acd06abd 538 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 539
acd06abd
JP
540 @see http://drupal.org/node/206761
541 @see http://drupal.org/node/37775
95d4bd32 542
acd06abd 543 \n\n\n
c7843b5a 544*/
acd06abd
JP
545function conStruct_access_settings_validate($form, &$form_state)
546{
0ee9948c
FG
547 global $user;
548
549 updateUserIpOnNetworks($form_state['values']["conStruct_AccessUser" . $user->uid]);
550}
551
04899e7f 552/*! @brief Update the IP of a user on linked structWSF instances.
0ee9948c
FG
553 \n
554
555 @param[in] $newIP The new IP of the user to update.
556
557 @return Returns final (it could have been changed from the input variable) the new IP assigned by the procedure.
558
559 @author Frederick Giasson, Structured Dynamics LLC.
560
561 \n\n\n
562*/
563function updateUserIpOnNetworks($newIP)
564{
acd06abd
JP
565 global $user;
566
567 // Check if the IP is being changed.
acd06abd
JP
568 $oldIP = variable_get("conStruct_AccessUser" . $user->uid, "");
569
570 if ($newIP == "")
571 {
572 $newIP = "self::$user->uid";
573 }
574
575 if ($oldIP == "")
576 {
577 $oldIP = "self::$user->uid";
578 }
579
580 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/WebServiceQuerier.php');
581 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/ProcessorXML.php');
582
583 // If it changed, we have to fix the access accordingly.
584 if ($oldIP != $newIP)
585 {
586 // Fix for each linked WSF
3350e82a 587 $wsfRegistry = variable_get("WSF-Registry", array());
acd06abd 588
3350e82a 589 if(count($wsfRegistry) > 0)
acd06abd
JP
590 {
591 $includedWsfAddresses = array();
592
593 $sidRegistry = variable_get("SID-Registry", "");
594
595 foreach ($wsfRegistry as $wsfAddress)
596 {
597 $sid = "";
598
599 // Make sure that we don't query the same server twice
600 foreach ($sidRegistry as $s => $wsfs)
601 {
602 if (array_search($wsfAddress, $wsfs) !== FALSE)
603 {
604 $sid = $s;
605 }
606 }
607
608 if ($sid !== FALSE && array_search($sid, $includedWsfAddresses) === FALSE)
609 {
610 array_push($includedWsfAddresses, $sid);
611 }
612 else
613 {
614 continue;
615 }
616
617 // Get all access descriptions for the old IP
618 $wsq = new WebServiceQuerier($wsfAddress . "auth/lister/", "get", "text/xml",
619 "registered_ip=" . urlencode($oldIP) . "&mode=access_user");
620
621 if ($wsq->getStatus() == 200)
622 {
623 $xml = new ProcessorXML();
624 $xml->loadXML($wsq->getResultset());
625
626 $accesses = $xml->getSubjectsByType("wsf:Access");
627
628 foreach ($accesses as $access)
629 {
630 $webServiceAccesses = "";
631 $datasetAccess = "";
632 $crud = "";
633 $registeredIP = "";
634 $access_uri = $xml->getURI($access);
0ee9948c 635
acd06abd
JP
636 // Get registered ip
637 $predicates = $xml->getPredicatesByType($access, "wsf:registeredIP");
638 $objects = $xml->getObjectsByType($predicates->item(0), "rdfs:Literal");
639 $registeredIP = $xml->getContent($objects->item(0));
640
0ee9948c 641 // Get datasetAccess
acd06abd
JP
642 $predicates = $xml->getPredicatesByType($access, "wsf:datasetAccess");
643 $objects = $xml->getObjectsByType($predicates->item(0), "void:Dataset");
644 $datasetAccess = $xml->getURI($objects->item(0));
645
646 // Get crud
647 $predicates = $xml->getPredicatesByType($access, "wsf:create");
648 $objects = $xml->getObjectsByType($predicates->item(0), "rdfs:Literal");
649 $crud = $xml->getContent($objects->item(0)) . ";";
650
651 $predicates = $xml->getPredicatesByType($access, "wsf:read");
652 $objects = $xml->getObjectsByType($predicates->item(0), "rdfs:Literal");
653 $crud .= $xml->getContent($objects->item(0)) . ";";
654
655 $predicates = $xml->getPredicatesByType($access, "wsf:update");
656 $objects = $xml->getObjectsByType($predicates->item(0), "rdfs:Literal");
657 $crud .= $xml->getContent($objects->item(0)) . ";";
658
659 $predicates = $xml->getPredicatesByType($access, "wsf:delete");
660 $objects = $xml->getObjectsByType($predicates->item(0), "rdfs:Literal");
661 $crud .= $xml->getContent($objects->item(0));
662
663 // Get webServiceAccess(es)
664 $webservicesType = $xml->getPredicatesByType($access, "wsf:webServiceAccess");
665
666 foreach ($webservicesType as $webserviceElement)
667 {
668 $webservicesTypeObj = $xml->getObjects($webserviceElement);
669
670 foreach ($webservicesTypeObj as $wto)
671 {
672 $webServiceAccesses .= $xml->getURI($wto) . ";";
673 }
674 }
675
676 $webServiceAccesses = substr($webServiceAccesses, 0, strlen($webServiceAccesses) - 1);
677
678 // Make sure we don't change the permissions of the World Readable default IP (0.0.0.0)
679 if ($registeredIP != "0.0.0.0")
680 {
681 // Update the access for this new IP for this Access.
682 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
683 "registered_ip=" . urlencode($newIP) . "&crud=$crud&ws_uris=" . urlencode($webServiceAccesses) .
684 "&dataset=" . urlencode($datasetAccess) . "&action=update&target_access_uri=" . urlencode($access_uri));
685
686 if ($wsq->getStatus() != 200)
687 {
688 // Throw an error
689 $wsq->displayError();
690 }
691 }
692 }
693 }
694 else
695 {
696 // Throw an error
697 $wsq->displayError();
698 }
699 }
700 }
0ee9948c
FG
701 }
702
703 return($newIP);
704}
705
706
707/*! @brief Handle user action (implementation of the hook_user Drupal hook)
708 @details This hook allows modules to react when operations are performed on user accounts. This
709 hook is implemented to change the IP address of a user each time he log in. If its IP address
710 changed, then it will be updated on some related structWSF instances.
711
712 @param[in] $op What kind of action is being performed. Possible values (in alphabetical order)
713 @param[in] $edit The array of form values submitted by the user.
714 @param[in] $account The user object on which the operation is being performed.
715 @param[in] $category The active category of user information being edited.
716
717 \n
718
719 @author Frederick Giasson, Structured Dynamics LLC.
720
721 @see http://api.drupal.org/api/function/hook_user
722
723 \n\n\n
724*/
725function conStruct_user($op, &$edit, &$account, $category = NULL)
726{
727 switch($op)
728 {
729 case "login":
730 case "view":
04899e7f
FG
731
732 $enabled = variable_get("conStruct_enableAutomaticIpChangeOnLogin", 0);
0ee9948c 733
04899e7f 734 if($enabled == 1)
0ee9948c 735 {
04899e7f 736 global $user;
0ee9948c 737
04899e7f
FG
738 /*
739 Each time a user login, or view its user page, we have to check if its his IP address
740 changed. If it did, then we will change it on the different structWSF instances where
741 he has accesses defined for him.
742
743 We do exactly the same procedure for a "view", because some users can still be logged
744 in with their laptop computer, and changed their location (from home to internet coffee
745 by exaple).
746 */
747
748 /*
749 A special case. If the operation is "view", then we have to make sure that the
750 user that view the page, is the one that is logged in. Otherwise, it would
751 "spoof" the user!
752 */
753 if($op == "view" && ($account->uid != $user->uid))
0ee9948c 754 {
04899e7f 755 return;
0ee9948c
FG
756 }
757
04899e7f
FG
758 /* Get the current IP of the user and process the IP change */
759 if(isset($_SERVER['REMOTE_ADDR']))
760 {
761 $newIP = updateUserIpOnNetworks($_SERVER['REMOTE_ADDR']);
762
763 /* Assign the newIP into Drupal's variable registry. */
764
765 /* If the new IP is a "self" IP, then we simply assign an empty string to it. We have
766 to proceed that way because it is what the software is expecting. We are only
767 mimicing what the "settings save" behavior of Drupal. */
768 if(strtolower(substr($newIP, 0, 4)) == "self")
769 {
770 $newIP = "";
771 }
772
773 variable_set("conStruct_AccessUser" . $user->uid, $newIP);
774 }
0ee9948c 775
04899e7f
FG
776 return;
777 }
0ee9948c 778 break;
acd06abd
JP
779 }
780}
781
782
783/*! @brief Handle Organic Groups changes
784 @details Hook Organic Groups to handle user subscription / unsubscription
785
786 @param[in] $op Operation done by OG
787 @param[in] $gid Group ID
788 @param[in] $uid User ID
789 @param[in] $args Arguments of the hook
790
791 \n
95d4bd32 792
acd06abd 793 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 794
acd06abd
JP
795 @see http://api.drupal-contrib.org/api/function/hook_og
796 @see http://api.freestylesystems.co.uk/api/function/og_og/6
95d4bd32 797
acd06abd
JP
798 \n\n\n
799*/
800function conStruct_og($op, $gid, $uid, $args)
801{
802 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/WebServiceQuerier.php');
803 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/ProcessorXML.php');
804
805 global $base_url;
806
807 switch ($op)
808 {
809 case "user insert":
810
0129fc85
FG
811 // We have to check if a "dataset" is already created for that group. If it is not, this means that
812 // this user is the owner of this dataset. The problem here is the execution order of hooks in drupal.
813 // "hook_og" which manage the subscription of users is executed BEFORE hook_nodeapi which manage the
814 // creation of groups (datasets).
acd06abd
JP
815 $wsfAddress = variable_get("Dataset-" . $gid . "-WSF", "");
816 $wsfAddressCreated = variable_get("Dataset-" . $gid . "-WSF-Created", "");
817
818 // Make sure we don't recreate the admin of this dataset twice
819 if ($wsfAddressCreated != "")
820 {
821 variable_del("Dataset-" . $gid . "-WSF-Created");
822 return;
823 }
824 if ($wsfAddress != "")
825 {
0129fc85
FG
826 // If we are in face of a linked dataset, we have to use the linked dataset URI as the
827 // target URI for this WSF query.
acd06abd
JP
828 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
829
8ed939fd 830 $targetDataset = variable_get("Dataset-" . $gid . "-ID", get_domain($base_url) . "/wsf/datasets/" . $gid . "/");
acd06abd
JP
831
832 if ($linkedDatasetRegistry != "")
833 {
834 if (isset($linkedDatasetRegistry[$gid]))
835 {
836 $targetDataset = $linkedDatasetRegistry[$gid];
837 }
838 }
839
840 $wsq =
841 new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml", "uri=" . urlencode($targetDataset));
842
843 $datasetCreated = TRUE;
844
845 if ($wsq->getStatus() != 200)
846 {
847 // Throw an error
848 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
849 {
850 $wsq->displayError();
851 }
852 }
853 else
854 {
0129fc85
FG
855 // If a new user get subscribed to a group, we have to check if an access IP is defined for him.
856 // If there is one, we have to create an access for it.
acd06abd
JP
857 $userIP = variable_get("conStruct_AccessUser" . $uid, "");
858
859 if ($userIP == "")
860 {
861 // If there is no IP for that user, we overload the IP of the node with "::"
862 $userIP = "self::$uid";
863 }
864
865 $wsfAddress = variable_get("Dataset-" . $gid . "-WSF", "");
866
867 if ($wsfAddress != "")
868 {
869 $wsq = new WebServiceQuerier($wsfAddress . "auth/lister/", "get", "text/xml", "mode=ws");
870
871 if ($wsq->getStatus() == 200)
872 {
873 // Get all web services
874 $webservices = "";
875
876 $xml = new ProcessorXML();
877 $xml->loadXML($wsq->getResultset());
878
879 $webServiceElements = $xml->getXPath('//predicate/object[attribute::type="wsf:WebService"]');
880
881 foreach ($webServiceElements as $element)
882 {
883 $webservices .= $xml->getURI($element) . ";";
884 }
885
886 $webservices = substr($webservices, 0, strlen($webservices) - 1);
887
888 unset($wsq);
889 unset($xml);
890
891 global $base_url;
892
0129fc85
FG
893 // By default CRUD is to "False;True;False;False". It is the duty of the dataset administrator
894 // to setup the proper CUD permissions for each user that have access to the dataset.
95d4bd32
FG
895 /*
896 $wsq = new WebServiceQuerier($wsfAddress."auth/registrar/access/", "post", "text/xml",
acd06abd
JP
897 "registered_ip=$userIP&crud=False;True;False;False&ws_uris".
898 "=$webservices&dataset=$targetDataset&action=create");
899 */
900 // If the user is an administrator, we give him full CRU. Otherwiser we give only R
901
902 $resultset =
903 db_query(
904 'SELECT {role}.name FROM {users_roles} INNER JOIN {role} ON {role}.rid = {users_roles}.rid WHERE uid=%d ',
905 $uid);
906
907 $roleNames = array();
908
909 // Get all WSF address still in use
910 while ($roleName = db_result($resultset))
911 {
912 array_push($roleNames, $roleName);
913 }
914
915 if (array_search("owner/curator", $roleNames) !== FALSE)
916 {
917 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
918 "registered_ip=" . urlencode($userIP) . "&crud=True;True;True;True&ws_uris" .
919 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
920 }
921 elseif (array_search("admin", $roleNames) !== FALSE)
922 {
923 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
924 "registered_ip=" . urlencode($userIP) . "&crud=True;True;True;True&ws_uris" .
925 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
926 }
927 else
928 {
929 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
930 "registered_ip=" . urlencode($userIP) . "&crud=False;True;False;False&ws_uris" .
931 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
932 }
933
934 if ($wsq->getStatus() != 200)
935 {
936 // Throw an error
937 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
938 {
939 $wsq->displayError();
940 }
941 }
942
943 unset($wsq);
944
945 // We have to add a reference, as a contributor of the dataset, in the description of the dataset.
946 $wsq = new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml",
947 "uri=" . urlencode($targetDataset));
948
949 $contributors = "";
950
951 if ($wsq->getStatus() != 200)
952 {
953 // Throw an error
954 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
955 {
956 $wsq->displayError();
957 }
958 }
959 else
960 {
961 $xml = new ProcessorXML();
962 $xml->loadXML($wsq->getResultset());
963
964 $datasets = $xml->getSubjectsByType("void:Dataset");
965
966 $predicates = $xml->getPredicatesByType($datasets->item(0), "dcterms:contributor");
967
968 foreach ($predicates as $predicate)
969 {
970 $objects = $xml->getObjectsByType($predicate, "sioc:User");
971
972 $contributors .= $xml->getURI($objects->item(0)) . ";";
973 }
974 }
975
976 $contributors .= $base_url . "/user/" . $uid . "/;";
977
978 $contributors = substr($contributors, 0, strlen($contributors) - 1);
979
980 unset($wsq);
981
982 $wsq = new WebServiceQuerier($wsfAddress . "dataset/update/", "post", "text/xml",
983 "uri=" . urlencode($targetDataset) . "&contributors=" . urlencode($contributors));
984
985 if ($wsq->getStatus() != 200)
986 {
987 // Throw an error
988 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
989 {
990 $wsq->displayError();
991 }
992 }
993 }
994 else
995 {
996 $wsq->displayError();
997 }
998 }
999 else
1000 {
1001 drupal_set_message(t("No WSF address linked to this dataset"), "error", TRUE);
1002 }
1003 }
1004 }
1005 break;
1006
1007 case "user update":
1008 // Trigged at dataset creation.
1009 // Trigged when the manager of a group is changed.
1010 break;
1011
1012 case "user delete":
1013 global $base_url;
1014
1015 // Delete the Access for that user since he has been unsubscribed from that group.
1016 $userIP = variable_get("conStruct_AccessUser" . $uid, "");
1017 if ($userIP == "")
1018 {
1019 // If there is no IP for that user, we overload the IP of the node with "::"
1020 $userIP = "self::$uid";
1021 }
1022
0ee9948c
FG
1023 // If we are in face of a linked dataset, we have to use the linked dataset URI as the target URI for this
1024 // WSF query.
acd06abd
JP
1025 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1026
8ed939fd 1027 $targetDataset = variable_get("Dataset-" . $gid . "-ID", get_domain($base_url) . "/wsf/datasets/" . $gid . "/");
acd06abd
JP
1028 if ($linkedDatasetRegistry != "")
1029 {
1030 if (isset($linkedDatasetRegistry[$gid]))
1031 {
1032 $targetDataset = $linkedDatasetRegistry[$gid];
1033 }
1034 }
1035
1036 $wsfAddress = variable_get("Dataset-" . $gid . "-WSF", "");
1037 if ($wsfAddress != "")
1038 {
1039 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1040 "registered_ip=" . urlencode($userIP) . "&dataset=" . urlencode($targetDataset) . "&action=delete_target");
1041
1042 if ($wsq->getStatus() != 200)
1043 {
1044 $wsq->displayError();
1045 }
1046
1047 unset($wsq);
1048
1049 // Delete the contributor reference in the dataset description
1050 $wsq =
1051 new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml", "uri=" . urlencode($targetDataset));
1052
1053 $contributors = "";
1054
1055 if ($wsq->getStatus() != 200)
1056 {
1057 $wsq->displayError();
1058 }
1059 else
1060 {
1061 $xml = new ProcessorXML();
1062 $xml->loadXML($wsq->getResultset());
1063
1064 $datasets = $xml->getSubjectsByType("void:Dataset");
1065
1066 $predicates = $xml->getPredicatesByType($datasets->item(0), "dcterms:contributor");
1067
1068 foreach ($predicates as $predicate)
1069 {
1070 $objects = $xml->getObjectsByType($predicate, "sioc:User");
1071
1072 if ($xml->getURI($objects->item(0)) != $base_url . "/user/" . $uid . "/")
1073 {
1074 $contributors .= $xml->getURI($objects->item(0)) . ";";
1075 }
1076 }
1077 }
1078
1079 $contributors = substr($contributors, 0, strlen($contributors) - 1);
1080
1081 unset($wsq);
1082
1083 $wsq = new WebServiceQuerier($wsfAddress . "dataset/update/", "post", "text/xml",
1084 "uri=" . urlencode($targetDataset) . "&contributors=" . urlencode($contributors));
1085
1086 if ($wsq->getStatus() != 200)
1087 {
1088 $wsq->displayError();
1089 }
1090 }
1091 else
1092 {
1093 drupal_set_message(t("No WSF address linked to this dataset"), "error", TRUE);
1094 }
1095
1096 break;
1097
1098 /*
1099 case "admin new":
1100 break;
95d4bd32 1101
acd06abd
JP
1102 case "admin create":
1103 break;
1104 */
1105 }
1106}
1107
1108
1109/*! @brief Monitor everything tha happens on Drupal
1110
1111 \n
95d4bd32 1112
acd06abd 1113 @author Frederick Giasson, Structured Dynamics LLC.
95d4bd32 1114
acd06abd 1115 \n\n\n
c7843b5a 1116*/
acd06abd
JP
1117function conStruct_nodeapi(&$node, $op, $teaser = NULL, $page = NULL)
1118{
1119 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/WebServiceQuerier.php');
1120 include_once('./' . drupal_get_path('module', 'conStruct') . '/framework/ProcessorXML.php');
1121
1122 switch ($op)
1123 {
1124 case 'validate':
0129fc85 1125
acd06abd
JP
1126 if (strtolower($node->op) != "delete") // Don't validate on a delete operation
1127 {
1128 if (og_is_group_type($node->type) && $node->type == "dataset")
1129 {
07c6ac40
FG
1130 // Make sure the WSF is registered to that node
1131 $wsfn = variable_get("WSF-Registry", array());
1132
1133 if(array_search("http://".$node->field_wsf[0]["value"]."/ws/", $wsfn) === FALSE)
1134 {
1135 form_set_error($node->field_wsf[0]["_error_element"],
1136 t("This WSF is not registered in this conStruct node. Please register it using the Networks module."));
1137 return;
1138 }
0129fc85
FG
1139
1140 if(isset($node->field_custom_dataset_uri[0]["value"]) && $node->field_custom_dataset_uri[0]["value"] != "")
1141 {
1142 // Make sure that if a custom dataset has been defined that we don't duplicate it.
1143 $resultset = db_query('SELECT nid FROM {og}');
1144
1145 while($datasetId = db_result($resultset))
1146 {
1147 if(variable_get("Dataset-" . $datasetId . "-ID", "") == $node->field_custom_dataset_uri[0]["value"])
1148 {
2884fa16
FG
1149 if($node->body == "Import")
1150 {
1151 form_set_error($node->field_custom_dataset_uri[0]["_error_element"],
1152 t("The dataset file you imported has been appended to the existing dataset referenced by the custom URI you provided."));
1153 }
1154 else
1155 {
1156 form_set_error($node->field_custom_dataset_uri[0]["_error_element"],
1157 t("This custom dataset URI is already used by another dataset. Please choose another one and create it again."));
1158 }
0129fc85
FG
1159 return;
1160 }
1161 }
1162 }
1163
07c6ac40 1164
acd06abd
JP
1165 if ($node->field_existing_dataset_uri[0]["value"] != "")
1166 {
1167 // Make sure that the linked dataset is not already linked by another group
1168 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1169
1170 if ($linkedDatasetRegistry != "")
1171 {
c393b737
FG
1172 $id = array_search($node->field_existing_dataset_uri[0]["value"], $linkedDatasetRegistry);
1173 if($id !== FALSE && $id != $node->nid)
acd06abd
JP
1174 {
1175 form_set_error($node->field_existing_dataset_uri[0]["_error_element"],
1176 t("A group of this Drupal node is already linked to this dataset URI"));
1177 return;
1178 }
1179 }
1180
1181 // Make sure the WSF is existing & that the dataset is existing
acd06abd
JP
1182 $wsq = new WebServiceQuerier("http://" . $node->field_wsf[0]["value"] . "/ws/" . "dataset/read/", "get",
1183 "text/xml", "uri=" . urlencode($node->field_existing_dataset_uri[0]["value"]));
1184
1185 if ($wsq->getStatus() != 200)
1186 {
1187 if ($wsq->getStatus() == 503)
1188 {
1189 form_set_error($node->field_wsf[0]["_error_element"],
1190 t("This WSF address is not existing or unreachable"));
1191 return;
1192 }
1193
1194 form_set_error($node->field_existing_dataset_uri[0]["_error_element"],
1195 t("Web service error: (status: @status) @status_message - @status_message_description", array(
1196 "status_message" => strip_tags($wsq->getStatusMessage()),
1197 "status_message_description" => strip_tags($wsq->getStatusMessageDescription())
1198 )));
1199
1200 return;
1201 }
1202 }
1203 }
1204 }
1205 break;
1206
1207 case 'insert':
1208
1209 // Handling OG group creation
1210 if (og_is_group_type($node->type) && $node->type == "dataset")
1211 {
1212 global $user;
07c6ac40 1213 global $base_url;
acd06abd
JP
1214
1215 // Save the WSF IP for this newly created dataset
0129fc85 1216 variable_set("Dataset-" . $node->nid . "-WSF", "http://" . $node->field_wsf[0]["value"] . "/ws/");
acd06abd
JP
1217 variable_set("Dataset-" . $node->nid . "-WSF-Created", "true");
1218
0129fc85
FG
1219 if(isset($node->field_custom_dataset_uri[0]["value"]) && $node->field_custom_dataset_uri[0]["value"] != "")
1220 {
1221 variable_set("Dataset-" . $node->nid . "-ID", $node->field_custom_dataset_uri[0]["value"]);
1222 }
1223 else
1224 {
1225 variable_set("Dataset-" . $node->nid . "-ID", "");
1226 }
1227
acd06abd
JP
1228 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1229
1230 // Save this new WSF address into the WSF registery
3350e82a 1231 $wsfRegistry = variable_get("WSF-Registry", array());
acd06abd
JP
1232
1233 if (array_search($wsfAddress, $wsfRegistry) === FALSE)
1234 {
1235 array_push($wsfRegistry, $wsfAddress);
1236 variable_set("WSF-Registry", $wsfRegistry);
1237 }
1238
1239 // Now, lets recreate the SID-Registry structure
1240 $sidRegistry = array();
1241
1242 foreach ($wsfRegistry as $wsfa)
1243 {
1244 $ch = curl_init();
1245
1246 curl_setopt($ch, CURLOPT_HEADER, 0);
1247 curl_setopt($ch, CURLOPT_URL, $wsfa . "index.php");
1248 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1249 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
1250
1251 $data = curl_exec($ch);
1252
1253 if (curl_errno($ch))
1254 {
1255 curl_close($ch);
1256 continue;
1257 }
1258
1259 $data = trim($data);
1260
1261 if (!isset($sidRegistry[$data]))
1262 {
1263 $sidRegistry[$data] = array($wsfa);
1264 }
1265 else
1266 {
1267 array_push($sidRegistry[$data], $wsfa);
1268 }
1269
1270 curl_close($ch);
1271 }
1272
1273 // Save the SID-Registry
1274 variable_set("SID-Registry", $sidRegistry);
1275
1276 // Check if a remote dataset URI as been defined
0129fc85 1277 if(isset($node->field_existing_dataset_uri[0]["value"]) && $node->field_existing_dataset_uri[0]["value"] != "")
acd06abd
JP
1278 {
1279 // Save the local group ID and the remote group ID in the Remote WSF registry
1280 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1281
1282 if ($linkedDatasetRegistry == "")
1283 {
1284 $linkedDatasetRegistry = array();
1285 }
1286
1287 $linkedDatasetRegistry[$node->nid] = $node->field_existing_dataset_uri[0]["value"];
1288
1289 $targetDataset = $linkedDatasetRegistry[$node->nid];
0129fc85
FG
1290
1291 variable_set("Dataset-" . $node->nid . "-ID", $targetDataset);
acd06abd
JP
1292
1293 variable_set("Linked-Dataset-Registry", $linkedDatasetRegistry);
1294
04899e7f
FG
1295 // If we link to an existing dataset, we register the user with full crud if he is an admin, or the
1296 // owner/curator of the conStruct node instance (CRUD == True;True;True;True.) Otherwise, he will get the
1297 // collaborator (CRUD == False;True;False;False) permissions.
1298 // it is up to the creator of the remote dataset to change these permissions to this user.
1299
acd06abd
JP
1300 // Note: we can't create this permission in hook_og.php for the only reason that this hook get executed
1301 // BEFORE this one. So the linkage is not yet done at that time.
1302
04899e7f
FG
1303 $wsq = new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml",
1304 "uri=" . urlencode($targetDataset));
acd06abd 1305
0129fc85 1306 if($wsq->getStatus() == 200)
acd06abd 1307 {
0ee9948c
FG
1308 // If a new user get subscribed to a group, we have to check if an access IP is defined for him. If there
1309 // is one, we have to create an access for it.
acd06abd
JP
1310 $userIP = variable_get("conStruct_AccessUser" . $user->uid, "");
1311
1312 if ($userIP == "")
1313 {
1314 // If there is no IP for that user, we overload the IP of the node with "::"
1315 $userIP = "self::$user->uid";
1316 }
1317
1318 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1319
1320 if ($wsfAddress != "")
1321 {
1322 $wsq = new WebServiceQuerier($wsfAddress . "auth/lister/", "get", "text/xml", "mode=ws");
1323
1324 if ($wsq->getStatus() == 200)
1325 {
1326 // Get all web services
1327 $webservices = "";
1328
1329 $xml = new ProcessorXML();
1330 $xml->loadXML($wsq->getResultset());
1331
1332 $webServiceElements = $xml->getXPath('//predicate/object[attribute::type="wsf:WebService"]');
1333
1334 foreach ($webServiceElements as $element)
1335 {
1336 $webservices .= $xml->getURI($element) . ";";
1337 }
1338
1339 $webservices = substr($webservices, 0, strlen($webservices) - 1);
1340
1341 unset($wsq);
1342 unset($xml);
1343
1344 global $base_url;
1345
04899e7f 1346 // Check to see what role the user has on the node, and then specify the proper permissions for him.
acd06abd
JP
1347 $resultset =
1348 db_query(
1349 'SELECT {role}.name FROM {users_roles} INNER JOIN {role} ON {role}.rid = {users_roles}.rid WHERE uid=%d ',
1350 $user->uid);
1351
1352 $roleNames = array();
1353
1354 // Get all WSF address still in use
1355 while ($roleName = db_result($resultset))
1356 {
1357 array_push($roleNames, $roleName);
1358 }
04899e7f 1359
acd06abd
JP
1360 if (array_search("owner/curator", $roleNames) !== FALSE)
1361 {
1362 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1363 "registered_ip=" . urlencode($userIP) . "&crud=True;True;True;True&ws_uris" .
1364 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
1365 }
1366 elseif (array_search("admin", $roleNames) !== FALSE)
1367 {
1368 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1369 "registered_ip=" . urlencode($userIP) . "&crud=True;True;True;True&ws_uris" .
1370 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
1371 }
1372 else
1373 {
1374 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1375 "registered_ip=" . urlencode($userIP) . "&crud=False;True;False;False&ws_uris" .
1376 "=" . urlencode($webservices) . "&dataset=" . urlencode($targetDataset) . "&action=create");
1377 }
1378
1379 if ($wsq->getStatus() != 200)
1380 {
1381 // Throw an error
1382 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
1383 {
1384 $wsq->displayError();
1385 }
1386 }
1387
1388 unset($wsq);
1389
1390 // We have to register the VO node with all permission to properly manage this dataset
1391 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1392 "registered_ip=self&crud=True;True;True;True&ws_uris=" . urlencode($webservices) . "&dataset="
1393 . urlencode($targetDataset) . "&action=create");
1394
1395 if ($wsq->getStatus() != 200)
1396 {
1397 // Throw an error
1398 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
1399 {
1400 $wsq->displayError();
1401 }
1402 }
1403
1404 unset($wsq);
1405
1406
1407 // We have to add a reference, as a contributor of the dataset, in the description of the dataset.
1408 $wsq = new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml",
1409 "uri=" . urlencode($targetDataset));
1410
1411 $contributors = "";
1412
1413 if ($wsq->getStatus() != 200)
1414 {
1415 // Throw an error
1416 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
1417 {
1418 $wsq->displayError();
1419 }
1420 }
1421 else
1422 {
1423 $xml = new ProcessorXML();
1424 $xml->loadXML($wsq->getResultset());
1425
1426 $datasets = $xml->getSubjectsByType("void:Dataset");
1427
1428 $predicates = $xml->getPredicatesByType($datasets->item(0), "dcterms:contributor");
1429
1430 foreach ($predicates as $predicate)
1431 {
1432 $objects = $xml->getObjectsByType($predicate, "sioc:User");
1433
1434 $contributors .= $xml->getURI($objects->item(0)) . ";";
1435 }
1436 }
1437
1438 $contributors .= $base_url . "/user/" . $user->uid . "/;";
1439
1440 $contributors = substr($contributors, 0, strlen($contributors) - 1);
1441
1442 unset($wsq);
1443
1444 $wsq = new WebServiceQuerier($wsfAddress . "dataset/update/", "post", "text/xml",
1445 "uri=" . urlencode($targetDataset) . "&contributors=" . urlencode($contributors));
1446
1447 if ($wsq->getStatus() != 200)
1448 {
1449 // Throw an error
1450 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
1451 {
1452 $wsq->displayError();
1453 }
1454 }
1455 }
1456 else
1457 {
1458 $wsq->displayError();
1459 }
1460 }
1461 else
1462 {
1463 drupal_set_message(t("No WSF address linked to this dataset"), "error", TRUE);
1464 }
1465 }
1466 else
1467 {
1468 $wsq->displayError();
1469 }
1470 }
1471 else
1472 {
1473 // If we are not linking the group to an existing dataset, we have to create it on the WSF
1474
1475 // Creating new Dataset
1476 $title = db_result(db_query('SELECT title FROM {node} WHERE nid=%d LIMIT 1', $node->nid));
1477 $description = db_result(db_query('SELECT og_description FROM {og} WHERE nid=%d LIMIT 1', $node->nid));
1478
1479 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
0129fc85
FG
1480
1481 $newDatasetUri = variable_get("Dataset-" . $node->nid . "-ID", "");
1482
1483 if($newDatasetUri == "")
1484 {
1485 // If no custom datasets have been defined, we use a generic one composed of its organic groups ID.
1486 $newDatasetUri = (strpos($baseDomain, "http://") === FALSE ? "http://" . $baseDomain : $baseDomain)
1487 . "/wsf/datasets/" . $node->nid . "/";
1488
1489 variable_set("Dataset-" . $node->nid . "-ID", $newDatasetUri);
1490 }
1491
acd06abd 1492 $wsq = new WebServiceQuerier($wsfAddress . "dataset/create/", "post", "text/xml", "uri="
0129fc85
FG
1493 . urlencode($newDatasetUri)
1494 . "&title=" . urlencode($title) . "&description=" . urlencode($description) . "&creator="
acd06abd
JP
1495 . urlencode($base_url . "/user/" . $user->uid . "/"));
1496
1497 if ($wsq->getStatus() != 200)
1498 {
1499 $wsq->displayError();
1500 return;
1501 }
1502
1503 unset($wsq);
1504
0ee9948c
FG
1505 // Creation of a full access for this VO node. Once it is done, it is the node that will manage interaction
1506 // between users and the dataset.
1507
1508 // create a new cURL resource
acd06abd
JP
1509 if (isset($_SERVER['REMOTE_ADDR']))
1510 {
1511 $wsq = new WebServiceQuerier($wsfAddress . "auth/lister/", "get", "text/xml", "mode=ws");
1512
1513 if ($wsq->getStatus() == 200)
1514 {
1515 // Get all web services
1516 $webservices = "";
8ed939fd 1517
acd06abd
JP
1518 $xml = new ProcessorXML();
1519 $xml->loadXML($wsq->getResultset());
1520
1521 $webServiceElements = $xml->getXPath('//predicate/object[attribute::type="wsf:WebService"]');
1522
1523 foreach ($webServiceElements as $element)
1524 {
1525 $webservices .= $xml->getURI($element) . ";";
1526 }
1527
1528 $webservices = substr($webservices, 0, strlen($webservices) - 1);
1529
acd06abd
JP
1530 unset($xml);
1531
1532 if ($webservices == "")
1533 {
1534 $wsq->displayError();
1535 return;
1536 }
1537
f1b11c3a
FG
1538 unset($wsq);
1539
acd06abd
JP
1540 // Create the access, of this VO node, to all registered web services of the WSF
1541 global $base_url;
1542
0ee9948c
FG
1543 // Take care with PHP's $_SERVER['SERVER_ADDR'] and EC2 instances. This variable is the private DNS IP
1544 // of the instance, AND NOT its IP accessible on the web.
acd06abd 1545
f3ebb395
FG
1546 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1547
acd06abd
JP
1548 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1549 "registered_ip=self&crud=true;true;true;true&ws_uris=" . urlencode($webservices) . "&dataset="
0129fc85 1550 . urlencode($newDatasetUri) . "&action=create");
acd06abd
JP
1551
1552 if ($wsq->getStatus() != 200)
1553 {
1554 $wsq->displayError();
1555 }
1556 }
1557 else
1558 {
1559 $wsq->displayError();
1560 }
1561 }
1562
1563 // We have to register the "public" user that has the "0.0.0.0" IP address
1564 // By default this public user has no permissions
f3ebb395
FG
1565
1566 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1567
acd06abd
JP
1568 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1569 "registered_ip=0.0.0.0&crud=False;False;False;False&ws_uris=" . urlencode($webservices) . "&dataset="
0129fc85 1570 . urlencode($newDatasetUri) . "&action=create");
acd06abd
JP
1571
1572 if ($wsq->getStatus() != 200)
1573 {
1574 // Throw an error
1575 if ($wsq->getStatusMessageDescription() != "This dataset doesn't exist in this WSF")
1576 {
1577 $wsq->displayError();
1578 }
1579 }
1580
1581 unset($wsq);
1582
1583
1584 // Registration of the administrator of this node
1585 global $user;
1586
1587 $userIP = variable_get("conStruct_AccessUser" . $user->uid, "");
1588
1589 if ($userIP == "")
1590 {
1591 // If there is no IP for that user, we overload the IP of the node with "::"
1592 $userIP = "self::$user->uid";
1593 }
1594
1595 $wsq = new WebServiceQuerier($wsfAddress . "auth/lister/", "get", "text/xml", "mode=ws");
1596
1597 if ($wsq->getStatus() == 200)
1598 {
1599 // Get all web services
1600 $webservices = "";
1601
1602 $xml = new ProcessorXML();
1603 $xml->loadXML($wsq->getResultset());
1604
1605 $webServiceElements = $xml->getXPath('//predicate/object[attribute::type="wsf:WebService"]');
1606
1607 foreach ($webServiceElements as $element)
1608 {
1609 $webservices .= $xml->getURI($element) . ";";
1610 }
1611
1612 $webservices = substr($webservices, 0, strlen($webservices) - 1);
1613
1614 unset($wsq);
1615 unset($xml);
1616
f3ebb395
FG
1617 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1618
acd06abd
JP
1619 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1620 "registered_ip=" . urlencode($userIP) . "&crud=True;True;True;True&ws_uris=$webservices&dataset="
0129fc85 1621 . urlencode($newDatasetUri) . "&action=create");
acd06abd
JP
1622
1623 if ($wsq->getStatus() != 200)
1624 {
1625 $wsq->displayError();
1626 }
1627
1628 unset($wsq);
1629 }
1630 else
1631 {
1632 $wsq->displayError();
1633 }
1634 }
1635 }
1636 break;
1637
1638 case 'delete':
1639
1640 // Handling OG group deletation
1641 if (og_is_group_type($node->type) && $node->type == "dataset")
1642 {
1643 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1644
1645 variable_del("Dataset-" . $node->nid . "-WSF");
0129fc85
FG
1646
1647 $datasetUri = variable_get("Dataset-" . $node->nid . "-ID", get_domain($base_url) . "/wsf/datasets/" . $node->nid . "/");
1648
1649 variable_del("Dataset-" . $node->nid . "-ID");
acd06abd
JP
1650
1651 // Clean up the WSF-Registry
07c6ac40
FG
1652
1653/*
1654 Not necessary anymore since we are now using structNetwork to manage the WSF-Registry.
1655*/
1656/*
acd06abd
JP
1657 $resultset = db_query('SELECT nid FROM {og}');
1658
1659 $usedWsf = array();
1660
1661 // Get all WSF address still in use
1662 while ($nid = db_result($resultset))
1663 {
1664 $wsf = variable_get("Dataset-" . $nid . "-WSF", "");
1665
1666 if (array_search($wsf, $usedWsf) === FALSE && $wsf != "")
1667 {
1668 array_push($usedWsf, $wsf);
1669 }
1670 }
1671
1672 // Recreate the WSF-Registry according to this list
1673 variable_set("WSF-Registry", $usedWsf);
07c6ac40 1674*/
acd06abd 1675
0ee9948c
FG
1676 // Check if it was a linked dataset. If it was, we only remove it from the linked dataset registry of this
1677 // drupal node
acd06abd
JP
1678 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1679
1680 if ($linkedDatasetRegistry != "")
1681 {
1682 if (isset($linkedDatasetRegistry[$node->nid]))
1683 {
1684 // Lets remove the remove accesses to this dataset for each user of this group
1685
1686 $resultset = db_query('SELECT uid FROM {og_uid} WHERE nid=%d', $node->nid);
1687
1688 while ($uid = db_result($resultset))
1689 {
1690 $userIP = variable_get("conStruct_AccessUser" . $uid, "");
1691
1692 if ($userIP == "")
1693 {
1694 // If there is no IP for that user, we overload the IP of the node with "::"
1695 $userIP = "self::$uid";
1696 }
1697
1698 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1699 "registered_ip=" . urlencode($userIP) . "&dataset=" . urlencode($linkedDatasetRegistry[$node->nid])
1700 . "&action=delete_target");
1701
1702 if ($wsq->getStatus() != 200)
1703 {
1704 $wsq->displayError();
1705 }
1706
1707 unset($wsq);
1708 }
1709
1710 // Then remove the access of this VO node
1711 $wsq = new WebServiceQuerier($wsfAddress . "auth/registrar/access/", "post", "text/xml",
1712 "registered_ip=self&dataset=" . urlencode($linkedDatasetRegistry[$node->nid])
1713 . "&action=delete_target");
1714
1715 // Finally, lets drop the linkage to this dataset and this group
1716
1717 unset($linkedDatasetRegistry[$node->nid]);
1718
1719 variable_set("Linked-Dataset-Registry", $linkedDatasetRegistry);
1720
1721 return;
1722 }
1723 }
1724
1725 // Otherwise, we delete the dataset that has been previously created
1726 global $base_url;
1727
1728 if ($wsfAddress != "")
1729 {
1730 $wsq = new WebServiceQuerier($wsfAddress . "dataset/delete/", "get", "text/xml",
0129fc85 1731 "uri=" . urlencode($datasetUri));
acd06abd
JP
1732
1733 if ($wsq->getStatus() != 200)
1734 {
1735 $wsq->displayError();
1736
1737 return;
1738 }
1739 }
1740 else
1741 {
1742 drupal_set_message(t("No WSF address linked to this dataset"), "error", TRUE);
1743 }
1744 }
1745
1746 break;
1747
1748 case 'update':
1749
1750 // Handling OG group update
1751 if (og_is_group_type($node->type) && $node->type == "dataset")
1752 {
1753 global $base_url;
1754
1755 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1756
1757 if ($wsfAddress != "")
1758 {
1759
1760 // if the WSF address changed, we first have to change it here.
1761 if ($wsfAddress != "http://" . $node->field_wsf[0]["value"] . "/ws/")
1762 {
1763 // Save the WSF IP for this newly created dataset
1764 variable_set("Dataset-" . $node->nid . "-WSF", "http://" . $node->field_wsf[0]["value"] . "/ws/");
1765
1766 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1767
1768 // Save this new WSF address into the WSF registery
3350e82a 1769 $wsfRegistry = variable_get("WSF-Registry", array());
acd06abd
JP
1770
1771 if (array_search($wsfAddress, $wsfRegistry) === FALSE)
1772 {
1773 array_push($wsfRegistry, $wsfAddress);
1774 variable_set("WSF-Registry", $wsfRegistry);
1775 }
1776
1777 // Now, lets recreate the SID-Registry structure
1778 $sidRegistry = array();
1779
1780 foreach ($wsfRegistry as $wsfAddress)
1781 {
1782 $ch = curl_init();
1783
1784 curl_setopt($ch, CURLOPT_HEADER, 0);
1785 curl_setopt($ch, CURLOPT_URL, $wsfAddress . "index.php");
1786 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1787 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
1788
1789 $data = curl_exec($ch);
1790
1791 if (curl_errno($ch))
1792 {
1793 curl_close($ch);
1794 continue;
1795 }
1796
1797 $data = trim($data);
1798
1799 if (!isset($sidRegistry[$data]))
1800 {
1801 $sidRegistry[$data] = array($wsfAddress);
1802 }
1803 else
1804 {
1805 array_push($sidRegistry[$data], $wsfAddress);
1806 }
1807
1808 curl_close($ch);
1809 }
1810
1811 // Save the SID-Registry
1812 variable_set("SID-Registry", $sidRegistry);
1813 }
1814
1815 // Then we check if the address of the linked dataset changed
1816 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1817
1818 if ($linkedDatasetRegistry == "")
1819 {
1820 if (isset($linkedDatasetRegistry[$node->nid]))
1821 {
1822 $linkedDatasetRegistry[$node->nid] = $node->field_existing_dataset_uri[0]["value"];
1823
1824 variable_set("Linked-Dataset-Registry", $linkedDatasetRegistry);
1825
1826 return;
1827 }
1828 }
1829
1830 // If not, we update the description of the dataset
1831 $wsq = new WebServiceQuerier($wsfAddress . "dataset/update/", "post", "text/xml",
0129fc85
FG
1832 "uri=" . urlencode(variable_get("Dataset-" . $node->nid . "-ID", get_domain($base_url) .
1833 "/wsf/datasets/" . $node->nid . "/")) . "&title="
acd06abd
JP
1834 . urlencode($node->title) . "&description=" . urlencode($node->og_description));
1835
1836 if ($wsq->getStatus() != 200)
1837 {
1838 $wsq->displayError();
1839 }
1840 }
1841 else
1842 {
1843 drupal_set_message(t("No WSF address linked to this dataset"), "error", TRUE);
1844 }
1845 }
1846 break;
1847 }
1848}
c7843b5a 1849
acd06abd 1850//@}
c7843b5a
FG
1851
1852?>