Tripal Plant PopGen Submit
page_4.php
Go to the documentation of this file.
1 <?php
2 
16 function tpps_page_4_validate_form(array &$form, array &$form_state) {
17 
18  if ($form_state['submitted'] == '1') {
19  unset($form_state['file_info'][TPPS_PAGE_4]);
20 
21  $form_values = $form_state['values'];
22  $organism_number = $form_state['saved_values'][TPPS_PAGE_1]['organism']['number'];
23 
24  for ($i = 1; $i <= $organism_number; $i++) {
25  $organism = $form_values["organism-$i"];
26 
27  if ($i > 1 and isset($organism['phenotype-repeat-check']) and $organism['phenotype-repeat-check'] == '1') {
28  unset($form_state['values']["organism-$i"]['phenotype']);
29  }
30  if (isset($form_state['values']["organism-$i"]['phenotype'])) {
31  tpps_validate_phenotype($form_state['values']["organism-$i"]['phenotype'], $i, $form, $form_state);
32  }
33 
34  if ($i > 1 and isset($organism['genotype-repeat-check']) and $organism['genotype-repeat-check'] == '1') {
35  unset($form_state['values']["organism-$i"]['genotype']);
36  }
37  if (isset($form_state['values']["organism-$i"]['genotype'])) {
38  tpps_validate_genotype($form_state['values']["organism-$i"]['genotype'], $i, $form, $form_state);
39  }
40 
41  if ($i > 1 and isset($organism['environment-repeat-check']) and $organism['environment-repeat-check'] == '1') {
42  unset($form_state['values']["organism-$i"]['environment']);
43  }
44  if (isset($form_state['values']["organism-$i"]['environment'])) {
45  tpps_validate_environment($form_state['values']["organism-$i"]['environment'], "organism-$i");
46  }
47  }
48 
49  if (form_get_errors() and !$form_state['rebuild']) {
50  $form_state['rebuild'] = TRUE;
51  $new_form = drupal_rebuild_form('tpps_main', $form_state, $form);
52 
53  for ($i = 1; $i <= $organism_number; $i++) {
54 
55  if (isset($new_form["organism-$i"]['phenotype']['metadata']['upload'])) {
56  $form["organism-$i"]['phenotype']['metadata']['upload'] = $new_form["organism-$i"]['phenotype']['metadata']['upload'];
57  $form["organism-$i"]['phenotype']['metadata']['upload']['#id'] = "edit-organism-$i-phenotype-metadata-upload";
58  }
59  if (isset($new_form["organism-$i"]['phenotype']['metadata']['columns'])) {
60  $form["organism-$i"]['phenotype']['metadata']['columns'] = $new_form["organism-$i"]['phenotype']['metadata']['columns'];
61  $form["organism-$i"]['phenotype']['metadata']['columns']['#id'] = "edit-organism-$i-phenotype-metadata-columns";
62  }
63 
64  if (isset($form["organism-$i"]['phenotype']['file'])) {
65  $form["organism-$i"]['phenotype']['file']['upload'] = $new_form["organism-$i"]['phenotype']['file']['upload'];
66  $form["organism-$i"]['phenotype']['file']['columns'] = $new_form["organism-$i"]['phenotype']['file']['columns'];
67  $form["organism-$i"]['phenotype']['file']['upload']['#id'] = "edit-organism-$i-phenotype-file-upload";
68  $form["organism-$i"]['phenotype']['file']['columns']['#id'] = "edit-organism-$i-phenotype-file-columns";
69  }
70 
71  $file_types = array(
72  'snps-assay',
73  'other',
74  );
75 
76  $field_types = array(
77  'upload',
78  'columns',
79  );
80 
81  foreach ($file_types as $type) {
82  foreach ($field_types as $field) {
83  if (isset($form["organism-$i"]['genotype']['files'][$type][$field]) and isset($new_form["organism-$i"]['genotype']['files'][$type][$field])) {
84  $form["organism-$i"]['genotype']['files'][$type][$field] = $new_form["organism-$i"]['genotype']['files'][$type][$field];
85  $form["organism-$i"]['genotype']['files'][$type][$field]['#id'] = "edit-organism-$i-genotype-files-{$type}-{$field}";
86  }
87  }
88  }
89  }
90  }
91  }
92 }
93 
106 function tpps_validate_phenotype(array $phenotype, $org_num, array $form, array &$form_state) {
107  $normal_check = $phenotype['normal-check'];
108  $iso_check = $phenotype['iso-check'];
109  $id = "organism-$org_num";
110  $thirdpage = $form_state['saved_values'][TPPS_PAGE_3];
111 
112  if (empty($normal_check) and empty($iso_check)) {
113  form_set_error("$id][phenotype][normal-check", t("Please choose at least one category of phenotypes to upload"));
114  }
115 
116  if ($normal_check) {
117  $phenotype_number = $phenotype['phenotypes-meta']['number'];
118  $phenotype_check = $phenotype['check'];
119  $phenotype_meta = $phenotype['metadata'];
120  $phenotype_file = $phenotype['file'];
121 
122  if ($phenotype_check == '1' and empty($phenotype_meta)) {
123  form_set_error("$id][phenotype][metadata", t("Phenotype Metadata File: field is required."));
124  }
125  if ($phenotype_check == '1' and !empty($phenotype_meta)) {
126  $required_groups = array(
127  'Phenotype Id' => array(
128  'id' => array(1),
129  ),
130  'Attribute' => array(
131  'attr' => array(2),
132  ),
133  'Description' => array(
134  'desc' => array(3),
135  ),
136  'Units' => array(
137  'units' => array(4),
138  ),
139  'Structure' => array(
140  'structure' => array(5),
141  ),
142  );
143 
144  $file_element = $form[$id]['phenotype']['metadata'];
145  $groups = tpps_file_validate_columns($form_state, $required_groups, $file_element);
146  if (!form_get_errors()) {
147  // Get phenotype name column.
148  $phenotype_name_col = $groups['Phenotype Id']['1'];
149 
150  // Preserve file if it is valid.
151  tpps_preserve_valid_file($form_state, $form_state['values'][$id]['phenotype']['metadata'], $org_num, "Phenotype_Metadata");
152  }
153  }
154 
155  for ($i = 1; $i <= $phenotype_number; $i++) {
156  $current_phenotype = $phenotype['phenotypes-meta']["$i"];
157  $name = $current_phenotype['name'];
158  $description = $current_phenotype['description'];
159  $units = $current_phenotype['units'];
160 
161  if ($name == '') {
162  form_set_error("$id][phenotype][phenotypes-meta][$i][name", "Phenotype $i Name: field is required.");
163  }
164 
165  if (!$current_phenotype['attribute']) {
166  form_set_error("$id][phenotype][phenotypes-meta][$i][attribute", "Phenotype $i Attribute: field is required.");
167  }
168 
169  if ($current_phenotype['attribute'] == 'other' and $current_phenotype['attr-other'] == '') {
170  form_set_error("$id][phenotype][phenotypes-meta][$i][attr-other", "Phenotype $i Custom Attribute: field is required.");
171  }
172 
173  if ($description == '') {
174  form_set_error("$id][phenotype][phenotypes-meta][$i][description", "Phenotype $i Description: field is required.");
175  }
176 
177  if ($units == '') {
178  form_set_error("$id][phenotype][phenotypes-meta][$i][units", "Phenotype $i Units: field is required.");
179  }
180  elseif ($units == 'other' and $current_phenotype['unit-other'] == '') {
181  form_set_error("$id][phenotype][phenotypes-meta][$i][unit-other", "Phenotype $i Custom Unit: field is required.");
182  }
183 
184  if ($current_phenotype['structure'] == 'other' and $current_phenotype['struct-other'] == '') {
185  form_set_error("$id][phenotype][phenotypes-meta][$i][struct-other", "Phenotype $i Custom Structure: field is required.");
186  }
187 
188  if (($current_phenotype['val-check'] or $current_phenotype['bin-check'] or $current_phenotype['units'] == tpps_load_cvterm('boolean')->cvterm_id) and $current_phenotype['min'] == '') {
189  form_set_error("$id][phenotype][phenotypes-meta][$i][min", "Phenotype $i Minimum Value: field is required.");
190  }
191 
192  if (($current_phenotype['val-check'] or $current_phenotype['bin-check'] or $current_phenotype['units'] == tpps_load_cvterm('boolean')->cvterm_id) and $current_phenotype['max'] == '') {
193  form_set_error("$id][phenotype][phenotypes-meta][$i][max", "Phenotype $i Maximum Value: field is required.");
194  }
195  }
196 
197  if ($phenotype['time']['time-check']) {
198  foreach ($phenotype['time']['time_phenotypes'] as $key => $val) {
199  if (!$val) {
200  unset($form_state['values'][$id]['phenotype']['time']['time_phenotypes'][$key]);
201  unset($form_state['values'][$id]['phenotype']['time']['time_values'][$key]);
202  }
203  }
204  if (empty($form_state['values'][$id]['phenotype']['time']['time_phenotypes'])) {
205  form_set_error("$id][phenotype][time][time_phenotypes", t("Time-based Phenotypes: field is required."));
206  }
207  }
208 
209  if (empty($phenotype_file)) {
210  form_set_error("$id][phenotype][file", t("Phenotypes: field is required."));
211  }
212  if (!empty($phenotype_file)) {
213  $required_groups = array(
214  'Tree Identifier' => array(
215  'id' => array(1),
216  ),
217  'Phenotype Data' => array(
218  'phenotype-data' => array(0),
219  ),
220  );
221  if ($phenotype['format'] != 0) {
222  $required_groups = array(
223  'Tree Identifier' => array(
224  'id' => array(1),
225  ),
226  'Phenotype Name/Identifier' => array(
227  'phenotype-name' => array(2),
228  ),
229  'Phenotype Value(s)' => array(
230  'val' => array(3),
231  ),
232  );
233  }
234 
235  $file_element = $form[$id]['phenotype']['file'];
236  $groups = tpps_file_validate_columns($form_state, $required_groups, $file_element);
237 
238  if (!form_get_errors()) {
239  $phenotype_file_tree_col = $groups['Tree Identifier']['1'];
240  $phenotype_names = array();
241  if ($phenotype['format'] == 0) {
242  $phenotype_file_name_cols = $groups['Phenotype Data']['0'];
243  $headers = tpps_file_headers($phenotype_file, !empty($phenotype['file-no-header']));
244  foreach ($phenotype_file_name_cols as $column_index) {
245  $phenotype_names[] = $headers[$column_index];
246  }
247  }
248  if ($phenotype['format'] != 0) {
249  $phenotype_file_name_col = $groups['Phenotype Name/Identifier']['2'];
250  $phenotype_names = tpps_parse_file_column($phenotype_file, $phenotype_file_name_col);
251  }
252 
253  $phenotype_meta_names = array();
254  if (isset($phenotype_name_col)) {
255  $phenotype_meta_names = tpps_parse_file_column($phenotype_meta, $phenotype_name_col);
256  }
257 
258  for ($i = 1; $i <= $phenotype_number; $i++) {
259  $phenotype_meta_names[] = $phenotype['phenotypes-meta'][$i]['name'];
260  }
261  $missing_phenotypes = array_diff($phenotype_names, $phenotype_meta_names);
262  if (!empty($missing_phenotypes)) {
263  $phenotype_id_str = implode(', ', $missing_phenotypes);
264  form_set_error("$id][phenotype][file", "Phenotype file: We detected Phenotypes that were not in your Phenotype Metadata file. Please either remove these phenotypes from your Phenotype file, or add them to your Phenotype Metadata file. The phenotypes we detected with missing definitions were: $phenotype_id_str");
265  }
266 
267  if (isset($phenotype_file_tree_col)) {
268  $species_index = empty($thirdpage['tree-accession']['check']) ? 'species-1' : "species-$org_num";
269  $tree_accession_file = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file'];
270  $column_vals = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file-columns'];
271 
272  foreach ($column_vals as $col => $val) {
273  if ($val == '1') {
274  $id_col_accession_name = $col;
275  break;
276  }
277  }
278  $acc_no_header = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file-no-header'];
279  $phenotype_no_header = $form_state['values'][$id]['phenotype']['file-no-header'];
280  $missing_trees = tpps_compare_files($form_state['values'][$id]['phenotype']['file'], $tree_accession_file, $phenotype_file_tree_col, $id_col_accession_name, $phenotype_no_header, $acc_no_header);
281  if ($missing_trees !== array()) {
282  $tree_id_str = implode(', ', $missing_trees);
283  form_set_error("$id][phenotype][file", "Phenotype file: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your Phenotype file, or add them to your Plant Accession file. The Plant Identifiers we found were: $tree_id_str");
284  }
285  }
286  }
287 
288  // Preserve file if it is valid.
289  tpps_preserve_valid_file($form_state, $form_state['values'][$id]['phenotype']['file'], $org_num, "Phenotype_Data");
290  }
291  }
292 
293  if ($iso_check) {
294  if (empty($phenotype['iso'])) {
295  form_set_error("$id][phenotype][iso", t("Phenotype Isotope/Mass Spectrometry File: field is required."));
296  }
297 
298  if (!form_get_errors()) {
299  $headers = tpps_file_headers($phenotype['iso']);
300  $id_col_name = key($headers);
301  while (($k = array_search(NULL, $headers))) {
302  unset($headers[$k]);
303  }
304  $num_columns = tpps_file_width($phenotype['iso']) - 1;
305  $num_unique_columns = count(array_unique($headers)) - 1;
306 
307  if ($num_unique_columns != $num_columns) {
308  form_set_error("$id][phenotype][iso", t("Mass spectrometry/Isotope file: some columns in the file you provided are missing or have duplicate header values. Please either enter valid header values for those columns or remove those columns, then reupload your file."));
309  }
310  }
311 
312  if (!form_get_errors()) {
313  $species_index = empty($thirdpage['tree-accession']['check']) ? 'species-1' : "species-$org_num";
314  $tree_accession_file = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file'];
315  $id_col_accession_name = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file-groups']['Tree Id']['1'];
316 
317  $acc_no_header = $form_state['saved_values'][TPPS_PAGE_3]['tree-accession'][$species_index]['file-no-header'];
318  $missing_trees = tpps_compare_files($phenotype['iso'], $tree_accession_file, $id_col_name, $id_col_accession_name, FALSE, $acc_no_header);
319 
320  if ($missing_trees !== array()) {
321  $tree_id_str = implode(', ', $missing_trees);
322  form_set_error("$id][phenotype][iso", "Mass spectrometry/Isotope file: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your file, or add them to your Plant Accession file. The Plant Identifiers we found were: $tree_id_str");
323  }
324  }
325 
326  // Preserve file if it is valid.
327  tpps_preserve_valid_file($form_state, $phenotype['iso'], $org_num, "Phenotype_Data");
328  }
329 }
330 
343 function tpps_validate_genotype(array $genotype, $org_num, array $form, array &$form_state) {
344  $id = "organism-$org_num";
345  $snps = $genotype['SNPs'];
346  $ref_genome = $genotype['ref-genome'];
347  $file_type = $genotype['files']['file-type'];
348  $vcf = isset($genotype['files']['vcf']) ? $genotype['files']['vcf'] : 0;
349  $snps_assay = isset($genotype['files']['snps-assay']) ? $genotype['files']['snps-assay'] : 0;
350  $assoc_file = $genotype['files']['snps-association'] ?? 0;
351  $other_file = isset($genotype['files']['other']) ? $genotype['files']['other'] : 0;
352  $thirdpage = $form_state['saved_values'][TPPS_PAGE_3];
353  $species_index = empty($thirdpage['tree-accession']['check']) ? 'species-1' : "species-$org_num";
354  $tree_accession_file = $thirdpage['tree-accession'][$species_index]['file'];
355  $id_col_accession_name = $thirdpage['tree-accession'][$species_index]['file-groups']['Tree Id']['1'];
356 
357  if (!$ref_genome) {
358  form_set_error("$id][genotype][ref-genome", t("Reference Genome: field is required."));
359  }
360  elseif ($ref_genome === 'bio') {
361  if (!$genotype['tripal_eutils']['accession']) {
362  form_set_error("$id][genotype][tripal_eutils][accession", t('NCBI Accession Number: field is required.'));
363  }
364  $connection = new \EUtils();
365  try {
366  $connection->setPreview();
367  $parsed = $connection->get($genotype['tripal_eutils']['db'], $genotype['tripal_eutils']['accession']);
368  foreach ($_SESSION['messages']['status'] as $key => $message) {
369  if ($message == '<pre>biosample</pre>') {
370  unset($_SESSION['messages']['status'][$key]);
371  if (empty($_SESSION['messages']['status'])) {
372  unset($_SESSION['messages']['status']);
373  }
374  break;
375  }
376  }
377  $form_state['values']['parsed'] = $parsed;
378  }
379  catch (\Exception $e) {
380  form_set_error("$id][genotype][tripal_eutils][accession", $e->getMessage());
381  }
382  }
383  elseif ($ref_genome === 'url' or $ref_genome === 'manual' or $ref_genome === 'manual2') {
384 
385  $class = 'FASTAImporter';
386  tripal_load_include_importer_class($class);
387  $fasta_vals = $genotype['tripal_fasta'];
388 
389  $file_upload = isset($fasta_vals['file']['file_upload']) ? trim($fasta_vals['file']['file_upload']) : 0;
390  $file_existing = isset($fasta_vals['file']['file_upload_existing']) ? trim($fasta_vals['file']['file_upload_existing']) : 0;
391  $file_remote = isset($fasta_vals['file']['file_remote']) ? trim($fasta_vals['file']['file_remote']) : 0;
392  $db_id = trim($fasta_vals['db']['db_id']);
393  $re_accession = trim($fasta_vals['db']['re_accession']);
394  $analysis_id = trim($fasta_vals['analysis_id']);
395  $seqtype = trim($fasta_vals['seqtype']);
396 
397  if (!$file_upload and !$file_existing and !$file_remote) {
398  form_set_error("$id][genotype][tripal_fasta][file", t("Assembly file: field is required."));
399  }
400 
401  if ($db_id and !$re_accession) {
402  form_set_error("$id][genotype][tripal_fasta][additional][re_accession", t('Accession regular expression: field is required.'));
403  }
404  if ($re_accession and !$db_id) {
405  form_set_error("$id][genotype][tripal_fasta][additional][db_id", t('External Database: field is required.'));
406  }
407 
408  if (!$analysis_id) {
409  form_set_error("$id][genotype][tripal_fasta][analysis_id", t('Analysis: field is required.'));
410  }
411  if (!$seqtype) {
412  form_set_error("$id][genotype][tripal_fasta][seqtype", t('Sequence Type: field is required.'));
413  }
414 
415  if (!form_get_errors()) {
416  $assembly = $file_existing ? $file_existing : ($file_upload ? $file_upload : $file_remote);
417  }
418  }
419 
420  if (implode('', $genotype['marker-type']) === '000') {
421  form_set_error("$id][genotype][marker-type", t("Genotype Marker Type: field is required."));
422  }
423  elseif ($genotype['marker-type']['SNPs']) {
424  if (!$snps['genotyping-design']) {
425  form_set_error("$id][genotype][SNPs][genotyping-design", t("Genotyping Design: field is required."));
426  }
427  elseif ($snps['genotyping-design'] == '1') {
428  if (!$snps['GBS']) {
429  form_set_error("$id][genotype][SNPs][GBS", t("GBS Type: field is required."));
430  }
431  elseif ($snps['GBS'] == '5' and !$snps['GBS-other']) {
432  form_set_error("$id][genotype][SNPs][GBS=other", t("Custom GBS Type: field is required."));
433  }
434  }
435  elseif ($snps['genotyping-design'] == '2') {
436  if (!$snps['targeted-capture']) {
437  form_set_error("$id][genotype][SNPs][targeted-capture", t("Targeted Capture: field is required."));
438  }
439  elseif ($snps['targeted-capture'] == '2' and !$snps['targeted-capture-other']) {
440  form_set_error("$id][genotype][SNPs][targeted-capture-other", t("Custom Targeted Capture: field is required."));
441  }
442  }
443  }
444  elseif ($genotype['marker-type']['SSRs/cpSSRs'] and empty($genotype['SSRs/cpSSRs'])) {
445  form_set_error("$id][genotype][SSRs/cpSSRs", t("SSRs/cpSSRs: field is required."));
446  }
447  elseif ($genotype['marker-type']['SSRs/cpSSRs'] and empty($genotype['files']['ploidy'])) {
448  form_set_error("$id][genotype][files][ploidy", t("Ploidy: field is required."));
449  }
450  elseif ($genotype['marker-type']['Other'] and empty($genotype['other-marker'])) {
451  form_set_error("$id][genotype][other-marker", t("Other Genotype marker: field is required."));
452  }
453 
454  if (preg_match('/^0+$/', implode('', $file_type))) {
455  form_set_error("$id][genotype][files][file-type", t("Genotype File Type: field is required."));
456  return;
457  }
458  $loaded_state = tpps_load_submission($form_state['accession']);
459  //$vcf = '';
460  if (!empty($loaded_state['vcf_replace'])) {
461  foreach ($loaded_state['vcf_replace'] as $org_num => $fid) {
462  if (file_load($fid)) {
463  $form_state['values']["organism-$org_num"]['genotype']['files']['vcf'] = $fid;
464  $vcf = $fid;
465  $form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf_check'] = NULL;
466  $form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf'] = NULL;
467  }
468  if (!file_load($fid)) {
469  form_set_error("$org_num][genotype][files][local_vcf", t("Local VCF File: File could not be loaded properly."));
470  }
471  }
472  }
473 
474  if (!empty($file_type['VCF']) and !$vcf and trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']) == '') {
475  form_set_error("$id][genotype][files][vcf", t("Genotype VCF File: field is required."));
476  }
477  elseif (!empty($file_type['VCF'])) {
478  if (($ref_genome === 'manual' or $ref_genome === 'manual2' or $ref_genome === 'url') and isset($assembly) and $assembly and !form_get_errors()) {
479  if (trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']) != '') {
480  $local_vcf_path = trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']);
481  $vcf_content = gzopen($local_vcf_path, 'r');
482  }
483  else {
484  $vcf_content = gzopen(file_load($vcf)->uri, 'r');
485  }
486  $assembly_content = gzopen(file_load($assembly)->uri, 'r');
487 
488  while (($vcf_line = gzgets($vcf_content)) !== FALSE) {
489  if ($vcf_line[0] != '#') {
490 
491  $vcf_values = explode("\t", $vcf_line);
492  $scaffold_id = $vcf_values[0];
493  $match = FALSE;
494 
495  while (($assembly_line = gzgets($assembly_content)) !== FALSE) {
496  if ($assembly_line[0] != '>') {
497  continue;
498  }
499  if (preg_match('/^(.*?)\s.*$/', $assembly_line, $matches)) {
500  $assembly_scaffold = $matches[1];
501  }
502  if ($assembly_scaffold[0] == '>') {
503  $assembly_scaffold = substr($assembly_scaffold, 1);
504  }
505  if ($assembly_scaffold == $scaffold_id) {
506  $match = TRUE;
507  break;
508  }
509  }
510  if (!$match) {
511  fclose($assembly_content);
512  $assembly_content = gzopen(file_load($assembly)->uri, 'r');
513  while (($assembly_line = gzgets($assembly_content)) !== FALSE) {
514  if ($assembly_line[0] != '>') {
515  continue;
516  }
517  if (preg_match('/^(.*?)\s.*$/', $assembly_line, $matches)) {
518  $assembly_scaffold = $matches[1];
519  }
520  if ($assembly_scaffold[0] == '>') {
521  $assembly_scaffold = substr($assembly_scaffold, 1);
522  }
523  if ($assembly_scaffold == $scaffold_id) {
524  $match = TRUE;
525  break;
526  }
527  }
528  }
529 
530  if (!$match) {
531  form_set_error("$id][genotype][files][vcf", t("VCF File: scaffold @scaffold_id not found in assembly file(s)", array('@scaffold_id' => $scaffold_id)));
532  }
533  }
534  }
535 
536  }
537  if (empty($loaded_state['vcf_replace']) && trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']) != '') {
538  form_set_error("$org_num][genotype][files][local_vcf", t("Local VCF File: File needs to be pre-validated. Please click on Pre-validate my VCF files button at the bottom."));
539  }
540 
541  if (!empty($loaded_state['vcf_validated']) and $loaded_state['vcf_validated'] === TRUE and empty($loaded_state['vcf_val_errors'])) {
542  drupal_set_message(t('VCF files pre-validated. Skipping VCF file validation'));
543  }
544  elseif (!form_get_errors()) {
545  $accession_ids = tpps_parse_file_column($tree_accession_file, $id_col_accession_name);
546  $vcf_file = file_load($vcf);
547  if (trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']) != '') {
548  $location = trim($form_state['values']["organism-$org_num"]['genotype']['files']['local_vcf']);
549  }
550  else {
551  $location = tpps_get_location($vcf_file->uri);
552  }
553  $vcf_content = gzopen($location, 'r');
554  $stocks = array();
555  while (($vcf_line = gzgets($vcf_content)) !== FALSE) {
556  if (preg_match('/#CHROM/', $vcf_line)) {
557  $vcf_line = explode("\t", $vcf_line);
558  for ($j = 9; $j < count($vcf_line); $j++) {
559  $stocks[] = trim($vcf_line[$j]);
560  }
561  break;
562  }
563  }
564 
565  if (count($stocks) == 0) {
566  form_set_error("$id][genotype][files][vcf", t("Genotype VCF File: unable to parse Plant Identifiers. The format of your VCF file must be invalid"));
567  }
568 
569  if (count($stocks) != 0) {
570  $missing_plants = array();
571  foreach ($stocks as $stock_id) {
572  if (array_search($stock_id, $accession_ids) === FALSE) {
573  $missing_plants[] = $stock_id;
574  }
575  }
576  if (count($missing_plants) > 0) {
577  $missing_plants = implode(', ', $missing_plants);
578  form_set_error("$id][genotype][files][vcf", t("Genotype VCF File: 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.", array('@missing_plants' => $missing_plants)));
579  }
580  }
581 
582  if (!form_get_errors()) {
583  $form_state['values'][$id]['genotype']['files']['vcf_genotype_count'] = tpps_file_len($vcf);
584  }
585  }
586 
587  // Preserve file if it is valid.
588  tpps_preserve_valid_file($form_state, $vcf, $org_num, "Genotype_VCF");
589  }
590 
591  if (!empty($file_type['SNPs Genotype Assay']) and !$snps_assay) {
592  form_set_error("$id][genotype][files][snps-assay", t("SNPs Assay file: field is required."));
593  }
594  elseif (!empty($file_type['SNPs Genotype Assay'])) {
595  $headers = tpps_file_headers($snps_assay);
596  $id_col_name = key($headers);
597  while (($k = array_search(NULL, $headers))) {
598  drupal_set_message(t('Following header column is Null which needs to be fixed. %data', array('%data' => $k)), 'error');
599  unset($headers[$k]);
600  }
601  $num_columns = tpps_file_width($snps_assay) - 1;
602  $num_unique_columns = count(array_unique($headers)) - 1;
603  if ($num_unique_columns != $num_columns) {
604  $duplicates = array_diff_assoc($headers, array_unique($headers));
605  if (!empty($duplicates)) {
606  drupal_set_message(t('Following header values are duplicate in provided snp file. %data', array('%data' => implode(',', $duplicates))), 'error');
607  }
608  form_set_error("$id][genotype][files][snps-assay", t("SNPs Assay file: some columns in the file you provided are missing or have duplicate header values. Please either enter valid header values for those columns or remove those columns, then reupload your file."));
609  }
610 
611  if (!form_get_errors()) {
612  $acc_no_header = $thirdpage['tree-accession'][$species_index]['file-no-header'];
613  $missing_trees = tpps_compare_files($snps_assay, $tree_accession_file, $id_col_name, $id_col_accession_name, FALSE, $acc_no_header);
614  if ($missing_trees !== array()) {
615  $tree_id_str = implode(', ', $missing_trees);
616  form_set_error("$id][genotype][files][snps-assay", t("SNPs Assay file: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your Genotype file, or add them to your Plant Accession file. The Plant Identifiers we found were: @tree_id_str", array('@tree_id_str' => $tree_id_str)));
617  }
618  }
619 
620  // Preserve file if it is valid.
621  tpps_preserve_valid_file($form_state, $snps_assay, $org_num, "Genotype_SNPs_Assay");
622 
623  if (!form_get_errors()) {
624  if (!empty($file_type['SNPs Associations']) and !$assoc_file) {
625  form_set_error("$id][genotype][files][snps-association", t("SNPs Associations file: field is required."));
626  }
627  elseif (!empty($file_type['SNPs Associations'])) {
628  $required_groups = array(
629  'SNP ID' => array(
630  'id' => array(1),
631  ),
632  'Scaffold' => array(
633  'scaffold' => array(2),
634  ),
635  'Position' => array(
636  'position' => array(3),
637  ),
638  'Allele' => array(
639  'allele' => array(4),
640  ),
641  'Associated Trait' => array(
642  'trait' => array(5),
643  ),
644  'Confidence Value' => array(
645  'confidence' => array(6),
646  ),
647  );
648 
649  $file_element = $form[$id]['genotype']['files']['snps-association'];
650  $groups = tpps_file_validate_columns($form_state, $required_groups, $file_element);
651 
652  if (!form_get_errors()) {
653  // Check that SNP IDs match Genotype Assay.
654  $snps_id_col = $groups['SNP ID'][1];
655  $assoc_no_header = $genotype['files']['snps-association-no-header'] ?? FALSE;
656 
657  $assay_snps = tpps_file_headers($snps_assay);
658  unset($assay_snps[key($assay_snps)]);
659  $assoc_snps = tpps_parse_file_column($assoc_file, $snps_id_col, $assoc_no_header);
660  $missing_snps = array_diff($assoc_snps, $assay_snps);
661 
662  if ($missing_snps !== array()) {
663  $snps_id_str = implode(', ', $missing_snps);
664  form_set_error("$id][genotype][files][snps-association", t("SNPs Association File: We detected SNP IDs that were not in your Genotype Assay. Please either remove these SNPs from your Association file, or add them to your Genotype Assay. The SNP Identifiers we found were: @snps_id_str", array('@snps_id_str' => $snps_id_str)));
665  }
666 
667  // Check that Phenotype names match phenotype metadata section.
668  $trait_id_col = $groups['Associated Trait'][5];
669  $association_phenotypes = tpps_parse_file_column($assoc_file, $trait_id_col, $assoc_no_header);
670 
671  $phenotype = $form_state['values'][$id]['phenotype'];
672  $phenotype_meta = $phenotype['metadata'];
673  $phenotype_number = $phenotype['phenotypes-meta']['number'];
674 
675  $phenotype_meta_names = array();
676  $phenotype_name_col = $form_state['values'][$id]['phenotype']['metadata-groups']['Phenotype Id']['1'] ?? NULL;
677  if (isset($phenotype_name_col)) {
678  $phenotype_meta_names = tpps_parse_file_column($phenotype_meta, $phenotype_name_col);
679  }
680 
681  for ($i = 1; $i <= $phenotype_number; $i++) {
682  $phenotype_meta_names[] = $phenotype['phenotypes-meta'][$i]['name'];
683  }
684 
685  $missing_phenotypes = array_diff($association_phenotypes, $phenotype_meta_names);
686  if ($missing_phenotypes !== array()) {
687  $phenotype_names_str = implode(', ', $missing_phenotypes);
688  form_set_error("$id][genotype][files][snps-association", "SNPs Association File: We detected Associated Traits that were not specified in the Phenotype Metadata Section. Please either remove these Traits from your Association file, or add them to your Phenotype Metadata section. The Trait names we foud were: $phenotype_names_str");
689  }
690 
691  // Check that position values are correctly formatted.
692  $position_col = $groups['Position'][3];
693  $positions = tpps_parse_file_column($assoc_file, $position_col, $assoc_no_header);
694  foreach ($positions as $position) {
695  if (!preg_match('/^(\d+):(\d+)$/', $position)) {
696  form_set_error("$id][genotype][files][snps-association", t('SNPs Association File: We detected SNP positions that do not match the required format. The correct format is: "start:stop".'));
697  break;
698  }
699  }
700  }
701 
702  // Preserve file if it is valid.
703  tpps_preserve_valid_file($form_state, $assoc_file, $org_num, "SNPs_Association");
704 
705  if (empty($genotype['files']['snps-association-type'])) {
706  form_set_error("$id][genotype][files][snps-association-type", t("SNPs Association Type: field is required."));
707  }
708 
709  if (empty($genotype['files']['snps-association-tool'])) {
710  form_set_error("$id][genotype][files][snps-association-tool", t("SNPs Association Tool: field is required."));
711  }
712 
713  if (!empty($genotype['files']['snps-pop-struct'])) {
714  // Preserve file if it is valid.
715  tpps_preserve_valid_file($form_state, $genotype['files']['snps-pop-struct'], $org_num, "SNPs_Population_Structure");
716  }
717 
718  if (!empty($genotype['files']['snps-kinship'])) {
719  // Preserve file if it is valid.
720  tpps_preserve_valid_file($form_state, $genotype['files']['snps-kinship'], $org_num, "SNPs_Kinship");
721  }
722  }
723  }
724  }
725 
726  if (!empty($file_type['Assay Design']) and !$genotype['files']['assay-load']) {
727  form_set_error("$id][genotype][files][assay-load", t("Assay Design: field is required."));
728  }
729  elseif (!empty($file_type['Assay Design']) and $genotype['files']['assay-load'] == 'new' and !$genotype['files']['assay-design']) {
730  form_set_error("$id][genotype][files][assay-design", t("Assay Design file: field is required."));
731  }
732  elseif (!empty($file_type['Assay Design']) and $genotype['files']['assay-load'] == 'new') {
733  // Preserve file if it is valid.
734  tpps_preserve_valid_file($form_state, $genotype['files']['assay-design'], $org_num, "Genotype_Assay_Design");
735  }
736  elseif (!empty($file_type['Assay Design']) and $genotype['files']['assay-load'] != 'new') {
737  $file = file_load($genotype['files']['assay-load']);
738  file_usage_add($file, 'tpps', 'tpps_project', substr($form_state['accession'], 4));
739  $form_state['file_info'][TPPS_PAGE_4][$file->fid] = '#NO_RENAME';
740  }
741 
742  if (!empty($file_type['SSRs/cpSSRs Genotype Spreadsheet']) and !$genotype['files']['ssrs']) {
743  form_set_error("$id][genotype][files][ssrs]", t("SSRs/cpSSRs Spreadsheet: field is required."));
744  }
745  elseif (!empty($file_type['SSRs/cpSSRs Genotype Spreadsheet']) and !empty($genotype['files']['ploidy'])) {
746  $headers = tpps_file_headers($genotype['files']['ssrs']);
747  $form_state['values']["organism-$org_num"]['genotype']['files']['ssrs-empty'] = $form["organism-$org_num"]['genotype']['files']['ssrs']['#value']['empty'];
748  $genotype['files']['ssrs-empty'] = $form_state['values']["organism-$org_num"]['genotype']['files']['ssrs-empty'];
749  $id_col_name = key($headers);
750  while (($k = array_search(NULL, $headers))) {
751  unset($headers[$k]);
752  }
753  $num_columns = tpps_file_width($genotype['files']['ssrs']) - 1;
754  $num_unique_columns = count(array_unique($headers)) - 1;
755 
756  tpps_ssr_valid_ploidy($genotype['files']['ploidy'], $num_columns, $num_unique_columns, "$id][genotype][files][ssrs");
757 
758  if (!empty($genotype['files']['ssr-extra-check'])) {
759  if (empty($genotype['files']['extra-ssr-type'])) {
760  form_set_error("$id][genotype][files][extra-ssr-type", t("Define Additional SSRs/cpSSRs Type: field is required."));
761  }
762 
763  if (!$genotype['files']['ssrs_extra']) {
764  form_set_error("$id][genotype][files][ssrs_extra]", t("SSRs/cpSSRs Additional Spreadsheet: field is required."));
765  }
766  elseif (!empty($genotype['files']['extra-ploidy'])) {
767  $headers = tpps_file_headers($genotype['files']['ssrs_extra']);
768  $id_col_name = key($headers);
769  while (($k = array_search(NULL, $headers))) {
770  unset($headers[$k]);
771  }
772  $num_columns = tpps_file_width($genotype['files']['ssrs_extra']) - 1;
773  $num_unique_columns = count(array_unique($headers)) - 1;
774 
775  tpps_ssr_valid_ploidy($genotype['files']['extra-ploidy'], $num_columns, $num_unique_columns, "$id][genotype][files][ssrs_extra");
776  }
777  }
778 
779  if (!form_get_errors()) {
780  $acc_no_header = $thirdpage['tree-accession'][$species_index]['file-no-header'];
781  $missing_trees = tpps_compare_files($genotype['files']['ssrs'], $tree_accession_file, $id_col_name, $id_col_accession_name, FALSE, $acc_no_header);
782 
783  if ($missing_trees !== array()) {
784  $tree_id_str = implode(', ', $missing_trees);
785  form_set_error("$id][genotype][files][ssrs", t("SSRs/cpSSRs Genotype Spreadsheet: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your Genotype file, or add them to your Plant Accession file. The Plant Identifiers we found were: @tree_id_str", array('@tree_id_str' => $tree_id_str)));
786  }
787  }
788 
789  if (!form_get_errors()) {
790  $options = array(
791  'empty' => $genotype['files']['ssrs-empty'] ?? NULL,
792  'org_num' => $org_num,
793  );
794  tpps_file_iterator($genotype['files']['ssrs'], 'tpps_ssr_valid_values', $options);
795  }
796 
797  // Preserve file if it is valid.
798  tpps_preserve_valid_file($form_state, $genotype['files']['ssrs'], $org_num, "Genotype_SSR_Spreadsheet");
799  if (!empty($genotype['files']['ssrs_extra'])) {
800  tpps_preserve_valid_file($form_state, $genotype['files']['ssrs_extra'], $org_num, "Genotype_SSR_Additional_Spreadsheet");
801  }
802  }
803 
804  if (!empty($file_type['Indel Genotype Spreadsheet']) and !$genotype['files']['indels']) {
805  form_set_error("$id][genotype][files][indels]", t("Indel Genotype Spreadsheet: field is required."));
806  }
807  elseif (!empty($file_type['Indel Genotype Spreadsheet'])) {
808  $indel_fid = $genotype['files']['indels'];
809  $headers = tpps_file_headers($indel_fid);
810  $id_col_name = key($headers);
811  while (($k = array_search(NULL, $headers))) {
812  unset($headers[$k]);
813  }
814  $num_columns = tpps_file_width($indel_fid) - 1;
815  $num_unique_columns = count(array_unique($headers)) - 1;
816 
817  if ($num_unique_columns != $num_columns) {
818  form_set_error("$id][genotype][files][indels", t("Indel Genotype Spreadsheet: some columns in the file you provided are missing or have duplicate header values. Please either enter valid header values for those columns or remove those columns, then reupload your file."));
819  }
820 
821  if (!form_get_errors()) {
822  $acc_no_header = $thirdpage['tree-accession'][$species_index]['file-no-header'];
823  $missing_trees = tpps_compare_files($indel_fid, $tree_accession_file, $id_col_name, $id_col_accession_name, FALSE, $acc_no_header);
824 
825  if ($missing_trees !== array()) {
826  $tree_id_str = implode(', ', $missing_trees);
827  form_set_error("$id][genotype][files][indels", t("Indel Genotype Spreadsheet: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your Genotype file, or add them to your Plant Accession file. The Plant Identifiers we found were: @tree_id_str", array('@tree_id_str' => $tree_id_str)));
828  }
829  }
830 
831  // Preserve file if it is valid.
832  tpps_preserve_valid_file($form_state, $indel_fid, $org_num, "Genotype_Indel_Assay");
833  }
834 
835  if (!empty($file_type['Other Marker Genotype Spreadsheet']) and !$genotype['files']['other']) {
836  form_set_error("$id][genotype][files][other]", t("Other Marker Spreadsheet: field is required."));
837  }
838  elseif (!empty($file_type['Other Marker Genotype Spreadsheet'])) {
839  if (array_key_exists('columns', $form[$id]['genotype']['files']['other'])) {
840  $required_groups = array(
841  'Tree Id' => array(
842  'id' => array(1),
843  ),
844  'Genotype Data' => array(
845  'data' => array(0),
846  ),
847  );
848 
849  $file_element = $form[$id]['genotype']['files']['other'];
850  $groups = tpps_file_validate_columns($form_state, $required_groups, $file_element);
851  // Get Plant Id column name.
852  if (!form_get_errors()) {
853  $id_col_genotype_name = $groups['Tree Id']['1'];
854  }
855  }
856  if (!array_key_exists('columns', $form[$id]['genotype']['files']['other'])) {
857  $headers = tpps_file_headers($genotype['files']['other']);
858  if (!form_get_errors()) {
859  $id_col_genotype_name = key($headers);
860  }
861  }
862 
863  if (!form_get_errors()) {
864  $acc_no_header = $thirdpage['tree-accession'][$species_index]['file-no-header'];
865  $other_no_header = $genotype['files']['other-no-header'] ?? FALSE;
866  $missing_trees = tpps_compare_files($other_file, $tree_accession_file, $id_col_genotype_name, $id_col_accession_name, $other_no_header, $acc_no_header);
867 
868  if ($missing_trees !== array()) {
869  $tree_id_str = implode(', ', $missing_trees);
870  form_set_error("$id][genotype][files][other", "Other Marker Genotype Spreadsheet: We detected Plant Identifiers that were not in your Plant Accession file. Please either remove these plants from your Genotype file, or add them to your Plant Accession file. The Plant Identifiers we found were: $tree_id_str");
871  }
872  }
873 
874  // Preserve file if it is valid.
875  tpps_preserve_valid_file($form_state, $other_file, $org_num, "Genotype_Other_Marker_Spreadsheet");
876  }
877 }
878 
887 function tpps_validate_environment(array &$environment, $id) {
888  // Using cartograplant environment layers.
889  $group_check = FALSE;
890  $new_layers = array();
891  foreach ($environment['env_layers_groups'] as $group_name => $group_id) {
892  if (!empty($group_id)) {
893  $group_check = TRUE;
894  if ($group_name == 'WorldClim v.2 (WorldClim)') {
895  $subgroups_query = db_select('cartogratree_layers', 'l')
896  ->distinct()
897  ->fields('l', array('subgroup_id'))
898  ->condition('group_id', $group_id)
899  ->execute();
900  while (($subgroup = $subgroups_query->fetchObject())) {
901  $subgroup_title = db_select('cartogratree_subgroups', 's')
902  ->fields('s', array('subgroup_name'))
903  ->condition('subgroup_id', $subgroup->subgroup_id)
904  ->execute()
905  ->fetchObject()->subgroup_name;
906  if (!empty($environment['env_layers'][$subgroup_title])) {
907  $new_layers[$subgroup_title] = $environment['env_layers'][$subgroup_title];
908  }
909  }
910  }
911  if ($group_name != 'WorldClim v.2 (WorldClim)') {
912  $layer_query = db_select('cartogratree_layers', 'l')
913  ->fields('l', array('title'))
914  ->condition('group_id', $group_id)
915  ->execute();
916  while (($layer = $layer_query->fetchObject())) {
917  if (!empty($environment['env_layers'][$layer->title])) {
918  $new_layers[$layer->title] = $environment['env_layers'][$layer->title];
919  }
920  }
921  }
922  }
923  }
924 
925  if (!empty($environment['env_layers']['other'])) {
926  if (empty($environment['env_layers']['other_db'])) {
927  form_set_error("$id][environment][env_layers][other_db", t('CartograPlant other environmental layer DB: field is required.'));
928  }
929 
930  if (empty($environment['env_layers']['other_name'])) {
931  form_set_error("$id][environment][env_layers][other_name", t('CartograPlant other environmental layer name: field is required.'));
932  }
933 
934  if (empty($environment['env_layers']['other_params'])) {
935  form_set_error("$id][environment][env_layers][other_params", t('CartograPlant other environmental layer parameters: field is required.'));
936  }
937 
938  if (!form_get_errors()) {
939  $new_layers['other'] = 'other';
940  $new_layers['other_db'] = $environment['env_layers']['other_db'];
941  $new_layers['other_name'] = $environment['env_layers']['other_name'];
942  }
943  }
944 
945  $environment['env_layers'] = $new_layers;
946 
947  if (!$group_check) {
948  form_set_error("$id][environment][env_layers_groups", t('CartograPlant environmental layers groups: field is required.'));
949  }
950  elseif (empty($new_layers)) {
951  form_set_error("$id][environment][env_layers", t('CartograPlant environmental layers: field is required.'));
952  }
953 }
954 
967 function tpps_ssr_valid_values($row, array &$options) {
968  $id = array_shift($row);
969  foreach ($row as $value) {
970  if ($value < 0 and $value !== $options['empty']) {
971  form_set_error("{$options['org_num']}-genotype-files-ssrs-{$id}", "SSRs Spreadsheet file: Some non-empty values are negative for plant \"{$id}\".");
972  break;
973  }
974  }
975 }
976 
992 function tpps_ssr_valid_ploidy($ploidy, $num_columns, $num_unique_columns, $name) {
993  switch ($ploidy) {
994  case 'Haploid':
995  if ($num_unique_columns != $num_columns) {
996  form_set_error($name, t("SSRs/cpSSRs Genotype Spreadsheet: some columns in the file you provided are missing or have duplicate header values. Please either enter header values for those columns or remove those columns, then reupload your file."));
997  }
998  break;
999 
1000  case 'Diploid':
1001  if ($num_unique_columns != $num_columns and $num_columns / $num_unique_columns !== 2) {
1002  form_set_error($name, t("SSRs/cpSSRs Genotype Spreadsheet: There is either an invalid number of columns in your file, or some of your columns are missing values. Please review and reupload your file."));
1003  }
1004  elseif ($num_unique_columns == $num_columns and $num_columns % 2 !== 0) {
1005  form_set_error($name, t("SSRs/cpSSRs Genotype Spreadsheet: There is either an invalid number of columns in your file, or some of your columns are missing values. Please review and reupload your file."));
1006  }
1007  break;
1008 
1009  case 'Polyploid':
1010  if ($num_columns % $num_unique_columns !== 0) {
1011  form_set_error($name, t("SSRs/cpSSRs Genotype Spreadsheet: There is either an invalid number of columns in your file, or some of your columns are missing values. Please review and reupload your file."));
1012  }
1013  break;
1014 
1015  default:
1016  break;
1017  }
1018 }
const TPPS_PAGE_1
Definition: tpps.module:12
tpps_validate_phenotype(array $phenotype, $org_num, array $form, array &$form_state)
Definition: page_4.php:106
tpps_file_width($fid)
Definition: file_utils.inc:115
tpps_page_4_validate_form(array &$form, array &$form_state)
Definition: page_4.php:16
tpps_ssr_valid_values($row, array &$options)
Definition: page_4.php:967
tpps_file_len($fid)
Definition: file_utils.inc:65
tpps_file_headers($fid, $no_header=FALSE)
Definition: file_utils.inc:972
tpps_ssr_valid_ploidy($ploidy, $num_columns, $num_unique_columns, $name)
Definition: page_4.php:992
tpps_parse_file_column($fid, $column, $no_header=FALSE)
Definition: file_utils.inc:334
tpps_load_submission($accession, $state=TRUE)
Definition: submissions.inc:27
tpps_preserve_valid_file(array &$form_state, $fid, $org_num=NULL, $prefix=NULL)
Definition: form_utils.inc:328
const TPPS_PAGE_4
Definition: tpps.module:15
tpps_load_cvterm($term, array $options=array(), $version=NULL, $refresh_cache=FALSE)
tpps_validate_genotype(array $genotype, $org_num, array $form, array &$form_state)
Definition: page_4.php:343
tpps_get_location($location)
Definition: file_utils.inc:640
tpps_validate_environment(array &$environment, $id)
Definition: page_4.php:887
tpps_file_validate_columns(array &$form_state, array $required_groups, array $file_element)
Definition: file_utils.inc:442
const TPPS_PAGE_3
Definition: tpps.module:14
tpps_file_iterator($fid, $function, array &$options=array())
tpps_compare_files($fid_1, $fid_2, $file_1_id_name, $file_2_id_name, $file_1_no_header=FALSE, $file_2_no_header=FALSE)
Definition: file_utils.inc:379