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
|
}
|