diff --git a/application/asset/js/global.js b/application/asset/js/global.js index 4b0c96e7f..97db7c2e8 100644 --- a/application/asset/js/global.js +++ b/application/asset/js/global.js @@ -227,7 +227,7 @@ var Omeka = { tableRowCell.text(tableRowValue); }); selectorRow.addClass('added'); - table.append(tableRow).removeClass('empty').trigger('appendRow'); + table.children('.resource-rows').append(tableRow).removeClass('empty').trigger('appendRow'); updateResourceCount(id); } @@ -235,6 +235,10 @@ var Omeka = { var resource = selector.find('[data-resource-id="' + id + '"]'); var resourceParent = resource.parents('.selector-parent'); var childCount = resourceParent.find('.selector-child-count').first(); + // Update the count only when the resource exists in the selector. + if (!selector.find(`.selector-child[data-resource-id="${id}"]`).length) { + return; + } if (resource.hasClass('added')) { var newTotalCount = parseInt(selectorCount.text()) - 1; var newChildCount = parseInt(childCount.text()) - 1; diff --git a/application/src/Api/Adapter/ItemAdapter.php b/application/src/Api/Adapter/ItemAdapter.php index d85bebd43..371009492 100644 --- a/application/src/Api/Adapter/ItemAdapter.php +++ b/application/src/Api/Adapter/ItemAdapter.php @@ -1,6 +1,7 @@ getValue('o:site'))) { - // On CREATE and when no "o:site" array is passed, assign this item - // to all sites where assignNewItems=true. - $dql = ' - SELECT site + if ($isCreate) { + // On CREATE we will need sites where assignNewItems=true. + $dql = 'SELECT site FROM Omeka\Entity\Site site WHERE site.assignNewItems = true'; $query = $this->getEntityManager()->createQuery($dql); + $assignNewItemsSites = new ArrayCollection($query->getResult()); + } + if ($isCreate && !is_array($request->getValue('o:site'))) { + // On CREATE and when no "o:site" array is passed, assign this item + // to all sites where assignNewItems=true. $sites = $entity->getSites(); - foreach ($query->getResult() as $site) { + foreach ($assignNewItemsSites as $site) { $sites->set($site->getId(), $site); } } elseif ($this->shouldHydrate($request, 'o:site')) { @@ -254,7 +258,11 @@ public function hydrate(Request $request, EntityInterface $entity, if (!$site) { // Assign site that was not already assigned. $site = $siteAdapter->findEntity($siteId); - if ($acl->userIsAllowed($site, 'can-assign-items')) { + if ($acl->userIsAllowed($site, 'can-assign-items') || ($isCreate && $assignNewItemsSites->contains($site))) { + // A user with the "can-assign-items" privilege can assign + // a site at any time. A user without the "can-assign-items" + // privilege can assign a site only on CREATE when the site + // has assignNewItems=true. $sites->set($site->getId(), $site); } } diff --git a/application/src/Form/Element/AbstractGroupByOwnerSelect.php b/application/src/Form/Element/AbstractGroupByOwnerSelect.php index f32242558..e5c94902d 100644 --- a/application/src/Form/Element/AbstractGroupByOwnerSelect.php +++ b/application/src/Form/Element/AbstractGroupByOwnerSelect.php @@ -50,12 +50,19 @@ public function getValueOptions(): array $query = []; } - $response = $this->getApiManager()->search($this->getResourceName(), $query); + $resourceReps = $this->getApiManager()->search($this->getResourceName(), $query)->getContent(); + + // Provide a way to filter the resource representations prior to + // building the value options. + $callback = $this->getOption('filter_resource_representations'); + if (is_callable($callback)) { + $resourceReps = $callback($resourceReps); + } if ($this->getOption('disable_group_by_owner')) { // Group alphabetically by resource label without grouping by owner. $resources = []; - foreach ($response->getContent() as $resource) { + foreach ($resourceReps as $resource) { $resources[$this->getValueLabel($resource)][] = $resource->id(); } ksort($resources); @@ -68,7 +75,7 @@ public function getValueOptions(): array } else { // Group alphabetically by owner email. $resourceOwners = []; - foreach ($response->getContent() as $resource) { + foreach ($resourceReps as $resource) { $owner = $resource->owner(); $index = $owner ? $owner->email() : null; $resourceOwners[$index]['owner'] = $owner; diff --git a/application/src/Form/UserForm.php b/application/src/Form/UserForm.php index f89463706..26c39ab78 100644 --- a/application/src/Form/UserForm.php +++ b/application/src/Form/UserForm.php @@ -199,6 +199,15 @@ public function init() 'options' => [ 'label' => 'Default sites for items', // @translate 'empty_option' => '', + 'filter_resource_representations' => function ($sites) { + // The user must have permission to assign items to the site. + foreach ($sites as $index => $site) { + if (!$site->userIsAllowed('can-assign-items')) { + unset($sites[$index]); + } + } + return $sites; + }, ], ]); $settingsFieldset->add([ diff --git a/application/view/omeka/admin/item/manage-sites.phtml b/application/view/omeka/admin/item/manage-sites.phtml index 2fbef150e..4d03fa3d4 100644 --- a/application/view/omeka/admin/item/manage-sites.phtml +++ b/application/view/omeka/admin/item/manage-sites.phtml @@ -1,21 +1,43 @@ sites(); + // This is an existing item. + + $sites = $item->sites(); + foreach ($sites as $site) { + if ($site->userIsAllowed('can-assign-items')) { + $canAssignItemsSites[] = ['id' => $site->id()]; + } else { + $cannotAssignItemsSites[$site->id()] = $site; + } + } } else { - $siteRepresentations = $this->api()->search('sites', ['assign_new_items' => true])->getContent(); + // This is a new item. - $userDefaultSites = $this->userSetting('default_item_sites'); - if (is_array($userDefaultSites)) { - $userDefaultSiteRepresentations = $this->api()->search('sites', ['id' => $userDefaultSites])->getContent(); - $siteRepresentations = array_merge($siteRepresentations, $userDefaultSiteRepresentations); + // Get all sites that allow item assignment in site settings. + $sites = $this->api()->search('sites', ['assign_new_items' => true])->getContent(); + foreach ($sites as $site) { + if ($site->userIsAllowed('can-assign-items')) { + $canAssignItemsSites[] = ['id' => $site->id()]; + } else { + $cannotAssignItemsSites[$site->id()] = $site; + } } -} -$sites = []; -foreach ($siteRepresentations as $siteRepresentation) { - $sites[] = [ - 'id' => $siteRepresentation->id(), - ]; + // Get all sites that the user set as default in user settings. + $defaultItemSites = $this->userSetting('default_item_sites'); + $sites = is_array($defaultItemSites) + ? $this->api()->search('sites', ['id' => $defaultItemSites])->getContent() + : []; + foreach ($sites as $site) { + if ($site->userIsAllowed('can-assign-items')) { + $canAssignItemsSites[] = ['id' => $site->id()]; + } else { + $cannotAssignItemsSites[$site->id()] = $site; + } + } } $siteTemplate = ' @@ -30,7 +52,7 @@ $siteTemplate = ' '; ?> -
translate('Title'); ?> | @@ -38,7 +60,20 @@ $siteTemplate = '||
---|---|---|
escapeHtml($site->title()); ?> | +escapeHtml($site->owner()->email()); ?> | +
+
|
+