Project

General

Profile

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

    
3
// at the moment we are using a static meta.xml file
4
define ("METADATA_FILE_NAME", "meta.xml");
5
define ("STATIC_DIR", "/static/");
6
define ("ARCHIVE_ROOT_DIR", "dwca_export/");
7
define ('FILE_MAP', 'dwca_export_archive_descriptor_file_map');
8

    
9

    
10
/**
11
 * Implements hook_menu().
12
 */
13
function dwca_export_menu() {
14

    
15
	$items = array();
16

    
17
	$items['admin/config/system/dwca_export'] = array(
18
		'title' => 'Darwin Core Archive export',
19
		'description' => t('Create a DarwinCore Archive of this scratchpad.'),
20
		'page callback' => 'drupal_get_form',
21
		'page arguments' => array('dwca_export_config_form'),
22
		'access arguments' => array('access DwC-A export settings'),
23
		'type' => MENU_NORMAL_ITEM,
24
		//'file' => 'dwca_export.admin.inc'
25
	);
26

    
27

    
28
	$items['dwca_export'] = array(
29
		'page callback' => 'dwca_export_deliver_archive',
30
		'access arguments' => array('access content'),
31
		'type' => MENU_CALLBACK
32
	);
33

    
34

    
35
	return $items;
36
}
37

    
38
/**
39
 * Implementation of hook_views_api()
40
 *
41
 * drupal will load dwca_export.views_default.inc when this hook is implemented
42
 */
43
function dwca_export_views_api() {
44
	return array(
45
		'api' => 3.0
46
	);
47
}
48

    
49
/**
50
* Implementation of hook_ctools_plugin_api().
51
*/
52
function dwca_export_ctools_plugin_api(){
53
	list($module, $api) = func_get_args();
54
	if($module == "strongarm" && $api == "strongarm"){
55
		return array(
56
      "version" => 1
57
		);
58
	}
59
}
60

    
61
/**
62
 * Form function, called by drupal_get_form()
63
 * in dwca_export_menu().
64
 */
65
function dwca_export_config_form($form, &$form_state) {
66

    
67
	global $base_url;
68

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

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

    
86
	$form['#submit'][] = 'dwca_export_config_form_submit';
87
	return system_settings_form($form);
88

    
89
}
90

    
91

    
92
function dwca_export_select_view_form() {
93

    
94
	$views = array(
95
    		'#type' => 'fieldset',
96
    		'#title' => t('View to file mapping'),
97
    		//'#tree' => TRUE,
98
  	);
99

    
100
	foreach(variable_get(FILE_MAP) as $dwca_filename => $view_data){
101
		
102
		
103
		$views[$dwca_filename] = array(
104
		  	'#type' => 'textfield',
105
		  	'#title' => t($dwca_filename),
106
		  	'#default_value' => $view_data['view_name'],
107
		  	'#size' => 60,
108
		  	'#maxlength' => 64,
109
		  	'#description' => t('specify view for ' . $dwca_filename),
110
		  	
111
		);
112
	}
113

    
114
	return $views;
115
}
116

    
117
function dwca_export_config_form_submit($form, &$form_state) {  
118

    
119
	$variables = $form_state['input'];
120
	$save_variables = '';
121
	$dwca_export_archive_descriptor_file_map = variable_get(FILE_MAP);
122
	
123
	foreach ($variables as $key => $value) {
124
		
125
		if (array_key_exists($key, $dwca_export_archive_descriptor_file_map)) {
126
		
127
			$dwca_export_archive_descriptor_file_map[$key]['view_name'] = $value;
128
			//$save_variables .= '<p>' . $key . ' ' . $value . '</p>';			
129
		}		
130
	}
131
	
132
	variable_del(FILE_MAP);
133
	variable_set(FILE_MAP, $dwca_export_archive_descriptor_file_map);
134
		
135
	//drupal_set_message(t('The classification view is ') . $save_variables);// . '<pre>' . print_r($form_state,true) . '</pre>');//$save_variables);
136
}
137

    
138
// Reports an error if view name entered by the user does not exist in the database.
139
function dwca_export_config_form_validate($form, &$form_state) {
140
	
141
	$variables = $form_state['input'];
142
	$dwca_export_archive_descriptor_file_map = variable_get(FILE_MAP);
143
	$view_names = array();
144
	$missing_view_names = '';
145
	$missing_view = false;
146
	
147
	foreach ($variables as $key => $value) {
148
		
149
		if (array_key_exists($key, $dwca_export_archive_descriptor_file_map)) {
150
					
151
			$view = views_get_view($value);
152
			// check whether there is a view named with this value 
153
			if(!$view) {
154
				$view_names[] = $value;
155
				$missing_view_names .= $value . ', ';
156
				$missing_view = true;
157
			}
158
		}
159
	}
160
	
161
	if ($missing_view) {
162
		form_set_error('', t('VIEW(S) ' . $missing_view_names . ' NOT FOUND. Please input another view name.'));
163
	}
164
	
165
}
166

    
167
/**
168
 * menu callback
169
 */
170
function dwca_export_deliver_archive() {
171

    
172
	$tmp_archive_file_name = dwca_export_create_archive( _dwca_export_archive_descriptor_file_map() );
173

    
174
	if($tmp_archive_file_name && file_valid_uri($tmp_archive_file_name)){
175
		file_transfer($tmp_archive_file_name, array('Content-Type' => 'application/zip'));
176
	} else {
177
		throw new Exception(t('Error creating the archive'));
178
	}
179
}
180

    
181

    
182
/**
183
 * Provides the archive_descriptor_file_map which maps dwca file name to a set of view information.
184
 * The view information contains the fields 'view_name', 'display_id', 'out_file_url'.
185
 * The 'out_file_url' is initailly empty and will be set when this function is called
186
 * with both parameters.
187
 *
188
 * @param String $file_name
189
 * @param String $out_file_url
190
 *
191
 * @return the archive_descriptor_file_map
192
 */
193
function _dwca_export_archive_descriptor_file_map($file_name = NULL, $out_file_url = null){
194
	static $file_map;
195

    
196
	if(!isset($file_map)){
197
		$file_map = variable_get(FILE_MAP);
198
	}
199

    
200
	if($file_name && $out_file_url){
201
		$file_map[$file_name]['out_file_url'] = $out_file_url;
202
	}
203

    
204
	return $file_map;
205
}
206

    
207

    
208
/**
209
 * Walks all view export paths defined in the $views_map.
210
 * Each file is downloaded to the tmp folder and a zip file
211
 * is bundeled of the resulting csv files plus the meta file.
212
 *
213
 * @param $views_map - maps a view paths to dwca filenames
214
 *
215
 * @return the path in the filesystem to the final archive,
216
 * or FALSE in case of an error.
217
 */
218
function dwca_export_create_archive($views_map) {
219

    
220
	global $base_url;
221

    
222
	// execute all views to export the data into
223
	// temporary csv files (temporary://dwca_export_*). the resulting filenames
224
	// will be stored in _dwca_export_archive_descriptor_file_map()
225
	foreach($views_map as $filename=>$view_data){
226

    
227
		$view = views_get_view($view_data['view_name']);
228
		$options = array (
229
		    'output_file' => $filename
230
		);
231
		_dwca_export_views_data_export_override_batch($view, $view_data['display_id'], $options);
232
		$view->execute_display($view_data['display_id']);
233

    
234
	}
235

    
236
	// all data is exported to temporary://dwca_export_*
237
	// now we can start bundling the actual archive
238
	$tmp_archive_file_name = drupal_tempnam("temporary://", "dwca_export_archive_");
239

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

    
249
	// there might be a better way to get at this information
250
	$module_static_dir_absolute_path = realpath(drupal_get_path('module', 'dwca_export')) . STATIC_DIR;
251

    
252
	if ($result !== TRUE) {
253
		throw new Exception(t('Could not create zip_archive %tmp_archive_file_name', array('%tmp_archive_file_name' => $tmp_archive_file_name)));
254
	}
255

    
256
	
257
	// add metadata
258
	$zip->addFile($module_static_dir_absolute_path.METADATA_FILE_NAME, ARCHIVE_ROOT_DIR.METADATA_FILE_NAME);
259
	// add the csv data files
260
	foreach(_dwca_export_archive_descriptor_file_map() as $dwca_filename=>$view_data){
261

    
262
		$view_temp_file = $view_data['out_file_url'];
263
		if($view_temp_file){
264
			$zip->addFile(drupal_realpath($view_temp_file), ARCHIVE_ROOT_DIR.$dwca_filename);
265
		}else{
266
			throw new Exception(t('Cannot create %file', array('%file' => $dwca_filename)));
267
		}
268
	}
269

    
270
	$zip->close();
271

    
272
	return $tmp_archive_file_name;
273
}
274

    
275
/**
276
 * Helper function that indicates that we want to
277
 * override the batch that the views_data_export view creates
278
 * on it's initial time through.
279
 *
280
 * Also provides a place to stash options that need to stay around
281
 * until the end of the batch
282
 *
283
 * adapted fom views_data_export.drush.inc
284
 */
285
function _dwca_export_views_data_export_override_batch($view = NULL, $display = NULL, $options = TRUE) {
286
	static $_views;
287
	if (isset($view)) {
288
		$_views[$view->name][$display] = $options;
289
	}
290
	return $_views;
291
}
292

    
293

    
294
/**
295
 * Implementation of hook_views_data_export_batch_alter()
296
 *
297
 * adapted fom views_data_export.drush.inc
298
 *
299
 *  @see batch_process() in form.inc
300
 */
301
function dwca_export_views_data_export_batch_alter(&$batch, &$final_destination, &$querystring) {
302

    
303
	$view_name = $batch['view_name'];
304
	$display_id = $batch['display_id'];
305

    
306
	$ok_to_override = _dwca_export_views_data_export_override_batch();
307

    
308
	// Make sure we do nothing if we are called not following the execution of
309
	// our drush command. This could happen if the file with this function in it
310
	// is included during the normal execution of the view
311
	if (!$ok_to_override[$view_name][$display_id]) {
312
		return;
313
	}
314

    
315
	$options = $ok_to_override[$view_name][$display_id];
316

    
317
	// We actually never return from the drupal_alter, but
318
	// use drush's batch system to run the same batch
319

    
320
	// Add a final callback
321
	$batch['operations'][] = array(
322
	    '_dwca_export_views_data_export_batch_finished', array($batch['eid'], $options['output_file']),
323
	);
324

    
325
	$batch['progressive'] = FALSE;
326
}
327

    
328
/**
329
* Implementation of hook_views_data_export_batch_alter()
330
*
331
* @see batch_process() in form.inc
332
*/
333
function dwca_export_batch_alter(&$batch, &$final_destination, &$querystring) {
334
	if($batch['source_url'] == 'dwca_export'){
335
		$batch['progressive'] = FALSE;
336
	}
337
}
338

    
339

    
340

    
341
/**
342
* Get's called at the end of the drush batch process that generated our export
343
*
344
* adapted fom views_data_export.drush.inc
345
*/
346
function _dwca_export_views_data_export_batch_finished($eid, $output_file, &$context) {
347
	// Fetch export info
348
	$export = views_data_export_get($eid);
349

    
350
	// Perform cleanup
351
	$view = views_data_export_view_retrieve($eid);
352
	$view->set_display($export->view_display_id);
353
	$view->display_handler->batched_execution_state = $export;
354
	$view->display_handler->remove_index();
355

    
356
	// Get path to temp file
357
	$temp_file = $view->display_handler->outputfile_path();
358

    
359
	_dwca_export_archive_descriptor_file_map($output_file, $temp_file);
360

    
361
}
(3-3/5)