diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php index 48f3c4bd..7e4fcb90 100644 --- a/lib/Controller/SearchController.php +++ b/lib/Controller/SearchController.php @@ -95,14 +95,28 @@ public function index(SearchService $searchService): JSONResponse $fieldsToSearch = ['title', 'description', 'summary']; - if($this->config->hasKey($this->appName, 'mongoStorage') === false - || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' + if($this->config->hasKey($this->appName, 'elasticLocation') === false + || $this->config->getValueString($this->appName, 'elasticLocation') === '' ) { $searchParams = $searchService->createMySQLSearchParams(filters: $filters); $searchConditions = $searchService->createMySQLSearchConditions(filters: $filters, fieldsToSearch: $fieldsToSearch); + + $limit = null; + $offset = null; + + if(isset($filters['_limit']) === true) { + $limit = $filters['_limit']; + } + + if(isset($filters['_page']) === true) { + $offset = ($limit * ($filters['_page'] - 1)); + } + $filters = $searchService->unsetSpecialQueryParams(filters: $filters); - return new JSONResponse(['results' => $this->publicationMapper->findAll(limit: null, offset: null, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams)]); + + + return new JSONResponse(['results' => $this->publicationMapper->findAll(limit: $limit, offset: $offset, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams)]); } //@TODO: find a better way to get query params. This fixes it for now. diff --git a/lib/Db/Catalog.php b/lib/Db/Catalog.php index 14e50db8..05958101 100644 --- a/lib/Db/Catalog.php +++ b/lib/Db/Catalog.php @@ -9,13 +9,15 @@ class Catalog extends Entity implements JsonSerializable { - protected ?string $title = null; - protected ?string $summary = null; - protected ?string $description = null; - protected ?string $image = null; - protected ?string $search = null; + protected ?string $title = null; + protected ?string $summary = null; + protected ?string $description = null; + protected ?string $image = null; + protected ?string $search = null; - protected bool $listed = false; + protected bool $listed = false; + protected ?string $organisation = null; + protected ?array $metadata = null; public function __construct() { $this->addType(fieldName: 'title', type: 'string'); @@ -24,6 +26,8 @@ public function __construct() { $this->addType(fieldName: 'image', type: 'string'); $this->addType(fieldName: 'search', type: 'string'); $this->addType(fieldName: 'listed', type: 'boolean'); + $this->addType(fieldName: 'organisation', type: 'string'); + $this->addType(fieldName: 'metadata', type: 'json'); } @@ -38,11 +42,17 @@ public function getJsonFields(): array public function hydrate(array $object): self { + + + if(isset($object['metadata']) === false) { + $object['metadata'] = []; + } + $jsonFields = $this->getJsonFields(); foreach($object as $key => $value) { if (in_array($key, $jsonFields) === true && $value === []) { - $value = null; + $value = []; } $method = 'set'.ucfirst($key); @@ -67,6 +77,8 @@ public function jsonSerialize(): array 'image' => $this->image, 'search' => $this->search, 'listed' => $this->listed, + 'metadata' => $this->metadata, + 'organisation'=> $this->organisation, ]; diff --git a/lib/Db/Publication.php b/lib/Db/Publication.php index c3f52249..3dc4edad 100644 --- a/lib/Db/Publication.php +++ b/lib/Db/Publication.php @@ -75,6 +75,12 @@ public function hydrate(array $object): self $this->setAttachments(null); $this->setOrganization(null); $this->setData(null); + $this->setModified(new DateTime()); + + + if(isset($object['published']) === false) { + $object['published'] = null; + } foreach($object as $key => $value) { if (in_array($key, $jsonFields) === true && $value === []) { @@ -114,8 +120,8 @@ public function jsonSerialize(): array 'portal' => $this->portal, 'catalogi' => $this->catalogi, 'metaData' => $this->metaData, - 'published' => $this->published->format('c'), - 'modified' => $this->modified->format('c'), + 'published' => $this->published?->format('c'), + 'modified' => $this->modified?->format('c'), 'featured' => $this->featured !== null ? (bool) $this->featured : null, 'organization' => $this->organization, 'data' => $this->data, diff --git a/lib/Migration/Version6Date20240723125106.php b/lib/Migration/Version6Date20240723125106.php index 4e18cd45..d12ccc8d 100644 --- a/lib/Migration/Version6Date20240723125106.php +++ b/lib/Migration/Version6Date20240723125106.php @@ -81,15 +81,15 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt ] ); $table->addColumn(name: 'organization', typeName: TYPES::JSON, options: [ - 'default' => [], + 'default' => 'a:0:{}', 'notnull' => false, ]); $table->addColumn(name: 'data', typeName: TYPES::JSON, options: [ - 'default' => [], + 'default' => 'a:0:{}', 'notnull' => false, ]); $table->addColumn(name: 'attachments', typeName: TYPES::JSON, options: [ - 'default' => [], + 'default' => 'a:0:{}', 'notnull' => false, ]); $table->addColumn(name: 'attachment_count', typeName: TYPES::INTEGER); diff --git a/lib/Migration/Version6Date20240808085441.php b/lib/Migration/Version6Date20240808085441.php new file mode 100644 index 00000000..28e43b3a --- /dev/null +++ b/lib/Migration/Version6Date20240808085441.php @@ -0,0 +1,77 @@ +hasTable(tableName: 'catalogi') === true) { + $table = $schema->getTable(tableName: 'catalogi'); + + if($table->hasColumn(name: 'organization') === false) { + $table->addColumn( + name: 'organization', + typeName: Types::STRING, + options: [ + 'notNull' => false, + 'default' => null + ]); + } + if($table->hasColumn(name: 'metadata') === false) { + $table->addColumn( + name: 'metadata', + typeName: Types::JSON, + options: [ + 'notNull' => false, + 'default' => 'a:0:{}' + ]); + } + + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Migration/Version6Date20240808092738.php b/lib/Migration/Version6Date20240808092738.php new file mode 100644 index 00000000..e5babbe7 --- /dev/null +++ b/lib/Migration/Version6Date20240808092738.php @@ -0,0 +1,63 @@ +hasTable(tableName: 'publications') === true) { + $table = $schema->getTable(tableName: 'publications'); + + if($table->hasColumn(name: 'published') === true) { + $column = $table->getColumn(name: 'published'); + $column->setDefault(default: null); + } + + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Migration/Version6Date20240808093230.php b/lib/Migration/Version6Date20240808093230.php new file mode 100644 index 00000000..81e9d2bc --- /dev/null +++ b/lib/Migration/Version6Date20240808093230.php @@ -0,0 +1,62 @@ +hasTable(tableName: 'publications') === true) { + $table = $schema->getTable(tableName: 'publications'); + + if($table->hasColumn(name: 'published') === true) { + $column = $table->getColumn(name: 'published'); + $column->setNotnull(notnull: false); + } + + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Migration/Version6Date20240808115347.php b/lib/Migration/Version6Date20240808115347.php new file mode 100644 index 00000000..4e60dccb --- /dev/null +++ b/lib/Migration/Version6Date20240808115347.php @@ -0,0 +1,71 @@ +hasTable(tableName: 'catalogi') === true) { + $table = $schema->getTable(tableName: 'catalogi'); + + if($table->hasColumn(name: 'organization') === true) { + $column = $table->dropColumn('organization'); + } + if($table->hasColumn(name: 'organisation') === false) { + $table->addColumn( + name: 'organisation', + typeName: Types::STRING, + options: [ + 'notNull' => false, + 'default' => null + ]); + } + + } + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/lib/Service/DirectoryService.php b/lib/Service/DirectoryService.php index 75d994a1..dc47b754 100644 --- a/lib/Service/DirectoryService.php +++ b/lib/Service/DirectoryService.php @@ -6,6 +6,7 @@ use GuzzleHttp\Client; use OCA\OpenCatalogi\Db\Catalog; use OCA\OpenCatalogi\Db\CatalogMapper; +use OCA\OpenCatalogi\Db\Listing; use OCA\OpenCatalogi\Db\ListingMapper; use OCP\IAppConfig; use OCP\IURLGenerator; @@ -52,21 +53,26 @@ public function registerToExternalDirectory (array $newDirectory = [], ?string $ if($this->config->getValueString($this->appName, 'mongoStorage') !== '1') { - $catalogi = $this->catalogMapper->findAll(); + $catalogi = $this->listingMapper->findAll(); } else { $dbConfig['base_uri'] = $this->config->getValueString('opencatalogi', 'mongodbLocation'); $dbConfig['headers']['api-key'] = $this->config->getValueString('opencatalogi', 'mongodbKey'); $dbConfig['mongodbCluster'] = $this->config->getValueString('opencatalogi', 'mongodbCluster'); - $catalogi = $this->objectService->findObjects(filters: ['_schema' => 'catalog'], config: $dbConfig)['documents']; + $catalogi = $this->objectService->findObjects(filters: ['_schema' => 'directory'], config: $dbConfig)['documents']; } foreach($catalogi as $catalog) { - if($catalog instanceof Catalog) { + if($catalog instanceof Listing) { $catalog = $catalog->jsonSerialize(); } - $directory = $this->getDirectoryEntry($catalog['id']); - $result = $this->client->post(uri: $url, options: ['json' => $directory, 'http_errors' => false]); + unset($catalog['_id'], $catalog['id'], $catalog['_schema']); + + if($catalog['directory'] !== $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(routeName:"opencatalogi.directory.index"))) { + continue; + } + + $result = $this->client->post(uri: $url, options: ['json' => $catalog, 'http_errors' => false]); } $externalDirectories = $this->fetchFromExternalDirectory(url: $url); @@ -107,8 +113,6 @@ private function createDirectoryFromResult(array $result): ?array $this->listingMapper->createFromArray($result); } - $this->registerToExternalDirectory(newDirectory: $result); - return $returnData; } diff --git a/lib/Service/ElasticSearchService.php b/lib/Service/ElasticSearchService.php index 73bf354c..fd02b699 100644 --- a/lib/Service/ElasticSearchService.php +++ b/lib/Service/ElasticSearchService.php @@ -91,6 +91,42 @@ public function updateObject(string $id, array $object, array $config): array } } + public function parseFilter(string $name, array $filter): array + { + + if(is_array($filter) === false) { + return ['match' => [$name => $filter]]; + } + + foreach($filter as $key => $value) { + switch($key) { + case 'regexp': + case 'like': + if(preg_match("/^\/.+\/[a-z]*$/i", $value) !== false) { + return ['regexp' => [$name => strtolower($value)]]; + } else { + return ['match' => [$name => $value]]; + } + case '>=': + case 'after': + return ['range' => [$key => ['gte' => $value]]]; + case '>': + case 'strictly_after': + return ['range' => [$key => ['gt' => $value]]]; + case '<=': + case 'before': + return ['range' => [$key => ['lte' => $value]]]; + case '<': + case 'strictly_before': + return ['range' => [$key => ['lt' => $value]]]; + default: + return ['match' => [$name => $value]]; + } + } + + return ['match' => [$name => $filter]]; + } + public function parseFilters (array $filters): array { $body = [ @@ -124,10 +160,23 @@ public function parseFilters (array $filters): array ]; } + if(isset($filters['.limit']) === true) { + $body['size'] = (int) $filters['.limit']; + unset($filters['.limit']); + } + + if(isset($filters['.page']) === true) { + if(isset($body['size']) === true) { + $body['from'] = $body['size'] * ($filters['.page'] - 1); + } + unset($filters['.page']); + } + unset($filters['.search'], $filters['.queries'], $filters['.catalogi']); foreach ($filters as $name => $filter) { - $body['query']['bool']['must'][] = ['match' => [$name => $filter]]; + + $body['query']['bool']['must'][] = $this->parseFilter($name, $filter); } return $body; diff --git a/lib/Service/SearchService.php b/lib/Service/SearchService.php index a24ee48c..3feb75f8 100644 --- a/lib/Service/SearchService.php +++ b/lib/Service/SearchService.php @@ -143,7 +143,15 @@ public function search(array $parameters, array $elasticConfig, array $dbConfig, } } - return ['results' => $results, 'facets' => $aggregations]; + return [ + 'results' => $results, + 'facets' => $aggregations, + 'count' => count($results), + 'limit' => 30, + 'page' => 1, + 'pages' => 1, + 'total' => 10 + ]; } /** diff --git a/src/modals/catalog/AddCatalogModal.vue b/src/modals/catalog/AddCatalogModal.vue index 9294a4f5..f8afc657 100644 --- a/src/modals/catalog/AddCatalogModal.vue +++ b/src/modals/catalog/AddCatalogModal.vue @@ -35,9 +35,9 @@ import { catalogiStore, navigationStore } from '../../store/store.js' maxlength="255" :value.sync="catalogi.description" /> - Listed + Publiek vindbaar - Listed + Publiek vindbaar - - + + + + + + + + Terug naar Catalogi + + + + + + Terug naar Metadata + - Published + Publicatie datum - - Modified - - + + + + + + + Toevoegen + - - - - - - Toevoegen - @@ -134,7 +144,6 @@ export default { description: '', reference: '', license: '', - modified: new Date(), featured: false, portal: '', category: '', @@ -185,13 +194,19 @@ export default { }) .then((response) => { response.json().then((data) => { + const selectedCatalogus = data.results.filter((catalogus) => catalogus.id.toString() === navigationStore.selectedCatalogus.toString())[0] this.catalogi = { options: Object.entries(data.results).map((catalog) => ({ id: catalog[1].id, label: catalog[1].title, })), - + value: navigationStore.selectedCatalogus + ? { + id: selectedCatalogus.id, + label: selectedCatalogus.title, + } + : null, } }) this.catalogiLoading = false @@ -269,7 +284,6 @@ export default { description: '', reference: '', license: '', - modified: new Date(), featured: false, portal: '', category: '', @@ -324,4 +338,8 @@ export default { flex-direction: row; align-items: center; } + +.apm-submit-button { + margin-block-start: 1rem +} diff --git a/src/modals/publication/EditPublicationModal.vue b/src/modals/publication/EditPublicationModal.vue index 43a40a87..6f1674ba 100644 --- a/src/modals/publication/EditPublicationModal.vue +++ b/src/modals/publication/EditPublicationModal.vue @@ -41,17 +41,11 @@ import { navigationStore, publicationStore } from '../../store/store.js' label="Portaal" :value.sync="publicationItem.portal" /> - Published + Publicatie datum - - Modified - - { response.json().then((data) => { publicationStore.setPublicationItem(data) + this.publicationItem = publicationStore.publicationItem }) this.loading = false }) @@ -180,65 +171,6 @@ export default { this.loading = false }) }, - fetchCatalogi() { - this.catalogiLoading = true - fetch('/index.php/apps/opencatalogi/api/catalogi', { - method: 'GET', - }) - .then((response) => { - response.json().then((data) => { - - const selectedCatalogi = data.results.find((catalogi) => catalogi.id.toString() === this.publicationItem.catalogi.toString()) - - this.catalogi = { - inputLabel: 'Catalogi', - options: data.results.map((catalog) => ({ - id: catalog.id, - label: catalog.title, - })), - // FIXME: for some reason the NcSelect uses the id instead of the label when displaying - value: [{ - id: selectedCatalogi.id ?? '', - label: selectedCatalogi.title ?? '', - }], - } - }) - this.catalogiLoading = false - }) - .catch((err) => { - console.error(err) - this.catalogiLoading = false - }) - }, - fetchMetaData() { - this.metaDataLoading = true - fetch('/index.php/apps/opencatalogi/api/metadata', { - method: 'GET', - }) - .then((response) => { - response.json().then((data) => { - const selectedMetaData = data.results.find((metadata) => metadata.id.toString() === this.publicationItem.metaData.toString()) - - this.metaData = { - inputLabel: 'MetaData', - options: data.results.map((metaData) => ({ - id: metaData.id, - label: metaData.title, - })), - // FIXME: for some reason the NcSelect uses the id instead of the label when displaying - value: { - id: selectedMetaData.id, - label: selectedMetaData.title, - }, - } - }) - this.metaDataLoading = false - }) - .catch((err) => { - console.error(err) - this.metaDataLoading = false - }) - }, updatePublication() { this.loading = true fetch( diff --git a/src/sidebars/directory/DirectorySideBar.vue b/src/sidebars/directory/DirectorySideBar.vue index e0e28842..e072e4c5 100644 --- a/src/sidebars/directory/DirectorySideBar.vue +++ b/src/sidebars/directory/DirectorySideBar.vue @@ -28,25 +28,57 @@ import { navigationStore, directoryStore } from '../../store/store.js' + + + + + + Beschickbaar maken voor mijn zoek opdrachten + + + Standaard mee nemen in de beantwoording van mijn zoekopdrachten + + + + + + + Welke meta data typen zou u uit deze catalogus willen overnemen? + + Metedata type 1 + +
Published
Publicatie datum
Modified