29 function tpps_dynamic_list(array &$form, array &$form_state, $id, array $repeat, array $options = array()) {
30 $label = $options[
'label'] ?? $id;
31 $parents = $options[
'parents'] ?? array();
32 $number_parents = $parents;
33 array_push($number_parents, $id,
'number');
34 $up = $options[
'up'] ??
"Add $label";
35 $down = $options[
'down'] ??
"Remove $label";
36 $name_suffix = $options[
'name_suffix'] ??
"";
37 $default = $options[
'default'] ?? 0;
38 $minimum = $options[
'minimum'] ?? $default;
39 $fieldset_title = $options[
'title'] ??
"$label information:";
40 $button_callback = $options[
'callback'] ??
"tpps_{$id}_callback";
41 $list_wrapper = $options[
'wrapper'] ??
"$id-wrapper";
42 $sub_keys = $options[
'substitute_keys'] ?? array();
43 $sub_fields = $options[
'substitute_fields'] ?? array();
44 $replace_pattern = $options[
'replacement_pattern'] ??
'/!num/';
45 $alt_buttons = $options[
'alternative_buttons'] ?? array();
46 $button_weights = $options[
'button_weights'] ?? array();
49 '#type' =>
'fieldset',
51 '#title' =>
"<div class=\"fieldset-title\">$fieldset_title</div>",
52 '#collapsible' => $options[
'collapsible'] ?? TRUE,
53 '#prefix' =>
"<div id=\"$list_wrapper\">",
54 '#suffix' =>
'</div>',
57 '#button_type' =>
'button',
59 '#name' => $up . $name_suffix,
61 'wrapper' => $list_wrapper,
62 'callback' => $button_callback,
64 '#weight' => $button_weights[$up] ?? NULL,
68 '#button_type' =>
'button',
70 '#name' => $down . $name_suffix,
72 'wrapper' => $list_wrapper,
73 'callback' => $button_callback,
75 '#weight' => $button_weights[$down] ?? NULL,
79 $number_options = array();
80 foreach ($alt_buttons as $button => $inc_value) {
81 $element[$button] = array(
83 '#button_type' =>
'button',
85 '#name' => $button . $name_suffix,
87 'wrapper' => $list_wrapper,
88 'callback' => $button_callback,
90 '#weight' => $button_weights[$button] ?? NULL,
92 $number_options[$button . $name_suffix] = $inc_value;
95 $number =
tpps_get_ajax_number($form_state, $number_parents, $up . $name_suffix, $down . $name_suffix, $default, $minimum, $number_options);
97 $element[
'number'] = array(
102 for ($i = 1; $i <= $number; $i++) {
104 foreach ($sub_fields as $field) {
105 if (!is_array($field)) {
106 $instance[$field] = preg_replace($replace_pattern, $i, $repeat[$field]);
109 $new_value = preg_replace($replace_pattern, $i, drupal_array_get_nested_value($repeat, $field));
110 drupal_array_set_nested_value($instance, $field, $new_value);
113 foreach ($sub_keys as $key) {
114 $value = drupal_array_get_nested_value($instance, $key);
115 drupal_array_set_nested_value($instance, $key, NULL);
117 foreach ($key as $key_item) {
118 $new_key[] = preg_replace($replace_pattern, $i, $key_item);
120 drupal_array_set_nested_value($instance, $new_key, $value);
122 $element[$i] = $instance;
125 $element_parents = $parents;
126 array_push($element_parents, $id);
127 drupal_array_set_nested_value($form, $element_parents, $element);
157 function tpps_get_ajax_number(array &$state, array $parents, $up, $down, $default = 0, $minimum = 0, array $options = array()) {
159 $page = $state[
'stage'] ??
'';
162 $value_parents = $parents;
166 $button_name = $state[
'triggering_element'][
'#name'] ??
'';
167 if (preg_match(
'/^.*_(upload|remove)_button$/', $button_name)) {
168 array_unshift($value_parents,
'complete form');
169 $val = drupal_array_get_nested_value($state, $value_parents);
170 if (isset($val[
'#type']) and $val[
'#type'] ==
'hidden') {
171 array_push($value_parents,
'#value');
175 array_unshift($value_parents,
'values');
177 $val = drupal_array_get_nested_value($state, $value_parents);
178 if (isset($val) and array_key_exists($button_name, $options)) {
179 $increment = $options[$button_name];
181 if (is_int($increment)) {
182 $new_val = $val + $increment;
183 if ($new_val < $minimum) {
187 if (is_string($increment) and function_exists($increment)) {
188 $new_val = $increment($button_name, $val);
190 drupal_array_set_nested_value($state, $value_parents, $new_val);
192 elseif (isset($val) and $button_name == $up) {
193 drupal_array_set_nested_value($state, $value_parents, $val + 1);
195 elseif (isset($val) and $button_name == $down and $val > $minimum) {
196 drupal_array_set_nested_value($state, $value_parents, $val - 1);
198 $val = drupal_array_get_nested_value($state, $value_parents);
204 $saved_value_parents = $parents;
205 array_unshift($saved_value_parents,
'saved_values', $page);
206 $saved_val = drupal_array_get_nested_value($state, $saved_value_parents);
207 if (isset($saved_val)) {
237 $page = $state[
'stage'];
238 $value_parents = $parents;
239 array_unshift($value_parents,
'values');
240 $element = drupal_array_get_nested_value($state, $value_parents);
241 if (isset($element[
'#type']) and $element[
'#type'] !=
'fieldset') {
242 array_push($value_parents,
'#value');
244 $val = drupal_array_get_nested_value($state, $value_parents);
249 $complete_parents = $parents;
250 array_unshift($complete_parents,
'complete form');
251 $element = drupal_array_get_nested_value($state, $complete_parents);
252 if (isset($element[
'#type']) and $element[
'#type'] !=
'fieldset') {
253 array_push($complete_parents,
'#value');
255 $val = drupal_array_get_nested_value($state, $complete_parents);
260 $saved_value_parents = $parents;
261 if (!empty($file_name)) {
262 $saved_value_parents = array();
264 foreach ($parents as $item) {
265 if ($last == $file_name) {
266 $item =
"$file_name-$item";
269 if ($item == $file_name) {
272 $saved_value_parents[] = $item;
275 array_unshift($saved_value_parents,
'saved_values', $page);
276 $saved_val = drupal_array_get_nested_value($state, $saved_value_parents);
277 return $saved_val ?? $default;
291 $new[
'saved_values'] = $old[
'saved_values'];
292 $new[
'stage'] = $old[
'stage'];
293 $new[
'accession'] = $old[
'accession'];
294 $new[
'dbxref_id'] = $old[
'dbxref_id'];
295 $new[
'stats'] = $old[
'stats'] ?? NULL;
296 $new[
'ids'] = $old[
'ids'] ?? NULL;
297 $new[
'tpps_type'] = $old[
'tpps_type'] ?? NULL;
298 $new[
'file_info'] = $old[
'file_info'] ?? NULL;
299 $new[
'status'] = $old[
'status'] ?? NULL;
300 $new[
'updated'] = $old[
'updated'] ?? time();
301 $new[
'created'] = $old[
'created'] ?? NULL;
302 $new[
'approved'] = $old[
'approved'] ?? NULL;
303 $new[
'completed'] = $old[
'completed'] ?? NULL;
304 $new[
'loaded'] = $old[
'loaded'] ?? NULL;
305 $new[
'submitting_uid'] = $old[
'submitting_uid'] ?? NULL;
306 $new[
'job_id'] = $old[
'job_id'] ?? NULL;
307 $new[
'revised_files'] = $old[
'revised_files'] ?? NULL;
308 $new[
'admin_comments'] = $old[
'admin_comments'] ?? NULL;
309 $new[
'alternative_accessions'] = $old[
'alternative_accessions'] ?? NULL;
310 $new[
'data'] = $old[
'data'] ?? NULL;
311 $new[
'phenotypes_edit'] = $old[
'phenotypes_edit'] ?? NULL;
329 if (!form_get_errors()) {
330 $file = file_load($fid);
331 file_usage_add($file,
'tpps',
'tpps_project', substr($form_state[
'accession'], 4));
333 if (!empty($org_num) and !empty($prefix)) {
334 $species = implode(
'_', explode(
' ', $form_state[
'saved_values'][
TPPS_PAGE_1][
'organism'][$org_num][
'name']));
335 $form_state[
'file_info'][
TPPS_PAGE_3][$file->fid] =
"{$prefix}_{$species}";
351 if (empty($accession) or empty($state)) {
352 drupal_json_output(
"Submission could not be loaded from accession");
355 $params = drupal_get_query_parameters(NULL, array());
356 $vcfs = $params[
'vcfs'] ?? NULL;
357 if (!is_array($vcfs) or empty($vcfs)) {
358 drupal_json_output(
"No VCF file ids were provided");
363 $state[
'vcf_replace'] = array();
364 foreach ($vcfs as $org_num => $fid) {
365 if (!file_load($fid)) {
366 if (!is_string($fid)) {
367 drupal_json_output(
"Could not load one or more VCFs from file ID");
370 elseif (!file_exists($fid)) {
371 drupal_json_output(
"One or more VCF local paths was invalid");
375 $existing_files = file_load_multiple(FALSE, array(
'uri' => $fid));
376 if (!empty($existing_files)) {
377 $file = current($existing_files);
380 $file =
new stdClass();
383 $file->filename = drupal_basename($fid);
384 $file->filemime = file_get_mimetype($file->uri);
385 $file->uid = $user->uid;
387 $file = file_save($file);
390 $vcfs[$org_num] = $file->fid;
391 $state[
'vcf_replace'][$org_num] = $file->fid;
395 if (empty($state[
'vcf_replace'])) {
396 unset($state[
'vcf_replace']);
399 $state[
'vcf_val_errors'] = array();
400 $state[
'vcf_validated'] = FALSE;
404 foreach ($vcfs as $org_num => $fid) {
406 $includes[] = module_load_include(
'inc',
'tpps',
'includes/form_utils');
407 $includes[] = module_load_include(
'inc',
'tpps',
'includes/file_parsing');
408 $args = array($accession, $fid, $org_num);
409 $jobs[] = tripal_add_job(
"{$accession} Pre-validate VCF {$fid}",
'tpps',
'tpps_pre_validate', $args, $user->uid, 10, $includes, TRUE);
411 drupal_get_messages(
'status', TRUE);
413 drupal_json_output($jobs);
425 $job = tripal_get_job($jid);
427 if ($job->status ==
'Completed') {
429 $job->val_errors = $state[
'vcf_val_errors'] ?? array();
430 if (empty($job->val_errors)) {
431 $state[
'vcf_validated'] = TRUE;
436 drupal_json_output($job);
455 $job->logMessage(
"[INFO] TGDR Accession: $accession");
456 $job->logMessage(
"[INFO] VCF File ID: $fid");
457 $job->logMessage(
"[INFO] Organism Number: $org_num");
458 $vcf_file = file_load($fid);
460 $job->logMessage(
"[ERROR] VCF File failed to load", array(), TRIPAL_ERROR);
463 $job->logMessage(
"[INFO] VCF File Location: {$vcf_file->uri}");
466 if (empty($state[
'saved_values'][
TPPS_PAGE_3][
'tree-accession'][
'check'])) {
467 $species_index =
'species-1';
470 $species_index =
"species-$org_num";
472 $tree_accession_file = $state[
'saved_values'][
TPPS_PAGE_3][
'tree-accession'][$species_index][
'file'];
473 $id_col_accession_name = $state[
'saved_values'][
TPPS_PAGE_3][
'tree-accession'][$species_index][
'file-groups'][
'Tree Id'][
'1'];
476 $job->logMessage(
"[INFO] Extracting VCF archive...");
478 $job->logMessage(
"[INFO] Opening $location...");
479 $vcf_content = gzopen($location,
'r');
481 while (($vcf_line = gzgets($vcf_content)) !== FALSE) {
482 if (preg_match(
'/#CHROM/', $vcf_line)) {
483 $vcf_line = explode(
"\t", $vcf_line);
484 for ($j = 9; $j < count($vcf_line); $j++) {
485 $stocks[] = trim($vcf_line[$j]);
491 $state_errors = $state[
'vcf_val_errors'] ?? array();
492 if (count($stocks) == 0) {
493 $message =
"unable to parse Plant Identifiers. The format of your VCF file must be invalid";
494 $job->logMessage(
"[ERROR] $message", array(), TRIPAL_ERROR);
495 $state_errors[] =
"Genotype VCF File: $message";
498 $missing_plants = array();
499 foreach ($stocks as $stock_id) {
500 if (array_search($stock_id, $accession_ids) === FALSE) {
501 $missing_plants[] = $stock_id;
504 if (count($missing_plants) > 0) {
505 $missing_plants = implode(
', ', $missing_plants);
506 $message =
"We found Plant Identifiers in your VCF file that were not present in your accession file. Please either add these plants to your accession file or remove them from your VCF file. The missing plants are: {$missing_plants}.";
507 $job->logMessage(
"[ERROR] $message", array(), TRIPAL_ERROR);
508 $state_errors[] =
"Genotype VCF File: $message";
512 if (empty($state_errors)) {
513 $job->logMessage(
"[INFO] VCF Validated successfully - no errors!");
516 $state[
'vcf_val_errors'] = $state_errors;
tpps_update_submission(array $state, array $options=array())
tpps_parse_file_column($fid, $column, $no_header=FALSE)
tpps_load_submission($accession, $state=TRUE)
tpps_get_location($location)