Extensis Logo SUPPORT | FORUMS | KNOWLEDGE BASE

PHP help - uploads


#1

Hello,

I work for a School of art and am trying to find a way for us to receive portfolios (student work) from students applying to the school.
Currently, we are using a third party web application hosted off campus. The service works, but is very expensive. We already own an instance of Portfolio Professional. I’m evaluating Portfolio Enterprise now to see if we can use it (along with the API) to create a way for applicants to upload directly to us and have their portfolio linked to our student system.

This isn’t a funded project yet, and I’m not a developer. I can look at PHP code and figure it out, but that is about as far as I can go.

The code samples provided in a previous post are helpful. I am having issues getting http upload to work. Can you possibly give an example of how to upload an items to Portfolio?
After upload is it possible to reduce the size of the file and change format after it is uploaded?

Any help or direction you can provide would be very much appreciated.


#2

Greetings,

Here is some sample PHP code that you can use to upload an image to the FileTransfer Servlet

$UPLOADFOLDER = "::server:share:directory";
$item = "photo.jpg";
$directory = "/Volumes/DriveB/Images/Upload";

$boundary = uniqid();
echo "$boundary\n";
$cr = "\r\n";
$bar = "--$boundary$cr";
$data = $bar;
//Create the Header.
$data .= "Content-Disposition: form-data; name=\"sessionId\"" . $cr . $cr . $sessionId . $cr . $bar;
$data .= "Content-Disposition: form-data; name=\"catalogId\"" . $cr . $cr . $catalogId . $cr . $bar;
$data .= "Content-Disposition: form-data; name=\"destinationFolder\"" . $cr . $cr . $UPLOADFOLDER . $cr . $bar;
$data .= "Content-Disposition: form-data; name=\"filename\"" . $cr . $cr . $item . $cr . $bar;
$data .= "Content-Disposition: form-data; name=\"action\"" . $cr . $cr . "upload" . $cr . $bar;
$data .= "Content-Disposition: form-data; name=\"Filedata\"; filename=\"" . $item . "\"" . $cr;
$data .= "Content-Type: application/octet-stream" . $cr . $cr;
//Get the file contents
$fileContents = file_get_contents("$directory/$item");
$data .= $fileContents;
//Close the document.
$data .= "\r\n--$boundary--";
//Set up the connection to the server.
$opts = array(
    'http'=>array(
        'method'=>'POST',
        'header'=> 'Content-Type: multipart/form-data; boundary='.$boundary ."\r\n" .
            "Accept-Types: text/*\r\n" .
            "Connection: close\r\n",
        'protocol_version'=>1.1 ,
        'content'=> $data
    )
);
$URL = "http://" . $SERVER_ADDRESS . ":8090/FileTransfer/upload";
$context = stream_context_create($opts);
//Submit to the server.
$stream = fopen($URL, "rb", false, $context);
//Close the connection.
fclose($stream);

It should be noted that for large files,(25MB and higher) this code sample may run into memory issues when uploading the file. I have found that C# and JAVA allows you to stream the file, alleviating these problems.

As for changing the format and size of the image, you can do that after you have uploaded the file to the catalog using the Jobs and Tasks. Here is an example.

$aQuery = new AssetQuery();
$qTerm = new AssetQueryTerm();

$qTerm->operator = queryOperator::ASSETS_BY_ID;
$qTerm->subqueries = array();
$qTerm->values = array(0 => $RecordID);

$aQuery->queryTerm = $qTerm;

$getAssets = new getAssets();
$getAssets->catalogId = $catalogId;
$getAssets->sessionId = $sessionId;
$getAssets->assets = $aQuery;

$Results = $service->getAssets($getAssets);
$AssetsResults = $Results->return;

if ( $AssetsResults->totalNumberOfAssets >= 1 ) {
    echo "$AssetsResults->totalNumberOfAssets found.\n";

    $myJob = new job();
    $myJob->sourceImage = SourceImage::ORIGINAL;

    $convertTask = new Task();
    $convertTask->type = TaskType::CONVERT;
    $convertSettings = array(
        0 => buildAtt(TaskSetting::OUTPUT_FILE_FORMAT, OutputFileFormat::JPEG),
        1 => buildAtt(TaskSetting::COLOR_MODE, ColorMode::GRAYSCALE),
        2 => buildAtt(TaskSetting::RESIZE_TYPE, ResizeType::FIT_WITHIN),
        3 => buildAtt(TaskSetting::RESIZE_HEIGHT, "512"),
        4 => buildAtt(TaskSetting::RESIZE_WIDTH, "256"),
        5 => buildAtt(TaskSetting::RESIZE_UNITS, Unit::PIXELS),
        6 => buildAtt(TaskSetting::COMPRESSION_TYPE, CompressionType::LZW)
    );
    $convertTask->settings = $convertSettings;

    $saveTask = new Task();
    $saveTask->type = TaskType::SAVE_ON_DISK;
    $saveTask->settings = array(
        0 => buildAtt(TaskSetting::ADD_TO_CATALOG, "true"),
        1 => buildAtt(TaskSetting::DESTINATION, "sameFolder")
        // or if you want to replace the original file with the converted file use this:
        // 1 => buildAtt(TaskSetting::DESTINATION, "replace")  
    );

    $myJob->tasks = array(0 => $convertTask, 1 => $saveTask);

    // Run the Job
    $runJob = new runJob();
    $runJob->sessionId = $sessionId;
    $runJob->catalogId = $catalogId;
    $runJob->assets = $aQuery;
    $runJob->job = $myJob;
    $jobResponse = $service->runJob($runJob);
    $myJobId = $jobResponse->return;

Please let me know if you have any questions.

Matt


#3

Hi Matt.

The sample code you provided works great.

I’ve got some additional questions.

Uploading or connecting to Portfolio via the API seems to take up licensed seats. Is there anyway around this? If we go with this solution we will have near 2,000 applicants uploading their work during admission season and can’t afford to limit ourselves to a set seat count.

We are looking to link the uploaded data to our internal Student Database that contains all of our student records including the existing portfolio review stuff we are using now.
The idea of using Portfolio is to allow the students to upload their work, it gets cataloged and stored in portfolio (converted to “good” file types and sizes) then linked to the student system. After the files get uploaded, is there a way to return a URL to each uploaded file?


#4

[quote=“jarrardrd”]
Uploading or connecting to Portfolio via the API seems to take up licensed seats. Is there anyway around this? If we go with this solution we will have near 2,000 applicants uploading their work during admission season and can’t afford to limit ourselves to a set seat count. [/quote]

This is actually a very common question for people using the API. Most developers have gotten around this issue by storing the Session ID and sharing it between connections.
Basically, it would work something like this. I want to log into the server. I enter my username and password and the login tool checks if my credentials are valid. If they are, it returns the stored Session ID.
(Please note that these credentials need not be Portfolio credentials, you could conceivably authenticate to your website using one username and password, but authenticate to Portfolio using a common, stored username and password. That way you don’t have to had thousands of users to your Portfolio Server.)

Before the login tool returns the Session ID, it should check that it is still valid. If it is not, then a new one should be acquired from the server. With a valid Session ID, the user can now communicate with the Portfolio Server.

A Session ID will expire after 15 minutes of being idle, but as long as it is in use, it can allow unlimited accessibility. Multiple connections to the server can use the same Session ID to connect. How you store that Session ID and share it between connections is up to you.

[quote=“jarrardrd”]
We are looking to link the uploaded data to our internal Student Database that contains all of our student records including the existing portfolio review stuff we are using now.
The idea of using Portfolio is to allow the students to upload their work, it gets cataloged and stored in portfolio (converted to “good” file types and sizes) then linked to the student system. After the files get uploaded, is there a way to return a URL to each uploaded file?[/quote]

Portfolio does not have built in URLs for each of its assets. However, some of our other customers have developed mini apps that when called on in a URL, return a thumbnail or preview image. An example of the URL code might look something like this:

If you have any questions, please let me know.

-Matt