Browse Source

Merge branch '7.x-3.x' into collections

Shawna Spoor 7 years ago
parent
commit
83a3e273dc

+ 3 - 0
.gitignore

@@ -1 +1,4 @@
 .DS_Store
 .DS_Store
+composer.lock
+vendor/*
+tests/.env

+ 37 - 0
.travis.yml

@@ -0,0 +1,37 @@
+language: php
+
+services:
+  - docker
+
+sudo: required
+
+before_script:
+  - docker pull statonlab/drupal7
+
+script:
+  # Set branch name
+  - export REPO=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_REPO_SLUG; else echo $TRAVIS_PULL_REQUEST_SLUG; fi)
+  - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
+  #  Travis does a shallow clone and we need a full clone to test Tripal v2 to v3 upgrade
+  - cd .. && rm -rf tripal && git clone https://github.com/$REPO.git tripal && cd tripal
+  - git checkout $BRANCH
+  # Test tripal 3 installation
+  - docker run -it -d --rm --name tripal3 -v "$(pwd)":/modules/tripal statonlab/drupal7
+  - sleep 15
+  - docker exec -it tripal3 drush en -y tripal tripal_chado tripal_chado_views tripal_ds tripal_ws
+  # Prepare Chado
+  - docker exec -it tripal3 drush eval "module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.install'); tripal_chado_load_drush_submit('Install Chado v1.3');"
+  - docker exec -it tripal3 drush trp-run-jobs --username=admin
+  # Prepare Drupal
+  - docker exec -it tripal3 drush eval "module_load_include('inc', 'tripal_chado', 'includes/setup/tripal_chado.setup'); tripal_chado_prepare_drush_submit();"
+  - docker exec -it tripal3 drush trp-run-jobs --username=admin
+  # Run PHPUnit tests
+  - docker exec -it tripal3 bash -c "cd /modules/tripal && composer install && DRUPAL_ROOT=/var/www/html ./vendor/bin/phpunit"
+  # Test Tripal v2 to v3 upgrade steps
+  - git checkout 7.x-2.x
+  - docker run -it -d --rm --name tripal2 -v "$(pwd)":/modules/tripal statonlab/drupal7
+  - sleep 15
+  - docker exec -it tripal2 drush en -y tripal_core
+  - docker exec -it tripal2 drush pm-disable tripal_core -y
+  - git checkout $BRANCH
+  - docker exec -it tripal2 drush en -y tripal

+ 14 - 0
README.md

@@ -1,3 +1,5 @@
+[![7.x-3.x Build Status](https://travis-ci.org/tripal/tripal.svg?branch=7.x-3.x)](https://travis-ci.org/tripal/tripal)
+
 ![alt tag](https://raw.githubusercontent.com/tripal/tripal/7.x-3.x/tripal/theme/images/tripal_logo.png)
 ![alt tag](https://raw.githubusercontent.com/tripal/tripal/7.x-3.x/tripal/theme/images/tripal_logo.png)
 
 
 Tripal is a toolkit for construction of online biological (genetics, genomics,
 Tripal is a toolkit for construction of online biological (genetics, genomics,
@@ -111,3 +113,15 @@ precise customizations as required by the community. A well-developed
 Tripal API provides a uniform set of variables and functions for 
 Tripal API provides a uniform set of variables and functions for 
 accessing any and all data within the Chado database. See the Tripal 3.x
 accessing any and all data within the Chado database. See the Tripal 3.x
 Developer's Handbook for additional details.
 Developer's Handbook for additional details.
+
+
+# Development Testing
+
+To run PHP unit tests on your local system, simply create a `.env` file in your `/Tests/` directory that defines the `DRUPAL_ROOT` variable, for example 
+
+```
+DRUPAL_ROOT=/var/www/html
+```
+Then run PHPUnit from your root Tripal directory.
+
+PHPUnit tests will also be run in the Travis CI build.

+ 5 - 0
composer.json

@@ -0,0 +1,5 @@
+{
+  "require-dev": {
+    "phpunit/phpunit": "^7"
+  }
+}

+ 11 - 0
phpunit.xml

@@ -0,0 +1,11 @@
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="phpunit.xsd"
+         bootstrap="tests/bootstrap.php"
+         verbose="true"
+         colors="true">
+    <testsuites>
+        <testsuite name="default">
+            <directory suffix=".test">./tests/</directory>
+        </testsuite>
+    </testsuites>
+</phpunit>

+ 21 - 0
tests/TripalJobsTest.test

@@ -0,0 +1,21 @@
+<?php
+
+use PHPUnit\Framework\TestCase;
+
+class TripalJobsTest extends TestCase {
+
+  /**
+   * Tests the ability to create a tripal job.
+   *
+   * @test
+   */
+  public function should_create_a_tripal_job() {
+    $job_id = tripal_add_job('Test adding jobs', 'tripal', 'tripal_tripal_cron_notification', [], 1);
+    $this->assertTrue(is_numeric($job_id));
+
+    // Clean up
+    if($job_id) {
+      db_query('DELETE FROM {tripal_jobs} WHERE job_id = :id', [':id' => $job_id]);
+    }
+  }
+}

+ 39 - 0
tests/bootstrap.php

@@ -0,0 +1,39 @@
+<?php
+// Set environment variables
+test_suite_read_and_set_environment_variables();
+
+// Get Drupal root path
+$drupal_root = getenv('DRUPAL_ROOT');
+define('DRUPAL_ROOT', $drupal_root ?: '/var/www/html');
+
+// Get Drupal bootstrap functions
+require_once DRUPAL_ROOT.'/includes/bootstrap.inc';
+$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+
+// Bootstrap Drupal.
+$current_dir = getcwd();
+chdir(DRUPAL_ROOT);
+drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+chdir($current_dir);
+
+/**
+ * Get and set environment variables from .env file if it exists.
+ *
+ * @throws \Exception
+ */
+function test_suite_read_and_set_environment_variables() {
+  $filename = __DIR__.'/.env';
+  if(file_exists($filename)) {
+    $file = fopen($filename, 'r');
+    while ($line = str_replace("\n", '', fgets($file))) {
+      // break line into key value
+      $env = explode('=', $line);
+      if(count($env) === 2) {
+        putenv($line);
+      } else {
+        throw new Exception('Invalid environment line: ' . $line);
+      }
+    }
+    fclose($file);
+  }
+}

+ 4 - 2
tripal/tripal.install

@@ -115,8 +115,10 @@ function tripal_enable() {
   }
   }
 
 
   // schema change
   // schema change
-  $sql = "ALTER TABLE tripal_jobs ADD COLUMN includes text";
-  db_query($sql);
+  if (!db_field_exists('tripal_jobs', 'includes')) {
+    $sql = "ALTER TABLE tripal_jobs ADD COLUMN includes text";
+    db_query($sql);
+  }
 
 
   tripal_add_variables();
   tripal_add_variables();
 }
 }

+ 34 - 0
tripal_chado/api/tripal_chado.property.api.inc

@@ -169,6 +169,7 @@ function chado_insert_property($record, $property, $options = array()) {
   $cv_id       = array_key_exists('cv_id', $property) ? $property['cv_id'] : '';
   $cv_id       = array_key_exists('cv_id', $property) ? $property['cv_id'] : '';
   $value       = array_key_exists('value', $property) ? $property['value'] : '';
   $value       = array_key_exists('value', $property) ? $property['value'] : '';
   $rank        = array_key_exists('rank', $property) ? $property['rank'] : 0;
   $rank        = array_key_exists('rank', $property) ? $property['rank'] : 0;
+  $cvalue_id   = array_key_exists('cvalue_id', $property) ? $property['cvalue_id'] : '';
 
 
   $update_if_present = array_key_exists('update_if_present', $options) ? $options['update_if_present'] : FALSE;
   $update_if_present = array_key_exists('update_if_present', $options) ? $options['update_if_present'] : FALSE;
   $force_rank = array_key_exists('force_rank', $options) ? $options['force_rank'] : FALSE;
   $force_rank = array_key_exists('force_rank', $options) ? $options['force_rank'] : FALSE;
@@ -249,6 +250,20 @@ function chado_insert_property($record, $property, $options = array()) {
       array('%property' => print_r($property, TRUE)));    return FALSE;
       array('%property' => print_r($property, TRUE)));    return FALSE;
   }
   }
 
 
+
+    //Check that the cvalue property exists
+    if ($cvalue_id){
+        $term = chado_select_record('cvterm', array('cvterm_id'), array('cvterm_id' => $cvalue_id), $options);
+       if (!$term or count($term) == 0) {
+            tripal_report_error('tripal_chado', TRIPAL_ERROR, "chado_insert_property: " .
+                "Cannot find the term for the property value described by: %property.",
+                array('%property' => print_r($property, TRUE)));
+           return FALSE;
+    }
+    $values['cvalue'] = $cvalue_id;
+  }
+
+
   // Get the foreign key for this property table
   // Get the foreign key for this property table
   $table_desc = chado_get_schema($base_table . 'prop');
   $table_desc = chado_get_schema($base_table . 'prop');
   $fkcol = key($table_desc['foreign keys'][$base_table]['columns']);
   $fkcol = key($table_desc['foreign keys'][$base_table]['columns']);
@@ -287,6 +302,9 @@ function chado_insert_property($record, $property, $options = array()) {
  *     -cv_name: The name of the CV that contains the term.
  *     -cv_name: The name of the CV that contains the term.
  *     -value: The specific value for the property.
  *     -value: The specific value for the property.
  *     -rank: The specific rank for the property.
  *     -rank: The specific rank for the property.
+ *     -cvalue_id: The cvterm_id of the value for the property.
+ *      **note** cvalue_id is an anticipated column in the the next Chado release (1.4).  It is included here for early adopters.
+ *
  * @param $options
  * @param $options
  *   An associative array containing the following keys:
  *   An associative array containing the following keys:
  *     -insert_if_missing: A boolean indicating whether a record should be
  *     -insert_if_missing: A boolean indicating whether a record should be
@@ -310,6 +328,7 @@ function chado_update_property($record, $property, $options = array()) {
   $cv_id       = array_key_exists('cv_id', $property) ? $property['cv_id'] : '';
   $cv_id       = array_key_exists('cv_id', $property) ? $property['cv_id'] : '';
   $value       = array_key_exists('value', $property) ? $property['value'] : '';
   $value       = array_key_exists('value', $property) ? $property['value'] : '';
   $rank        = array_key_exists('rank', $property) ? $property['rank'] : 0;
   $rank        = array_key_exists('rank', $property) ? $property['rank'] : 0;
+  $cvalue_id   = array_key_exists('cvalue_id', $property) ? $property['cvalue_id'] : '';
 
 
   $insert_if_missing = array_key_exists('insert_if_missing', $options) ? $options['insert_if_missing'] : FALSE;
   $insert_if_missing = array_key_exists('insert_if_missing', $options) ? $options['insert_if_missing'] : FALSE;
 
 
@@ -385,6 +404,18 @@ function chado_update_property($record, $property, $options = array()) {
     $values['rank'] = $rank;
     $values['rank'] = $rank;
   }
   }
 
 
+  // If a cvalue_id is supplied, check that it is a valid cvterm
+    if ($cvalue_id) {
+        $term = chado_select_record('cvterm', array('cvterm_id'), array('cvterm_id' => $cvalue_id), $options);
+        if (!$term or count($term) == 0) {
+            tripal_report_error('tripal_chado', TRIPAL_ERROR, "chado_insert_property: " .
+                "Cannot find the term for the property value described by: %property.",
+                array('%property' => print_r($property, TRUE)));
+            return FALSE;
+    }
+    $values['cvalue_id'] = $cvalue_id;
+  }
+
   // If we have the unique property_id then we can also update the type
   // If we have the unique property_id then we can also update the type
   // thus add it to the values to be updated
   // thus add it to the values to be updated
   if ($prop_id) {
   if ($prop_id) {
@@ -516,6 +547,9 @@ function chado_delete_property($record, $property) {
  *     -cv_name: The name of the CV that contains the term.
  *     -cv_name: The name of the CV that contains the term.
  *     -value: The specific value for the property.
  *     -value: The specific value for the property.
  *     -rank: The specific rank for the property.
  *     -rank: The specific rank for the property.
+ *     -cvalue_id: The cvterm_id of the value for the property.
+ *      **note** cvalue_id is an anticipated column in the the next Chado release (1.4).  It is included here for early adopters.
+ * 
  * @param $options
  * @param $options
  *   An array of options supported by chado_generate_var(). These keys
  *   An array of options supported by chado_generate_var(). These keys
  *   are used for generating the cvterm objects returned by this function.
  *   are used for generating the cvterm objects returned by this function.

+ 15 - 2
tripal_chado/api/tripal_chado.schema.api.inc

@@ -41,9 +41,19 @@
  */
  */
 function chado_table_exists($table) {
 function chado_table_exists($table) {
 
 
+  // Get the default database and chado schema.
   global $databases;
   global $databases;
-
   $default_db = $databases['default']['default']['database'];
   $default_db = $databases['default']['default']['database'];
+  $chado_schema = tripal_get_schema_name('chado');
+
+  // If we've already lookup up this table then don't do it again, as
+  // we don't need to keep querying the database for the same tables.
+  if (array_key_exists("chado_tables", $GLOBALS) and
+      array_key_exists($default_db, $GLOBALS["chado_tables"]) and
+      array_key_exists($chado_schema, $GLOBALS["chado_tables"][$default_db]) and
+      array_key_exists($table, $GLOBALS["chado_tables"][$default_db][$chado_schema])) {
+    return TRUE;
+  }
 
 
   $sql = "
   $sql = "
     SELECT 1
     SELECT 1
@@ -55,7 +65,7 @@ function chado_table_exists($table) {
   ";
   ";
   $args = array(
   $args = array(
     ':table_name' => $table,
     ':table_name' => $table,
-    ':chado' => tripal_get_schema_name('chado'),
+    ':chado' => $chado_schema,
     ':default_db' => $default_db
     ':default_db' => $default_db
   );
   );
   $results = db_query($sql, $args);
   $results = db_query($sql, $args);
@@ -63,6 +73,9 @@ function chado_table_exists($table) {
   if (!$exists) {
   if (!$exists) {
     return FALSE;
     return FALSE;
   }
   }
+
+  // Set this table in the GLOBALS so we don't query for it again the next time.
+  $GLOBALS["chado_tables"][$default_db][$chado_schema][$table] = TRUE;
   return TRUE;
   return TRUE;
 }
 }
 /**
 /**

+ 1 - 0
tripal_chado/tripal_chado.module

@@ -85,6 +85,7 @@ function tripal_chado_set_globals() {
     $GLOBALS["chado_is_local"]      = chado_is_local();
     $GLOBALS["chado_is_local"]      = chado_is_local();
     $GLOBALS["chado_version"]       = chado_get_version();
     $GLOBALS["chado_version"]       = chado_get_version();
     $GLOBALS["exact_chado_version"] = chado_get_version(TRUE);
     $GLOBALS["exact_chado_version"] = chado_get_version(TRUE);
+    $GLOBALS["chado_tables"] = array();
   }
   }
 }
 }
 
 

+ 5 - 4
tripal_ds/api/tripal_ds.pane.api.inc

@@ -31,11 +31,12 @@
  *  field_create_instance($instance);
  *  field_create_instance($instance);
  *  tripal_ds_field_create_field($field_label, $field, $bundle);
  *  tripal_ds_field_create_field($field_label, $field, $bundle);
  */
  */
-function tripal_ds_field_create_field($field_label, $field, $bundle_name) {
+function tripal_ds_create_field($field_label, $field_name, $bundle_name) {
+  $field_name = str_replace(' ', '_', strtolower($field_name));
   //Build the rest of the passes parameters.
   //Build the rest of the passes parameters.
-  $group_field_name = 'gp_'.$field['field_name'];
+  $group_field_name = 'gp_'.$field_name;
   //Create the field groups.
   //Create the field groups.
-  _additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field);
+  tripal_ds_additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field_name);
   //Place the field groups in the layout.
   //Place the field groups in the layout.
-  tripal_ds_update_ds_layout($bundle_name, $field, $group_field_name);
+  tripal_ds_update_ds_layout($bundle_name, $field_name, $group_field_name);
 }
 }

+ 2 - 2
tripal_ds/includes/tripal_ds.ds.inc

@@ -134,7 +134,7 @@ function _ds_layout_settings_info($bundle_name, $instances) {
         // Add random numbers to ensure the field name is unique within the 32
         // Add random numbers to ensure the field name is unique within the 32
         // character limit of the field.
         // character limit of the field.
         $group_field_name = $group_field_name.rand(0, 99999);
         $group_field_name = $group_field_name.rand(0, 99999);
-        _additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
+        tripal_ds_additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
       }
       }
     }
     }
 
 
@@ -328,7 +328,7 @@ function _ds_layout_pub_settings_info($bundle_name, $instances) {
       $group_field_name = $group_field_name.rand(0, 99999);
       $group_field_name = $group_field_name.rand(0, 99999);
 
 
       // Build the field group.
       // Build the field group.
-      _additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
+      tripal_ds_additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
 
 
       // Update arrays.
       // Update arrays.
       array_push($temporary_field, $group_field_name, $other_field['field_name']);
       array_push($temporary_field, $group_field_name, $other_field['field_name']);

+ 1 - 1
tripal_ds/includes/tripal_ds.field_group.inc

@@ -230,7 +230,7 @@ function _data_sequence_field_group_info($bundle_name, $fields){
  * @param $field_name
  * @param $field_name
  *  Machine name of the child element.
  *  Machine name of the child element.
  */
  */
-function _additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field_name){
+function tripal_ds_additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $field_name){
   //Write to the tripal_ds table to record the new tripal pane.
   //Write to the tripal_ds table to record the new tripal pane.
   tripal_ds_bundle_menu_item($bundle_name, $field_label, $group_field_name, 'TripalEntity');
   tripal_ds_bundle_menu_item($bundle_name, $field_label, $group_field_name, 'TripalEntity');
 
 

+ 15 - 6
tripal_ds/tripal_ds.module

@@ -4,6 +4,10 @@ require_once "includes/tripal_ds.inc";
 require_once "includes/tripal_ds.ds.inc";
 require_once "includes/tripal_ds.ds.inc";
 require_once "includes/tripal_ds.field_group.inc";
 require_once "includes/tripal_ds.field_group.inc";
 require_once "includes/tripal_ds.field_formatter.inc";
 require_once "includes/tripal_ds.field_formatter.inc";
+require_once "includes/tripal_ds.field_formatter.inc";
+
+// Import the full Tripal_DS API into scope.
+tripal_ds_import_api();
 
 
 /**
 /**
  * Implements hook_init().
  * Implements hook_init().
@@ -376,12 +380,9 @@ function tripal_ds_pane_addition_button_form_submit($form, &$form_state) {
   $bundle_name = $form_state['build_info']['args'][0];
   $bundle_name = $form_state['build_info']['args'][0];
   //Build the rest of the passed variables.
   //Build the rest of the passed variables.
   $field_name = $form_state['input']['field_name'];
   $field_name = $form_state['input']['field_name'];
-  $group_field_name = 'gp_'.$form_state['input']['field_name'];
-  //Create the field groups, last passed parameter is NULL because there are no
-  //children.
-  _additional_fields_field_group_info($bundle_name, $field_name, $group_field_name, NULL);
-  //Place the field groups in the layout.
-  tripal_ds_update_ds_layout($bundle_name, NULL, $group_field_name);
+  $field_label = $form_state['input']['field_name'];
+
+  tripal_ds_create_field($field_label, $field_name, $bundle_name);
   drupal_goto("admin/structure/bio_data/manage/$bundle_name/display");
   drupal_goto("admin/structure/bio_data/manage/$bundle_name/display");
 }
 }
 
 
@@ -583,3 +584,11 @@ function tripal_ds_toc_order($bundle, $fields = array()){
   }
   }
 }
 }
 
 
+/**
+ * Imports all of the Tripal_DS API into scope.
+ *
+ *
+ */
+function tripal_ds_import_api() {
+  module_load_include('inc', 'tripal_ds', 'api/tripal_ds.pane.api');
+}