fbg13 Posted November 23, 2016 Posted November 23, 2016 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?
fbg13 Posted November 24, 2016 Author Posted November 24, 2016 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?
Robin S Posted November 24, 2016 Posted November 24, 2016 You will find debugging much easier using Tracy Debugger than with $this->message. Have you seen these modules and topics relating to Amazon storage? http://modules.processwire.com/modules/amazon-s3-cloudfront/ http://modules.processwire.com/modules/schedule-cloud-backups/ 1
fbg13 Posted November 25, 2016 Author Posted November 25, 2016 @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.
fbg13 Posted November 25, 2016 Author Posted November 25, 2016 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.
fbg13 Posted January 2, 2017 Author Posted January 2, 2017 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.
fbg13 Posted January 4, 2017 Author Posted January 4, 2017 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; }
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now