Update the version info of structOntology.
[project/construct.git] / conStruct.module
1 <?php
2
3
4 /*! @defgroup ConStructModule conStruct Drupal Module */
5 //@{
6
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.
10
11 @author Frederick Giasson, Structured Dynamics LLC.
12
13 \n\n\n
14 */
15
16
17 // Include the utilities function used by the hooks and tools
18 include_once("framework/utilities.php");
19
20 // Loading needed global variables
21 global $base_url;
22
23 ini_set("memory_limit","64M");
24
25 // Enable global WSF debug information
26 //$_GET['wsf_debug'] = 1;
27 /*
28 global $user;
29
30 if($user->uid == 1)
31 {
32 ini_set("display_errors", "On");
33 $_GET['wsf_debug'] = 1;
34 error_reporting(E_ALL);
35 }
36 */
37 // cache_clear_all('variables', 'cache');
38
39 /*!@brief Main Drupal hook procedure
40 @details This hook is the first one called by Drupal when one of the module's page is accessed.
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
54 function 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.
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
79 block and/or an item appears in the menu administration page (q=admin/menu).
80
81 \n
82
83
84 @return An array of menu items. Each menu item has a key corresponding to the Drupal path being registered.
85 The item is an associative array.
86
87 @author Frederick Giasson, Structured Dynamics LLC.
88
89 @see http://api.drupal.org/api/function/hook_block
90
91 \n\n\n
92 */
93 function conStruct_menu()
94 {
95 $items = array();
96
97 // Registration of the conStruct module settings page path
98 $items['admin/settings/conStruct'] = array(
99 'title' => t('conStruct Settings'),
100 'description' => t('Basic settings for a conStruct instance'),
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
117 // Registration of the main conStruct module page path
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
127 function 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
135 function _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
158 /*! @brief Declare a block or set of blocks.
159 @details Any module can export a block (or blocks) to be displayed by defining the _block hook. This hook
160 is called by theme.inc to display a block, and also by block.module to procure the list of available blocks.
161
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"
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
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
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.
177
178 @param[in] $edit If $op is 'save', the submitted form data from the configuration form.
179
180 @return If $op is 'list': An array of block descriptions. Each block description is an associative array.
181
182 @author Frederick Giasson, Structured Dynamics LLC.
183
184 @see http://api.drupal.org/api/function/hook_block
185
186 \n\n\n
187 */
188 function 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
261
262 @return A string where the HTML menus have been defined.
263
264 @author Frederick Giasson, Structured Dynamics LLC.
265
266 \n\n\n
267 */
268 function 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
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
290 if (user_access('access conStruct') && $user->uid)
291 {
292 /*! note: this procedure can have performence issue with big structWSF instances (big datasets). */
293 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
294 . "/admin/settings/conStruct/access/\">Access Settings</a><br />";
295 }
296
297 if (user_access('access conStruct') && $user->uid && module_exists("structOntology"))
298 {
299 /*! note: this procedure can have performence issue with big structWSF instances (big datasets). */
300 $menuItems .= "<img src=\"" . $localPath . "kcontrol.png\" style=\"padding-right:5px;\" alt=\"\" /><a href=\"" . $base_url
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 />";
309 }
310
311 return variable_get('conStruct_string', t($menuItems));
312 }
313 }
314
315
316 /*! @brief Define user permissions.
317 @details This hook can supply permissions that the module defines, so that they can be selected on the user
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
326
327 @note Currently only two kind of users exist: (1) "access" and (2) "administer". However, we expect to have more
328 kind of users in the future for different node maintenance purposes
329
330 @note Once new permissions are created, the node administrator has to set their permissions in the setting panel
331 of the node
332
333 @return An array of permissions strings.
334
335 @author Frederick Giasson, Structured Dynamics LLC.
336
337 @see http://api.drupal.org/api/function/hook_perm
338
339 \n\n\n
340 */
341 function 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.
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
355 administrative interface.
356
357 \n
358
359 @warning The access hook is not yet implemented
360
361 @param[in] $op The operation to be performed. Possible values:
362 @li "create"
363 @li "delete"
364 @li "update"
365 @li "view
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
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.
371
372 @author Frederick Giasson, Structured Dynamics LLC.
373
374 @todo Implementing the access hook properly
375
376 @see http://api.drupal.org/api/function/hook_access
377
378 \n\n\n
379 */
380
381 function conStruct_access($op, $node, $account)
382 {
383 return TRUE;
384 }
385
386 /*! @brief Access callback for the conStruct_main() page
387
388 \n
389
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.
393
394 @author Frederick Giasson, Structured Dynamics LLC.
395
396 @todo Implementing the callback function for the access hook
397
398 @see http://api.drupal.org/api/function/hook_access
399
400 \n\n\n
401 */
402
403 function conStruct_access_callback()
404 {
405 return TRUE;
406 }
407
408 /*! @brief Create the settings form
409 @details This procedure is called to create the settings form displayed to the administrator
410 when the settings page of the conStruct module is accessed
411
412 \n
413
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.
417
418 @author Frederick Giasson, Structured Dynamics LLC.
419
420 @see http://drupal.org/node/206761
421 @see http://drupal.org/node/37775
422
423 \n\n\n
424 */
425 function 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 );
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 );
455
456 return system_settings_form($form);
457 }
458
459
460 /*! @brief Validate the settings form
461 @details This procedure validate the fields filled by the administrator
462
463 \n
464
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.
471
472 @author Frederick Giasson, Structured Dynamics LLC.
473
474 @see http://drupal.org/node/206761
475 @see http://drupal.org/node/37775
476
477 \n\n\n
478 */
479 function 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
495 /*! @brief Access settings
496 \n
497
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
502
503 @author Frederick Giasson, Structured Dynamics LLC.
504
505 @see http://drupal.org/node/206761
506 @see http://drupal.org/node/37775
507
508 \n\n\n
509 */
510 function 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
526 );
527
528 return system_settings_form($form);
529 }
530
531
532 /*! @brief Validate access settings
533 \n
534
535 @param[in] $form Form to validate
536 @param[out] $form_state
537
538 @author Frederick Giasson, Structured Dynamics LLC.
539
540 @see http://drupal.org/node/206761
541 @see http://drupal.org/node/37775
542
543 \n\n\n
544 */
545 function conStruct_access_settings_validate($form, &$form_state)
546 {
547 global $user;
548
549 updateUserIpOnNetworks($form_state['values']["conStruct_AccessUser" . $user->uid]);
550 }
551
552 /*! @brief Update the IP of a user on linked structWSF instances.
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 */
563 function updateUserIpOnNetworks($newIP)
564 {
565 global $user;
566
567 // Check if the IP is being changed.
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
587 $wsfRegistry = variable_get("WSF-Registry", array());
588
589 if(count($wsfRegistry) > 0)
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);
635
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
641 // Get datasetAccess
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 }
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 */
725 function conStruct_user($op, &$edit, &$account, $category = NULL)
726 {
727 switch($op)
728 {
729 case "login":
730 case "view":
731
732 $enabled = variable_get("conStruct_enableAutomaticIpChangeOnLogin", 0);
733
734 if($enabled == 1)
735 {
736 global $user;
737
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))
754 {
755 return;
756 }
757
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 }
775
776 return;
777 }
778 break;
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
792
793 @author Frederick Giasson, Structured Dynamics LLC.
794
795 @see http://api.drupal-contrib.org/api/function/hook_og
796 @see http://api.freestylesystems.co.uk/api/function/og_og/6
797
798 \n\n\n
799 */
800 function 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
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).
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 {
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.
828 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
829
830 $targetDataset = variable_get("Dataset-" . $gid . "-ID", get_domain($base_url) . "/wsf/datasets/" . $gid . "/");
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 {
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.
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
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.
895 /*
896 $wsq = new WebServiceQuerier($wsfAddress."auth/registrar/access/", "post", "text/xml",
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
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.
1025 $linkedDatasetRegistry = variable_get("Linked-Dataset-Registry", "");
1026
1027 $targetDataset = variable_get("Dataset-" . $gid . "-ID", get_domain($base_url) . "/wsf/datasets/" . $gid . "/");
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;
1101
1102 case "admin create":
1103 break;
1104 */
1105 }
1106 }
1107
1108
1109 /*! @brief Monitor everything tha happens on Drupal
1110
1111 \n
1112
1113 @author Frederick Giasson, Structured Dynamics LLC.
1114
1115 \n\n\n
1116 */
1117 function 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':
1125
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 {
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 }
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 {
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 }
1159 return;
1160 }
1161 }
1162 }
1163
1164
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 {
1172 $id = array_search($node->field_existing_dataset_uri[0]["value"], $linkedDatasetRegistry);
1173 if($id !== FALSE && $id != $node->nid)
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
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;
1213 global $base_url;
1214
1215 // Save the WSF IP for this newly created dataset
1216 variable_set("Dataset-" . $node->nid . "-WSF", "http://" . $node->field_wsf[0]["value"] . "/ws/");
1217 variable_set("Dataset-" . $node->nid . "-WSF-Created", "true");
1218
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
1228 $wsfAddress = variable_get("Dataset-" . $node->nid . "-WSF", "");
1229
1230 // Save this new WSF address into the WSF registery
1231 $wsfRegistry = variable_get("WSF-Registry", array());
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
1277 if(isset($node->field_existing_dataset_uri[0]["value"]) && $node->field_existing_dataset_uri[0]["value"] != "")
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];
1290
1291 variable_set("Dataset-" . $node->nid . "-ID", $targetDataset);
1292
1293 variable_set("Linked-Dataset-Registry", $linkedDatasetRegistry);
1294
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
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
1303 $wsq = new WebServiceQuerier($wsfAddress . "dataset/read/", "get", "text/xml",
1304 "uri=" . urlencode($targetDataset));
1305
1306 if($wsq->getStatus() == 200)
1307 {
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.
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
1346 // Check to see what role the user has on the node, and then specify the proper permissions for him.
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 }
1359
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));
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
1492 $wsq = new WebServiceQuerier($wsfAddress . "dataset/create/", "post", "text/xml", "uri="
1493 . urlencode($newDatasetUri)
1494 . "&title=" . urlencode($title) . "&description=" . urlencode($description) . "&creator="
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
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
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 = "";
1517
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
1530 unset($xml);
1531
1532 if ($webservices == "")
1533 {
1534 $wsq->displayError();
1535 return;
1536 }
1537
1538 unset($wsq);
1539
1540 // Create the access, of this VO node, to all registered web services of the WSF
1541 global $base_url;
1542
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.
1545
1546 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1547
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="
1550 . urlencode($newDatasetUri) . "&action=create");
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
1565
1566 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1567
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="
1570 . urlencode($newDatasetUri) . "&action=create");
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
1617 $baseDomain = variable_get("conStruct_UrisDomain", get_domain($base_url));
1618
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="
1621 . urlencode($newDatasetUri) . "&action=create");
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");
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");
1650
1651 // Clean up the WSF-Registry
1652
1653 /*
1654 Not necessary anymore since we are now using structNetwork to manage the WSF-Registry.
1655 */
1656 /*
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);
1674 */
1675
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
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",
1731 "uri=" . urlencode($datasetUri));
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
1769 $wsfRegistry = variable_get("WSF-Registry", array());
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",
1832 "uri=" . urlencode(variable_get("Dataset-" . $node->nid . "-ID", get_domain($base_url) .
1833 "/wsf/datasets/" . $node->nid . "/")) . "&title="
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 }
1849
1850 //@}
1851
1852 ?>