Skip to content

Commit

Permalink
Merge branch 'hotfix/sync-publication-types'
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvdlinde committed Oct 20, 2024
2 parents 002d611 + 744f274 commit 2c83fac
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 18 deletions.
2 changes: 1 addition & 1 deletion appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
['name' => 'directory#update', 'url' => '/api/directory', 'verb' => 'POST'],
['name' => 'directory#publicationType', 'url' => '/api/directory/publication_types/{id}', 'verb' => 'GET'], // Should be in directory becouse its public
// Publication
['name' => 'synchronise#synchronise', 'url' => '/api/publication_types/synchronise', 'verb' => 'POST'],
['name' => 'publication_types#synchronise', 'url' => '/api/publication_types/synchronise', 'verb' => 'POST'],
// Dashboard
['name' => 'dashboard#index', 'url' => '/index', 'verb' => 'GET'],
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/DirectoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public function show(string|int $id): JSONResponse
public function publicationType(string|int $id): JSONResponse
{
try {
$publicationType = $this->objectService->get('publicationType', $id);
$publicationType = $this->objectService->getObject('publicationType', $id);
return new JSONResponse($publicationType);
} catch (DoesNotExistException $e) {
return new JSONResponse(['error' => 'Publication type not found'], 404);
Expand Down
58 changes: 49 additions & 9 deletions lib/Controller/PublicationTypesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use OCA\OpenCatalogi\Db\PublicationTypeMapper;
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\DirectoryService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
Expand All @@ -25,13 +26,15 @@ class PublicationTypesController extends Controller
* @param IAppConfig $config The app configuration
* @param PublicationTypeMapper $publicationTypeMapper The publication type mapper
* @param ObjectService $objectService The object service
* @param DirectoryService $directoryService The directory service
*/
public function __construct(
$appName,
IRequest $request,
private readonly IAppConfig $config,
private readonly PublicationTypeMapper $publicationTypeMapper,
private readonly ObjectService $objectService
private readonly ObjectService $objectService,
private readonly DirectoryService $directoryService
)
{
parent::__construct($appName, $request);
Expand Down Expand Up @@ -159,25 +162,62 @@ public function destroy(string|int $id): JSONResponse
}

/**
* Copy or update a publication type from an external directory
* Synchronize or delete a publication type based on listing status
*
* @PublicPage
* @NoCSRFRequired
* @return JSONResponse The JSON response containing the copied publication type or error message
* @return JSONResponse The JSON response containing the result of the operation
*/
public function synchronise(): JSONResponse
{
$url = $this->request->getParam('publicationType');
// Get the source and listed parameters from the request
$source = $this->request->getParam('source');
$listed = $this->request->getParam('listed', false);

if (empty($url)) {
return new JSONResponse(['error' => 'publicationType parameter is required'], 400);
// Check if the source parameter is provided
if (empty($source)) {
return new JSONResponse(['error' => 'source parameter is required'], 400);
}

try {
$copiedPublicationType = $this->directoryService->syncPublicationType($url);
return new JSONResponse($copiedPublicationType);
if ($listed) {
// If listed is true, synchronize the publication type
$syncedPublicationType = $this->directoryService->syncPublicationType($source);
return new JSONResponse($syncedPublicationType);
} else {
// If listed is false, attempt to delete the publication type
// @todo: we cant get a single object by parameters yet but we can use the find method and grab the first array result
// Check if a publication type with the same name already exists
$publicationTypes = $this->objectService->getObjects(
objectType: 'publicationType',
filters: [
['source' => $source]
]
);

// Check the number of publication types found
if (count($publicationTypes) === 1) {
$publicationType = $publicationTypes[0];
} elseif (count($publicationTypes) > 1) {
// If multiple publication types are found, return an error
return new JSONResponse(['error' => 'Multiple publication types found for the given source'], 409);
} else {
// If no publication types are found, return an error
return new JSONResponse(['error' => 'Publication type not found'], 404);
}

// If a publication type is found, attempt to delete it
if ($publicationType) {
$result = $this->objectService->deleteObject('publicationType', $publicationType['id']);
return new JSONResponse(['success' => $result], $result === true ? 200 : 404);
}

// If no publication type is found (this should not be reached due to earlier check)
return new JSONResponse(['message' => 'Publication type not found'], 404);
}
} catch (\Exception $e) {
return new JSONResponse(['error' => 'An error occurred while copying the publication type: ' . $e->getMessage()], 500);
// If an exception occurs, return an error response
return new JSONResponse(['error' => 'An error occurred: ' . $e->getMessage()], 500);
}
}
}
38 changes: 37 additions & 1 deletion lib/Service/DirectoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class DirectoryService
/** @var Client The HTTP client for making requests */
private Client $client;

/** @var array The list of external publication types that are used by this instance */
private array $externalPublicationTypes = [];

/**
* Constructor for DirectoryService
*
Expand Down Expand Up @@ -103,6 +106,22 @@ public function updateExternalDirectory(string $directoryUrl): int
}
}

/**
* Get the list of external publication types that are used by this instance
*
* @return array The list of external publication types
*/
private function getExternalPublicationTypes(): array
{
if (empty($this->externalPublicationTypes)) {
$result = $this->objectService->getObjects('publicationType');
$this->externalPublicationTypes = array_filter($result, function($pt) {
return !empty($pt['source']);
});
}
return $this->externalPublicationTypes;
}

/**
* Convert a listing object or array to a directory array
*
Expand Down Expand Up @@ -131,8 +150,25 @@ private function getDirectoryFromListing(Listing|array $listing): array
if ($publicationType instanceof \JsonSerializable) {
$publicationType = $publicationType->jsonSerialize();
}

// set listed and owner to false by default
$publicationType['listed'] = false;
$publicationType['owner'] = false;


// check if this publication type is used by this instance
if (isset($publicationType['source'])) {
// Get all external publication types used by this instance
$externalPublicationTypes = $this->getExternalPublicationTypes();

// Filter external types to find matches with the current publication type
$matchingTypes = array_filter($externalPublicationTypes, function($externalType) use ($publicationType) {
// Check if the external type has a source and if it matches the current publication type's source
return isset($externalType['source']) && $externalType['source'] === $publicationType['source'];
});

// Set 'listed' to true if there are any matching types, false otherwise
$publicationType['listed'] = !empty($matchingTypes);
}
}
}

Expand Down
49 changes: 43 additions & 6 deletions src/sidebars/directory/DirectorySideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,20 @@ import { navigationStore, directoryStore, publicationTypeStore } from '../../sto
</template>
Welke publicatietype zou u uit deze catalogus willen overnemen?
<div v-if="!loading">
<NcCheckboxRadioSwitch v-for="(publicationType, i) in directoryStore.listingItem.publicationTypes"
:key="`${publicationType}${i}`"
:checked.sync="checkedPublicationTypeObject[publicationType]"
type="switch">
{{ publicationType.title ?? publicationType.source ?? publicationType }}
</NcCheckboxRadioSwitch>
<template v-for="(publicationType, i) in directoryStore.listingItem.publicationTypes">
<div v-if="publicationType.owner" :key="`${publicationType}${i}`" class="publication-type-item">
<Check :size="20" />
{{ publicationType.title ?? publicationType.source ?? publicationType }}
</div>
<NcCheckboxRadioSwitch
v-else
:key="`${publicationType}${i}`"
:checked="publicationType.listed"
type="switch"
@update:checked="togglePublicationType(publicationType)">
{{ publicationType.title ?? publicationType.source ?? publicationType }}
</NcCheckboxRadioSwitch>
</template>
</div>
<NcLoadingIcon v-if="loading" :size="20" />
</NcAppSidebarTab>
Expand All @@ -128,6 +136,7 @@ import CogOutline from 'vue-material-design-icons/CogOutline.vue'
import FileTreeOutline from 'vue-material-design-icons/FileTreeOutline.vue'
import InformationSlabSymbol from 'vue-material-design-icons/InformationSlabSymbol.vue'
import CertificateOutline from 'vue-material-design-icons/CertificateOutline.vue'
import Check from 'vue-material-design-icons/Check.vue'
export default {
name: 'DirectorySideBar',
Expand All @@ -146,6 +155,7 @@ export default {
listing: '',
loading: false,
syncLoading: false,
publicationTypeLoading: false,
}
},
computed: {
Expand Down Expand Up @@ -333,6 +343,33 @@ export default {
this.syncLoading = false
})
},
togglePublicationType(publicationType) {
publicationType.listed = !publicationType.listed
this.synchronizePublicationType(publicationType)
},
synchronizePublicationType(publicationType) {
this.publicationTypeLoading = true
fetch(
`/index.php/apps/opencatalogi/api/publication_types/synchronise`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
listed: publicationType.listed,
source: publicationType.source
}),
},
)
.then(() => {
this.publicationTypeLoading = false
})
.catch((err) => {
this.error = err
this.publicationTypeLoading = false
})
},
},
}
</script>
Expand Down

0 comments on commit 2c83fac

Please sign in to comment.