How to make files for items private/public?

102 views
Skip to first unread message

Lukas Pukas

unread,
May 12, 2016, 3:39:36 AM5/12/16
to Omeka Dev
Hi,

I would like to make files uploaded for items public or private. Public files would be visible/downloadable via public site for non-logged users, while private files would be visible only for logged in users (all roles). I was looking at code, but didn't find any good way of doing so.
Item model is getting all files via
Table_File::findByItem()

, but there is no filter that would allow me to alter the select query. Did I miss something, or is the only way changing core files?

Thanks for help,
Lukas

Anurag Spatzenegger

unread,
May 12, 2016, 9:19:28 AM5/12/16
to omek...@googlegroups.com

Files, unlike Items, by default, do not have a private / public setting.

But you can easily modify the related views to display download links based on the Items private/public settings and user permissions.

Something along the lines of:

<?php

$user = current_user();

if(!$item['public'] && $user) : ?>

<!-- download link goes here -->

<?php endif; ?>

All the best,

Anurag

Lukas Pukas

unread,
May 12, 2016, 10:34:13 AM5/12/16
to Omeka Dev
Hi Anurag,

thank you for the advice! But I'm after file-based, not item-based privacy level. For items I would like to have several files, where some of them should be private and some public.
I guess I need to add new column `public` into `files` DB table, update upload or edit file form. And then update all method that are fetching files, to either accept additional parameters for public flag or add filters. The latter part is bit nightmare, I guess...

Refards,
Luk

Anurag Spatzenegger

unread,
May 12, 2016, 11:04:19 AM5/12/16
to omek...@googlegroups.com

Dear Luk,

I'd be hesitant to modify the DB and/or Omeka core, as this could make upgrading a real nightmare. Since a file can have associated metadata - at least DublinCore - I am wondering whether you could utilize one of those, because it would be fairly easy to filter by that. For example in the extended DC set there is an Audience field (as per description: A class of entity for whom the resource is intended or useful. ). Although this approach is perhaps not the cleanest approach in terms of archival standards ;)

All the best,

Anurag

Lukas Pukas

unread,
May 24, 2016, 3:09:41 PM5/24/16
to Omeka Dev
Thank you Anurag!

I tried to move forward with this, and I don't think there is any difference whether I modify DB or use some of available DC fields, for very simple reason - there is still no way to filter only public files. I have now 2 options:

1. rewrite all functions/helpers in public theme, that are fetching files, so that I can modify the SQL (this feels horrible)

2. modify Omeka core (this I like more). After digging into code, I was thinking the best way is to add new filter/hook into Omeka_Db_Table::getSelect(), something like:
$select = apply_filters($this->_getHookName('select_sql'), $select);
It would produce filter names like "files_select_sql, items_select_sql, ..." Then I can simply inject the SQL with WHERE public = 1|0 clause, or even use the built-in Omeka_Db_Select_PublicPermissions('Files') in my plugin. The only other problem I encountered is that I will have to rewrite few methods to use getSelectForCount() or getSelect():
  • Item::fileCount()
  • Item::hasThumbnail()
Aside from that I think there is no other issue. But I'm not experienced Omeka coder, and it very likely I'm missing some important side-effect of proposed change of the core. So I'd like to ask others here for guidance.

Do you see any problem with this idea? Can it be for example considerable performance killer? Or do you think it's better to place the proposed hook only inside Table_File::getSelect(), so it doesn't affect any other models? Or any other suggestions?

If I receive positive response, I'm ready to create pull request. Also please let me know if you prefer to open this as an issue on github.

Thanks,
Luk

Anurag Spatzenegger

unread,
May 25, 2016, 5:00:27 PM5/25/16
to omek...@googlegroups.com

Dear Luk,

Maybe I am misunderstanding what you are trying to achieve, but isn't the following scenario what you want to do?

In the DC metadata associated to the file you use the Audience field to contain your desired audience i.e. "public" / "private"

Then in the relevant views you simply check what the metadata status is for each file and if the item is set to "private" and there is no logged in user, the link or image does not get displayed. Since the check happens server side, a "private" image would never get displayed on the site for a not authorized i.e. not logged in user.

The code in items/view could look something along these lines (I am assuming as I did not test it):

// get user

$user = current_user();

// get associated files

$itemFiles = $item->Files;

foreach($itemFiles as $file) {

    $audience = metadata($file, array('Dublin Core', 'Audience');

    if($audience == "public" ) {

        // display "public" file or output link to download

    } else {

        if($user) {

            // display "private" file or output link to download

        }

    }

}

All the best,

Anurag

Lukas Pukas

unread,
May 25, 2016, 6:35:34 PM5/25/16
to Omeka Dev
Hi Anurag,

thanks again for helping me out!

You understand exactly what I'm trying to do. But your approach requires rewriting all public/theme views containing images, not just items, but also collections, exhibits and possibly landing page. Besides, there are many functions for getting images, even helpers for generating complete HTML markup, almost none of those can be used in the form they are. For that reason also doesn't really matter if I push new DB column "public" into files table, or use DC:Audience, since they both require same amount of changes. It is not hard to rewrite views, but any updates in core will need to be manually ported into my custom code, that's why I don't like it at all...
In comparison, adding the proposed filter for select_sql will need only few lines of code in some plugin (for adding where condition), nothing else. All views and functions/helpers can stay as they are, no worries about Omeka core updates... For the price of additional filter callback of course. I'm not sure if the select_sql filter is really as simple as I describe it, but I hope I explained better, why it seems to be better solution.

Maybe additional question for Omeka devs who created few themes - are you trying to reuse the Omeka functions (globals.php) and related core helpers, or are you more comfortable writing own theme-specific globals.php/helpers? Because I assumed everybody wants to reuse existing code to keep it DRY...

Good night Omekans,
Luk

Anurag Spatzenegger

unread,
May 29, 2016, 9:18:38 AM5/29/16
to omek...@googlegroups.com
Since I am looking at it from a perspective of deploying the Omeka instance for one institution at a time, I would not worry too much about rewriting the view files (there are not that many), because I am more or less in control of the theme being used, and I'd much rather leave the core alone, therefor making future upgrades more painless.

If I'd have to create a solution which is being downloaded and deployed by multiple institutions, I'd also try to find a more elegant solution.  

In addition, I always thought that the private / public solution for items / collections isn't done very well.

For example, to me it would make more sense if items, which are part of a private collection, should inherit that status from the collection by default.

But that's another topic :)

Anurag
--
You received this message because you are subscribed to the Google Groups "Omeka Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to omeka-dev+...@googlegroups.com.
To post to this group, send email to omek...@googlegroups.com.
Visit this group at https://groups.google.com/group/omeka-dev.
For more options, visit https://groups.google.com/d/optout.

Natalia Salcedo

unread,
Oct 10, 2016, 6:44:39 PM10/10/16
to Omeka Dev
Hi Anurag,

Could you please tell me in which php file I have to add these lines to add the required functionality ?

Thanks in advance
Reply all
Reply to author
Forward
0 new messages