Project

General

Profile

Download (9.71 KB) Statistics
| Branch: | Tag: | Revision:
1 9c7f9ab7 Andreas Kohlbecker
<?php
2
3 dc70e39a n.hoffmann
// at the moment we are using a static meta.xml file
4 e3d8e63e n.hoffmann
define ("METADATA_FILE_NAME", "meta.xml");
5
define ("STATIC_DIR", "/static/");
6 dc70e39a n.hoffmann
define ("ARCHIVE_ROOT_DIR", "dwca_export/");
7
8 e3d8e63e n.hoffmann
function _dwca_export_get_static_file_map(){
9 dc70e39a n.hoffmann
	$static_file_map = array(
10 e3d8e63e n.hoffmann
		'classification.txt' => array(
11 dc70e39a n.hoffmann
			'view_name'=> 'dwca_export_classification',
12
			'display_id' => 'views_data_export_1',
13
			'out_file_url' => NULL
14
		),
15 e3d8e63e n.hoffmann
		'typesandspecimen.txt' => array(
16 dc70e39a n.hoffmann
			'view_name'=> 'view_test_specimen_export',
17
			'display_id' => 'views_data_export_1',
18
			'out_file_url' => NULL
19
		)
20
	);
21
	return $static_file_map;
22
}
23
24
25 9c7f9ab7 Andreas Kohlbecker
/**
26
 * Implements hook_menu().
27
 */
28
function dwca_export_menu() {
29
30
	$items = array();
31
32 3ac1e968 Andreas Kohlbecker
	$items['admin/config/system/dwca_export'] = array(
33
		'title' => 'Darwin Core Archive export',
34 1e97110c n.hoffmann
		'description' => t('Create a DarwinCore Archive of this scratchpad.'),
35 9c7f9ab7 Andreas Kohlbecker
		'page callback' => 'drupal_get_form',
36
		'page arguments' => array('dwca_export_config_form'),
37 1e97110c n.hoffmann
		'access arguments' => array('access DwC-A export settings'),
38 3ac1e968 Andreas Kohlbecker
		'type' => MENU_NORMAL_ITEM,
39 9c7f9ab7 Andreas Kohlbecker
		//'file' => 'dwca_export.admin.inc'
40
	);
41
42 ab2258a1 l.morris
43 9c7f9ab7 Andreas Kohlbecker
	$items['dwca_export'] = array(
44
		'page callback' => 'dwca_export_deliver_archive',
45 6ab7ce86 Andreas Kohlbecker
		'access arguments' => array('access content'),
46 9c7f9ab7 Andreas Kohlbecker
		'type' => MENU_CALLBACK
47
	);
48
49
50
	return $items;
51
}
52
53 d0c09d70 Andreas Kohlbecker
/**
54
 * Implementation of hook_views_api()
55
 *
56
 * drupal will load dwca_export.views_default.inc when this hook is implemented
57
 */
58
function dwca_export_views_api() {
59 7156bdbf n.hoffmann
	return array(
60
		'api' => 3.0
61
	);
62 d0c09d70 Andreas Kohlbecker
}
63
64 9c7f9ab7 Andreas Kohlbecker
/**
65
 * Form function, called by drupal_get_form()
66
 * in dwca_export_menu().
67
 */
68
function dwca_export_config_form($form, &$form_state) {
69
70 6ab7ce86 Andreas Kohlbecker
	global $base_url;
71
72 dc70e39a n.hoffmann
	$form['dwca_export_info'] = array(
73
		'#markup' => '<p>For general information on the DarwinCore Archive format please refer to  '
74 3ac1e968 Andreas Kohlbecker
		. l('GBIF - Standards and Tools - Darwin Core Archives', 'http://www.gbif.org/informatics/standards-and-tools/publishing-data/data-standards/darwin-core-archives/')
75 6ab7ce86 Andreas Kohlbecker
		.'</p>'
76 9c7f9ab7 Andreas Kohlbecker
	);
77
78 dc70e39a n.hoffmann
	$form['dwca_export_execute'] = array(
79
		'#markup' => '<p>The DarwinCore Archive export is available at '. l('dwca_export', 'dwca_export').'</p>'
80
		//'#type' => 'button',
81
		//'#value' => t('Export Scratchpad to DarwinCore Archive'), 
82
	  //'#weight' => 19,
83
	);
84
	
85
	$form['dwca_export_view_mapping'] = dwca_export_select_view_form();
86
	
87
	
88 ab2258a1 l.morris
89
	$form['#submit'][] = 'dwca_export_config_form_submit';
90 9c7f9ab7 Andreas Kohlbecker
	return system_settings_form($form);
91 ab2258a1 l.morris
92
}
93
94
95
function dwca_export_select_view_form() {
96
97
	$views = array(
98
    		'#type' => 'fieldset',
99 dc70e39a n.hoffmann
    		'#title' => t('View to file mapping'),
100 ab2258a1 l.morris
    		//'#tree' => TRUE,
101
  	);
102
103 dc70e39a n.hoffmann
	//$default_value = _dwca_export_archive_descriptor_file_map();
104
105
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename => $view_data){
106
		
107
		
108
		$views[$dwca_filename . '_view'] = array(
109
	  	'#type' => 'textfield',
110
	  	'#title' => t($dwca_filename),
111
	  	'#default_value' => $view_data['view_name'],
112
	  	'#size' => 60,
113
	  	'#maxlength' => 64,
114 e3d8e63e n.hoffmann
	  	'#description' => t('specify view for ' . $dwca_filename),
115 dc70e39a n.hoffmann
		);
116
	}
117 ab2258a1 l.morris
118
	return $views;
119
}
120
121
function dwca_export_config_form_submit($form, &$form_state) {  
122
123
// 	db_query("INSERT INTO {table} (classification_view) VALUES ('%s')", $form_state['values']['classification_view']);  
124
//variable_set($name, $value)
125
	drupal_set_message(t('Your config form has been saved.'));
126
127
//throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
128 9c7f9ab7 Andreas Kohlbecker
}
129
130
131
/**
132
 * menu callback
133
 */
134
function dwca_export_deliver_archive() {
135
136 7fcb8ba6 Andreas Kohlbecker
	$tmp_archive_file_name = dwca_export_create_archive( _dwca_export_archive_descriptor_file_map() );
137 9c7f9ab7 Andreas Kohlbecker
138 7156bdbf n.hoffmann
	if($tmp_archive_file_name && file_valid_uri($tmp_archive_file_name)){
139 04291712 Andreas Kohlbecker
		file_transfer($tmp_archive_file_name, array('Content-Type' => 'application/zip'));
140
	} else {
141 7156bdbf n.hoffmann
		throw new Exception(t('Error creating the archive'));
142 04291712 Andreas Kohlbecker
	}
143 9c7f9ab7 Andreas Kohlbecker
}
144
145 7fcb8ba6 Andreas Kohlbecker
146
/**
147
 * Provides the archive_descriptor_file_map which maps dwca file name to a set of view information.
148
 * The view information contains the fields 'view_name', 'display_id', 'out_file_url'.
149
 * The 'out_file_url' is initailly empty and will be set when this function is called
150
 * with both parameters.
151
 *
152 dc70e39a n.hoffmann
 * @param String $file_name
153
 * @param String $out_file_url
154 7fcb8ba6 Andreas Kohlbecker
 *
155
 * @return the archive_descriptor_file_map
156
 */
157
function _dwca_export_archive_descriptor_file_map($file_name = NULL, $out_file_url = null){
158
	static $file_map;
159
160
	if(!isset($file_map)){
161
		//TODO load from variables, consider using strongarm
162 dc70e39a n.hoffmann
		// current implementation uses a static filemap
163 e3d8e63e n.hoffmann
		$file_map = _dwca_export_get_static_file_map();
164 7fcb8ba6 Andreas Kohlbecker
	}
165
166
	if($file_name && $out_file_url){
167
		$file_map[$file_name]['out_file_url'] = $out_file_url;
168
	}
169
170
	return $file_map;
171
}
172
173 ab2258a1 l.morris
174 9c7f9ab7 Andreas Kohlbecker
/**
175
 * Walks all view export paths defined in the $views_map.
176
 * Each file is downloaded to the tmp folder and a zip file
177
 * is bundeled of the resulting csv files plus the meta file.
178
 *
179 7fcb8ba6 Andreas Kohlbecker
 * @param $views_map - maps a view paths to dwca filenames
180 9c7f9ab7 Andreas Kohlbecker
 *
181 04291712 Andreas Kohlbecker
 * @return the path in the filesystem to the final archive,
182
 * or FALSE in case of an error.
183 9c7f9ab7 Andreas Kohlbecker
 */
184
function dwca_export_create_archive($views_map) {
185
186 7fcb8ba6 Andreas Kohlbecker
	global $base_url;
187
188
	// execute all views to export the data into
189
	// temporary csv files (temporary://dwca_export_*). the resulting filenames
190
	// will be stored in _dwca_export_archive_descriptor_file_map()
191
	foreach($views_map as $filename=>$view_data){
192
193
		$view = views_get_view($view_data['view_name']);
194
		$options = array (
195
		    'output_file' => $filename
196
		);
197
		_dwca_export_views_data_export_override_batch($view, $view_data['display_id'], $options);
198
		$view->execute_display($view_data['display_id']);
199
200
	}
201
202
	// all data is exported to temporary://dwca_export_*
203 dc70e39a n.hoffmann
	// now we can start bundling the actual archive
204 7fcb8ba6 Andreas Kohlbecker
	$tmp_archive_file_name = drupal_tempnam("temporary://", "dwca_export_archive_");
205 9c7f9ab7 Andreas Kohlbecker
206 7156bdbf n.hoffmann
	// Unfortunately we cannot use drupals ArchiverZip because there ís
207
	// no way to pass in ZipArchive::CREATE to the constructor to create the archive
208
	// TODO test if zip functionality is available (i.e. if(function_exists('zip_open'))
209
	// but I don't know where the proper location for such a check would be
210
	$zip = new ZipArchive();
211
	// it is safe to use drupal_realpath as the tmp file will be certainly local
212
	// and php's ZipArchive does not handle stream URIs
213
	$result = $zip->open(drupal_realpath($tmp_archive_file_name), ZipArchive::CREATE);
214
215
	// there might be a better way to get at this information
216 e3d8e63e n.hoffmann
	$module_static_dir_absolute_path = realpath(drupal_get_path('module', 'dwca_export')) . STATIC_DIR;
217 7156bdbf n.hoffmann
218
	if ($result !== TRUE) {
219
		throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
220 7fcb8ba6 Andreas Kohlbecker
	}
221 dc70e39a n.hoffmann
222 95cfb699 n.hoffmann
	
223
	// add metadata
224 e3d8e63e n.hoffmann
	$zip->addFile($module_static_dir_absolute_path.METADATA_FILE_NAME, ARCHIVE_ROOT_DIR.METADATA_FILE_NAME);
225 95cfb699 n.hoffmann
	// add the csv data files
226 7fcb8ba6 Andreas Kohlbecker
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename=>$view_data){
227
228
		$view_temp_file = $view_data['out_file_url'];
229
		if($view_temp_file){
230 e3d8e63e n.hoffmann
			$zip->addFile(drupal_realpath($view_temp_file), ARCHIVE_ROOT_DIR.$dwca_filename);
231 7fcb8ba6 Andreas Kohlbecker
		}else{
232 e3d8e63e n.hoffmann
			throw new Exception(t('Cannot create %file', array('%file' => $dwca_filename)));
233 7156bdbf n.hoffmann
		}
234 7fcb8ba6 Andreas Kohlbecker
	}
235
236
	$zip->close();
237
238
	return $tmp_archive_file_name;
239 7156bdbf n.hoffmann
}
240
241
/**
242 7fcb8ba6 Andreas Kohlbecker
 * Helper function that indicates that we want to
243
 * override the batch that the views_data_export view creates
244
 * on it's initial time through.
245 7156bdbf n.hoffmann
 *
246 7fcb8ba6 Andreas Kohlbecker
 * Also provides a place to stash options that need to stay around
247
 * until the end of the batch
248
 *
249
 * adapted fom views_data_export.drush.inc
250 7156bdbf n.hoffmann
 */
251 7fcb8ba6 Andreas Kohlbecker
function _dwca_export_views_data_export_override_batch($view = NULL, $display = NULL, $options = TRUE) {
252
	static $_views;
253
	if (isset($view)) {
254
		$_views[$view->name][$display] = $options;
255
	}
256
	return $_views;
257 9c7f9ab7 Andreas Kohlbecker
}
258
259 7fcb8ba6 Andreas Kohlbecker
260 9c7f9ab7 Andreas Kohlbecker
/**
261 7fcb8ba6 Andreas Kohlbecker
 * Implementation of hook_views_data_export_batch_alter()
262
 *
263
 * adapted fom views_data_export.drush.inc
264 9c7f9ab7 Andreas Kohlbecker
 *
265 7fcb8ba6 Andreas Kohlbecker
 *  @see batch_process() in form.inc
266 9c7f9ab7 Andreas Kohlbecker
 */
267 7fcb8ba6 Andreas Kohlbecker
function dwca_export_views_data_export_batch_alter(&$batch, &$final_destination, &$querystring) {
268 9c7f9ab7 Andreas Kohlbecker
269 7fcb8ba6 Andreas Kohlbecker
	$view_name = $batch['view_name'];
270
	$display_id = $batch['display_id'];
271
272
	$ok_to_override = _dwca_export_views_data_export_override_batch();
273
274
	// Make sure we do nothing if we are called not following the execution of
275
	// our drush command. This could happen if the file with this function in it
276
	// is included during the normal execution of the view
277
	if (!$ok_to_override[$view_name][$display_id]) {
278
		return;
279
	}
280
281
	$options = $ok_to_override[$view_name][$display_id];
282
283
	// We actually never return from the drupal_alter, but
284
	// use drush's batch system to run the same batch
285
286
	// Add a final callback
287
	$batch['operations'][] = array(
288
	    '_dwca_export_views_data_export_batch_finished', array($batch['eid'], $options['output_file']),
289 9c7f9ab7 Andreas Kohlbecker
	);
290 7fcb8ba6 Andreas Kohlbecker
291
	$batch['progressive'] = FALSE;
292
}
293
294
/**
295
* Implementation of hook_views_data_export_batch_alter()
296
*
297
* @see batch_process() in form.inc
298
*/
299
function dwca_export_batch_alter(&$batch, &$final_destination, &$querystring) {
300
	if($batch['source_url'] == 'dwca_export'){
301
		$batch['progressive'] = FALSE;
302
	}
303
}
304
305
306
307
/**
308
* Get's called at the end of the drush batch process that generated our export
309
*
310
* adapted fom views_data_export.drush.inc
311
*/
312
function _dwca_export_views_data_export_batch_finished($eid, $output_file, &$context) {
313
	// Fetch export info
314
	$export = views_data_export_get($eid);
315
316
	// Perform cleanup
317
	$view = views_data_export_view_retrieve($eid);
318
	$view->set_display($export->view_display_id);
319
	$view->display_handler->batched_execution_state = $export;
320
	$view->display_handler->remove_index();
321
322
	// Get path to temp file
323
	$temp_file = $view->display_handler->outputfile_path();
324
325
	_dwca_export_archive_descriptor_file_map($output_file, $temp_file);
326
327 9c7f9ab7 Andreas Kohlbecker
}