[Q&A Friday] How to Attach Files to Documents with REST API


Fri 07 June 2013 By Laurent Doguin

This article may contain some outdated content and may not be runnable in the current Nuxeo version.

Today we have a common question asked by sk90:, How can I attach files to documents through REST API?.

In his example, he uses our old REST API based on restlets. This API is deprecated and we now use Content Automation. Following are some examples for doing this.

Java Automation Client


This is an example using nuxeo-automation-client in a unit test. The test deploys a basic Nuxeo in a Jetty. Thanks to the EmbeddedAutomationServerFeature test feature, everything we need is deployed (core doc types, content automation etc...).

The first thing to do is create a File document at the root. Then we create a Blob with the automation-client API. Then comes the Blob.Attach request. Finally we test that the blob has been attached to the document.

package org.nuxeo.sample.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.nuxeo.ecm.automation.client.Constants;
import org.nuxeo.ecm.automation.client.Session;
import org.nuxeo.ecm.automation.client.model.Blob;
import org.nuxeo.ecm.automation.client.model.StringBlob;
import org.nuxeo.ecm.automation.test.EmbeddedAutomationServerFeature;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.runtime.test.runner.Features;
import org.nuxeo.runtime.test.runner.FeaturesRunner;
import org.nuxeo.runtime.test.runner.Jetty;

import com.google.inject.Inject;

@RunWith(FeaturesRunner.class)
@Features(EmbeddedAutomationServerFeature.class)
@Jetty(port = 18080)
public class AutomationTest {

@Inject
CoreSession coreSession;

@Inject
Session session;

@Test
public void testAttachDocument() throws Exception {
  // Create the document and get its ID
  DocumentModel fileDocument = coreSession.createDocumentModel("/", "testFile", "File");
  fileDocument = coreSession.createDocument(fileDocument);
  String documentID = fileDocument.getId();
  coreSession.save(); // flush changes to the embedded database

  // create a file and attach it to the document
  Blob b = new StringBlob("myFile.txt", "file content", "text/plain");
  session.newRequest("Blob.Attach")
    .setHeader(Constants.HEADER_NX_VOIDOP, "true").setInput(b)
    .set("document", documentID).execute();
  coreSession.save();// flush changes to the embedded database

  // retrieve the document again and make sure the blob has been set
  fileDocument = coreSession.getDocument(fileDocument.getRef());
  org.nuxeo.ecm.core.api.Blob nxBlob = (org.nuxeo.ecm.core.api.Blob) fileDocument.getPropertyValue("file:content");

  assertNotNull(nxBlob);
  assertEquals(b.getFileName(), nxBlob.getFilename());
  }
}

PHP Automation Client

Here's a sample taken from the nuxeo-automation-php-client repository. It lists the available workspaces and lets you choose a file to upload. Then it creates the document in the selected workspace using the filename. Next, it attaches the file to the document in another request. We use the same Blob.Attach operation for that. You'll find more details in our documentation.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<?php
/*
* (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Gallouin Arthur
*/
?>
<html>
<head>
<title>B4 test php Client</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<link rel="stylesheet" media="screen" type="text/css" title="Design" href="design.css"/>
</head>
<body>
Create a file at the path chosen with file path and attach the blob chosen in<br/>
the blob path field to it.<br/>

<form action="B4.php" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>Blob Path</td>
<td><input type="file" name="blobPath"/></td>
</tr>
<tr>
<td>File Path</td>
<td><?php

include ('../NuxeoAutomationClient/NuxeoAutomationAPI.php');

$client = new NuxeoPhpAutomationClient('http://localhost:8080/nuxeo/site/automation');

$session = $client->getSession('Administrator', 'Administrator');

$answer = $session->newRequest("Document.Query")->set('params', 'query', "SELECT * FROM Workspace")->sendRequest();

$array = $answer->getDocumentList();
$value = sizeof($array);
echo '<select name="TargetNuxeoDocumentPath">';
for ($test = 0; $test < $value; $test++) {
echo '<option value="' . current($array)->getPath() . '">' . current($array)->getTitle() . '</option>';
next($array);
}
echo '</select>';
?></td>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form>
<?php

/**
*
* AttachBlob function
*
* @param String $blob contains the path of the blob to load as an attachment
* @param String $filePath contains the path of the folder where the fille holding the blob will be created
* @param String $blobtype contains the type of the blob (given by the $_FILES['blobPath']['type'])
*/
function attachBlob($blob = '../test.txt', $filePath = '/default-domain/workspaces/document', $blobtype = 'application/binary') {

//only works on LINUX / MAC
// We get the name of the file to use it for the name of the document
$ename = explode("/", $blob);
$filename = end($ename);
$client = new NuxeoPhpAutomationClient('http://localhost:8080/nuxeo/site/automation');

$session = $client->getSession('Administrator', 'Administrator');

$properties = "dc:title=". $filename;

//We create the document that will hold the file
$answer = $session->newRequest("Document.Create")->set('input', 'doc:' . $filePath)->set('params', 'type', 'File')->set('params', 'name', end($ename))->set('params', 'properties', $properties)->sendRequest();

//We upload the file
$answer = $session->newRequest("Blob.Attach")->set('params', 'document', $answer->getDocument(0)->getPath())
->loadBlob($blob, $blobtype)
->sendRequest();
}

if (!isset($_FILES['blobPath']) AND $_FILES['blobPath']['error'] == 0) {
echo 'BlobPath is empty';
exit;
}
if (!isset($_POST['TargetNuxeoDocumentPath']) OR empty($_POST['TargetNuxeoDocumentPath'])) {
echo 'TargetNuxeoDocumentPath is empty';
exit;
}
if ((isset($_FILES['blobPath']) && ($_FILES['blobPath']['error'] == UPLOAD_ERR_OK))) {
$targetPath = '../blobs/';
if (!is_dir('../blobs'))
mkdir('../blobs');
move_uploaded_file($_FILES['blobPath']['tmp_name'], $targetPath . $_FILES['blobPath']['name']);
}

attachBlob($targetPath . $_FILES['blobPath']['name'], $_POST['TargetNuxeoDocumentPath'], $_FILES['blobPath']['type']);
unlink($targetPath . $_FILES['blobPath']['name']);

?></body>
</html>

Category: Product & Development
Tagged: Nuxeo Automation, Q&A, REST API