Browse Source

Merge branch '7.x' of github.com:Islandora/islandora into 7.x-METRO-53

pull/529/head
Jordan Dukart 10 years ago
parent
commit
40fb47f710
  1. 13
      includes/datastream.version.inc
  2. 6
      includes/ingest.form.inc
  3. 5
      includes/mime_detect.inc
  4. 152
      includes/tuque_wrapper.inc
  5. 56
      includes/utilities.inc
  6. 17
      islandora.module
  7. 4
      tests/hooks.test
  8. 8
      tests/islandora_hooks_test.module

13
includes/datastream.version.inc

@ -280,17 +280,16 @@ function islandora_datastream_version_replace_form($form, &$form_state, Abstract
$form_state['object_id'] = $object->id; $form_state['object_id'] = $object->id;
$form_state['dsid'] = $datastream->id; $form_state['dsid'] = $datastream->id;
$form_state['object'] = $object; $form_state['object'] = $object;
$extensions = islandora_get_object_extensions($object); $datastream_mime_map = islandora_get_object_extensions($object);
$mime_detect = new MimeDetect(); $mime_detect = new MimeDetect();
$ext = array(); $ext = array();
if (isset($extensions[$datastream->id])) { if (isset($datastream_mime_map[$datastream->id])) {
foreach ($extensions[$datastream->id]['mime'] as $key => $value) { foreach ($datastream_mime_map[$datastream->id]['mime'] as $key => $value) {
$str = $mime_detect->getExtension($value); $extensions = $mime_detect->getValidExtensions($value);
array_push($ext, $str); $ext = array_merge($ext, $extensions);
} }
} }
$comma = count($ext) > 1 ? "," : "";
$ext = array(implode($comma, $ext));
$upload_size = min((int) ini_get('post_max_size'), (int) ini_get('upload_max_filesize')); $upload_size = min((int) ini_get('post_max_size'), (int) ini_get('upload_max_filesize'));
return array( return array(
'dsid_fieldset' => array( 'dsid_fieldset' => array(

6
includes/ingest.form.inc

@ -706,7 +706,11 @@ function islandora_ingest_form_ingest_button(array &$form_state) {
$validate_callback = $form_id . '_validate'; $validate_callback = $form_id . '_validate';
$validate = function_exists($validate_callback) ? array($validate_callback) : NULL; $validate = function_exists($validate_callback) ? array($validate_callback) : NULL;
$submit_callback = $form_id . '_submit'; $submit_callback = $form_id . '_submit';
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_submit') : array('islandora_ingest_form_submit'); $submit = function_exists($submit_callback) ? array(
$submit_callback,
'islandora_ingest_form_pre_submit',
'islandora_ingest_form_submit',
) : array('islandora_ingest_form_pre_submit', 'islandora_ingest_form_submit');
return array( return array(
'#type' => 'submit', '#type' => 'submit',
'#name' => 'ingest', '#name' => 'ingest',

5
includes/mime_detect.inc

@ -132,7 +132,8 @@ class MimeDetect {
'wbxml' => 'application/vnd.wap.wbxml', 'wbxml' => 'application/vnd.wap.wbxml',
'xht' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml',
'xhtml' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml',
'xsl' => 'text/xml', 'xsl' => 'text/xsl',
'xslt' => 'text/xsl',
'xml' => 'text/xml', 'xml' => 'text/xml',
'csv' => 'text/csv', 'csv' => 'text/csv',
'tsv' => 'text/tab-separated-values', 'tsv' => 'text/tab-separated-values',
@ -224,6 +225,8 @@ class MimeDetect {
"zip" => "application/x-zip", "zip" => "application/x-zip",
// others: // others:
'bin' => 'application/octet-stream', 'bin' => 'application/octet-stream',
// Web Archives:
"warc" => "application/warc",
); );
protected $protectedFileExtensions; protected $protectedFileExtensions;
protected $extensionExceptions = array( protected $extensionExceptions = array(

152
includes/tuque_wrapper.inc

@ -144,6 +144,41 @@ class IslandoraFedoraObject extends FedoraObject {
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
/**
* Magical magic, to allow recursive modifications.
*
* So... Magic functions in PHP are not re-entrant... Meaning that if you
* have something which tries to call __set on an object anywhere later in
* the callstack after it has already been called, it will not call the
* magic method again; instead, it will set the property on the object
* proper. Here, we detect the property being set on the object proper, and
* restore the magic functionality as long as it keeps getting set...
*
* Not necessary to try to account for this in Tuque proper, as Tuque itself
* does not have a mechanism to trigger modifications resulting from other
* modifications.
*
* @param string $name
* The name of the property being set.
* @param mixed $value
* The value to which the property should be set.
*/
public function __set($name, $value) {
parent::__set($name, $value);
// XXX: Due to the structure of the code, we cannot use property_exists()
// (because many of the properties are declared in the class, and the magic
// triggers due them being NULLed), nor can we use isset() (because it is
// implemented as another magic function...).
$vars = get_object_vars($this);
while (isset($vars[$name])) {
$new_value = $this->$name;
unset($this->$name);
parent::__set($name, $new_value);
$vars = get_object_vars($this);
}
}
/** /**
* Ingest the given datastream. * Ingest the given datastream.
* *
@ -173,6 +208,30 @@ class IslandoraFedoraObject extends FedoraObject {
throw $e; throw $e;
} }
} }
/**
* Inherits.
*
* Calls parent and invokes object modified and deleted(/purged) hooks.
*
* @see FedoraObject::modifyObject()
*/
protected function modifyObject($params) {
try {
parent::modifyObject($params);
islandora_invoke_object_hooks(ISLANDORA_OBJECT_MODIFIED_HOOK, $this->models, $this);
if ($this->state == 'D') {
islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $this->models, $this->id);
}
}
catch (Exception $e) {
watchdog('islandora', 'Failed to modify object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $this->id,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
} }
class IslandoraRepositoryConnection extends RepositoryConnection {} class IslandoraRepositoryConnection extends RepositoryConnection {}
@ -219,25 +278,10 @@ class IslandoraFedoraApiM extends FedoraApiM {
if (isset($params['lastModifiedDate'])) { if (isset($params['lastModifiedDate'])) {
$params['lastModifiedDate'] = (string) $object[$dsid]->createdDate; $params['lastModifiedDate'] = (string) $object[$dsid]->createdDate;
} }
try {
if ($context['block']) { if ($context['block']) {
throw new Exception('Modify Datastream was blocked.'); throw new Exception('Modify Datastream was blocked.');
} }
$ret = parent::modifyDatastream($pid, $dsid, $params); return parent::modifyDatastream($pid, $dsid, $params);
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $object->models, $dsid, $object, $datastream);
if (isset($params['dsState']) && $params['dsState'] == 'D') {
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $object->models, $dsid, $object, $dsid);
}
return $ret;
}
catch (Exception $e) {
watchdog('islandora', 'Failed to modify datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@dsid' => $dsid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
} }
/** /**
@ -254,24 +298,10 @@ class IslandoraFedoraApiM extends FedoraApiM {
); );
islandora_alter_object($object, $context); islandora_alter_object($object, $context);
$params = $context['params']; $params = $context['params'];
try {
if ($context['block']) { if ($context['block']) {
throw new Exception('Modify Object was blocked.'); throw new Exception('Modify Object was blocked.');
} }
$ret = parent::modifyObject($pid, $params); return parent::modifyObject($pid, $params);
islandora_invoke_object_hooks(ISLANDORA_OBJECT_MODIFIED_HOOK, $object->models, $object);
if (isset($params['state']) && $params['state'] == 'D') {
islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $object->models, $object->id);
}
return $ret;
}
catch (Exception $e) {
watchdog('islandora', 'Failed to modify object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
} }
/** /**
@ -377,6 +407,66 @@ class IslandoraNewFedoraDatastream extends NewFedoraDatastream {
class IslandoraFedoraDatastream extends FedoraDatastream { class IslandoraFedoraDatastream extends FedoraDatastream {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
/**
* Magical magic, to allow recursive modifications.
*
* So... Magic functions in PHP are not re-entrant... Meaning that if you
* have something which tries to call __set on an object anywhere later in
* the callstack after it has already been called, it will not call the
* magic method again; instead, it will set the property on the object
* proper. Here, we detect the property being set on the object proper, and
* restore the magic functionality as long as it keeps getting set...
*
* Not necessary to try to account for this in Tuque proper, as Tuque itself
* does not have a mechanism to trigger modifications resulting from other
* modifications.
*
* @param string $name
* The name of the property being set.
* @param mixed $value
* The value to which the property should be set.
*/
public function __set($name, $value) {
parent::__set($name, $value);
// XXX: Due to the structure of the code, we cannot use property_exists()
// (because many of the properties are declared in the class, and the magic
// triggers due them being NULLed), nor can we use isset() (because it is
// implemented as another magic function...).
$vars = get_object_vars($this);
while (isset($vars[$name])) {
$new_value = $this->$name;
unset($this->$name);
parent::__set($name, $new_value);
$vars = get_object_vars($this);
}
}
/**
* Inherits.
*
* Calls parent and invokes modified and purged hooks.
*
* @see FedoraDatastream::modifyDatastream()
*/
protected function modifyDatastream(array $args) {
try {
parent::modifyDatastream($args);
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $this->parent->models, $this->id, $this->parent, $this);
if ($this->state == 'D') {
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $this->parent->models, $this->id, $this->parent, $this->id);
}
}
catch (Exception $e) {
watchdog('islandora', 'Failed to modify datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $this->parent->id,
'@dsid' => $this->id,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
} }
class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion { class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion {

56
includes/utilities.inc

@ -30,16 +30,16 @@ function islandora_convert_bytes_to_human_readable($bytes, $precision = 2) {
return $bytes . ' B'; return $bytes . ' B';
} }
elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) { elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
return round($bytes / $kilobyte, $precision) . ' KB'; return round($bytes / $kilobyte, $precision) . ' KiB';
} }
elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) { elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
return round($bytes / $megabyte, $precision) . ' MB'; return round($bytes / $megabyte, $precision) . ' MiB';
} }
elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) { elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
return round($bytes / $gigabyte, $precision) . ' GB'; return round($bytes / $gigabyte, $precision) . ' GiB';
} }
elseif ($bytes >= $terabyte) { elseif ($bytes >= $terabyte) {
return round($bytes / $terabyte, $precision) . ' TB'; return round($bytes / $terabyte, $precision) . ' TiB';
} }
else { else {
return $bytes . ' B'; return $bytes . ' B';
@ -649,54 +649,6 @@ function islandora_system_settings_form_default_value($name, $default_value, arr
return isset($form_state['values'][$name]) ? $form_state['values'][$name] : variable_get($name, $default_value); return isset($form_state['values'][$name]) ? $form_state['values'][$name] : variable_get($name, $default_value);
} }
/**
* Returns basic information about DS-COMPOSITE-MODEL.
*
* @deprecated
* The pre-existing--and more flexible--
* islandora_get_datastreams_requirements_from_content_model() should be
* preferred, as it addresses the case where a stream can be allowed to have
* one of a set of mimetypes (this functions appears to only return the last
* declared mimetype for a given datastream).
*
* @param string $pid
* The PID of content model containing DS_COMP stream.
*
* @return array
* An associative array mapping datastream IDs to an associative array
* representing the parsed DS-COMPOSITE-MODEL of the form:
* - DSID: A string containing the datastream ID.
* - "mimetype": A string containing the last mimetype declared for the
* given datastream ID.
* - "optional": An optional boolean indicating that the given datastream
* is optional.
*/
function islandora_get_comp_ds_mappings($pid) {
$message = islandora_deprecated('7.x-1.2', t('Refactor to use the more flexible islandora_get_datastreams_requirements_from_content_model().'));
trigger_error(filter_xss($message), E_USER_DEPRECATED);
$cm_object = islandora_object_load($pid);
if (!isset($cm_object) || !isset($cm_object['DS-COMPOSITE-MODEL'])) {
return FALSE;
}
$datastream = $cm_object['DS-COMPOSITE-MODEL'];
$ds_comp_stream = $datastream->content;
$sxml = new SimpleXMLElement($ds_comp_stream);
$mappings = array();
foreach ($sxml->dsTypeModel as $ds) {
$dsid = (string) $ds['ID'];
$optional = (string) $ds['optional'];
foreach ($ds->form as $form) {
$mime = (string) $form['MIME'];
if ($optional) {
$mappings[$dsid]['optional'] = $optional;
}
$mappings[$dsid]['mimetype'] = $mime;
}
}
return $mappings;
}
/** /**
* Checks that the given/current account has all the given permissions. * Checks that the given/current account has all the given permissions.
* *

17
islandora.module

@ -184,7 +184,6 @@ function islandora_menu() {
ISLANDORA_INGEST, ISLANDORA_INGEST,
), 2), ), 2),
); );
$islandora_path = drupal_get_path('module', 'islandora');
$items['islandora/object/%islandora_object/manage/overview'] = array( $items['islandora/object/%islandora_object/manage/overview'] = array(
'title' => 'Overview', 'title' => 'Overview',
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
@ -1906,6 +1905,22 @@ function islandora_find_package($package_name) {
return $found && user_access('administer site configuration'); return $found && user_access('administer site configuration');
} }
/**
* Helper function for ingest steps and batches.
*
* When batches within batches are triggered within ingest steps
* the submit handler becomes out of scope. When it becomes time to execute the
* submit the function cannot be found and fails. This pre-submit is to
* get around this problem.
*
* @see https://www.drupal.org/node/2300367
*
* @see https://www.drupal.org/node/1300928
*/
function islandora_ingest_form_pre_submit($form, &$form_state) {
module_load_include('inc', 'islandora', 'includes/ingest.form');
}
/** /**
* Implements hook_menu_local_tasks_alter(). * Implements hook_menu_local_tasks_alter().
*/ */

4
tests/hooks.test

@ -109,9 +109,11 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$this->repository->ingestObject($object); $this->repository->ingestObject($object);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; $_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK] = 0;
$object->label = "New Label!"; $object->label = "New Label!";
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when modifying via set magic functions.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.');
$this->assertEqual('New Label! + 3', $object->label, 'Re-entered ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.');
// Test blocking the modification. // Test blocking the modification.
try { try {
@ -191,10 +193,12 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$ds = $object->constructDatastream('TEST'); $ds = $object->constructDatastream('TEST');
$object->ingestDatastream($ds); $object->ingestDatastream($ds);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = 0;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; $_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$ds->label = "New Label!"; $ds->label = "New Label!";
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when modifying via set magic functions.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.');
$this->assertEqual('New Label! + 3', $ds->label, 'Re-entered ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.');
// Test blocking modifying. // Test blocking modifying.
try { try {

8
tests/islandora_hooks_test.module

@ -112,6 +112,10 @@ function islandora_hooks_test_islandora_object_ingested(AbstractObject $object)
function islandora_hooks_test_islandora_object_modified(AbstractObject $object) { function islandora_hooks_test_islandora_object_modified(AbstractObject $object) {
if ($object->id == 'test:testModifiedObjectHook') { if ($object->id == 'test:testModifiedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE; $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE;
if ($_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK]++ < 3) {
$new_label = 'New Label! + ' . $_SESSION['islandora_hooks']['iteration'][ISLANDORA_OBJECT_MODIFIED_HOOK];
$object->label = $new_label;
}
} }
} }
@ -139,6 +143,10 @@ function islandora_hooks_test_islandora_datastream_ingested(AbstractObject $obje
function islandora_hooks_test_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) { function islandora_hooks_test_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
if ($object->id == 'test:testModifiedDatastreamHook' && $datastream->id == "TEST") { if ($object->id == 'test:testModifiedDatastreamHook' && $datastream->id == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE; $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE;
if ($_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK]++ < 3) {
$new_label = 'New Label! + ' . $_SESSION['islandora_hooks']['iteration'][ISLANDORA_DATASTREAM_MODIFIED_HOOK];
$datastream->label = $new_label;
}
} }
} }

Loading…
Cancel
Save