/[drupal]/contributions/modules/opencalais/calais.module
ViewVC logotype

Contents of /contributions/modules/opencalais/calais.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.6 - (show annotations) (download) (as text)
Thu Apr 24 17:56:49 2008 UTC (19 months ago) by febbraro
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +11 -1 lines
File MIME type: text/x-php
added license
1 <?php
2 /*
3 Copyright (C) 2008 by Phase2 Technology.
4 Author(s): Frank Febbraro, Irakli Nadareishvili
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY. See the LICENSE.txt file for more details.
10
11 $Id$
12 */
13
14 define('CALAIS_PROCESS_NO', 'NO');
15 define('CALAIS_PROCESS_AUTO', 'AUTO');
16 define('CALAIS_PROCESS_MANUAL', 'MANUAL');
17
18 module_load_include('inc', 'calais', 'calais.ui');
19
20 /**
21 * Implementation of hook_perm().
22 */
23 function calais_perm() {
24 return array('administer calais', 'access calais');
25 }
26
27 /**
28 * Implementation of hook_menu().
29 */
30 function calais_menu() {
31 $items = array();
32
33 $items['admin/settings/calais'] = array(
34 'title' => 'Calais Node Settings',
35 'description' => 'Configurations for Calais Integration with content nodes',
36 'page callback' => 'drupal_get_form',
37 'page arguments' => array('calais_admin_settings'),
38 'access arguments' => array('administer calais'),
39 );
40
41 $items['node/%node/calais'] = array(
42 'title' => 'Calais',
43 'page callback' => 'drupal_get_form',
44 'page arguments' => array('calais_keywords_form', 1),
45 'access callback' => 'calais_access',
46 'access arguments' => array(1),
47 'weight' => 2,
48 'type' => MENU_LOCAL_TASK
49 );
50
51 return $items;
52 }
53
54 /**
55 * Implementation of hook_access()
56 */
57 function calais_access($node) {
58 return user_access('access calais') && calais_processing_type($node) != CALAIS_PROCESS_NO;
59 }
60
61 /**
62 * Build the administration page for Calais and Content Types
63 */
64 function calais_admin_settings() {
65
66 $form = array();
67
68 calais_build_entity_settings($form);
69 calais_build_nodetype_settings($form);
70
71 $form['#submit'][] = 'calais_admin_settings_submit';
72
73 $form = system_settings_form($form);
74 return $form;
75 }
76
77 /**
78 * Build the Entity selector. Used for Entity suppression.
79 */
80 function calais_build_entity_settings(&$form, $type = 'global', $name = 'Global', $allow_disable = false) {
81 $entity_attributes = array();
82 $entities = array_keys(calais_get_entity_vocabularies());
83 sort($entities);
84
85 $disabled = false;
86 if ($allow_disable) {
87 $var_name = "calais_use_global_{$type}";
88 $disabled = variable_get($var_name, true);
89
90 $form[$var_name] = array(
91 '#type' => 'checkbox',
92 '#title' => t('Use Calais Global Entity defaults'),
93 '#default_value' => $disabled,
94 '#description' => t('If checked, this content type will use the Global Calais Entities.'),
95 );
96
97 if ($disabled) {
98 $entity_attributes['style'] = 'display:none';
99 }
100
101 $field_id = 'edit-' . str_replace(array('][', '_', ' '), '-', $var_name);
102 drupal_add_js("$(document).ready(function() {
103 $('#$field_id').click(function() {
104 $('.{$type}_entities').toggle();
105 });
106 });", 'inline');
107 }
108
109 $params = array('@name' => $name);
110 $form["calais_entity_settings_{$type}"] = array(
111 '#type' => 'fieldset',
112 '#title' => t('@name Calais Entities', $params),
113 '#attributes' => array_merge(array('class' => "{$type}_entities"), $entity_attributes),
114 '#collapsible' => TRUE,
115 '#collapsed' => TRUE,
116 );
117
118 $form["calais_entity_settings_{$type}"]["calais_applied_entities_{$type}"] = array(
119 '#type' => 'checkboxes',
120 '#title' => t('Which Calais Entities do you wish to use?'),
121 '#default_value' => variable_get("calais_applied_entities_{$type}", $entities),
122 '#options' => drupal_map_assoc($entities),
123 '#description' => t('These are the entities that will get applied to content. If an Entity is not selected then the Calais suggestions will be ignored'),
124 );
125 }
126
127 /**
128 * Build the node type settings form for Calais integration.
129 */
130 function calais_build_nodetype_settings(&$form) {
131 node_types_rebuild();
132
133 $node_types = node_get_types('types', NULL, TRUE);
134 $options = array(
135 CALAIS_PROCESS_NO => t('Not processed by Calais (default)'),
136 CALAIS_PROCESS_MANUAL => t('Have keywords be suggested (manual term association)'),
137 CALAIS_PROCESS_AUTO => t('Have keywords automatically applied'),
138 );
139
140 foreach ($node_types as $nt) {
141 $key = strtolower($nt->type);
142 $name = $nt->name;
143 $paramName = array('@node' => $name);
144
145 $form["calais_{$key}_settings"] = array(
146 '#type' => 'fieldset',
147 '#title' => t('Processing Settings for @node', $paramName),
148 '#collapsible' => TRUE,
149 '#collapsed' => FALSE,
150 );
151
152 $form["calais_{$key}_settings"]["calais_node_{$key}_process"] = array(
153 '#type' => 'radios',
154 '#parents' => array('calais_node_'. $key .'_process'),
155 '#title' => t('Calais Processing'),
156 '#default_value' => variable_get("calais_node_{$key}_process", CALAIS_PROCESS_NO),
157 '#options' => $options,
158 );
159 $form["calais_{$key}_settings"]["calais_api_allow_searching_{$key}"] = array(
160 '#type' => 'checkbox',
161 '#title' => t('Allow Calais Searching'),
162 '#default_value' => variable_get("calais_api_allow_searching_{$key}", NULL),
163 '#description' => t('Indicates whether future searches can be performed on the extracted metadata by Calais'),
164 );
165 $form["calais_{$key}_settings"]["calais_api_allow_distribution_{$key}"] = array(
166 '#type' => 'checkbox',
167 '#title' => t('Allow Calais Distribution'),
168 '#default_value' => variable_get("calais_api_allow_distribution_{$key}", NULL),
169 '#description' => t('Indicates whether the extracted metadata can be distributed by Calais'),
170 );
171
172 calais_build_entity_settings($form["calais_{$key}_settings"], $key, $name, true);
173 }
174 }
175
176 /**
177 * Have to override so that we can manage vocabulary - node_type relationships.
178 *
179 * @param unknown_type $form_id
180 * @param unknown_type $form_state
181 */
182 function calais_admin_settings_submit($form, &$form_state) {
183
184 system_settings_form_submit($form, $form_state);
185
186 // Also, set vocabulary-node relationships
187 $node_types = node_get_types('types', NULL, TRUE);
188 $all_vocabularies = calais_get_entity_vocabularies();
189 foreach ($node_types as $nt) {
190 $key = strtolower($nt->type);
191 $state = variable_get('calais_node_'. $key .'_process', CALAIS_PROCESS_NO);
192 foreach ($all_vocabularies as $entity => $vid) {
193 // Clean-up
194 db_query("DELETE FROM {vocabulary_node_types} WHERE vid='%d' and type='%s'", $vid, $key);
195 }
196 if ($state !== CALAIS_PROCESS_NO) {
197 // assign all configured calais vocabs to this node type
198 $node_vocabularies = calais_get_entity_vocabularies($key);
199 foreach ($node_vocabularies as $entity => $vid) {
200 db_query("INSERT INTO {vocabulary_node_types} (vid, type) values('%d','%s') ", $vid, $key);
201 }
202 }
203 }
204 }
205
206 /**
207 * Implementation of hook_nodeapi().
208 *
209 * Process node updates and if applicable, update the Calais terms.
210 */
211 function calais_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
212
213 switch ($op) {
214 case "delete":
215 db_query("DELETE FROM {calais_term_node} WHERE nid=%d", $node->nid);
216 break;
217
218 case "insert":
219 case "update":
220 if (calais_processing_type($node) == CALAIS_PROCESS_NO)
221 return;
222
223 cache_clear_all();
224 db_query("DELETE FROM {calais_term_node} WHERE nid=%d", $node->nid);
225 $data = "$node->title \n $node->body";
226 $node_settings = calais_get_node_settings($node);
227 $keywords = calais_api_analyze($node, $data, $node_settings);
228 $vocabularies = calais_get_entity_vocabularies();
229
230 foreach ($keywords as $cat => $terms) {
231 $vid = $vocabularies[$cat];
232
233 // Create a vocabulary if we come across an entity that we dont know of.
234 if (!$vid) {
235 $vid = calais_create_entity_vocabulary($cat);
236 $vocabularies[$cat] = $vid;
237 variable_set('calais_vocabulary_names', $vocabularies);
238
239 drupal_set_message(t('Added a new Vocabulary for new Calais Entity %entity. You may need to update your Calais Node Settings to take advantage of this new entity.', array('%entity' => $cat)));
240 }
241
242 foreach ($terms as $term) {
243 $term = trim($term);
244 $tid = calais_verify_and_get_term($vid, $term, 'calais');
245 if ($tid) {
246 calais_assign_node_calaisterm($node->nid, $tid);
247 }
248 else {
249 watchdog('Calais', "Could not create Calais Term: $term");
250 }
251
252 //-- Auto-assign Taxonomy Terms
253 if (calais_processing_type($node) == CALAIS_PROCESS_AUTO) {
254 $tid = calais_verify_and_get_term($vid, $term, 'taxonomy');
255 if ($tid) {
256 calais_assign_node_taxonomyterm($node->nid, $node->vid, $tid);
257 }
258 else {
259 watchdog('Calais', "Could not assign Taxonomy Term: $term");
260 }
261 }
262 }
263 }
264 break;
265 }
266 }
267
268 /**
269 * Checks if a specified term exists in a specified vocabulary.
270 * If it does not exist - creates it.
271 *
272 * @param int $vid
273 * @param name $term
274 *
275 * @return int $tid Term id in {calais_term} table
276 */
277 function calais_verify_and_get_term($vid, $term, $module) {
278
279 switch ($module) {
280 case 'calais':
281 $tablename = "calais_term";
282 break;
283
284 case 'taxonomy':
285 $tablename = 'term_data';
286 break;
287
288 default:
289 return NULL;
290 }
291
292 $bool = false;
293 $term = trim($term);
294
295 $bool = db_result(db_query("SELECT count(*) FROM {".$tablename."} where name='%s' and vid=%d", $term, $vid));
296
297 if (!$bool) {
298
299 $form_values = array('vid' => $vid, 'name' => $term);
300
301 switch ($module) {
302 case 'calais':
303 db_query("INSERT INTO {".$tablename."}(name,vid) values('%s',%d)", $term, $vid);
304 break;
305
306 case 'taxonomy':
307 taxonomy_save_term($form_values);
308 break;
309 }
310 }
311
312 $tid = db_result(db_query("SELECT tid FROM {".$tablename."} WHERE name='%s' and vid=%d", $term, $vid));
313
314 cache_clear_all();
315 return $tid;
316 }
317
318 function calais_assign_node_calaisterm($nid, $tid) {
319 db_query("DELETE FROM {calais_term_node} where nid=%d and tid=%d", $nid, $tid);
320 db_query("INSERT INTO {calais_term_node} (nid, tid) VALUES(%d, %d)", $nid, $tid);
321 }
322
323 function calais_assign_node_taxonomyterm($nid, $vid, $tid) {
324 db_query("DELETE FROM {term_node} where nid=%d and vid=%d and tid=%d", $nid, $vid, $tid);
325 db_query("INSERT INTO {term_node} (nid, vid, tid) VALUES(%d, %d, %d)", $nid, $vid, $tid);
326 }
327
328 /**
329 * Determines which processing type (none, manual, auto) is
330 * applicable to a node specific node instance passed as an argument.
331 *
332 * @param mixed $var either a Node object or a valid node_type String
333 *
334 * @return constant one of: CALAIS_PROCESS_NO, CALAIS_PROCESS_AUTO or CALAIS_PROCESS_MANUAL
335 */
336 function calais_processing_type($var) {
337
338 if (is_object($var)) {
339 $nodetype = $var->type;
340 }
341 else {
342 $nodetype = $var;
343 }
344 $key = strtolower($nodetype);
345
346 return variable_get('calais_node_'. $key .'_process', CALAIS_PROCESS_NO);
347 }
348
349 /**
350 * Return the Calais parameter settings for the specific node type.
351 */
352 function calais_get_node_settings($node) {
353 $settings = array(
354 'allowSearch' => variable_get("calais_api_allow_searching_{$node->type}", false) ? 'true' : 'false',
355 'allowDistribution' => variable_get("calais_api_allow_distribution_{$node->type}", false) ? 'true' : 'false',
356 );
357 return $settings;
358 }
359
360 /**
361 * Get a list of the entities that Calais API defines:
362 * http://opencalais.mashery.com/page/calaissemanticmetadata
363 *
364 * IF $type is not specified it will return all known Calais Entities.
365 * however if $type is specified it will return only those Entities that the
366 * specific node type is interested in, or the global list if no specific node type
367 * settings have been configures.
368 *
369 * @param $type - A node type, if Entities need to be filtered.
370 *
371 * @return Associative array of [entity_name => vid]'s
372 */
373 function calais_get_entity_vocabularies($type = NULL) {
374 $all_vocabs = variable_get('calais_vocabulary_names', false);
375
376 $applied_entities = array();
377 if ($type) {
378 $applied_entities = variable_get('calais_applied_entities_global', false);
379 if (!variable_get("calais_use_global_{$type}", true)) {
380 $applied_entities = variable_get("calais_applied_entities_{$type}", false);
381 }
382 }
383
384 foreach ($applied_entities as $entity => $apply_entity) {
385 if (!$apply_entity) {
386 unset($all_vocabs[$entity]);
387 }
388 }
389
390 return $all_vocabs;
391 }
392
393 /**
394 * Returns the Calais vocabularies that are enabled for this node type.
395 * <p>Compare to: calais_api_get_all_entities() which gives entityname/vid pairs.
396 * Vocabulary names can be updated by users. Entity names stay as defined
397 * by Calais.
398 *
399 * @param $node_type The node type
400 *
401 * @return Array of vocabularies keyed on vid;
402 */
403 function calais_get_vocabularies($type = NULL) {
404
405 $vocs = calais_get_entity_vocabularies($type);
406 $pattern = implode(",", $vocs);
407
408 if ($type) {
409
410 $result = db_query("SELECT v.vid, v.*, n.type
411 FROM {vocabulary} v
412 LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid
413 WHERE n.type = '%s' and v.vid in (%s)
414 ORDER BY v.weight, v.name",
415 $type, $pattern);
416 }
417 else {
418 $result = db_query('SELECT v.*
419 FROM {vocabulary} v
420 WHERE v.vid in (%s)
421 ORDER BY v.weight, v.name',
422 $pattern);
423 }
424
425 $vocabularies = array();
426 $node_types = array();
427 while ($voc = db_fetch_object($result)) {
428
429 // If no node types are associated with a vocabulary, the LEFT JOIN will
430 // return a NULL value for type.
431 if (isset($voc->type)) {
432 $node_types[$voc->vid][$voc->type] = $voc->type;
433 unset($voc->type);
434 $voc->nodes = $node_types[$voc->vid];
435 }
436 elseif (!isset($voc->nodes)) {
437 $voc->nodes = array();
438 }
439 $vocabularies[$voc->vid] = $voc;
440 }
441
442 return $vocabularies;
443 }
444
445 /**
446 * Returns a map of suggested terms for a given vocabulary id. This will return
447 * sugested terms for all vocabularies if no vid is specified.
448 *
449 * @param $nid The node id to get the calais keywords
450 * @param $vid Optional, a specific vocabulary id to return terms
451 *
452 * @return Array { $vid => array('term1', 'term2', 'term3') }
453 */
454 function calais_get_keywords($nid, $vid = null) {
455 $terms = array();
456
457 if ($vid) {
458 $res = db_query(" SELECT name
459 FROM {calais_term} t
460 JOIN {calais_term_node} tn ON tn.tid=t.tid
461 WHERE tn.nid=%d and t.vid=%d
462 ORDER BY name asc ", $nid, $vid);
463
464 $terms[$vid] = array();
465 while ($obj = db_fetch_object($res)) {
466 $terms[$vid][] = $obj->name;
467 }
468 }
469 else {
470 $vocabularies = calais_get_entity_vocabularies();
471 foreach ($vocabularies as $vid) {
472 $keys = calais_get_keywords($nid, $vid = null);
473 $terms[$vid] = $keys[$vid];
474 }
475 }
476
477 return $terms;
478 }
479
480 /**
481 * Creates a new vocabulary for the supplied Calais entity name.
482 */
483 function calais_create_entity_vocabulary($entity) {
484 $description = t("Calais Entity Vocabulary: @name", array('@name' => $entity));
485 db_query("INSERT INTO {vocabulary} (name,description,module,tags) values('%s','%s','taxonomy',1)",
486 $entity, $description);
487 return db_last_insert_id('vocabulary', 'vid');
488 }
489
490
491 function ____debug($array, $exit = true) {
492 echo "<pre>". print_r($array, true) ."</pre>";
493
494 if ($exit)
495 exit(0);
496 }
497

  ViewVC Help
Powered by ViewVC 1.1.2