diff --git a/islandora.info b/islandora.info index fea3ead2..4b48bc29 100644 --- a/islandora.info +++ b/islandora.info @@ -18,4 +18,5 @@ files[] = tests/ingest.test files[] = tests/hooked_access.test files[] = tests/islandora_manage_permissions.test files[] = tests/datastream_versions.test +files[] = tests/derivatives.test php = 5.3 diff --git a/islandora.module b/islandora.module index b8109a21..989dd36e 100644 --- a/islandora.module +++ b/islandora.module @@ -1421,31 +1421,75 @@ function islandora_islandora_basic_collection_get_query_filters() { * Implements hook_islandora_datastream_ingested(). */ function islandora_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) { - $logging_results = islandora_do_derivatives($object); - dd($logging_results, 'logging'); - foreach ($logging_results as $result) { + $logging_results = islandora_do_derivatives($object, array( + 'source_dsid' => $datastream->id, + )); + islandora_derivative_logging($logging_results); +} - } +/** + * Implements hook_islandora_datastream_modified(). + */ +function islandora_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) { + $logging_results = islandora_do_derivatives($object, array( + 'source_dsid' => $datastream->id, + 'force' => TRUE, + )); + islandora_derivative_logging($logging_results); } -function islandora_do_derivatives(AbstractObject $object, $force = FALSE, $all = TRUE) { +function islandora_do_derivatives(AbstractObject $object, array $options = array()) { + $options += array( + 'force' => FALSE, + 'source_dsid' => NULL, + 'destination_dsid' => NULL, + ); $hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array()); uasort($hooks, 'drupal_sort_weight'); $results = array(); - dd($hooks, 'hooks'); + + if ($options['source_dsid'] !== NULL) { + $hooks = array_filter($hooks, function($filter_hook) use($options) { + return !isset($filter_hook['source_dsid']) || + (isset($filter_hook['source_dsid']) && $filter_hook['source_dsid'] == $options['source_dsid']); + }); + } + if ($options['destination_dsid'] !== NULL) { + $hooks = array_filter($hooks, function($filter_hook) use($options) { + return !isset($filter_hook['destination_dsid']) || + (isset($filter_hook['destination_dsid']) && $filter_hook['destination_dsid'] == $options['destination_dsid']); + }); + } + dd($hooks, 'hooooooks'); foreach ($hooks as $hook) { - if (!$all && !isset($hook['source_dsid'])) { - continue; - } if (isset($hook['file'])) { - require_once($hook['file']); + require_once $hook['file']; } foreach ($hook['function'] as $function) { - $logging = call_user_func($function, $object, $force); + $logging = call_user_func($function, $object, $options['force']); if (!empty($logging)) { $results[] = $logging; } } } return $results; +} + +function islandora_derivative_logging(array $logging_results) { + foreach ($logging_results as $result) { + foreach ($result['messages'] as $message) { + if ($message['type'] >= WATCHDOG_WARNING) { + if ($message['type'] == WATCHDOG_WARNING) { + $status = 'warning'; + } + else { + $status = 'status'; + } + drupal_set_message(format_string($message['message'], isset($message['message_sub']) ? $message['message_sub'] : array()), $status); + } + else { + watchdog('islandora', $message['message'], isset($message['message_sub']) ? $message['message_sub'] : array(), $message['type']); + } + } + } } \ No newline at end of file diff --git a/tests/derivatives.test b/tests/derivatives.test new file mode 100644 index 00000000..a98753f7 --- /dev/null +++ b/tests/derivatives.test @@ -0,0 +1,185 @@ + 'Islandora Derivative Generation', + 'description' => 'Ensure that the derivative generation hooks return appropriate results.', + 'group' => 'Islandora', + ); + } + + /** + * Creates an admin user and a connection to a fedora repository. + * + * @see IslandoraWebTestCase::setUp() + */ + public function setUp() { + parent::setUp( + array( + 'islandora_derivatives_test', + ) + ); + $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora'); + $this->connection = new RepositoryConnection($url, $this->admin->name, $this->admin->pass); + $this->connection->reuseConnection = TRUE; + $this->api = new FedoraApi($this->connection); + $this->cache = new SimpleCache(); + $this->repository = new FedoraRepository($this->api, $this->cache); + $this->pid = $this->randomName() . ":" . $this->randomName(); + } + + /** + * Free any objects/resources created for this test. + * + * @see IslandoraWebTestCase::tearDown() + */ + public function tearDown() { + $tuque = islandora_get_tuque_connection(); + parent::tearDown(); + } + + public function testDerivativeOnIngest() { + global $ingest_method; + $ingest_method = 'modifyDatastream'; + $tuque = islandora_get_tuque_connection(); + $object = $tuque->repository->constructObject($this->pid); + $object->models = array( + 'some:cmodel', + ); + $dsid = 'OBJ'; + $ds = $object->constructDatastream($dsid); + $ds->label = 'Test'; + $ds->content = 'test'; + $object->ingestDatastream($ds); + $tuque->repository->ingestObject($object); + $this->assertDatastreams($object, array( + 'RELS-EXT', + 'DC', + 'OBJ', + 'DERIV', + )); + $this->assertEqual('ingestDatastream', $ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $ingest_method . '".'); + $this->assertEqual('test some string', $object['DERIV']->content, 'The expected content of the DERIV datastream is "test some string", got "' . $object['DERIV']->content . '".'); + } + + public function testDerivativeOnForceExistingDatastream() { + global $ingest_method; + $ingest_method = 'ingestDatastream'; + $object = $this->constructBaseObject(); + $this->constructDERIVDatastream($object); + $islandora_object = islandora_object_load($this->pid); + islandora_do_derivatives($islandora_object, array( + 'force' => TRUE, + )); + $this->assertEqual('modifyDatastream', $ingest_method, 'The expected ingest method is "modifyDatastream", got "' . $ingest_method . '".'); + $this->assertEqual('FORCEFULLY APPENDING CONTENT TO test', $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO test", got "' . $islandora_object['DERIV']->content . '".'); + } + + public function testDerivativeOnForceNonExistingDatastream() { + global $ingest_method; + $ingest_method = 'modifyDatastream'; + $this->constructBaseObject(); + $object = islandora_object_load($this->pid); + islandora_do_derivatives($object, array( + 'force' => TRUE, + )); + $this->assertEqual('ingestDatastream', $ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $ingest_method . '".'); + $this->assertEqual('FORCEFULLY APPENDING CONTENT TO test', $object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO test", got "' . $object['DERIV']->content . '".'); + } + + public function testDerivativeOnModifyExistingDatastream() { + global $ingest_method; + $ingest_method = 'ingestDatastream'; + $object = $this->constructBaseObject(); + $this->constructDERIVDatastream($object); + $connection = islandora_get_tuque_connection(); + $connection->cache->resetCache(); + $islandora_object = islandora_object_load($this->pid); + $changed_content = 'islandora beast'; + $islandora_object['OBJ']->content = $changed_content; + $this->assertEqual('modifyDatastream', $ingest_method, 'The expected ingest method is "modifyDatastream", got "' . $ingest_method . '".'); + $this->assertEqual('FORCEFULLY APPENDING CONTENT TO ' . $changed_content, $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO islandora beast", got "' . $islandora_object['DERIV']->content . '".'); + } + + public function testDerivativeOnModifyNonExistingDatastream() { + global $ingest_method; + $ingest_method = 'modifyDatastream'; + $this->constructBaseObject(); + // Need to do this as Tuque caches. + $connection = islandora_get_tuque_connection(); + $connection->cache->resetCache(); + $islandora_object = islandora_object_load($this->pid); + $changed_content = 'islandora beast'; + $islandora_object['OBJ']->content = $changed_content; + $this->assertEqual('ingestDatastream', $ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $ingest_method . '".'); + $this->assertEqual('FORCEFULLY APPENDING CONTENT TO ' . $changed_content, $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO islandora beast", got "' . $islandora_object['DERIV']->content . '".'); + } + + public function testDerivativeFilteringOnSourceDSID() { + global $derivative_functions; + $derivative_functions = array(); + $this->constructBaseObject(); + $object = islandora_object_load($this->pid); + islandora_do_derivatives($object, array( + 'source_dsid' => 'OBJ', + )); + $this->assertEqual(1, count($derivative_functions), 'Expected 1 derivative function for the source_dsid of "OBJ", got ' . count($derivative_functions) . '.'); + $called_function = (string) reset($derivative_functions); + $this->assertEqual('islandora_derivatives_test_create_deriv_datastream', $called_function, 'Expected derivative function is "islandora_derivatives_test_create_deriv_datastream", got "' . $called_function . '".'); + + // Reset the derivative functions array as we are going to use it again. + $derivative_functions = array(); + islandora_do_derivatives($object, array( + 'source_dsid' => 'SOMEWEIRDDATASTREAM', + )); + $this->assertEqual(1, count($derivative_functions), 'Expected 1 derivative function for the source_dsid of "SOMEWEIRDDATASTREAM", got ' . count($derivative_functions) . '.'); + $called_function = (string) reset($derivative_functions); + $this->assertEqual('islandora_derivatives_test_create_some_weird_datastream', $called_function, 'Expected derivative function is "islandora_derivatives_test_create_some_weird_datastream", got "' . $called_function . '".'); + } + + /** + * Helper function that will construct a base object. + */ + public function constructBaseObject() { + $object = $this->repository->constructObject($this->pid); + $object->models = array( + 'some:cmodel', + ); + $dsid = 'OBJ'; + $ds = $object->constructDatastream($dsid); + $ds->label = 'Test'; + $ds->content = 'test'; + $object->ingestDatastream($ds); + $this->repository->ingestObject($object); + return $object; + } + + public function constructDERIVDatastream(AbstractObject $object) { + $dsid = 'DERIV'; + $ds = $object->constructDatastream($dsid); + $ds->label = 'Test'; + $ds->content = 'test'; + $object->ingestDatastream($ds); + return $object; + } + + } + diff --git a/tests/islandora_derivatives_test.info b/tests/islandora_derivatives_test.info new file mode 100644 index 00000000..338b39fe --- /dev/null +++ b/tests/islandora_derivatives_test.info @@ -0,0 +1,7 @@ +name = Islandora Derivatives Generation testing +description = Tests derivative generation hooks. Do not enable. +core = 7.x +package = Testing +hidden = TRUE +files[] = islandora_derivatives_test.module +dependencies[] = islandora diff --git a/tests/islandora_derivatives_test.module b/tests/islandora_derivatives_test.module new file mode 100644 index 00000000..36b6380c --- /dev/null +++ b/tests/islandora_derivatives_test.module @@ -0,0 +1,114 @@ + 'OBJ', + 'destination_dsid' => 'DERIV', + 'weight' => '0', + 'function' => array( + 'islandora_derivatives_test_create_deriv_datastream', + ), + ), + array( + 'source_dsid' => 'SOMEWEIRDDATASTREAM', + 'destination_dsid' => 'STANLEY', + 'weight' => '-1', + 'function' => array( + 'islandora_derivatives_test_create_some_weird_datastream', + ), + ), + ); +} + +function islandora_derivatives_test_create_deriv_datastream(AbstractObject $object, $force = FALSE) { + global $derivative_functions; + $derivative_functions[] = 'islandora_derivatives_test_create_deriv_datastream'; + $return = ''; + if (!isset($object['DERIV']) || (isset($object['DERIV']) && $force === TRUE)) { + if ($force !== TRUE) { + $deriv_string = $object['OBJ']->content . ' some string'; + } + else { + $deriv_string = "FORCEFULLY APPENDING CONTENT TO " . $object['OBJ']->content; + } + $added_successfully = islandora_derivatives_test_add_datastream($object, 'DERIV', $deriv_string); + if ($added_successfully !== TRUE) { + $return = islandora_derivatives_test_failed_adding($added_successfully); + } + else { + $return = array( + 'success' => TRUE, + 'messages' => array( + array( + 'message' => t('The DERIV datastream was added successfully for @pid!'), + 'message_sub' => array('@pid' => $object->id), + 'type' => WATCHDOG_INFO, + ), + ), + ); + } + return $return; + } +} + +/** + * Stub function that should never actually get called because of DSID filtering. + * + * @param AbstractObject $object + * An AbstractObject representing a Fedora object. + * @param bool $force + * Whether the derivatives are being forcefully generated or not. + */ +function islandora_derivatives_test_create_some_weird_datastream(AbstractObject $object, $force = FALSE) { + global $derivative_functions; + // Add to the global that we got to this function. + $derivative_functions[] = 'islandora_derivatives_test_create_some_weird_datastream'; +} + +function islandora_derivatives_test_add_datastream(AbstractObject $object, $dsid, $deriv_string) { + global $ingest_method; + try { + $ingest = !isset($object[$dsid]); + if ($ingest) { + $ds = $object->constructDatastream($dsid, 'M'); + $ds->label = $dsid; + } + else { + $ds = $object[$dsid]; + } + $ds->content = $deriv_string; + if ($ingest) { + $ingest_method = 'ingestDatastream'; + $object->ingestDatastream($ds); + } + else { + $ingest_method = 'modifyDatastream'; + } + return TRUE; + } + catch (exception $e) { + $message = $e->getMessage(); + return $message; + } +} + +function islandora_derivatives_test_failed_adding($message) { + return array( + 'success' => FALSE, + 'messages' => array( + array( + 'message' => $message, + 'type' => WATCHDOG_ERROR, + ), + ), + ); +} \ No newline at end of file