diff --git a/includes/object.entity_controller.inc b/includes/object.entity_controller.inc
index 9464d7b5..87b5e4de 100644
--- a/includes/object.entity_controller.inc
+++ b/includes/object.entity_controller.inc
@@ -30,6 +30,7 @@ class IslandoraObjectEntityController implements DrupalEntityControllerInterface
*/
public function load($ids = array(), $conditions = array()) {
if (!empty($conditions)) {
+ // TODO: Allow loading by specifying IDs in the condition.
throw new Exception('Conditions not implemented.');
}
diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc
index 53942554..d14a86b3 100644
--- a/includes/tuque_wrapper.inc
+++ b/includes/tuque_wrapper.inc
@@ -115,10 +115,6 @@ class IslandoraFedoraRepository extends FedoraRepository {
foreach ($object as $dsid => $datastream) {
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_INGESTED_HOOK, $object->models, $dsid, $object, $datastream);
}
- // Fire of event if rules is enabled.
- if (module_exists('rules')) {
- rules_invoke_event('islandora_object_ingested', $object);
- }
return $ret;
}
catch (Exception $e) {
@@ -228,10 +224,6 @@ class IslandoraFedoraObject extends FedoraObject {
if ($this->state == 'D') {
islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $this->models, $this->id);
}
- // Fire of event if rules is enabled.
- if (module_exists('rules')) {
- rules_invoke_event('islandora_object_modified', $object);
- }
}
catch (Exception $e) {
watchdog('islandora', 'Failed to modify object: @pidcode: @code
message: @msg', array(
diff --git a/includes/utilities.inc b/includes/utilities.inc
index 26633df5..7476948b 100644
--- a/includes/utilities.inc
+++ b/includes/utilities.inc
@@ -188,12 +188,18 @@ function islandora_describe_repository($url = NULL) {
*/
function islandora_invoke_hook_list($hook, array $refinements, array $args) {
$return = array();
- foreach (islandora_build_hook_list($hook, $refinements) as $hook) {
- array_unshift($args, $hook);
+ foreach (islandora_build_hook_list($hook, $refinements) as $refined_hook) {
+ array_unshift($args, $refined_hook);
$result = call_user_func_array('module_invoke_all', $args);
$return = array_merge_recursive($return, $result);
array_shift($args);
}
+ if (module_exists('rules') && $event = rules_get_cache("event_$hook")) {
+ $parameters = $event->parameterInfo();
+ $rule_args = array_slice($args, 0, count($parameters));
+ array_unshift($rule_args, $hook);
+ $result = call_user_func_array('rules_invoke_event', $rule_args);
+ }
return $return;
}
diff --git a/islandora.info b/islandora.info
index 55c50359..580a81ac 100644
--- a/islandora.info
+++ b/islandora.info
@@ -13,6 +13,7 @@ files[] = includes/dublin_core.inc
files[] = includes/tuque.inc
files[] = includes/tuque_wrapper.inc
files[] = includes/object.entity_controller.inc
+files[] = includes/datastream.entity_controller.inc
files[] = tests/includes/datastream_validators.inc
files[] = tests/includes/islandora_web_test_case.inc
files[] = tests/includes/islandora_unit_test_case.inc
diff --git a/islandora.module b/islandora.module
index 0b2a3ce8..85bcd2bc 100644
--- a/islandora.module
+++ b/islandora.module
@@ -1543,21 +1543,25 @@ function islandora_entity_property_info() {
'type' => 'text',
'label' => t('Object Label'),
'description' => t('The label of the object.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
$object_properties['owner'] = array(
'type' => 'text',
'label' => t('Object Owner'),
'description' => t('The name of the owner of the object.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
$object_properties['state'] = array(
'type' => 'text',
'label' => t('Object State'),
'description' => t('An initial representing the state of the object.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
$object_properties['models'] = array(
'type' => 'list',
'label' => t('Content Models'),
'description' => t('The list of content models which the object has.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
$object_properties['createdDate'] = array(
'type' => 'text',
@@ -1574,11 +1578,24 @@ function islandora_entity_property_info() {
'type' => 'text',
'label' => t('Datastream Label'),
'description' => t('The label of the datastream.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
$datastream_properties['mimetype'] = array(
'type' => 'text',
'label' => t('MIME type'),
'description' => t('Content type of the datastream.'),
+ 'setter callback' => 'entity_property_verbatim_set',
+ );
+ $datastream_properties['parent'] = array(
+ 'type' => 'islandora_object',
+ 'label' => t('Object'),
+ 'description' => t('The Tuque object on which this datastream exists.'),
+ );
+ $datastream_properties['content'] = array(
+ 'type' => 'text',
+ 'label' => t('Datastream content'),
+ 'description' => t('The contents of the datastream; only useful when the content is textual.'),
+ 'setter callback' => 'entity_property_verbatim_set',
);
return $info;
@@ -1762,10 +1779,6 @@ function islandora_islandora_object_ingested(AbstractObject $object) {
* equal to the current ingested datastream's id.
*/
function islandora_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) {
- if (module_exists('rules')) {
- rules_invoke_event('islandora_datastream_ingested', $object, $datastream->id);
- }
-
module_load_include('inc', 'islandora', 'includes/derivatives');
// Defer derivatives if necessary.
if (islandora_get_defer_derivatives_flag($object)) {
@@ -1782,10 +1795,6 @@ function islandora_islandora_datastream_ingested(AbstractObject $object, Abstrac
* existing derivatives will be updated to reflect the change in the source.
*/
function islandora_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
- if (module_exists('rules')) {
- rules_invoke_event('islandora_datastream_modified', $object, $datastream->id);
- }
-
module_load_include('inc', 'islandora', 'includes/derivatives');
$logging_results = islandora_do_derivatives($object, array(
'source_dsid' => $datastream->id,
diff --git a/islandora.rules.inc b/islandora.rules.inc
index 17fa8227..aca1d9dc 100644
--- a/islandora.rules.inc
+++ b/islandora.rules.inc
@@ -31,7 +31,7 @@ function islandora_rules_event_info() {
'description' => t('A Tuque object for the Fedora object on which the datastream exists, as an entity.'),
),
'datastream' => array(
- 'type' => 'text',
+ 'type' => 'islandora_datastream',
'label' => t('Datastream ID'),
'description' => t('The ID of the ingested datastream.'),
),
@@ -57,10 +57,37 @@ function islandora_rules_event_info() {
'label' => t('The modified object'),
'description' => t('A Tuque object for the Fedora object on which the datastream exists, as an entity.'),
),
+ 'datastream' => array(
+ 'type' => 'islandora_datastream',
+ 'label' => t('Datastream'),
+ 'description' => t('The modified datastream.'),
+ ),
+ ),
+ ),
+ 'islandora_object_purged' => array(
+ 'group' => t('Islandora'),
+ 'label' => t('Object purged'),
+ 'variables' => array(
+ 'object' => array(
+ 'type' => 'text',
+ 'label' => t('Object ID'),
+ 'description' => t('The ID of the purged object.'),
+ ),
+ ),
+ ),
+ 'islandora_datastream_purged' => array(
+ 'group' => t('Islandora'),
+ 'label' => t('Datastream purged'),
+ 'variables' => array(
+ 'object' => array(
+ 'type' => 'islandora_object',
+ 'label' => t('Object'),
+ 'description' => t('A Tuque object for the Fedora object from which the datastream exists, as an entity.'),
+ ),
'datastream' => array(
'type' => 'text',
'label' => t('Datastream ID'),
- 'description' => t('The ID of the ingested datastream.'),
+ 'description' => t('The identifier of the purged datastream.'),
),
),
),
@@ -105,15 +132,10 @@ function islandora_rules_relationship_parameter_array() {
function islandora_rules_base_xpath_parameters() {
return array(
- 'object' => array(
- 'type' => 'islandora_object',
- 'label' => t('Object'),
- 'description' => t('The object in which to check the XPath.'),
- ),
'datastream' => array(
- 'type' => 'text',
- 'label' => t('Datastream ID'),
- 'description' => t('The ID of the XML datastream to check.'),
+ 'type' => 'islandora_datastream',
+ 'label' => t('Datastream'),
+ 'description' => t('The XML datastream to check.'),
),
'xpath' => array(
'type' => 'text',
@@ -167,8 +189,94 @@ function islandora_rules_action_info() {
'parameter' => islandora_rules_relationship_parameter_array(),
);
+ $cond['islandora_rules_datastream_load_domxpath'] = array(
+ 'label' => t('Load a DOMXPath for a given XML.'),
+ 'group' => t('Islandora DOMXPath'),
+ 'parameter' => array(
+ 'datastrea,' => array(
+ 'type' => 'text',
+ 'label' => t('XML'),
+ 'description' => t('A string containing the XML to load.'),
+ ),
+ ),
+ 'provides' => array(
+ 'islandora_domxpath' => array(
+ 'type' => 'islandora_domxpath',
+ 'label' => t('Loaded DOMXPath instance'),
+ ),
+ ),
+ );
+ $cond['islandora_rules_datastream_load_xpath'] = array(
+ 'label' => t('Load a DOMXPath from a datastream.'),
+ 'group' => t('Islandora DOMXPath'),
+ 'parameter' => array(
+ 'datastream' => array(
+ 'type' => 'islandora_datastream',
+ 'label' => t('Datastream'),
+ 'description' => t('A datastream containing the XML to load.'),
+ ),
+ ),
+ 'provides' => array(
+ 'islandora_domxpath' => array(
+ 'type' => 'islandora_domxpath',
+ 'label' => t('Loaded DOMXPath instance'),
+ ),
+ ),
+ );
+ $cond['islandora_rules_datastream_load_namespace_vocab'] = array(
+ 'label' => t('Register namespaces on a DOMXPath instance.'),
+ 'group' => t('Islandora DOMXPath'),
+ 'parameter' => array(
+ 'value' => array(
+ 'type' => 'islandora_domxpath',
+ 'label' => t('DOMXPath instance'),
+ 'description' => t('The DOMXPath instance on which to register the namespaces.'),
+ ),
+ 'xpath_namespaces' => array(
+ 'type' => 'taxonomy_vocabulary',
+ 'label' => t('XPath Namespace Taxonomy'),
+ 'description' => t('A flat taxonomy of which the terms are namespace prefixes and the description contains the URI for the namespace.')
+ ),
+ ),
+ );
+ $cond['islandora_rules_datastream_query_xpath'] = array(
+ 'label' => t('Query nodes from DOMXPath instance.'),
+ 'group' => t('Islandora DOMXPath'),
+ 'parameter' => array(
+ 'xpath' => array(
+ 'type' => 'islandora_domxpath',
+ 'label' => t('DOMXPath instance'),
+ 'description' => t('The DOMXPath instance on which to perform the query.'),
+ ),
+ 'query' => array(
+ 'type' => 'text',
+ 'label' => t('XPath query'),
+ 'description' => t('The XPath query to perform.')
+ ),
+ ),
+ 'provides' => array(
+ 'nodes' => array(
+ 'type' => 'list',
+ 'label' => t('Queried DOMNode elements'),
+ ),
+ ),
+ );
+
+ $cond['islandora_rules_datastream_set_xpath'] = array(
+ 'label' => t('Set value in elements matched by an XPath in an XML datastream'),
+ 'group' => t('Islandora'),
+ 'parameter' => islandora_rules_base_xpath_parameters() + array(
+ 'value' => array(
+ 'type' => 'text',
+ 'label' => t('Value'),
+ 'description' => t('The value to set in the XML on elements matched by the XPath.'),
+ ),
+ ),
+ );
+
return $cond;
}
+
/**
* Checks that there is a relationship match on the given object.
*
@@ -209,19 +317,107 @@ function islandora_object_add_relationship($sub, $pred_uri, $pred, $object, $typ
$sub->relationships->add($pred_uri, $pred, $object, $type);
}
-function islandora_rules_datastream_has_xpath(AbstractObject $object, $datastream_id, $search_xpath, $xpath_vocab) {
- if (!isset($object[$datastream_id])) {
- // Datastream does no exists... No match.
- return FALSE;
- }
-
- $datastream = $object[$datastream_id];
+function islandora_rules_datastream_load_domxpath($string) {
$doc = new DOMDocument();
- $doc->loadXML($datastream->content);
+ $doc->loadXML($string);
$xpath = new DOMXPath($doc);
+ return array('islandora_domxpath' => $xpath);
+}
+
+function islandora_rules_datastream_load_namespace_vocab($xpath, $xpath_vocab) {
foreach (taxonomy_get_tree($xpath_vocab->vid, 0, 1, FALSE) as $term) {
$xpath->registerNamespace($term->name, $term->description);
}
- $result = $xpath->query($search_xpath);
+}
+
+/**
+ * Rules XPath helper; grab the datastream content and build a DOMXPath.
+ */
+function islandora_rules_datastream_load_xpath(AbstractDatastream $datastream, $xpath_vocab) {
+ $result = islandora_rules_datastream_load_domxpath($datastream->content, $xpath_vocab);
+ islandora_rules_datastream_load_namespace_vocab($result['islandora_domxpath'], $xpath_vocab);
+ return $result;
+}
+
+function islandora_rules_datastream_has_xpath(AbstractDatastream $datastream, $search_xpath, $xpath_vocab) {
+ $xpath = islandora_rules_datastream_load_xpath($datastream, $xpath_vocab);
+ $result = $xpath['islandora_domxpath']->query($search_xpath);
return $result->length > 0;
}
+
+function islandora_rules_datastream_set_xpath(AbstractDatastream $datastream, $search_xpath, $xpath_vocab, $value) {
+ $xpath = islandora_rules_datastream_load_xpath($datastream, $xpath_vocab);
+ $result = $xpath['islandora_domxpath']->query($search_xpath);
+ foreach ($result as $node) {
+ $node->nodeValue = $value;
+ }
+ $datastream->content = $xpath['islandora_domxpath']->document->saveXML();
+}
+
+/**
+ * Implements hook_rules_data_info().
+ */
+function islandora_rules_data_info() {
+ return array(
+ 'islandora_domxpath' => array(
+ 'label' => t('DOMXPath instance'),
+ 'group' => t('Islandora'),
+ 'property info' => array(
+ 'content' => array(
+ 'type' => 'text',
+ 'label' => t('XML Content'),
+ 'computed' => TRUE,
+ 'getter callback' => 'islandora_rules_get_domxpath_document_content',
+ 'token type' => 'string',
+ ),
+ ),
+ 'wrap' => TRUE,
+ ),
+ 'islandora_domnode' => array(
+ 'label' => t('DOMNode instance'),
+ 'group' => t('Islandora'),
+ 'property info' => array(
+ 'node_value' => array(
+ 'type' => 'text',
+ 'label' => t('Node value'),
+ 'computed' => TRUE,
+ 'getter callback' => 'islandora_rules_domnode_get',
+ 'setter callback' => 'islandora_rules_domnode_set',
+ 'property' => 'nodeValue',
+ 'token type' => 'string',
+ ),
+ 'text_content' => array(
+ 'type' => 'text',
+ 'label' => t('Text content'),
+ 'computed' => TRUE,
+ 'getter callback' => 'islandora_rules_domnode_get',
+ 'property' => 'textContent',
+ 'token type' => 'string',
+ ),
+ ),
+ 'wrap' => TRUE,
+ ),
+ 'islandora_domelement' => array(
+ 'label' => t('DOMElement instance'),
+ 'group' => t('Islandora'),
+ 'parent' => 'islandora_domnode',
+ 'wrap' => TRUE,
+ ),
+ );
+}
+
+function islandora_rules_domnode_get($data, $options, $name, $type, $info) {
+ return $data->$info['property'];
+}
+
+function islandora_rules_domnode_set(&$data, $name, $value, $langcode, $type, $info) {
+ $data->$info['property'] = $value;
+}
+
+function islandora_rules_get_domxpath_document_content(DOMXPath $xpath) {
+ return $xpath->document->saveXML();
+}
+
+function islandora_rules_datastream_query_xpath(DOMXPath $xpath, $query) {
+ return array('nodes' => iterator_to_array($xpath->query($query)));
+}