Project

General

Profile

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

    
3
/**
4
 * Implements hook_menu().
5
 */
6
function dwca_export_menu() {
7

    
8
	$items = array();
9

    
10
	$items['admin/config/system/dwca_export'] = array(
11
		'title' => 'Darwin Core Archive export',
12
		'description' => t('Create a DarwinCore Archive of this scratchpad.'),
13
		'page callback' => 'drupal_get_form',
14
		'page arguments' => array('dwca_export_config_form'),
15
		'access arguments' => array('access DwC-A export settings'),
16
		'type' => MENU_NORMAL_ITEM,
17
		//'file' => 'dwca_export.admin.inc'
18
	);
19

    
20
	$items['dwca_export'] = array(
21
		'page callback' => 'dwca_export_deliver_archive',
22
		'access arguments' => array('access content'),
23
		'type' => MENU_CALLBACK
24
	);
25

    
26

    
27
	return $items;
28
}
29

    
30
/**
31
 * Implementation of hook_views_api()
32
 *
33
 * drupal will load dwca_export.views_default.inc when this hook is implemented
34
 */
35
function dwca_export_views_api() {
36
	return array(
37
		'api' => 3.0
38
	);
39
}
40

    
41
/**
42
 * Form function, called by drupal_get_form()
43
 * in dwca_export_menu().
44
 */
45
function dwca_export_config_form($form, &$form_state) {
46

    
47
	global $base_url;
48

    
49
	$form['dwca_export_todo'] = array(
50
		'#markup' => '<p><em>No settings implemented yet...</em></p>'
51
		.'<p>The DarwinCore Archive export is available at '. l('dwca_export', 'dwca_export').'</p>'
52
		.'<p>For general information on the DarwinCore Archive format please refer to  '
53
		. l('GBIF - Standards and Tools - Darwin Core Archives', 'http://www.gbif.org/informatics/standards-and-tools/publishing-data/data-standards/darwin-core-archives/')
54
		.'</p>'
55
	);
56

    
57
	return system_settings_form($form);
58
}
59

    
60

    
61
/**
62
 * menu callback
63
 */
64
function dwca_export_deliver_archive() {
65

    
66
	$tmp_archive_file_name = dwca_export_create_archive( _dwca_export_archive_descriptor_file_map() );
67

    
68
	if($tmp_archive_file_name && file_valid_uri($tmp_archive_file_name)){
69
		file_transfer($tmp_archive_file_name, array('Content-Type' => 'application/zip'));
70
	} else {
71
		throw new Exception(t('Error creating the archive'));
72
	}
73
}
74

    
75

    
76
/**
77
 * Provides the archive_descriptor_file_map which maps dwca file name to a set of view information.
78
 * The view information contains the fields 'view_name', 'display_id', 'out_file_url'.
79
 * The 'out_file_url' is initailly empty and will be set when this function is called
80
 * with both parameters.
81
 *
82
 * @param unknown_type $file_name
83
 * @param unknown_type $out_file_url
84
 *
85
 * @return the archive_descriptor_file_map
86
 */
87
function _dwca_export_archive_descriptor_file_map($file_name = NULL, $out_file_url = null){
88
	static $file_map;
89

    
90
	if(!isset($file_map)){
91
		//TODO load from variables, consider using strongarm
92
		$file_map = array(
93
			'classification.txt' => array(
94
				'view_name'=> 'dwca_export_classification',
95
				'display_id' => 'views_data_export_1',
96
				'out_file_url' => NULL
97
			),
98
			'typesandspecimen.txt' => array(
99
				'view_name'=> 'view_test_specimen_export',
100
				'display_id' => 'views_data_export_1',
101
				'out_file_url' => NULL
102
			)
103
		);
104
	}
105

    
106
	if($file_name && $out_file_url){
107
		$file_map[$file_name]['out_file_url'] = $out_file_url;
108
	}
109

    
110
	return $file_map;
111
}
112

    
113
/**
114
 * Walks all view export paths defined in the $views_map.
115
 * Each file is downloaded to the tmp folder and a zip file
116
 * is bundeled of the resulting csv files plus the meta file.
117
 *
118
 * @param $views_map - maps a view paths to dwca filenames
119
 *
120
 * @return the path in the filesystem to the final archive,
121
 * or FALSE in case of an error.
122
 */
123
function dwca_export_create_archive($views_map) {
124

    
125
	global $base_url;
126

    
127
	// execute all views to export the data into
128
	// temporary csv files (temporary://dwca_export_*). the resulting filenames
129
	// will be stored in _dwca_export_archive_descriptor_file_map()
130
	foreach($views_map as $filename=>$view_data){
131

    
132
		$view = views_get_view($view_data['view_name']);
133
		$options = array (
134
		    'output_file' => $filename
135
		);
136
		_dwca_export_views_data_export_override_batch($view, $view_data['display_id'], $options);
137
		$view->execute_display($view_data['display_id']);
138

    
139
	}
140

    
141
	// all data is exported to temporary://dwca_export_*
142
	// now we can start bundeling the actual archive
143
	$tmp_archive_file_name = drupal_tempnam("temporary://", "dwca_export_archive_");
144

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

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

    
157
	// at the moment we are using a static meta.xml file
158
	$metadata = "meta.xml";
159

    
160
	$zip_root_dir = "dwca_export/";
161

    
162
	if ($result !== TRUE) {
163
		throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
164
	}
165
	
166
	
167
	// add metadata
168
	$zip->addFile($module_static_dir_absolute.$metadata, $zip_root_dir.$metadata);
169
	// add the csv data files
170
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename=>$view_data){
171

    
172
		$view_temp_file = $view_data['out_file_url'];
173
		if($view_temp_file){
174
			$zip->addFile(drupal_realpath($view_temp_file), $zip_root_dir.$dwca_filename);
175
		}else{
176
			throw new Exception(t('Cannot create %file', array('%file' => $dwca_filename)));
177
		}
178
	}
179

    
180
	$zip->close();
181

    
182
	return $tmp_archive_file_name;
183

    
184

    
185
}
186

    
187
/**
188
 * Helper function that indicates that we want to
189
 * override the batch that the views_data_export view creates
190
 * on it's initial time through.
191
 *
192
 * Also provides a place to stash options that need to stay around
193
 * until the end of the batch
194
 *
195
 * adapted fom views_data_export.drush.inc
196
 */
197
function _dwca_export_views_data_export_override_batch($view = NULL, $display = NULL, $options = TRUE) {
198
	static $_views;
199
	if (isset($view)) {
200
		$_views[$view->name][$display] = $options;
201
	}
202
	return $_views;
203
}
204

    
205

    
206
/**
207
 * Implementation of hook_views_data_export_batch_alter()
208
 *
209
 * adapted fom views_data_export.drush.inc
210
 *
211
 *  @see batch_process() in form.inc
212
 */
213
function dwca_export_views_data_export_batch_alter(&$batch, &$final_destination, &$querystring) {
214

    
215
	$view_name = $batch['view_name'];
216
	$display_id = $batch['display_id'];
217

    
218
	$ok_to_override = _dwca_export_views_data_export_override_batch();
219

    
220
	// Make sure we do nothing if we are called not following the execution of
221
	// our drush command. This could happen if the file with this function in it
222
	// is included during the normal execution of the view
223
	if (!$ok_to_override[$view_name][$display_id]) {
224
		return;
225
	}
226

    
227
	$options = $ok_to_override[$view_name][$display_id];
228

    
229
	// We actually never return from the drupal_alter, but
230
	// use drush's batch system to run the same batch
231

    
232
	// Add a final callback
233
	$batch['operations'][] = array(
234
	    '_dwca_export_views_data_export_batch_finished', array($batch['eid'], $options['output_file']),
235
	);
236

    
237
	$batch['progressive'] = FALSE;
238
}
239

    
240
/**
241
* Implementation of hook_views_data_export_batch_alter()
242
*
243
* @see batch_process() in form.inc
244
*/
245
function dwca_export_batch_alter(&$batch, &$final_destination, &$querystring) {
246
	if($batch['source_url'] == 'dwca_export'){
247
		$batch['progressive'] = FALSE;
248
	}
249
}
250

    
251

    
252

    
253
/**
254
* Get's called at the end of the drush batch process that generated our export
255
*
256
* adapted fom views_data_export.drush.inc
257
*/
258
function _dwca_export_views_data_export_batch_finished($eid, $output_file, &$context) {
259
	// Fetch export info
260
	$export = views_data_export_get($eid);
261

    
262
	// Perform cleanup
263
	$view = views_data_export_view_retrieve($eid);
264
	$view->set_display($export->view_display_id);
265
	$view->display_handler->batched_execution_state = $export;
266
	$view->display_handler->remove_index();
267

    
268
	// Get path to temp file
269
	$temp_file = $view->display_handler->outputfile_path();
270

    
271
	_dwca_export_archive_descriptor_file_map($output_file, $temp_file);
272

    
273
}
(3-3/4)