Create Items and Files in the code

Hello everyone,
A few weeks ago, I’ve started working on an Omeka plugin that gathers data from users, stores it in its database tables (so, not using Items) and then builds some visualizations. All of this was build by another dev that is no longer with us, and now the project needs deal with user-submitted files.

As I’d like to use Omeka’s built-in file handling rather than re-implement it in the plugin, my guess is that I should create a File record (and possibly a dummy Item record to attach it to) through code rather than using the usual graphical interface. However, I’ve tried browsing the docs and some existing code to get started, but can’t find anything that seems to be relevant.

Any idea on how I should proceed, or maybe some code that I should look at ?

TL;DR : How can I create Omeka Items and Files with code, without using the graphical interface ?

The usual path for adding items (and files at the same time) is the insert_item function.

Thanks John, using insert_item() I was able to create items and upload images using the following code:

foreach ($_FILES as $fileKey => $fileEntry) {
  $itemMetaData = array(
    'public' => false,
    'featured' => false
  );
  $elementTextsData = array();
  $fileMetaData = array(
    'file_transfer_type' => 'Upload',
    'file_ingest_options' => array(),
    'files' => $fileKey
  );
  $testItem = insert_item($itemMetaData, $elementTextsData, $fileMetaData);
}

However, while the expected records are added to the database, the following message is returned :

Warning: Invalid argument supplied for foreach() in <MyOmekaFolder>/application/libraries/Omeka/File/MimeType/Detect/Strategy/Browser.php on line 22

which corresponds to the following code from the Omeka library (line 22 is the first line):

foreach ($_FILES['file']['tmp_name'] as $key => $tmpName)  {
  if ($file == $tmpName) {
    return $_FILES['file']['type'][$key];
  }
}

From my understanding, this assumes that the html input for the file has name='file', and a structure similar to what is described in the second half of the third user note here, or in the second half of the fourth user note here. As you may have guessed, my $_FILES structure actually corresponds to the one described in the first halves of the links I provided, regardless of whether ot not I allow multiple files upload.

Is my understanding of the code wrong ? And if I’m right, any idea on how to fix this ?

You’re correct that this specific detector code requires that the name of the input is file: the Upload code isn’t really used anywhere in the “standard” file uploading interfaces where that’s guaranteed to be the case.

This code you’re looking at here is merely the lowest-priority mime type detector; it’s basically irrelevant. Having the file named file[0] would silence the warning, though.

Thanks for the reply. However, renaming the file input is not an option since it’s used for other purposes as well.
You said that the Upload code isn’t really used, and that I’m dealing with the lowest-priority mime type detector. If I were to look at other file transfer strategies than Upload, or maybe choose another way to detect the file’s mime type, any idea where to start ?

The upload code is used very often, it’s the usual method for people to add files, just rarely used outside the “official” locations it’s used.

Are you having an actual problem with mime type detection, or just this warning? As I said, this is basically the lowest-priority detection method: in other words, the value here only gets looked at if all the other mime detection methods don’t give a useful answer. Usually, the PHP “fileinfo” mime detection is what’s actually used. In other words, though the warning gets issued, it’s almost always irrelevant.

But, if you do want to use another strategy, that’s an option, too. “Filesystem” allows you to ingest a file from the server’s local filesystem, so you could process the upload and put the file at some temporary location and then ingest from there. Url is also an option, but probably won’t work well if users are just uploading files from their client machines.

Ok, I got your explanation of “lowest priority code” wrong, it’s clearer now. I’ve investigated things, and you are right: the PHP “fileinfo” is able to detect the mime type, but the browser detection is still performed and issues its warning.

This is however problematic, since the warning bubbles up into something that is expected to be valid JSON. I can “fix” this in the following way :

set_error_handler(function() {});
$testItem = insert_item($itemMetaData, $elementTextsData, $fileMetaData);
restore_error_handler(); 

But this would also absorb any “legitimate” warning or error issued during the item creation. Do you see a better way to handle things here ?