Project

General

Profile

Download (9.71 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
define ("CSV_FILE_EXTENSION", ".txt");
4
// at the moment we are using a static meta.xml file
5
define ("METADATA_FILE", "meta.xml");
6

    
7
define ("ARCHIVE_ROOT_DIR", "dwca_export/");
8

    
9
function _get_static_file_map(){
10
	$static_file_map = array(
11
		'classification' => array(
12
			'view_name'=> 'dwca_export_classification',
13
			'display_id' => 'views_data_export_1',
14
			'out_file_url' => NULL
15
		),
16
		'typesandspecimen' => array(
17
			'view_name'=> 'view_test_specimen_export',
18
			'display_id' => 'views_data_export_1',
19
			'out_file_url' => NULL
20
		)
21
	);
22
	return $static_file_map;
23
}
24

    
25

    
26
/**
27
 * Implements hook_menu().
28
 */
29
function dwca_export_menu() {
30

    
31
	$items = array();
32

    
33
	$items['admin/config/system/dwca_export'] = array(
34
		'title' => 'Darwin Core Archive export',
35
		'description' => t('Create a DarwinCore Archive of this scratchpad.'),
36
		'page callback' => 'drupal_get_form',
37
		'page arguments' => array('dwca_export_config_form'),
38
		'access arguments' => array('access DwC-A export settings'),
39
		'type' => MENU_NORMAL_ITEM,
40
		//'file' => 'dwca_export.admin.inc'
41
	);
42

    
43

    
44
	$items['dwca_export'] = array(
45
		'page callback' => 'dwca_export_deliver_archive',
46
		'access arguments' => array('access content'),
47
		'type' => MENU_CALLBACK
48
	);
49

    
50

    
51
	return $items;
52
}
53

    
54
/**
55
 * Implementation of hook_views_api()
56
 *
57
 * drupal will load dwca_export.views_default.inc when this hook is implemented
58
 */
59
function dwca_export_views_api() {
60
	return array(
61
		'api' => 3.0
62
	);
63
}
64

    
65
/**
66
 * Form function, called by drupal_get_form()
67
 * in dwca_export_menu().
68
 */
69
function dwca_export_config_form($form, &$form_state) {
70

    
71
	global $base_url;
72

    
73
	$form['dwca_export_info'] = array(
74
		'#markup' => '<p>For general information on the DarwinCore Archive format please refer to  '
75
		. l('GBIF - Standards and Tools - Darwin Core Archives', 'http://www.gbif.org/informatics/standards-and-tools/publishing-data/data-standards/darwin-core-archives/')
76
		.'</p>'
77
	);
78

    
79
	$form['dwca_export_execute'] = array(
80
		'#markup' => '<p>The DarwinCore Archive export is available at '. l('dwca_export', 'dwca_export').'</p>'
81
		//'#type' => 'button',
82
		//'#value' => t('Export Scratchpad to DarwinCore Archive'), 
83
	  //'#weight' => 19,
84
	);
85
	
86
	$form['dwca_export_view_mapping'] = dwca_export_select_view_form();
87
	
88
	
89

    
90
	$form['#submit'][] = 'dwca_export_config_form_submit';
91
	return system_settings_form($form);
92

    
93
}
94

    
95

    
96
function dwca_export_select_view_form() {
97

    
98
	$views = array(
99
    		'#type' => 'fieldset',
100
    		'#title' => t('View to file mapping'),
101
    		//'#tree' => TRUE,
102
  	);
103

    
104
	//$default_value = _dwca_export_archive_descriptor_file_map();
105

    
106
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename => $view_data){
107
		
108
		
109
		$views[$dwca_filename . '_view'] = array(
110
	  	'#type' => 'textfield',
111
	  	'#title' => t($dwca_filename),
112
	  	'#default_value' => $view_data['view_name'],
113
	  	'#size' => 60,
114
	  	'#maxlength' => 64,
115
	  	'#description' => t('specify view for ' . $dwca_filename . CSV_FILE_EXTENSION),
116
		);
117
	}
118

    
119
	return $views;
120
}
121

    
122
function dwca_export_config_form_submit($form, &$form_state) {  
123

    
124
// 	db_query("INSERT INTO {table} (classification_view) VALUES ('%s')", $form_state['values']['classification_view']);  
125
//variable_set($name, $value)
126
	drupal_set_message(t('Your config form has been saved.'));
127

    
128
//throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
129
}
130

    
131

    
132
/**
133
 * menu callback
134
 */
135
function dwca_export_deliver_archive() {
136

    
137
	$tmp_archive_file_name = dwca_export_create_archive( _dwca_export_archive_descriptor_file_map() );
138

    
139
	if($tmp_archive_file_name && file_valid_uri($tmp_archive_file_name)){
140
		file_transfer($tmp_archive_file_name, array('Content-Type' => 'application/zip'));
141
	} else {
142
		throw new Exception(t('Error creating the archive'));
143
	}
144
}
145

    
146

    
147
/**
148
 * Provides the archive_descriptor_file_map which maps dwca file name to a set of view information.
149
 * The view information contains the fields 'view_name', 'display_id', 'out_file_url'.
150
 * The 'out_file_url' is initailly empty and will be set when this function is called
151
 * with both parameters.
152
 *
153
 * @param String $file_name
154
 * @param String $out_file_url
155
 *
156
 * @return the archive_descriptor_file_map
157
 */
158
function _dwca_export_archive_descriptor_file_map($file_name = NULL, $out_file_url = null){
159
	static $file_map;
160

    
161
	if(!isset($file_map)){
162
		//TODO load from variables, consider using strongarm
163
		// current implementation uses a static filemap
164
		$file_map = _get_static_file_map();
165
	}
166

    
167
	if($file_name && $out_file_url){
168
		$file_map[$file_name]['out_file_url'] = $out_file_url;
169
	}
170

    
171
	return $file_map;
172
}
173

    
174

    
175
/**
176
 * Walks all view export paths defined in the $views_map.
177
 * Each file is downloaded to the tmp folder and a zip file
178
 * is bundeled of the resulting csv files plus the meta file.
179
 *
180
 * @param $views_map - maps a view paths to dwca filenames
181
 *
182
 * @return the path in the filesystem to the final archive,
183
 * or FALSE in case of an error.
184
 */
185
function dwca_export_create_archive($views_map) {
186

    
187
	global $base_url;
188

    
189
	// execute all views to export the data into
190
	// temporary csv files (temporary://dwca_export_*). the resulting filenames
191
	// will be stored in _dwca_export_archive_descriptor_file_map()
192
	foreach($views_map as $filename=>$view_data){
193

    
194
		$view = views_get_view($view_data['view_name']);
195
		$options = array (
196
		    'output_file' => $filename
197
		);
198
		_dwca_export_views_data_export_override_batch($view, $view_data['display_id'], $options);
199
		$view->execute_display($view_data['display_id']);
200

    
201
	}
202

    
203
	// all data is exported to temporary://dwca_export_*
204
	// now we can start bundling the actual archive
205
	$tmp_archive_file_name = drupal_tempnam("temporary://", "dwca_export_archive_");
206

    
207
	// Unfortunately we cannot use drupals ArchiverZip because there ís
208
	// no way to pass in ZipArchive::CREATE to the constructor to create the archive
209
	// TODO test if zip functionality is available (i.e. if(function_exists('zip_open'))
210
	// but I don't know where the proper location for such a check would be
211
	$zip = new ZipArchive();
212
	// it is safe to use drupal_realpath as the tmp file will be certainly local
213
	// and php's ZipArchive does not handle stream URIs
214
	$result = $zip->open(drupal_realpath($tmp_archive_file_name), ZipArchive::CREATE);
215

    
216
	// there might be a better way to get at this information
217
	$module_static_dir_absolute = realpath(drupal_get_path('module', 'dwca_export')) . "/static/";
218

    
219
	if ($result !== TRUE) {
220
		throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
221
	}
222

    
223
	
224
	// add metadata
225
	$zip->addFile($module_static_dir_absolute.$metadata, ARCHIVE_ROOT_DIR.METADATA_FILE);
226
	// add the csv data files
227
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename=>$view_data){
228

    
229
		$view_temp_file = $view_data['out_file_url'];
230
		if($view_temp_file){
231
			$zip->addFile(drupal_realpath($view_temp_file), ARCHIVE_ROOT_DIR.$dwca_filename.CSV_FILE_EXTENSION);
232
		}else{
233
			throw new Exception(t('Cannot create %file', array('%file' => $dwca_filename.CSV_FILE_EXTENSION)));
234
		}
235
	}
236

    
237
	$zip->close();
238

    
239
	return $tmp_archive_file_name;
240
}
241

    
242
/**
243
 * Helper function that indicates that we want to
244
 * override the batch that the views_data_export view creates
245
 * on it's initial time through.
246
 *
247
 * Also provides a place to stash options that need to stay around
248
 * until the end of the batch
249
 *
250
 * adapted fom views_data_export.drush.inc
251
 */
252
function _dwca_export_views_data_export_override_batch($view = NULL, $display = NULL, $options = TRUE) {
253
	static $_views;
254
	if (isset($view)) {
255
		$_views[$view->name][$display] = $options;
256
	}
257
	return $_views;
258
}
259

    
260

    
261
/**
262
 * Implementation of hook_views_data_export_batch_alter()
263
 *
264
 * adapted fom views_data_export.drush.inc
265
 *
266
 *  @see batch_process() in form.inc
267
 */
268
function dwca_export_views_data_export_batch_alter(&$batch, &$final_destination, &$querystring) {
269

    
270
	$view_name = $batch['view_name'];
271
	$display_id = $batch['display_id'];
272

    
273
	$ok_to_override = _dwca_export_views_data_export_override_batch();
274

    
275
	// Make sure we do nothing if we are called not following the execution of
276
	// our drush command. This could happen if the file with this function in it
277
	// is included during the normal execution of the view
278
	if (!$ok_to_override[$view_name][$display_id]) {
279
		return;
280
	}
281

    
282
	$options = $ok_to_override[$view_name][$display_id];
283

    
284
	// We actually never return from the drupal_alter, but
285
	// use drush's batch system to run the same batch
286

    
287
	// Add a final callback
288
	$batch['operations'][] = array(
289
	    '_dwca_export_views_data_export_batch_finished', array($batch['eid'], $options['output_file']),
290
	);
291

    
292
	$batch['progressive'] = FALSE;
293
}
294

    
295
/**
296
* Implementation of hook_views_data_export_batch_alter()
297
*
298
* @see batch_process() in form.inc
299
*/
300
function dwca_export_batch_alter(&$batch, &$final_destination, &$querystring) {
301
	if($batch['source_url'] == 'dwca_export'){
302
		$batch['progressive'] = FALSE;
303
	}
304
}
305

    
306

    
307

    
308
/**
309
* Get's called at the end of the drush batch process that generated our export
310
*
311
* adapted fom views_data_export.drush.inc
312
*/
313
function _dwca_export_views_data_export_batch_finished($eid, $output_file, &$context) {
314
	// Fetch export info
315
	$export = views_data_export_get($eid);
316

    
317
	// Perform cleanup
318
	$view = views_data_export_view_retrieve($eid);
319
	$view->set_display($export->view_display_id);
320
	$view->display_handler->batched_execution_state = $export;
321
	$view->display_handler->remove_index();
322

    
323
	// Get path to temp file
324
	$temp_file = $view->display_handler->outputfile_path();
325

    
326
	_dwca_export_archive_descriptor_file_map($output_file, $temp_file);
327

    
328
}
(3-3/4)