diff --git a/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml b/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml index 071b3787..e4a6f5fb 100644 --- a/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml +++ b/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml @@ -34,9 +34,6 @@ fieldMappings: rdf_type: properties: - 'rdf:type' - vclock: - properties: - - 'islandora:vclock' user_id: properties: - 'schema:author' diff --git a/fedora_resource.page.inc b/fedora_resource.page.inc index fd28f0b3..dfa7f9f6 100644 --- a/fedora_resource.page.inc +++ b/fedora_resource.page.inc @@ -52,20 +52,20 @@ function template_preprocess_fedora_resource(array &$variables) { * @see block_content_add_page() */ function template_preprocess_fedora_resource_content_add_list(array &$variables) { - $variables['types'] = array(); + $variables['types'] = []; $query = \Drupal::request()->query->all(); foreach ($variables['content'] as $type) { - $variables['types'][$type->id()] = array( - 'link' => Link::fromTextAndUrl($type->label(), new Url('entity.fedora_resource.add_form', array( + $variables['types'][$type->id()] = [ + 'link' => Link::fromTextAndUrl($type->label(), new Url('entity.fedora_resource.add_form', [ 'fedora_resource_type' => $type->id(), - ), array('query' => $query))), - 'description' => array( + ], ['query' => $query])), + 'description' => [ '#markup' => $type->label(), - ), + ], 'title' => $type->label(), - 'localized_options' => array( + 'localized_options' => [ 'query' => $query, - ), - ); + ], + ]; } } diff --git a/islandora.install b/islandora.install new file mode 100644 index 00000000..e900f2f6 --- /dev/null +++ b/islandora.install @@ -0,0 +1,42 @@ + 'Keeps track of the number of changes to an entity', + 'fields' => [ + 'id' => [ + 'description' => 'Autoincrementing id for record', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ], + 'uuid' => [ + 'description' => 'UUID for an entity', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'unique' => TRUE, + ], + 'count' => [ + 'description' => 'Number of times an entity has been updated.', + 'type' => 'int', + 'unsigned' => TRUE, + 'default' => 0, + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'uuid' => ['uuid'], + ], + ]; + return $schema; +} diff --git a/islandora.module b/islandora.module index 6bbab8e3..6fc5a00b 100644 --- a/islandora.module +++ b/islandora.module @@ -14,6 +14,8 @@ * @author Diego Pino Navarro https://github.com/diegopino */ +use Drupal\Core\Database\IntegrityConstraintViolationException; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; /** @@ -54,7 +56,7 @@ function islandora_theme() { * Implements hook_theme_suggestions_HOOK(). */ function islandora_theme_suggestions_fedora_resource(array $variables) { - $suggestions = array(); + $suggestions = []; $entity = $variables['elements']['#fedora_resource']; $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_'); @@ -71,7 +73,7 @@ function islandora_theme_suggestions_fedora_resource(array $variables) { */ function islandora_rdf_namespaces() { // Yes, it's amazing, rdf is not registered by default! - return array( + return [ 'ldp' => 'http://www.w3.org/ns/ldp#', 'dc11' => 'http://purl.org/dc/elements/1.1/', 'nfo' => 'http://www.semanticdesktop.org/ontologies/2007/03/22/nfo/v1.1/', @@ -82,5 +84,41 @@ function islandora_rdf_namespaces() { 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'islandora' => 'http://islandora.ca/CLAW/', 'pcdm' => 'http://pcdm.org/models#', - ); + ]; +} + +/** + * Implements hook_ENTITY_TYPE_insert(). + */ +function islandora_fedora_resource_insert(EntityInterface $entity) { + // Creates a record in the db to track the number of changes to the entity. + $versionCounter = \Drupal::service('islandora.versioncounter'); + try { + $versionCounter->create($entity->uuid()); + } + catch (IntegrityConstraintViolationException $e) { + \Drupal::logger('islandora')->error( + 'Attempted to create duplicate entry for @uuid in version counter ' . + 'table. This should never happen.', + ['@uuid' => $entity->uuid()] + ); + } +} + +/** + * Implements hook_ENTITY_TYPE_update(). + */ +function islandora_fedora_resource_update(EntityInterface $entity) { + // Increments the number of changes to the entity. + $versionCounter = \Drupal::service('islandora.versioncounter'); + $versionCounter->increment($entity->uuid()); +} + +/** + * Implements hook_ENTITY_TYPE_update(). + */ +function islandora_fedora_resource_delete(EntityInterface $entity) { + // Deletes the record in the db to track the number of changes to the entity. + $versionCounter = \Drupal::service('islandora.versioncounter'); + $versionCounter->delete($entity->uuid()); } diff --git a/islandora.services.yml b/islandora.services.yml index d078fe08..44eead48 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -18,3 +18,6 @@ services: arguments: ['@entity_type.manager', '@current_user'] tags: - { name: event_subscriber } + islandora.versioncounter: + class: Drupal\islandora\VersionCounter\VersionCounter + arguments: ['@database'] diff --git a/src/Controller/FedoraResourceAddController.php b/src/Controller/FedoraResourceAddController.php index 9b33634a..782b21c7 100644 --- a/src/Controller/FedoraResourceAddController.php +++ b/src/Controller/FedoraResourceAddController.php @@ -73,14 +73,14 @@ class FedoraResourceAddController extends ControllerBase { return $this->addForm($type, $request); } if (count($types) === 0) { - return array( + return [ '#markup' => $this->t('You have not created any %bundle types yet. @link to add a new type.', [ '%bundle' => 'Fedora resource', '@link' => $this->l($this->t('Go to the type creation page'), Url::fromRoute('entity.fedora_resource_type.add_form')), ]), - ); + ]; } - return array('#theme' => 'fedora_resource_content_add_list', '#content' => $types); + return ['#theme' => 'fedora_resource_content_add_list', '#content' => $types]; } /** @@ -95,9 +95,9 @@ class FedoraResourceAddController extends ControllerBase { * A form array as expected by drupal_render(). */ public function addForm(EntityInterface $fedora_resource_type, Request $request) { - $entity = $this->storage->create(array( + $entity = $this->storage->create([ 'type' => $fedora_resource_type->id(), - )); + ]); return $this->entityFormBuilder()->getForm($entity); } @@ -112,7 +112,7 @@ class FedoraResourceAddController extends ControllerBase { */ public function getAddFormTitle(EntityInterface $fedora_resource_type) { return t('Create of bundle @label', - array('@label' => $fedora_resource_type->label()) + ['@label' => $fedora_resource_type->label()] ); } diff --git a/src/Entity/FedoraResource.php b/src/Entity/FedoraResource.php index f31e16d0..a9939619 100644 --- a/src/Entity/FedoraResource.php +++ b/src/Entity/FedoraResource.php @@ -96,21 +96,9 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac */ public static function preCreate(EntityStorageInterface $storage_controller, array &$values) { parent::preCreate($storage_controller, $values); - $values += array( + $values += [ 'user_id' => \Drupal::currentUser()->id(), - ); - } - - /** - * {@inheritdoc} - */ - public function preSave(EntityStorageInterface $storage) { - parent::preSave($storage); - - // Increment the vclock. - if (!$this->isNew()) { - $this->set("vclock", $this->get("vclock")->value + 1); - } + ]; } /** @@ -262,13 +250,6 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac return NULL; } - /** - * {@inheritdoc} - */ - public function getVclock() { - return $this->get('vclock')->value; - } - /** * {@inheritdoc} */ @@ -291,11 +272,6 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Fedora resource entity.')) ->setReadOnly(TRUE); - $fields['vclock'] = BaseFieldDefinition::create('integer') - ->setLabel(t('Vector Clock')) - ->setDescription(t('Simple accumulator used for causality tracking')) - ->setDefaultValue(0) - ->setSetting('unsigned', TRUE); $fields['user_id'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Authored by')) @@ -305,21 +281,21 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setSetting('handler', 'default') ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'autocomplete_type' => 'tags', 'placeholder' => '', - ), - )) + ], + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); @@ -331,41 +307,41 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setSetting('handler', 'default') ->setDefaultValueCallback('Drupal\islandora\Entity\FedoraResource::getFedoraRoot') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'autocomplete_type' => 'tags', 'placeholder' => '', - ), - )) + ], + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); $fields['name'] = BaseFieldDefinition::create('string') ->setLabel(t('Name')) ->setDescription(t('The name of the Fedora resource entity.')) - ->setSettings(array( + ->setSettings([ 'max_length' => 50, 'text_processing' => 0, - )) + ]) ->setDefaultValue('') - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'above', 'type' => 'string', 'weight' => -4, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -4, - )) + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); @@ -377,10 +353,10 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac $fields['langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Language code')) ->setDescription(t('The language code for the Fedora resource entity.')) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'language_select', 'weight' => 10, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['created'] = BaseFieldDefinition::create('created') @@ -396,13 +372,13 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDefaultValue(TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'boolean_checkbox', - 'settings' => array( + 'settings' => [ 'display_label' => TRUE, - ), + ], 'weight' => 15, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['sticky'] = BaseFieldDefinition::create('boolean') @@ -410,13 +386,13 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDefaultValue(FALSE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'boolean_checkbox', - 'settings' => array( + 'settings' => [ 'display_label' => TRUE, - ), + ], 'weight' => 16, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['revision_timestamp'] = BaseFieldDefinition::create('created') @@ -437,13 +413,13 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setDescription(t('Briefly describe the changes you have made.')) ->setRevisionable(TRUE) ->setDefaultValue('') - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'string_textarea', 'weight' => 25, - 'settings' => array( + 'settings' => [ 'rows' => 4, - ), - )); + ], + ]); $fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Revision translation affected')) diff --git a/src/Entity/FedoraResourceViewsData.php b/src/Entity/FedoraResourceViewsData.php index 0c4679df..9b59822a 100644 --- a/src/Entity/FedoraResourceViewsData.php +++ b/src/Entity/FedoraResourceViewsData.php @@ -16,11 +16,11 @@ class FedoraResourceViewsData extends EntityViewsData implements EntityViewsData public function getViewsData() { $data = parent::getViewsData(); - $data['fedora_resource']['table']['base'] = array( + $data['fedora_resource']['table']['base'] = [ 'field' => 'id', 'title' => $this->t('Fedora resource'), 'help' => $this->t('The Fedora resource ID.'), - ); + ]; $data['fedora_resource_field_data']['table']['wizard_id'] = 'fedora_resource'; $data['fedora_resource_field_revision']['table']['wizard_id'] = 'fedora_resource_revision'; diff --git a/src/FedoraResourceInterface.php b/src/FedoraResourceInterface.php index 59e871d3..8fe58a8e 100644 --- a/src/FedoraResourceInterface.php +++ b/src/FedoraResourceInterface.php @@ -117,12 +117,4 @@ interface FedoraResourceInterface extends ContentEntityInterface, EntityChangedI */ public function setParent(EntityTypeInterface $entity); - /** - * Gets the vector clock of this entity. - * - * @return int - * The vector clock, used for determining causality. - */ - public function getVclock(); - } diff --git a/src/Form/FedoraResourceEntityInlineForm.php b/src/Form/FedoraResourceEntityInlineForm.php index 802f78f6..744709ca 100644 --- a/src/Form/FedoraResourceEntityInlineForm.php +++ b/src/Form/FedoraResourceEntityInlineForm.php @@ -262,7 +262,7 @@ class FedoraResourceEntityInlineForm extends EntityInlineForm implements InlineF $parents = $entity_form[$field_name]['#parents']; array_pop($parents); if (!empty($parents)) { - $field_state = array(); + $field_state = []; WidgetBase::setWidgetState($parents, $field_name, $form_state, $field_state); } } diff --git a/src/Form/FedoraResourceTypeDeleteForm.php b/src/Form/FedoraResourceTypeDeleteForm.php index 98f1885b..6913dfa5 100644 --- a/src/Form/FedoraResourceTypeDeleteForm.php +++ b/src/Form/FedoraResourceTypeDeleteForm.php @@ -15,7 +15,7 @@ class FedoraResourceTypeDeleteForm extends EntityConfirmFormBase { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to delete %name?', array('%name' => $this->entity->label())); + return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]); } /** diff --git a/src/Form/FedoraResourceTypeForm.php b/src/Form/FedoraResourceTypeForm.php index ba36b360..ac1a19ef 100644 --- a/src/Form/FedoraResourceTypeForm.php +++ b/src/Form/FedoraResourceTypeForm.php @@ -19,23 +19,23 @@ class FedoraResourceTypeForm extends EntityForm { $form = parent::form($form, $form_state); $fedora_resource_type = $this->entity; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $fedora_resource_type->label(), '#description' => $this->t("Label for the Fedora resource type."), '#required' => TRUE, - ); + ]; - $form['id'] = array( + $form['id'] = [ '#type' => 'machine_name', '#default_value' => $fedora_resource_type->id(), - '#machine_name' => array( + '#machine_name' => [ 'exists' => '\Drupal\islandora\Entity\FedoraResourceType::load', - ), + ], '#disabled' => !$fedora_resource_type->isNew(), - ); + ]; /* You will need additional form elements for your custom properties. */ diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 35606f82..db33fce8 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -40,24 +40,24 @@ class IslandoraSettingsForm extends ConfigFormBase { public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config(self::CONFIG_NAME); - $form[self::BROKER_URL] = array( + $form[self::BROKER_URL] = [ '#type' => 'textfield', '#title' => $this->t('Broker URL'), '#default_value' => $config->get(self::BROKER_URL), - ); + ]; - $form[self::BROADCAST_QUEUE] = array( + $form[self::BROADCAST_QUEUE] = [ '#type' => 'textfield', '#title' => $this->t('Broadcast Queue'), '#default_value' => $config->get(self::BROADCAST_QUEUE), - ); + ]; - $form[self::FEDORA_REST_ENDPOINT] = array( + $form[self::FEDORA_REST_ENDPOINT] = [ '#type' => 'textfield', '#title' => $this->t('Fedora REST Endpoint'), '#description' => $this->t('The URL for your Fedora instance.'), '#default_value' => $config->get(self::FEDORA_REST_ENDPOINT), - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/src/Plugin/Search/FedoraEntitySearch.php b/src/Plugin/Search/FedoraEntitySearch.php index e1905ef9..3a0ace07 100644 --- a/src/Plugin/Search/FedoraEntitySearch.php +++ b/src/Plugin/Search/FedoraEntitySearch.php @@ -141,11 +141,11 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces * * @var array */ - protected $advanced = array( - 'name' => array( + protected $advanced = [ + 'name' => [ 'column' => 'c.name', - ), - ); + ], + ]; /** * A constant for setting and checking the query string. @@ -246,7 +246,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces } } - return array(); + return []; } /** @@ -265,7 +265,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces // Build matching conditions. $query = $this->database - ->select('search_index', 'i', array('target' => 'replica')) + ->select('search_index', 'i', ['target' => 'replica']) ->extend('Drupal\search\SearchQuery') ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); @@ -294,7 +294,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $parameters = $this->getParameters(); if (!empty($parameters['f']) && is_array($parameters['f'])) { // @todo This loop should probably be moved to a helper function. - $filters = array(); + $filters = []; // Match any query value that is an expected option and a value // separated by ':' like 'first_name:Jane'. $pattern = '/^(' . implode('|', array_keys($this->advanced)) . '):([^ ]*)/i'; @@ -330,7 +330,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $find = $query // Add the language code of the indexed item to the result of the query, // since the entity will be rendered using the respective language. - ->fields('i', array('langcode')) + ->fields('i', ['langcode']) // And since SearchQuery makes these into GROUP BY queries, if we add // a field, for PostgreSQL we also need to make it an aggregate or a // GROUP BY. In this case, we want GROUP BY. @@ -342,7 +342,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $status = $query->getStatus(); if ($status & SearchQuery::EXPRESSIONS_IGNORED) { - drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $this->searchSettings->get('and_or_limit'))), 'warning'); + drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $this->searchSettings->get('and_or_limit')]), 'warning'); } if ($status & SearchQuery::LOWER_CASE_OR) { @@ -366,7 +366,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces * Array of search result item render arrays (empty array if no results). */ protected function prepareResults(StatementInterface $found) { - $results = array(); + $results = []; // 'fedora_resource' comes from the entity type id declared // in the annotation for \Drupal\islandora\Entity\FedoraResource. @@ -395,13 +395,13 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $language = $this->languageManager->getLanguage($item->langcode); - $result = array( + $result = [ 'link' => $entity->url( 'canonical', - array( + [ 'absolute' => TRUE, 'language' => $language, - ) + ] ), 'type' => 'Fedora Resource', 'title' => $entity->label(), @@ -410,7 +410,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces 'score' => $item->calculated_score, 'snippet' => search_excerpt($keys, $rendered, $item->langcode), 'langcode' => $entity->language()->getId(), - ); + ]; $this->addCacheableDependency($entity); @@ -473,7 +473,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces if (isset($values['join']) && !isset($tables[$values['join']['alias']])) { $query->addJoin($values['join']['type'], $values['join']['table'], $values['join']['alias'], $values['join']['on']); } - $arguments = isset($values['arguments']) ? $values['arguments'] : array(); + $arguments = isset($values['arguments']) ? $values['arguments'] : []; $query->addScore($values['score'], $arguments, $entity_rank); } } @@ -488,7 +488,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces // index per cron run. $limit = (int) $this->searchSettings->get('index.cron_limit'); - $result = $this->database->queryRange("SELECT c.id, MAX(sd.reindex) FROM {fedora_resource} c LEFT JOIN {search_dataset} sd ON sd.sid = c.id AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0 GROUP BY c.id ORDER BY MAX(sd.reindex) is null DESC, MAX(sd.reindex) ASC, c.id ASC", 0, $limit, array(':type' => $this->getPluginId()), array('target' => 'replica')); + $result = $this->database->queryRange("SELECT c.id, MAX(sd.reindex) FROM {fedora_resource} c LEFT JOIN {search_dataset} sd ON sd.sid = c.id AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0 GROUP BY c.id ORDER BY MAX(sd.reindex) is null DESC, MAX(sd.reindex) ASC, c.id ASC", 0, $limit, [':type' => $this->getPluginId()], ['target' => 'replica']); $rids = $result->fetchCol(); if (!$rids) { @@ -569,9 +569,9 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces public function indexStatus() { $total = $this->database->query('SELECT COUNT(*) FROM {fedora_resource}')->fetchField(); - $remaining = $this->database->query("SELECT COUNT(DISTINCT c.id) FROM {contact} c LEFT JOIN {search_dataset} sd ON sd.sid = c.id AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", array(':type' => $this->getPluginId()))->fetchField(); + $remaining = $this->database->query("SELECT COUNT(DISTINCT c.id) FROM {contact} c LEFT JOIN {search_dataset} sd ON sd.sid = c.id AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", [':type' => $this->getPluginId()])->fetchField(); - return array('remaining' => $remaining, 'total' => $total); + return ['remaining' => $remaining, 'total' => $total]; } /** @@ -582,77 +582,77 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $keys = $this->getKeywords(); $used_advanced = !empty($parameters[self::ADVANCED_FORM]); if ($used_advanced) { - $f = isset($parameters['f']) ? (array) $parameters['f'] : array(); + $f = isset($parameters['f']) ? (array) $parameters['f'] : []; $defaults = $this->parseAdvancedDefaults($f, $keys); } else { - $defaults = array('keys' => $keys); + $defaults = ['keys' => $keys]; } $form['basic']['keys']['#default_value'] = $defaults['keys']; // Add advanced search keyword-related boxes. - $form['advanced'] = array( + $form['advanced'] = [ '#type' => 'details', '#title' => t('Advanced search'), - '#attributes' => array('class' => array('search-advanced')), + '#attributes' => ['class' => ['search-advanced']], '#access' => $this->account && $this->account->hasPermission('use advanced search'), '#open' => $used_advanced, - ); - $form['advanced']['keywords-fieldset'] = array( + ]; + $form['advanced']['keywords-fieldset'] = [ '#type' => 'fieldset', '#title' => t('Keywords'), - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['or'] = array( + $form['advanced']['keywords-fieldset']['keywords']['or'] = [ '#type' => 'textfield', '#title' => t('Containing any of the words'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['or']) ? $defaults['or'] : '', - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['phrase'] = array( + $form['advanced']['keywords-fieldset']['keywords']['phrase'] = [ '#type' => 'textfield', '#title' => t('Containing the phrase'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['phrase']) ? $defaults['phrase'] : '', - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['negative'] = array( + $form['advanced']['keywords-fieldset']['keywords']['negative'] = [ '#type' => 'textfield', '#title' => t('Containing none of the words'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['negative']) ? $defaults['negative'] : '', - ); + ]; - $form['advanced']['misc-fieldset'] = array( + $form['advanced']['misc-fieldset'] = [ '#type' => 'fieldset', - ); + ]; // \Drupal\search\SearchQuery requires that there be valid keywords // submitted in the standard fields. - $form['advanced']['misc-fieldset']['note'] = array( + $form['advanced']['misc-fieldset']['note'] = [ '#markup' => t('You must still enter keyword(s) above when using these fields.'), '#weight' => -10, - ); + ]; - $form['advanced']['misc-fieldset']['name'] = array( + $form['advanced']['misc-fieldset']['name'] = [ '#type' => 'textfield', '#title' => t('Name'), - '#description' => t('Search %field field for exact matches.', array('%field' => 'Name')), - '#default_value' => isset($defaults['name']) ? $defaults['name'] : array(), - ); + '#description' => t('Search %field field for exact matches.', ['%field' => 'Name']), + '#default_value' => isset($defaults['name']) ? $defaults['name'] : [], + ]; - $form['advanced']['submit'] = array( + $form['advanced']['submit'] = [ '#type' => 'submit', '#value' => t('Advanced search'), '#prefix' => '', '#suffix' => '', '#weight' => 100, - ); + ]; } /** @@ -665,7 +665,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces $advanced = FALSE; // Collect extra filters. - $filters = array(); + $filters = []; // Advanced form, custom_content_entity_example_contact fields. if ($form_state->hasValue('name') && !empty(($value = trim($form_state->getValue('name'))))) { @@ -695,7 +695,7 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces // Put the keywords and advanced parameters into GET parameters. Make sure // to put keywords into the query even if it is empty, because the page // controller uses that to decide it's time to check for search results. - $query = array('keys' => $keys); + $query = ['keys' => $keys]; if ($filters) { $query['f'] = $filters; } @@ -722,20 +722,20 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces * a modified 'keys' element for the bare search keywords. */ protected function parseAdvancedDefaults(array $f, $keys) { - $defaults = array(); + $defaults = []; // Split out the advanced search parameters. foreach ($f as $advanced) { list($key, $value) = explode(':', $advanced, 2); if (!isset($defaults[$key])) { - $defaults[$key] = array(); + $defaults[$key] = []; } $defaults[$key][] = $value; } // Split out the negative, phrase, and OR parts of keywords. // For phrases, the form only supports one phrase. - $matches = array(); + $matches = []; $keys = ' ' . $keys . ' '; if (preg_match('/ "([^"]+)" /', $keys, $matches)) { $keys = str_replace($matches[0], ' ', $keys); @@ -778,9 +778,9 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces * {@inheritdoc} */ public function defaultConfiguration() { - $configuration = array( - 'rankings' => array(), - ); + $configuration = [ + 'rankings' => [], + ]; return $configuration; } @@ -789,34 +789,34 @@ class FedoraResourceSearch extends ConfigurableSearchPluginBase implements Acces */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { // Output form for defining rank factor weights. - $form['content_ranking'] = array( + $form['content_ranking'] = [ '#type' => 'details', '#title' => t('Content ranking'), '#open' => TRUE, - ); - $form['content_ranking']['info'] = array( + ]; + $form['content_ranking']['info'] = [ '#markup' => '' . $this->t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '', - ); + ]; // Prepare table. $header = [$this->t('Factor'), $this->t('Influence')]; - $form['content_ranking']['rankings'] = array( + $form['content_ranking']['rankings'] = [ '#type' => 'table', '#header' => $header, - ); + ]; // Note: reversed to reflect that higher number = higher ranking. $range = range(0, 10); $options = array_combine($range, $range); foreach ($this->getRankings() as $var => $values) { - $form['content_ranking']['rankings'][$var]['name'] = array( + $form['content_ranking']['rankings'][$var]['name'] = [ '#markup' => $values['title'], - ); - $form['content_ranking']['rankings'][$var]['value'] = array( + ]; + $form['content_ranking']['rankings'][$var]['value'] = [ '#type' => 'select', '#options' => $options, '#attributes' => ['aria-label' => $this->t("Influence of '@title'", ['@title' => $values['title']])], '#default_value' => isset($this->configuration['rankings'][$var]) ? $this->configuration['rankings'][$var] : 0, - ); + ]; } return $form; } diff --git a/src/Plugin/views/wizard/FedoraResource.php b/src/Plugin/views/wizard/FedoraResource.php index ecc8be43..50c12f1c 100644 --- a/src/Plugin/views/wizard/FedoraResource.php +++ b/src/Plugin/views/wizard/FedoraResource.php @@ -35,9 +35,9 @@ class FedoraResource extends WizardPluginBase { */ public function getAvailableSorts() { // You can't execute functions in properties, so override the method. - return array( + return [ 'fedora_resource_field_data-name:ASC' => $this->t('Name'), - ); + ]; } /** @@ -83,8 +83,8 @@ class FedoraResource extends WizardPluginBase { */ protected function pageDisplayOptions(array $form, FormStateInterface $form_state) { $display_options = parent::pageDisplayOptions($form, $form_state); - $row_plugin = $form_state->getValue(array('page', 'style', 'row_plugin')); - $row_options = $form_state->getValue(array('page', 'style', 'row_options'), array()); + $row_plugin = $form_state->getValue(['page', 'style', 'row_plugin']); + $row_options = $form_state->getValue(['page', 'style', 'row_options'], []); $this->display_options_row($display_options, $row_plugin, $row_options); return $display_options; } @@ -94,8 +94,8 @@ class FedoraResource extends WizardPluginBase { */ protected function blockDisplayOptions(array $form, FormStateInterface $form_state) { $display_options = parent::blockDisplayOptions($form, $form_state); - $row_plugin = $form_state->getValue(array('block', 'style', 'row_plugin')); - $row_options = $form_state->getValue(array('block', 'style', 'row_options'), array()); + $row_plugin = $form_state->getValue(['block', 'style', 'row_plugin']); + $row_options = $form_state->getValue(['block', 'style', 'row_options'], []); $this->displayOptionsRow($display_options, $row_plugin, $row_options); return $display_options; } diff --git a/src/VersionCounter/VersionCounter.php b/src/VersionCounter/VersionCounter.php new file mode 100644 index 00000000..ffaba139 --- /dev/null +++ b/src/VersionCounter/VersionCounter.php @@ -0,0 +1,78 @@ +database = $database; + } + + /** + * {@inheritdoc} + */ + public function create($uuid) { + $this->database->insert('islandora_version_count') + ->fields([ + 'uuid' => $uuid, + ]) + ->execute(); + } + + /** + * {@inheritdoc} + */ + public function get($uuid) { + $query = $this->database->select('islandora_version_count', 'ivc') + ->condition('ivc.uuid', $uuid) + ->fields('ivc', ['count']); + + $results = $query->execute(); + + foreach ($results as $result) { + return $result->count; + } + + return -1; + } + + /** + * {@inheritdoc} + */ + public function increment($uuid) { + return $this->database->update('islandora_version_count') + ->expression('count', 'count + 1') + ->condition('uuid', $uuid) + ->execute(); + } + + /** + * {@inheritdoc} + */ + public function delete($uuid) { + return $this->database->delete('islandora_version_count') + ->condition('uuid', $uuid) + ->execute(); + } + +} diff --git a/src/VersionCounter/VersionCounterInterface.php b/src/VersionCounter/VersionCounterInterface.php new file mode 100644 index 00000000..5ee83849 --- /dev/null +++ b/src/VersionCounter/VersionCounterInterface.php @@ -0,0 +1,59 @@ +installSchema('system', 'sequences'); $this->installEntitySchema('user'); $this->installConfig('filter'); + $this->installSchema('islandora', 'islandora_version_count'); $this->installEntitySchema('fedora_resource'); } diff --git a/tests/src/Kernel/VectorClockTest.php b/tests/src/Kernel/VectorClockTest.php deleted file mode 100644 index 26f06996..00000000 --- a/tests/src/Kernel/VectorClockTest.php +++ /dev/null @@ -1,69 +0,0 @@ -user = $this->createUser(['add fedora resource entities', 'edit fedora resource entities']); - - // Create a test entity. - $this->entity = FedoraResource::create([ - "type" => "rdf_source", - "uid" => $this->user->get('uid'), - "name" => "Test Fixture", - "langcode" => "und", - "status" => 1, - ]); - $this->entity->save(); - - } - - /** - * Tests the basic behavior of the vector clock. - * - * @covers \Drupal\islandora\Entity\FedoraResource::getVclock - */ - public function testVectorClock() { - // Check the vclock is set to 0 when a new entity is created. - $this->assertTrue($this->entity->getVclock() == 0, "Vector clock must be initialized to zero."); - - // Edit the entity. - $this->entity->setName("Edited Test Fixture")->save(); - - // Check the vclock is incremented when the entity is updated. - $this->assertTrue($this->entity->getVclock() == 1, "Vector clock must be incremented on update."); - } - -} diff --git a/tests/src/Kernel/VersionCounterTest.php b/tests/src/Kernel/VersionCounterTest.php new file mode 100644 index 00000000..9255f256 --- /dev/null +++ b/tests/src/Kernel/VersionCounterTest.php @@ -0,0 +1,102 @@ +user = $this->createUser(['add fedora resource entities', 'edit fedora resource entities']); + + // Create a test entity. + $this->entity = FedoraResource::create([ + "type" => "rdf_source", + "uid" => $this->user->get('uid'), + "name" => "Test Fixture", + "langcode" => "und", + "status" => 1, + ]); + $this->entity->save(); + } + + /** + * @covers \Drupal\islandora\VersionCounter\VersionCounter::create + * @covers \Drupal\islandora\VersionCounter\VersionCounter::get + */ + public function testInitializesRecord() { + $versionCounter = $this->container->get('islandora.versioncounter'); + + $this->assertTrue($versionCounter->get($this->entity->uuid()) == 0, + "Version counter db record must be initialized to 0." + ); + } + + /** + * @covers \Drupal\islandora\VersionCounter\VersionCounter::create + * @expectedException \Drupal\Core\Database\IntegrityConstraintViolationException + */ + public function testCannotCreateDuplicateRecord() { + $versionCounter = $this->container->get('islandora.versioncounter'); + $versionCounter->create($this->entity->uuid()); + } + + /** + * @covers \Drupal\islandora\VersionCounter\VersionCounter::increment + * @covers \Drupal\islandora\VersionCounter\VersionCounter::get + */ + public function testRecordIncrementsOnUpdate() { + $this->entity->setName("New Name"); + $this->entity->save(); + + $versionCounter = $this->container->get('islandora.versioncounter'); + + $this->assertTrue($versionCounter->get($this->entity->uuid()) == 1, + "Version counter db record must increment on entity update." + ); + } + + /** + * @covers \Drupal\islandora\VersionCounter\VersionCounter::delete + * @covers \Drupal\islandora\VersionCounter\VersionCounter::get + */ + public function testRecordsGetCleanedUp() { + $this->entity->delete(); + + $versionCounter = $this->container->get('islandora.versioncounter'); + + $this->assertTrue($versionCounter->get($this->entity->uuid()) == -1, + "Version counter db record must be deleted on entity delete." + ); + } + +}