Project

General

Profile

Download (9.12 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * CDM Node functions.
5
 */
6

    
7

    
8
define('CDM_DRUPAL_NODE_CREATION', 'cdm_drupal_node_creation');
9

    
10
function do_persist_drupal_nodes(){
11
  static $value = null;
12
  if($value === NULL){
13
    $value = variable_get(CDM_DRUPAL_NODE_CREATION, FALSE);
14
  }
15
  return $value;
16
}
17

    
18
/**
19
 * Implements hook_node_view().
20
 *
21
 * TODO This should also be used for other cdm node types like name page?
22
 */
23
function cdm_dataportal_node_view($node, $view_mode = 'full') {
24

    
25

    
26
  if($view_mode == 'search_index'){
27
    // this view mode is used by _node_index_node()
28
    // allowing drupal search to index the cdm instance
29
    // nodes can be a big performance problem, to this
30
    // viewmode is ignored
31
    // If you need a fearch function, use the cdm serach facilities instead.
32
    return;
33
  }
34

    
35
  // See cdm_add_node_content.
36
  switch ($node->type) {
37
    case 'cdm_' . NODETYPE_TAXON:
38
    case 'cdm_' . NODETYPE_SPECIMEN:
39
    case 'cdm_' . NODETYPE_NAME:
40
    case 'cdm_' . NODETYPE_REFERENCE:
41
    case 'cdm_' . NODETYPE_MEDIA:
42
      if (!isset($node->cdm) && arg(0) == 'node') {
43
        // If a node page is loaded directly, e.g. node/%nid instead of
44
        // cdm_dataportal/taxon/%uuid, try to load the taxon page content
45
        // into $node->cdm.
46
        // only do this for node pages (where arg(0) = node),
47
        // not for pages like comment/reply/%nid.
48
        $cdmnode = db_query('SELECT uuid FROM {node_cdm} WHERE nid = :nid', array(
49
          ':nid' => $node->nid,
50
        ))->fetch();
51
        if (isset($cdmnode->uuid)) {
52
          cdm_dataportal_taxon_page_view($cdmnode->uuid);
53
        }
54
      }
55
      $node->content['cdm'] = isset($node->cdm) ? $node->cdm : '';
56
      break;
57
  }
58

    
59
}
60

    
61
/**
62
 * Implements hook_node_delete().
63
 */
64
function cdm_dataportal_node_delete($node) {
65
  if (array_key_exists($node->type, cdm_get_nodetypes())) {
66
    db_delete('node_cdm')->condition('nid', $node->nid)->execute();
67
  }
68
}
69

    
70
/**
71
 * Loads the node if one exist for $uuid, or else creates one.
72
 *
73
 * @param string $nodetype
74
 *   The node type.
75
 * @param string $uuid
76
 *   UUID for which to load the node.
77
 * @param string $title
78
 *   The node title to display for the node.
79
 *
80
 * @return mixed
81
 *   The node object for $uuid.
82
 */
83
function cdm_load_node($nodetype, $uuid, $title) {
84

    
85
  // Try to find node id.
86
  $cdmnode = db_query('SELECT nid, cdmtype FROM {node_cdm} WHERE wsuri = :wsuri AND cdmtype = :cdmtype AND uuid = :uuid', array(
87
    ':wsuri' => variable_get('cdm_webservice_url', NULL),
88
    ':cdmtype' => $nodetype,
89
    ':uuid' => $uuid,
90
  ))->fetch();
91

    
92
  // Nid should not be 0 , if it is, something is wrong with the record.
93
  if (isset($cdmnode->nid) && $cdmnode->nid == 0) {
94
    drupal_set_message(t('Something is wrong with the record for uuid=%uuid,
95
      please contact the helpdesk.', array('%uuid' => $uuid)), 'error');
96
    return;
97
  }
98
  if (isset($cdmnode->nid) && is_numeric($cdmnode->nid)) {
99
    $node = node_load($cdmnode->nid);
100
  }
101
  else {
102
    // Create a new node.
103
    $node = new stdClass();
104
    $node->type = 'cdm_' . $nodetype;
105
    // Comment @WA TODO set to e.g. 'en' if locale is enabled.
106
    $node->language = LANGUAGE_NONE;
107

    
108
    // Set some default values for:
109
    // 'status', 'promote', 'sticky', 'uid' and 'created'.
110
    node_object_prepare($node);
111

    
112
    // Use just the plain text of the HTML title.
113
    $title = filter_xss($title, array());
114

    
115
    // Limit length to the max length of the database field 128.
116
    $title = substr($title, 0, 128);
117
    $node->title = $title;
118

    
119
    if(do_persist_drupal_nodes()){
120

    
121
      // using the system admin user for all new nodes
122
      $node->uid = 0;
123

    
124
      // 2 = comments on, 1 = comments off.
125
      $node->comment = variable_get('comment_' . $node->type);
126

    
127
      // Preserve the current messages but before saving the node.
128
      $messages = drupal_set_message();
129

    
130
      if ($node = node_submit($node)) {
131
        // Prepare node for saving by populating author and creation date.
132
        // Comment @WA: Note that node_save is using a helper function to save a
133
        // revision with the uid of the current user so the revision will not
134
        // have uid = 0 but the uid of the current user.
135
        // I guess that is not a problem so I leave it like this. Remedy would be
136
        // to alter that revision entry afterwards.
137
        // Will create a watchdog log entry if it fails to create the node.
138
        node_save($node);
139
      }
140

    
141
      // Restore the messages.
142
      $_SESSION['messages'] = $messages;
143

    
144
      // Comment @WA: I think http://dev.e-taxonomy.eu/trac/ticket/2964 is not
145
      // relevant here anymore, since node_save will roll_back if node cannot be
146
      // created.
147
      if (!isset($node->nid)) {
148
        $message = t('Could not create node for !nodetype (!title).', array(
149
          '!nodetype' => $nodetype,
150
          '!title' => $title,
151
        ));
152
        drupal_set_message($message, 'error');
153
        watchdog('content', '@message', array('@message' => $message), WATCHDOG_ERROR);
154
        return NULL;
155
      }
156

    
157
      // Hash as a 32-character hexadecimal number.
158
      $hash = md5(variable_get('cdm_webservice_url') . $uuid);
159

    
160
      $id = db_insert('node_cdm')->fields(array(
161
        'nid' => $node->nid,
162
        'wsuri' => variable_get('cdm_webservice_url'),
163
        'hash' => $hash,
164
        'cdmtype' => $nodetype,
165
        'uuid' => $uuid,
166
      ))->execute();
167
    } else {
168
      // Drupal node is not persisted
169
      // need to create fake nid
170
      $node->nid = 0;
171
    }
172
  }
173

    
174
  return $node;
175
}
176

    
177
/**
178
 * Wrapper function around node_show()
179
 *
180
 * Just like the drupal function node_show() this function will generate an
181
 * array which displays a node detail page. Prior calling node_show() this
182
 * function assures that the special cdm node types are undegone the nessecary
183
 * preprocessing.
184
 *
185
 * This function will be called by a cdm_dataportal_{CDM_NODE_TYPE}_view function.
186
 *
187
 *
188
 * @param String $cdm_node_type
189
 *     one of the cdm content type names as defined in
190
 *     the file node_types.php. Possible values are 'taxon', 'media', 'reference', 'name'.
191
 *     you may want to use the according contstants instred of the string: NODETYPE_TAXON,
192
 *     NODETYPE_MEDIA, NODETYPE_REFERENCE, NODETYPE_NAME.
193
 * @param String $uuid
194
 *     the UUID string of the cdm entitiy to be shown. The cdm type is of cource defined by
195
 *     the  $cdm_node_type value
196
 * @param String $title
197
 *     the Page title
198
 * @param String or render array? $content
199
 *
200
 * @return
201
 *     A $page element suitable for use by drupal_render().
202
 */
203
function cdm_node_show($cdm_node_type, $uuid, $title, $content) {
204

    
205
  if(!user_access('access cdm content')){
206
    drupal_access_denied();
207
  }
208

    
209
  // tell drupal code to load the node
210
  $node = cdm_load_node($cdm_node_type, $uuid, $title);
211
  // set the title coming supplied by a cdm_dataportal_{CDM_NODE_TYPE}_view function
212
  drupal_set_title($title, PASS_THROUGH);
213

    
214
  cdm_add_node_content($node, $content);
215

    
216
  if(do_persist_drupal_nodes()){
217
    // use the full node_show()
218
    $nodes = node_show($node);
219
  } else {
220
    // only use a part of the methods called in the node_show() method
221
    $nodes = node_view_multiple(array($node->nid => $node), 'full');
222
  }
223
  return $nodes;
224
}
225

    
226
/**
227
 * Simulates the influence on the page layout by cdm_node_show().
228
 *
229
 * Adds a div as first element for the general part, which usually is empty in dataporal pages.
230
 *
231
 * @param $content
232
 */
233
function cdm_node_show_simulate($content)
234
{
235
  $general_div = "<div id=\"general\" class=\"page-part\"></div>";
236
  if(is_array($content)){
237
    array_unshift($content, array("general-part" => markup_to_render_array($general_div)));
238
    return drupal_render($content);
239
  } else {
240
    return $general_div . $content;
241
  }
242
}
243

    
244

    
245
/**
246
 * Sets the $content given a paramater to the $node object
247
 *
248
 * The $content can either be a string or an array.
249
 *
250
 * see:
251
 *  - element_children()
252
 *  - drupal_render()
253
 *  - http://api.drupal.org/api/drupal/includes!common.inc/function/drupal_render/7#comment-6644
254
 *
255
 * TODO see notes near bottom of function
256
 *
257
 * @param object $node
258
 *   A $node object
259
 * @param string|array $content
260
 *   The content to set for the $node
261
 *
262
 */
263
function cdm_add_node_content(&$node, $content) {
264

    
265
  if(is_array($content)) {
266
    // $content seems to be a render array suitable for drupal_render()
267
    $cdm_content = array(
268
        // Wrap content in cdm_dataportal specific container.
269
        '#prefix' => '<div id="cdm_dataportal.node">',
270
        '#suffix' => '</div>',
271
        // the key of child elements can be chosen arbitrarily it only must not start with a '#'
272
        'content' => $content,
273
        '#weight' => variable_get('cdm_content_weight', -1),
274
    );
275
  } else {
276
    // Wrap content in cdm_dataportal specific container.
277
    $cdm_content = markup_to_render_array( $content, variable_get('cdm_content_weight', -1));
278
  }
279

    
280
  //  $node->content is cleared in node_build_content() therefore we need to
281
  //  implement the 'view' hook in order to set the  $node->content
282
  //  properly => cdm_dataportal_node_view()
283
  $node->cdm = $cdm_content;
284
}
285

    
286
/**
287
 * Deletes all cdm nodes, used when module is uninstalled
288
 */
289
function cdm_delete_all_cdm_nodes() {
290
  $result = db_query('SELECT n.nid FROM {node} n WHERE n.type like :type', array(':type' => 'cdm_%'));
291
  foreach ($result as $node) {
292
    node_delete($node->nid);
293
  }
294
}
(6-6/12)