/[drupal]/contributions/modules/marc/marc.module
ViewVC logotype

Contents of /contributions/modules/marc/marc.module

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


Revision 1.3 - (show annotations) (download) (as text)
Fri Jun 13 01:48:07 2008 UTC (17 months, 2 weeks ago) by aaustin
Branch: MAIN
CVS Tags: DRUPAL-6--1-0, DRUPAL-6--1-1, DRUPAL-6--1-2, HEAD
Changes since 1.2: +1032 -1014 lines
File MIME type: text/x-php
Drupal 6 Update
1 <?php
2 // $Id: marc.module
3
4 /**
5 * @file
6 * Enables the creation and upload of library item holdings
7 */
8
9
10 function marc_menu() {
11
12 $items = array();
13
14 $items['admin/content/marc'] = array(
15 'title' => 'Marc Import',
16 'description' => 'Import MARC Records.',
17 'page callback' => 'drupal_get_form',
18 'page arguments' => array('marc_import_form'),
19 'access callback' => 'user_access',
20 'access arguments' => array('import marc records'),
21 'type' => MENU_NORMAL_ITEM,
22 );
23 $items['admin/settings/marc'] = array(
24 'title' => 'MARC Settings',
25 'description' => 'Configure MARC general settings',
26 'weight' => -10,
27 'page callback' => 'drupal_get_form',
28 'page arguments' => array('marc_admin_settings'),
29 'access callback' => 'user_access',
30 'access arguments' => array('administer marc imports'),
31 'type' => MENU_NORMAL_ITEM,
32 );
33
34 $items['node/%node/marc'] = array(
35 'title' => 'MARC',
36 'page callback' => 'marc_view_record',
37 'page arguments' => array(1),
38 'access callback' => 'marc_access',
39 'access arguments' => array(1),
40 'weight' => 2,
41 'type' => MENU_LOCAL_TASK,
42 );
43
44 return $items;
45 }
46
47 function marc_access($node){
48 if (marc_is_record($node) && user_access('view marc')){
49 return TRUE;
50 }
51 else {
52 return FALSE;
53 }
54 }
55
56 /**
57 * Implementation of hook_perm
58 */
59 function marc_perm() {
60 return array('administer marc imports', 'import marc records', 'view marc');
61 }
62
63 function marc_cron() {
64 $marc_limit = variable_get('marc_import_limit', 100);
65 marc_import_records($marc_limit);
66 }
67
68 //We need the marc_mid field on the node form, so we can set the value using drupal_execute
69
70 function marc_form_alter(&$form, $form_state, $form_id) {
71 $node_types = marc_import_nodes();
72 foreach ($node_types as $node_type) {
73 if ($form_id == $node_type .'_node_form') {
74 $form['marc_id'] = array(
75 '#type' => 'hidden',
76 '#default_value' => 0,
77 );
78 }
79 }
80 }
81
82 /**
83 * Define the settings form.
84 */
85 function marc_admin_settings() {
86
87 if (module_exists('content')){
88 $message = t('To map your MARC records to more than the title and author field,
89 visit the '. l(t('Content types'), 'admin/content/types').' page and select the
90 content type that you will be importing MARC records to and then select the MARC tab.');
91 }
92 else {
93 $message = t('By default, you can import MARC records in to the title, body fields and taxonomy fields
94 of your content.');
95 }
96
97 $form['marc_file_directory_path'] = array(
98 '#type' => 'textfield',
99 '#title' => t('Path to your MARC files'),
100 '#description' => t('If blank, it will use your default files directory path.'),
101 '#default_value' => variable_get('marc_file_directory_path', file_directory_path()),
102 );
103
104 $form['marc_file_extensions'] = array(
105 '#type' => 'textfield',
106 '#title' => t('Valid MARC file extensions'),
107 '#description' => t('Separate extensions with a single space.'),
108 '#default_value' => variable_get('marc_file_extensions', 'mrc mrk 001'),
109 );
110
111 $form['marc_import_limit'] = array(
112 '#type' => 'textfield',
113 '#title' => t('Records to import per cron run'),
114 '#description' => t('Maximum number of nodes to create from MARC records per cron run.'),
115 '#default_value' => variable_get('marc_import_limit', '50'),
116 );
117
118 $form['marc_index_all'] = array(
119 '#type' => 'checkbox',
120 '#title' => t('Index Full MARC Record'),
121 '#description' => t('Should the full MARC record be included in Drupal\'s interal search index.'),
122 '#default_value' => variable_get('marc_index_all', FALSE),
123 );
124
125 $form['marc_load_record'] = array(
126 '#type' => 'checkbox',
127 '#title' => t('Load Full MARC Record'),
128 '#description' => t('Should the full MARC record be available when the node is loaded to view.'),
129 '#default_value' => variable_get('marc_load_record', FALSE),
130 );
131 $form['mapping'] = array(
132 '#type' => 'fieldset',
133 '#title' => t('Mapping'),
134 );
135 $options = marc_field_choices();
136 $form['mapping']['marc_default_title'] = array(
137 '#prefix' => '<p>'. $message .'</p>',
138 '#type' => 'select',
139 '#title' => t('Default Title Mapping'),
140 '#description' => t('This is the MARC field that will be imported by default, you can override this
141 in the individual content type MARC administration form'),
142 '#options' => $options,
143 '#default_value' => variable_get('marc_default_title', '245|a'),
144 );
145 $form['mapping']['marc_default_body'] = array(
146 '#type' => 'select',
147 '#title' => t('Default Body Mapping'),
148 '#description' => t('This is the MARC field that will be imported by default, you can override this
149 in the individual content type MARC administration form'),
150 '#options' => $options,
151 '#default_value' => variable_get('marc_default_body', '520|a'),
152 );
153 $form['advanced mapping'] = array(
154 '#type' => 'fieldset',
155 '#collapsible' => TRUE,
156 '#collapsed' => TRUE,
157 '#title' => t('Advanced Mapping Options'),
158 );
159
160 $form['advanced mapping']['mapping_note'] = array(
161 '#title' => t('Advanced Mapping Option'),
162 '#value' => t('<div>To have a more control over your marc mappings, you can add a function to a local module
163 <br />function yourmodule_marc_mapping_alter($mapping){ <br />
164 $mapping[\'yourcontenttype\'][\'values\'][\'field_isbn\'][0][\'value\'] = \'020|a\';<br />
165 $mapping[\'yourcontenttype\'][\'values\'][\'field_format\'][0][\'value\'] = \'format\';<br />
166 return $mapping;<br />
167 }</div>'),
168 );
169 $vocabularies = taxonomy_get_vocabularies();
170 foreach($vocabularies as $vid => $voc){
171 //This could be fixed so that you could map all vocabulary types
172 if ($voc->tags){
173 $form['mapping']['marc_default_vocabulary_'.$vid] = array(
174 '#type' => 'select',
175 '#title' => t('Default @vocabulary Mapping', array('@vocabulary' => $voc->name)),
176 '#description' => t('This is the MARC field that will be imported by default, you can override this in the
177 individual content type MARC administration form'),
178 '#options' => $options,
179 '#default_value' => variable_get('marc_default_vocabulary_'.$vid, null),
180 );
181 }
182 }
183
184 return system_settings_form($form);
185 }
186
187 /*
188 * Implementation of nodeapi
189 *
190 *
191 */
192
193 function marc_nodeapi(&$node, $op, $arg = 0) {
194 //Let's freeze this to manifestations for now.
195 switch ($op) {
196 case 'load':
197 if (variable_get('marc_load_record', FALSE)){
198 if (marc_is_record($node)){
199 $node->marc = marc_from_node($node);
200 }
201 }
202 break;
203
204 //case 'presave':
205 //marc_check_change($node);
206 //Someday we will have a MARC editor that operates separately from the marc edit form
207 //break;
208
209 case 'insert':
210 $node->marc = marc_from_node($node);
211 if ($node->marc['record']){
212 $marc->mid = $node->marc['mid'];
213 $marc->nid = $node->nid;
214 $marc->changed = time();
215 drupal_set_message('Trying to write marc record');
216 drupal_write_record('marc_records', $marc, 'mid');
217 }
218 break;
219
220 case 'delete':
221 db_query("DELETE FROM {marc_records} WHERE nid = %d", $node->nid);
222 break;
223
224 case 'update index':
225 if (variable_get('marc_index_all', FALSE) && $node->marc['mid']) {
226 $marc = marc_from_node($node);
227 foreach ($marc['record'] AS $field) {
228 if (is_array($field)) {
229 foreach ($field AS $iteration) {
230 if (is_array($iteration)) {
231 foreach ($iteration AS $subfields => $subfield_data) {
232 if ($subfield != 'i1' AND $subfield != 'i2') {
233 $marc_data .= $subfield_data .' ';
234 }
235 }
236 }
237 }
238 }
239 }
240 }
241 return $marc_data;
242 break;
243
244 }
245 }
246
247 function marc_is_record($node){
248 if ($node->nid){
249 $mid = db_result(db_query("SELECT mid FROM {marc_records} WHERE nid = %d", $node->nid));
250 if ($mid){
251 return TRUE;
252 }
253 }
254 }
255
256 function marc_view_record($node) {
257 if (!$node->marc['record']){
258 $node->marc = marc_from_node($node);
259 }
260 $fields = $node->marc['record'];
261 drupal_set_title($fields['245'][0]['a']);
262 if ($fields['leader']){
263 $row[] = array('leader', null, null, $fields['leader']);
264 }
265 if ($fields['007']){
266 $row[] = array('007', null, null, $fields['007']);
267 }
268 if ($fields['008']){
269 $row[] = array('008', null, null, $fields['008']);
270 }
271 foreach ($fields AS $field => $iterations) {
272 if (is_array($iterations)) {
273 foreach ($iterations AS $iteration => $subfield_data) {
274
275 if (is_array($subfield_data)) {
276 $i1 = $subfield_data[1];
277 $i2 = $subfield_data[2];
278 $subfields = array_slice($subfield_data, 2);
279 foreach ($subfields AS $subfield => $value) {
280 $row[] = array($field, $i1 . $i2, $subfield, check_plain($value));
281 }
282 }
283 }
284 }
285 }
286 if (count($row) > 0){
287 $header = array('Field', ' ', 'Subfield', 'Value');
288 }
289 else {
290 drupal_set_message(t('No MARC record found'));
291 }
292
293 //This needs a real theme function at some point
294 $output = theme('table', $header, $row);
295 return $output;
296 }
297
298 /**
299 *
300 * Marc import
301 *
302 * Form function to set parameters for uploading marc fields.
303 *
304 * @param $filename name of file to be imported,
305 * if null, it appears as form selection.
306 *
307 * @return form ultimately returns a page with success message and the number of rows imported.
308 *
309 */
310
311 function marc_import_form($filename = null) {
312
313 $file_options = marc_import_files();
314 if (!is_array($file_options)){
315 drupal_set_message(t('You do not have any valid files available, see the !link for more information.', array('!link' => l(t('MARC Settings'), 'admin/settings/marc') )));
316 }
317
318 //form_field checkboxes, choices built by marc_import_files
319 $form['marc_file'] = array(
320 '#type' => 'radios',
321 '#title' => t('MARC file name'),
322 '#options' => $file_options,
323 '#description' => t('Choose the file to import'),
324 '#required' => TRUE,
325 );
326
327 $form['content_type'] = array(
328 '#type' => 'radios',
329 '#title' => t('Content type'),
330 '#options' => marc_import_nodes(),
331 '#description' => t('Choose your content type to create'),
332 '#required' => TRUE,
333 );
334
335 $form['nid'] = array(
336 '#type' => 'hidden',
337 '#default_value' => 1,
338 );
339
340 $form['records'] = array(
341 '#type' => 'hidden',
342 '#value' => 0,
343 );
344
345 $form['submit'] = array(
346 '#value' => t('Import Records'),
347 '#type' => 'submit',
348 );
349
350 return $form;
351 }
352
353 /*
354 * Build array of potential files to be imported.
355 */
356
357 function marc_import_files() {
358 $directory = variable_get('marc_file_directory_path', file_directory_path());
359 $extensions = explode(' ', variable_get('marc_file_extensions', 'mrc mrk 001'));
360 $regex = array();
361 foreach ($extensions as $extension) {
362 $regex[] = '\.'. $extension .'$';
363 }
364 $mask = implode('|', $regex);
365 $files = drupal_system_listing($mask, $directory , 'marc', 0);
366
367 //drupal_system_listing returns an array of objects (filename, basename and name)
368 foreach ($files as $file) {
369 $key = $file->filename;
370 $value = $file->basename;
371 $fileoptions[$key] = $value;
372 }
373
374 return $fileoptions;//array of files in specified directory of marc records.
375 }
376
377 /*
378 * Build array of potential nodetypes, based on what content types the user can create.
379 */
380
381 function marc_import_nodes() {
382
383 //$result = db_query("SELECT content_type FROM {marc_content_type_mapping}");
384 $types = node_get_types();
385 $valid_types = array();
386 foreach(array_keys($types) as $type) {
387 if (user_access(t('create @type content', array('@type', $type)))) {
388 $valid_types[$type] = $type;
389 }
390 }
391 return $valid_types;
392 }
393
394 /*
395 * The actual file import starts when the form is submitted
396 */
397
398 function marc_import_form_submit($form, $form_state){
399 //Drupal 5.x thing
400 $form_values = $form_state['values'];
401 $content_type = $form_values['content_type'];
402
403 $import->timestamp = time();
404 $import->filename = $form_values['marc_file'];
405 $import->nid = $form_values['nid'];
406 $import->content_type = $content_type;
407 $import->records = $count;
408 drupal_write_record('marc_import', $import);
409 $iid = db_last_insert_id('marc_import', 'miid');
410
411 $count = marc_import_file($form_values['marc_file'], $content_type, $iid);
412 drupal_set_message(t('@count records have been added to the queue and will be added incrementally by each !cron run.', array('@count' => $count, '!cron' => l('cron', 'cron.php'))));
413 }
414
415 /*
416 * This is now a separate function so we can call it from elsewhere,
417 * like a node submission from something like a content type dedicated
418 * to form uploads -- which will be very powerful. Think metadata + workflow
419 */
420
421 function marc_import_file($filename, $content_type = null, $iid){
422 $marc_records = file_get_contents($filename);
423
424
425 //break marc file in to records
426 //http://www.loc.gov/marc/specifications/specrecstruc.html
427 //MARC record terminator is 1D(hex) or Decimal 29, Oct 035, Character GS
428 $marc_records = explode(chr(29), $marc_records);
429
430 // Add individual records to rows in the database
431 $count = 0;
432 foreach ($marc_records as $marc_record) {
433 if (strlen($marc_record) > 12) {
434 //Drupal 5.x
435 //$ = db_next_id('{marc_records}_id');
436 //db_query("INSERT INTO {marc_records} (``, `nid`, `content_type`, `iid`, `status`, `record`) VALUES (%d, '0', '%s', %d, 0, '%s');", $mrid, $content_type, $iid, $marc_record);
437 //Drupal 6.x
438 $record->nid = 0;
439 $record->content_type = $content_type;
440 $record->iid = $iid;
441 $record->record = $marc_record;
442 drupal_write_record('marc_records', $record);
443 $record = null;
444 $count++;
445 }
446 }
447
448 $import->records = $count;
449 $import->miid = $iid;
450 drupal_write_record('marc_import', $import, 'miid');
451 return $count;
452
453 }
454
455 function marc_fields($marc_record = null) {
456
457 // Just want to get marc fields out of MARC format and in to an usable array
458 // http://www.loc.gov/marc/specifications/specrecstruc.html
459
460 // Split record in to fields
461
462 // field terminator
463 // FT 1E(hex), 30(Dec), 036(Oct), RS(Char)
464
465
466 // Create array by exploding the marc records
467 $marc_field_values = explode(chr(30), $marc_record);
468
469 // Now this is harder, we need to break the leader from the directory
470 $start_length = strlen($marc_field_values[0]);
471 $leader = substr($marc_field_values[0], 0, 23);
472 $directory = substr($marc_field_values[0], 24, $start_length);
473 $marc_field_values[0] = $leader;
474
475 // Get the field numbers from the directory
476 // $directoryfields contaings the fieldname, start position and length
477 // that will get taken care of in a second
478 $directory_fields = str_split($directory, 12);
479
480 //Start building marcfields array
481
482 //First we set the leader and take the leader value out of the values
483 $marc_fields['leader'] = $leader;
484 array_splice($marc_field_values, 0, 1);
485
486 //Then we loop through the directory fields and build array
487 foreach ($directory_fields AS $key => $directory_field) {
488
489 //The marc field number is just the first 3 characters
490 $field_number = substr($directory_field, 0, 3);
491 //The field value is the correpsonding value in the marcfieldvalues array.
492 $field_value = $marc_field_values[$key];
493
494 //We need to keep track of the field iterations
495 if ($marc_field_count[$field_number]) {
496 $marc_field_count[$field_number]++;
497 }
498 else{
499 $marc_field_count[$field_number] = 0;
500 }
501 $field_count = $marc_field_count[$field_number];
502
503 if (substr($directory_field, 0, 2) == '00') {
504
505 // Populate Control fields
506 // Technically control fields can be repeated, not that I ever see it.
507 $marc_fields[$field_number][$field_count] = $field_value;
508 }
509 else {
510 //Populate Indicators
511 //$marc_fields[$field_number][$field_count]['field'] = $field_value;
512 $marc_fields[$field_number][$field_count]['i1'] = substr($field_value, 0, 1);
513 $marc_fields[$field_number][$field_count]['i2'] = substr($field_value, 1, 1);
514
515 //Start work on subfields
516 // US (char) 31(dec) 1F 037 - character used to seperate subfields
517 $subfields = explode(chr(31), $marc_field_values[$key]);
518
519 //Get rid of indicators
520 array_splice($subfields, 0, 1);
521
522 //$output .= $subfields[0]. '<br>';
523
524 //Insert subfields in database
525 foreach ($subfields as $subfield) {
526 $subfield_code = substr($subfield, 0, 1);
527 $subfield_value = substr($subfield, 1, (strlen($subfield)-1));
528 $marc_fields[$field_number][$field_count][$subfield_code] = $subfield_value;
529 }
530 }
531 }
532 return $marc_fields;
533 }
534
535
536 /**
537 *
538 * MARC import records
539 *
540 * Gets mapping and loops through desired records.
541 *
542 * @param $content_type, the Drupal node type.
543 * $records, an array of marc record ids to be imported
544 *
545 * @return
546 *
547 */
548
549 function marc_import_records($record_limit) {
550
551 //This could take a while.
552 set_time_limit($record_limit);
553
554 $result = db_query("SELECT * FROM {marc_records} WHERE nid = %d LIMIT %d", 0, $record_limit);
555 $content_type = 'manifestation';
556 $mapping = marc_mapping($marc->content_type);
557 $count = 0;
558 while ($marc_record = db_fetch_object($result)) {
559 if ($content_type != $marc_record->content_type) {
560 $content_type = $marc_record->content_type;
561 $mapping = marc_mapping($content_type);
562 }
563 //$marc['mid'] = $marc_record->mid;
564 $marc = array('mid' => $marc_record->mid);
565 $marc = marc_get_marc($marc);
566 marc_execute_node($content_type, $marc, $mapping);
567 $count++;
568 }
569 return $count;
570 }
571
572 /**
573 *
574 * MARC execute node
575 *
576 * Function uses drupal_execute to submit MARC data as Drupal node
577 *
578 * @param $content_type, the Drupal node type.
579 * $marc, the MARC data to be insterted
580 *
581 */
582
583 function marc_execute_node($content_type, $marc, $mapping = null) {
584 module_load_include('inc', 'node', 'node.pages');
585 //We should have on the admin settings page, a default import user - Thomas Dewey, NYS Govn'r
586 $user->name = 'aaustin';
587
588 $form_id = $content_type .'_node_form';
589
590 //Maybe we won't always call this from marc_import_records?
591 if (!$mapping) {
592 $mapping = marc_mapping($content_type);
593 }
594 $mapping_values = $mapping[$content_type]['values'];
595
596 $node = array('type' => $content_type, 'name' => $user->name, 'uid' => $user->uid);
597 $node['marc_id'] = $marc['mid'];
598 $node['marc'] = $marc;
599
600 drupal_alter('marc_execute', $node);
601 if (!$node['title']){
602 $node['title'] = t('Book');
603 }
604 $record = $node['marc']['record'];
605 $form_values['nid'] = $node['nid'];
606 $form_values = array();
607 foreach($mapping_values as $k1 => $v1){
608 if (!is_array($v1)){
609 //$form_state['values'][$k1] = marc_field($v1);
610 $keys = array($k1);
611 //$form_values = array_merge($form_values, marc_form_field($keys, $v1, $marc));
612 marc_form_field($form_values, $keys, $v1, $record);
613 }
614 else{
615 foreach($v1 as $k2 => $v2){
616 if (!is_array($v2)){
617 //$form_state['values'][$k1][$k2] = marc_field($v2);
618 $keys = array($k1, $k2);
619 //$form_values = array_merge($form_values, marc_form_field($keys, $v2, $marc));
620 marc_form_field($form_values, $keys, $v2, $record);
621 }
622 foreach($v2 as $k3 => $v3){
623 if (!is_array($v3)){
624 $keys = array($k1, $k2, $k3);
625 //$form_values = array_merge($form_values, marc_form_field($keys, $v3, $marc));
626 marc_form_field($form_values, $keys, $v3, $record);
627 }
628 else {
629 //Need to set an error message if it goes this far?
630 }
631 }
632 }
633 }
634 }
635 $form_values['marc_id'] = $node['marc_id'];
636 $form_values['marc'] = $node['marc'];
637 $form_state = array();
638 $form_state['values'] = $form_values;
639 if (!$node->name){
640 $user1 = user_load(1);
641 $form_state['values']['name'] = $user1->name;
642 }
643 else {
644 $form_state['values']['name'] = $node->name;
645 }
646 $form_state['values']['op'] = t('Save');
647
648 drupal_execute($content_type.'_node_form', $form_state, (object)$node);
649 }
650
651 // New plan = old plan
652 // For some reason I wanted to replicate the nested array structure of the form in the mapping.
653 // But for a number of reasons, i.e. we want this a 2 way street, simplicity, the ugliness of the below code
654 // I want to move back to the old way 'taxonomy-tag-2' but add some meta data to the array
655 // Is it cck, taxonomy, etc. but
656
657
658 function marc_form_field(&$form_values, $keys, $definition, $marc){
659
660 $marc_field = marc_field($definition, $marc);
661 $field = null;
662 $k1 = $keys[0];
663 $k2 = $keys[1];
664 $k3 = $keys[2];
665
666 // Is it a simple node field like title?
667 if (count($keys) == 1){
668 $form_values[$k1] = $marc_field[0];
669 }
670 // Maybe it is a CCK field?
671 elseif (is_numeric($keys[1])){
672 foreach($marc_field as $delta => $field){
673 $form_values[$k1][$delta][$k3] = $field;
674 }
675 }
676 // Could it be a free tagging taxonomy?
677 elseif ($k1 == 'taxonomy' && $k2 == 'tags'){
678 //$tags = array();
679 //foreach($marc_field as $delta => $field){
680 // $tags[] = '"'.$field.'"';
681 //}
682 //print_r($marc_field);
683 $form_values[$k1][$k2][$k3] = implode(',', $marc_field);
684 //drupal_set_message('Trying to set taxonomy '.$k3.'to '.$form_values[$k1][$k2][$k3] );
685 }
686 //Ok it could be something like ['body_field']['body']
687 elseif (count($keys) == 2) {
688 $form_values[$k1][$k2] = $marc_field[0];
689 }
690 //Nothing I know of goes this deep but who knows?
691 else {
692 $form_values[$k1][$k2][$k3] = $marc_field[0];
693 }
694 //drupal_set_message('$values['.$k1.']['.$k2.']['.$k3.'] = '.$marc_field[0]);
695 return $form_values;
696 }
697
698 function marc_field($def, $marc){
699 $mfd = marc_field_definitions();
700 if (isset($mfd[$def])){
701 $type = $mfd[$def]['#type'];
702 $definition = $mfd[$def]['#definition'];
703 }
704 // I have faith here that if $def is 5 chars long it is a marc field definition
705 elseif (strlen($def) == 5){
706 $type = $mfds[$def]['#type'];
707 $definition = $mfds[$def]['#definition'];
708 }
709 $values = array();
710 switch ($type){
711 case 'simple':
712 $definition_parts = explode('|', $definition);
713 $field = $definition_parts[0];
714 $subfield = $definition_parts[1];
715 $marcfield = $marc[$field];
716 $values = array();
717 if ($marcfield){
718 foreach ($marcfield as $i){
719 if ($i[$subfield]) {
720 $values[] = marc_clean_field($i[$subfield]);
721 }
722 }
723 }
724 break;
725
726 case 'callback':
727 $values = call_user_func($definition, $marc);
728 break;
729 }
730 return $values;
731 }
732
733 function marc_mapping($content_type = null){
734 if ($content_type){
735 $types = array($content_type);
736 }
737 else {
738 $types = array_keys(node_get_types());
739 }
740 $mapping = array();
741 foreach($types as $type){
742 //drupal_set_message('Test '.variable_get('marc_default_title', null));
743 $mapping[$type]['values']['title'] = variable_get('marc_default_title', null);
744 $mapping[$type]['values']['body'] = variable_get('marc_default_body', null);
745 $vocabularies = taxonomy_get_vocabularies();
746 foreach($vocabularies as $vid => $voc){
747 if ($voc->tags){
748 $mapping[$type]['values']['taxonomy']['tags'][$voc->vid] = variable_get('marc_default_vocabulary_'.$voc->vid, null);
749 }
750 }
751 }
752 drupal_alter('marc_mapping', $mapping);
753 return $mapping;
754 }
755
756 /**
757 *
758 * MARC field choices
759 *
760 * Gets available Marc field choices from database
761 *
762 */
763
764 function marc_field_choices() {
765 $fields = array();
766 $fields = marc_field_definitions();
767 $choices = array();
768 foreach ($fields As $key => $field) {
769 $id = $key;
770 $choices[$id] = $field['#title'] .'-'. $field['#description'];
771 }
772 return $choices;
773 }
774
775 /*
776 * MARC Field Definition functions
777 */
778
779 function marc_field_subject_all($marc) {
780 $fields = array(
781 '600',
782 '610',
783 '611',
784 '630',
785 '650',
786 '651',
787 '654',
788 '653',
789 '655',
790 '657',
791 '658',
792 '690',
793 '691',
794 '692',
795 '693',
796 '694',
797 '695',
798 '696',
799 '697',
800 '698',
801 '699',
802 );
803 return marc_field_separate_subfields($fields, $marc);
804 }
805
806 function marc_field_separate_subfields($fields = array(), $marc = array()) {
807 $data = array();
808 foreach ($fields as $field) {
809 $select_field = $marc[$field];
810 if ($select_field) {
811 foreach ($select_field as $field) {
812 $subfields = array_slice($field, 2);
813 $subfields['0'] = null;
814 foreach ($subfields as $subfield) {
815 $data[] = '"'. marc_clean_field($subfield) .'"';
816 }
817 }
818 }
819 }
820 return $data;
821 }
822
823 function marc_field_author_tags($marc = array()) {
824 $data = array();
825 $authors = array();
826 if ($marc['100']) {
827 $authors = array_merge($authors, $marc['100']);
828 }
829 if ($marc['110']) {
830 $authors = array_merge($authors, $marc['110']);
831 }
832 if ($marc['111']) {
833 $authors = array_merge($authors, $marc['111']);
834 }
835 if ($marc['700']) {
836 $authors = array_merge($authors, $marc['700']);
837 }
838 if ($marc['710']) {
839 $authors = array_merge($authors, $marc['710']);
840 }
841 if ($marc['711']) {
842 $authors = array_merge($authors, $marc['711']);
843 }
844 if ($marc['752']) {
845 $authors = array_merge($authors, $marc['752']);
846 }
847 if ($marc['753']) {
848 $authors = array_merge($authors, $marc['753']);
849 }
850 if ($marc['754']) {
851 $authors = array_merge($authors, $marc['754']);
852 }
853 if (is_array($authors)) {
854 foreach ($authors as $author) {
855 $data[] = '"'. marc_clean_field($author['a']) .'"';
856 }
857 }
858 return $data;
859 }
860
861 //Checks for weird random aacr2 character at end of field.
862 //This has been known to remove the period at the end of summaries...
863 function marc_clean_field($aacr2) {
864 $bad_chars = marc_aarc2_chars();
865 $clean_field = substr($aacr2, 0, (strlen($aacr2)-1)) . str_replace($bad_chars, "", substr($aacr2, -1, 1));
866 return $clean_field;
867 }
868
869 function marc_aarc2_chars(){
870 return array("/", ":", ".", ";", ",");
871 }
872
873 function marc_field_definitions(){
874 $field_definitions = array();
875 $field_definitions['020|a'] = array('#title' => t('020a'), '#description' => t('ISBN'), '#type' => 'simple', '#definition' => '020|a');
876 $field_definitions['245|a'] = array('#title' => t('245a'), '#description' => t('Title'), '#type' => 'simple', '#definition' => '245|a');
877 $field_definitions['245|b'] = array('#title' => t('245b'), '#description' => t('Remainder of title'), '#type' => 'simple', '#definition' => '245|b');
878 $field_definitions['300|a'] = array('#title' => t('300a'), '#description' => t('Accomanying material'), '#type' => 'simple', '#definition' => '300|a');
879 $field_definitions['300|b'] = array('#title' => t('300b'), '#description' => t('Other physical description'), '#type' => 'simple', '#definition' => '300|b');
880 $field_definitions['300|c'] = array('#title' => t('300c'), '#description' => t('Dimensions'), '#type' => 'simple', '#definition' => '300|c');
881 $field_definitions['300|e'] = array('#title' => t('300e'), '#description' => t('Accompanying material'), '#type' => 'simple', '#definition' => '300|e');
882 $field_definitions['490|a'] = array('#title' => t('490a'), '#description' => t('Series'), '#type' => 'simple', '#definition' => '490|a');
883 $field_definitions['520|a'] = array('#title' => t('520a'), '#description' => t('Summary'), '#type' => 'simple', '#definition' => '520|a');
884 $field_definitions['521|a'] = array('#title' => t('521a'), '#description' => t('Audience'), '#type' => 'simple', '#definition' => '521|a');
885 $field_definitions['852|p'] = array('#title' => t('852p'), '#description' => t('Barcode'), '#type' => 'simple', '#definition' => '852|p');
886 $field_definitions['author_tags'] = array('#title' => t('Author tags'), '#description' => t('Directory style'), '#type' => 'callback', '#definition' => 'marc_field_author_tags');
887 $field_definitions['subjects_all'] = array('#title' => t('Subjects (all)'), '#description' => t('All subject fields'), '#type' => 'callback', '#definition' => 'marc_field_subject_all');
888 $field_definitions['copyright_numeric'] = array('#title' => t('Copyright'), '#description' => t('Numeric publication date'), '#type' => 'callback', '#definition' => 'marc_field_copyright_number');
889 $field_definitions['call_number'] = array('#title' => t('Call number'), '#description' => t('Single line call number'), '#type' => 'callback', '#definition' => 'marc_field_call_numbers');
890 $field_definitions['format'] = array('#title' => t('Format'), '#description' => t('Format'), '#type' => 'callback', '#definition' => 'marc_get_format');
891 drupal_alter('marc_field_definitions', $field_definitions);
892 return $field_definitions;
893 }
894
895 function marc_stop_words($language = 'en'){
896 switch ($language){
897 case 'en':
898 $words = array(
899 'i', 'a', 'an', 'and', 'are', 'as', 'at', 'be',
900 'by', 'for', 'from', 'how', 'in', 'is', 'it',
901 'la', 'of', 'on', 'or', 'that', 'the', 'this',
902 'to', 'was', 'what', 'when', 'where', 'who',
903 'will', 'with',
904 );
905 break;
906 }
907 return $words;
908 }
909
910
911 function marc_get_format($marc){
912 $record_type = substr($marc['leader'], 6, 1);
913 $bibliographic_level = substr($marc['leader'], 7, 1);
914 $material_category = substr($marc['007'][0], 0, 1);
915 $material_designation = substr($marc['007'][0], 1, 1);
916 $video_format = substr($marc['007'][0], 4, 1);
917 switch ($record_type){
918 case 'r':
919 $format = 'artifact';
920 break;
921 case 'k':
922 $format = 'photo';
923 break;
924 case 'g':
925 $format = 'projected';
926 break;
927 case 'o':
928 case 'p':
929 $format = 'kit';
930 break;
931 case 'e':
932 case 'f':
933 $format = 'map';
934 break;
935 case 'm':
936 $format = 'file';
937 break;
938 case 'c':
939 case 'd':
940 $format = 'music';
941 break;
942 case 'a':
943 default:
944 if ($bibliographic_level == 's'){
945 $format = 'journal';
946 }
947 else {
948 $format = 'book';
949 }
950 }
951 if ($material_category == 'v'){
952 if ($video_format == 'v'){
953 $format = 'DVD';
954 }
955 else {
956 $format = 'VHS';
957 }
958 if ($material_category == 's'){
959 if ($material_designation == 's'){
960 $format = 'cassette';
961 }
962 elseif ($material_designation == 's'){
963 $format = 'CD';
964 }
965 }
966 }
967 return array($format);
968 }
969
970 function marc_check_change($node){
971 $marc_changed = db_result(db_query("SELECT changed FROM {marc_records} WHERE nid = %d", $node->nid));
972 if ($marc_changed > $node->changed){
973 $node->marc['update'] = 'marc';
974 }
975 else {
976 $node->marc['update'] = 'node';
977 }
978 }
979
980 function marc_from_node($node){
981 if ($node->marc['mid'] > 0){
982 $situation = 'Marc data already exists.';
983 $marc = marc_get_marc($node->marc);
984 }
985 elseif ($node->marc_id){
986 $marc['mid'] = $node->marc_id;
987 $marc = marc_get_marc($marc);
988 $situation = 'node->marc_mid exists.';
989 }
990 else {
991 $marc['mid'] = db_result(db_query("SELECT mid FROM {marc_records} WHERE nid = %d", $node->nid));
992 $marc = marc_get_marc($marc);
993 $situation = 'No marc data exists, trying to use nid.';
994 }
995 if (!is_array($marc['record'])){
996 drupal_set_message('Marc record did not load when '.$situation);
997 }
998 //print_r($marc);
999 return $marc;
1000 }
1001
1002 function marc_get_marc($marc){
1003 //Do we even need to load Marc Record?
1004 $leader = $marc['record']['leader'];
1005 if (!$leader){
1006 $result = db_query("SELECT record, status FROM {marc_records} WHERE mid = %d", $marc['mid']);
1007 while ($marc_result = db_fetch_object($result)){
1008 $record = $marc_result->record;
1009 $status = $marc_result->status;
1010 }
1011 if ($record && $status == 0){
1012 $marc['record'] = marc_fields($record);
1013 if ($marc['mid'] != 0){
1014 $marc_record->record = serialize($marc['record']);
1015 $marc_record->mid = $marc['mid'];
1016 $marc_record->status = 1;
1017 drupal_write_record('marc_records', $marc_record, 'mid');
1018 }
1019 }
1020 elseif($record && $status == 1){
1021 $marc['record'] = unserialize($record);
1022 }
1023 else {
1024 drupal_set_message('No record found for Marc mid: '.$marc['mid']);
1025 }
1026
1027 }
1028 else {
1029 //drupal_set_message('Tried to load record when it already existed.'.$leader);
1030 }
1031 return $marc;
1032 }

  ViewVC Help
Powered by ViewVC 1.1.2