diff --git a/lib/Db/Listing.php b/lib/Db/Listing.php index de0825ad..a26a5a48 100644 --- a/lib/Db/Listing.php +++ b/lib/Db/Listing.php @@ -21,6 +21,7 @@ class Listing extends Entity implements JsonSerializable protected ?DateTime $lastSync = null; protected ?bool $default = false; protected ?bool $available = false; + protected ?string $organisation = null; public function __construct() { $this->addType(fieldName: 'title', type: 'string'); @@ -34,6 +35,7 @@ public function __construct() { $this->addType(fieldName: 'lastSync', type: 'datetime'); $this->addType(fieldName: 'default', type: 'boolean'); $this->addType(fieldName: 'available', type: 'boolean'); + $this->addType(fieldName: 'organisation', type: 'string'); } public function getJsonFields(): array @@ -81,6 +83,7 @@ public function jsonSerialize(): array 'lastSync' => $this->lastSync->format('c'), 'default' => $this->default, 'available' => $this->available, + 'organisation'=> $this->organisation, ]; $jsonFields = $this->getJsonFields(); diff --git a/lib/Db/ListingMapper.php b/lib/Db/ListingMapper.php index bbe56e0e..a97a4730 100644 --- a/lib/Db/ListingMapper.php +++ b/lib/Db/ListingMapper.php @@ -3,6 +3,7 @@ namespace OCA\OpenCatalogi\Db; use OCA\OpenCatalogi\Db\Listing; +use OCA\OpenCatalogi\Db\Organisation; use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\QBMapper; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -28,34 +29,104 @@ public function find(int $id): Listing return $this->findEntity(query: $qb); } - public function findAll(?int $limit = null, ?int $offset = null, ?array $filters = [], ?array $searchConditions = [], ?array $searchParams = []): array - { - $qb = $this->db->getQueryBuilder(); + /** + * CUSTOM FOR JOINS + */ + protected function mapRowToEntityCustom(array $row): Entity { + unset($row['DOCTRINE_ROWNUM']); // remove doctrine/dbal helper column + + // Map the Organisation fields to a sub-array + $organisationData = [ + 'id' => $row['organisation_id'] ?? null, + 'title' => $row['organisation_title'] ?? null, + 'summary' => $row['organisation_summary'] ?? null, + 'description' => $row['organisation_description'] ?? null, + 'image' => $row['organisation_image'] ?? null, + 'oin' => $row['organisation_oin'] ?? null, + 'tooi' => $row['organisation_tooi'] ?? null, + 'rsin' => $row['organisation_rsin'] ?? null, + 'pki' => $row['organisation_pki'] ?? null, + ]; + + $organisationIsEmpty = true; + foreach ($organisationData as $key => $value) { + if ($value !== null) { + $organisationIsEmpty = false; + break; + } + } - $qb->select('*') - ->from('listings') - ->setMaxResults($limit) - ->setFirstResult($offset); - - foreach($filters as $filter => $value) { - if ($value === 'IS NOT NULL') { - $qb->andWhere($qb->expr()->isNotNull($filter)); - } elseif ($value === 'IS NULL') { - $qb->andWhere($qb->expr()->isNull($filter)); - } else { - $qb->andWhere($qb->expr()->eq($filter, $qb->createNamedParameter($value))); + $row['organisation'] = $organisationIsEmpty === true ? null : Organisation::fromRow($organisationData); + + return \call_user_func($this->entityClass .'::fromRow', $row); + } + + /** + * Runs a sql query and returns an array of entities CUSTOM FOR JOINS + * + * @param IQueryBuilder $query + * @return Entity[] all fetched entities + * @psalm-return T[] all fetched entities + * @throws Exception + * @since 14.0.0 + */ + protected function findEntitiesCustom(IQueryBuilder $query): array { + $result = $query->executeQuery(); + try { + $entities = []; + while ($row = $result->fetch()) { + $entities[] = $this->mapRowToEntityCustom($row); } - } + return $entities; + } finally { + $result->closeCursor(); + } + } + public function findAll(?int $limit = null, ?int $offset = null, ?array $filters = [], ?array $searchConditions = [], ?array $searchParams = []): array + { + $qb = $this->db->getQueryBuilder(); + + $qb->select( + 'l.*', + 'o.id AS organisation_id', + 'o.title AS organisation_title', + 'o.summary AS organisation_summary', + 'o.description AS organisation_description', + 'o.image AS organisation_image', + 'o.oin AS organisation_oin', + 'o.tooi AS organisation_tooi', + 'o.rsin AS organisation_rsin', + 'o.pki AS organisation_pki' + ) + ->from('listings', 'l') + ->leftJoin('l', 'organizations', 'o', 'l.organisation = o.id') + ->setMaxResults($limit) + ->setFirstResult($offset); + + + // Apply filters + foreach ($filters as $filter => $value) { + if ($value === 'IS NOT NULL') { + $qb->andWhere($qb->expr()->isNotNull($filter)); + } elseif ($value === 'IS NULL') { + $qb->andWhere($qb->expr()->isNull($filter)); + } else { + $qb->andWhere($qb->expr()->eq($filter, $qb->createNamedParameter($value))); + } + } + + // Apply search conditions if (!empty($searchConditions)) { $qb->andWhere('(' . implode(' OR ', $searchConditions) . ')'); foreach ($searchParams as $param => $value) { $qb->setParameter($param, $value); } } - - return $this->findEntities(query: $qb); - } + + // Use the existing findEntities method to fetch and map the results + return $this->findEntitiesCustom($qb); + } public function createFromArray(array $object): Listing { diff --git a/lib/Migration/Version6Date20240809120147.php b/lib/Migration/Version6Date20240809120147.php new file mode 100644 index 00000000..eb923ff0 --- /dev/null +++ b/lib/Migration/Version6Date20240809120147.php @@ -0,0 +1,72 @@ +hasTable(tableName: 'listings') === true) { + $table = $schema->getTable(tableName: 'listings'); + + 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 + ]); + $output->info('organisation should be added to listing'); + } + + } + + 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 dc47b754..4de3e99b 100644 --- a/lib/Service/DirectoryService.php +++ b/lib/Service/DirectoryService.php @@ -222,7 +222,9 @@ public function listCatalog (array $catalog): array $listing = $this->getDirectoryEntry(catalogId: $catalogId); - $listing['title'] = $catalog['title']; + $listing['title'] = $catalog['title']; + $listing['organisation'] = $catalog['organisation']; + $listing['metaData'] = $catalog['metaData']; if($this->config->hasKey($this->appName, 'mongoStorage') === false || $this->config->getValueString($this->appName, 'mongoStorage') !== '1' diff --git a/src/views/directory/DirectoryList.vue b/src/views/directory/DirectoryList.vue index 017aad2b..65c1a737 100644 --- a/src/views/directory/DirectoryList.vue +++ b/src/views/directory/DirectoryList.vue @@ -42,6 +42,7 @@ import { navigationStore, directoryStore } from '../../store/store.js' :key="`${listing}${i}`" :name="listing.name ?? listing.title" :active="directoryStore.listingItem?.id === listing?.id" + :details="listing?.organisation?.title || 'Geen organisatie'" @click="directoryStore.setListingItem(listing)">