fbg13

Fieldtype/inputfield for uploading to aws s3 module

7 posts in this topic

I trying to build a module for uploading files  to aws s3, but i'm stuck as i can't figure out how everything works just by looking at the FieldtypeFile and InputfieldFile (and others) modules.

I managed to display the field on the page, but i can't understand how to access and upload/store the files i select.

This is what i have so far, the FieldType

Spoiler

<?php namespace ProcessWire;
/**
 * ProcessWire AmazonS3File Fieldtype
 *
 * Allows uploads to AmazonS3
 *
 * amazon key = 
 * amazon secret = 
 *
 * For documentation about the fields used in this class, please see:
 * /wire/core/Fieldtype.php
 *
 * ProcessWire 2.x
 * Copyright (C) 2016 by Ryan Cramer
 * Licensed under MPL 2.0
 *
 * https://processwire.com
 *
 * @todo implement a getMatchQuery method and support LIKE with address.
 *
 * @property string $googleApiKey
 *
 */

use Aws\S3\S3Client;

class FieldtypeAmazonS3File extends FieldtypeMulti {

	public static function getModuleInfo() {
		return array(
			'title' => 'FieldtypeAmazonS3File',
			'version' => 001,
			'summary' => 'FieldtypeAmazonS3File.',
			'installs' => 'InputfieldAmazonS3File',
			);
	}

    public function getInputfield(Page $page, Field $field) {
        $inputfield = $this->modules->get("InputfieldAmazonS3File");
        return $inputfield;
    }
}

 

The InputField

Spoiler

<?php namespace ProcessWire;

use Aws\S3\S3Client;

class InputfieldAmazonS3File extends Inputfield implements InputfieldItemList {

	public static function getModuleInfo() {
		return array(
			'title' => 'InputfieldAmazonS3File',
			'version' => 001,
			'summary' => "InputfieldAmazonS3File",
			'requires' => 'FieldtypeAmazonS3File ',
		);
	}

    public function init()
    {
        parent::init();
        $this->attr('type', 'file');
        $this->attr('multiple', 'multiple');
    }

    public function ___render()
    {
        $attrs = $this->getAttributes();
        if(substr($attrs['name'], -1) != ']') $attrs['name'] .= '[]';

        $attrStr = $this->getAttributesString($attrs);
        $out = "<input $attrStr>";
        return $out;
    }

    public function ___processInput(WireInputData $input)
    {
        //$this->message($_FILES['s3']);
        return $this;
    }

}

 

This "$this->message($_FILES['s3']);" inside the ___processInput method gives me the $_FILES array but i'm don't think that's the way to do it.

So how and where am i supposed to access the $_FILES array?

Are there other methods i need to implement?

Share this post


Link to post
Share on other sites

I changed the type to text and  $this->message($input[$this->name]); returns the value for text field but not for file field

public function ___processInput(WireInputData $input)
{
    // this displays the value of the text field after the page was saved,
    // but if the field is of type file i get nothing
    // this->name is the name of the field
    // 
    // $this->message( $_FILES[$this->name] ); - this does displays the array

    $this->message($input[$this->name]);
    return $this;
}

The values are not saved in the db so the text value comes from the input, which makes me think that ___processInput is where i should get the values from the field, process them and save them to the db.

Why $this->message( $input[$this->name] ); doesn't work for file type fields?

What am i missing?

Share this post


Link to post
Share on other sites

@Robin S Yes i saw some of those, but it's not quite what i try to achieve.

I can upload the files to S3 if i use the $_FILES array directly. I just don't know if that's ok, i thought i could use the $input variable passed to ___processInput(WireInputData $input), to get the files, like i can get the value from a text field.

Share this post


Link to post
Share on other sites

Think i managed to understand what the InputfieldFile ___processInput does.

It passes the name of the file type field to the WireUpload class which takes the $_FILES array and uploads the files from the field with the matching name.

So $input doesn't have the files, meaning i can/have to use the $_FILES array.

Share this post


Link to post
Share on other sites

I need to hook the url method to change it to the s3 location, but if i have a local file field its url changes too.

Can i hook the url method of only my field?

Currently i'm adding the hook to the inputfield class in the init method:

public function init() {
    parent::init();
    $this->addHookAfter('PagefilesManager::url', $this, 'newURL');
}

protected function newURL($event) {
    $ssl = ($this->useSSL) ? 'https' : 'http';
    $domain = $this->domain();
    $event->return = "{$ssl}://{$domain}/" . $event->object->page . "/" . $event->object->name;
}

The fieldtype and inputfield classes extend the default fieldtypefile and inputfieldfile classes.

Share this post


Link to post
Share on other sites

Instead of hooking the url method i added a new method to the Pagefile object

public function init() {
	parent::init();
	$this->addHook('Pagefile::s3url', $this, 's3url');
}
protected function s3url($event) {
	$ssl = ($this->useSSL) ? 'https' : 'http';
	$domain = $this->domain();
	$event->return = "{$ssl}://{$domain}/" . $event->object->page . "/" . $event->object->name;
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.