Collection private and public fields

I would like to only show selected public fields on the public API get of a collection.

So e.g. the following collection entry

{
        Name: "Item name",
    Stream: "http://example.com/guid",
    Image: {
    path: "/2018/05/02/5ae99e452a072Anna.jpg",
    title: "Anna.jpg",
    mime: "image/jpeg",
    description: "",
    tags: [ ],
    size: 446990,
    image: true,
    video: false,
    audio: false,
    archive: false,
    document: false,
    code: false,
    created: 1525259845,
    modified: 1525259845,
    _by: "5ae99d2fef8b3doc343583183",
    width: 1944,
    height: 2592,
    colors: [
    "2b1911",
    "c68f77",
    917164,
    "947c6c",
    "9c2020"
    ],
    _id: "5ae99e4543ad5doc1315561261"
    },
    _mby: "5ae99d2fef8b3doc343583183",
    _by: "5ae99d2fef8b3doc343583183",
    _modified: 1525260039,
    _created: 1525259852,
    _id: "5ae99e4ccf48bdoc85498314",
    _order: 0
    }, 

I would like to present as below on the public API:

{
    name: "Item name",
    stream: "http://example.com/guid",
    Image: {
      path: "/2018/05/02/5ae99e452a072Anna.jpg",
      width: 1944,
      height: 2592,
      _id: "5ae99e4543ad5doc1315561261"
    },
    _order: 0
    }, 

I would like to map private fields to public fields or aliases per entry for the complete collection.
Does Cockpit come with functionality for this?

I guess you can do something with the Collections > Collection: [Permission Tab] (read chip) <?php options. But I cannot find any documentation for this.

Can you point me to some documentation or share an example here?

you can achieve this in many ways … here are two possible ways:

1. Custom api entry point

Create a file in /config/api named custom.php with the following content:

<?php

return cockpit('collections')->find('items', [
   'filter'=> $this->param('filter', []),
   'fields' => ['name'=>1, 'stream'=>1, 'Image'=>1, '_order'=>1]
];

now you can query /api/posts and you’ll always only get published posts.

2. Bind on collections.find.before

add the following snippet to /config/bootstrap.php:

<?php

$app->on('collections.find.before.items', function($name, &$options) {

    if (COCKPIT_API_REQUEST) {
        $options['fields'] = ['name'=>1, 'stream'=>1, 'Image'=>1, '_order'=>1];
    }
});

3. Do it in the collection rules for read with the following content:

<?php

if (COCKPIT_API_REQUEST) {
    $context->options['fields'] =  ['name'=>1, 'stream'=>1, 'Image'=>1, '_order'=>1];
}

Greets,
Artur

1 Like

Thank you for your reply.
I would prefer option 3, as I do not want to globally define public field sets for all collections.

However whenever I enter something in the collection rules read textarea and enable read options, it gets disabled on collection save.
Is this a known bug, or am I doing something wrong? I am using Cockpit version 0.5.4 in the provided Docker image.

Ah yes sorry, this should be fixed in the next branch - https://github.com/agentejo/cockpit/tree/next

1 Like

Thank you for your swift replay and info!