fbg13 Posted November 23, 2016 Share 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? Link to comment Share on other sites More sharing options...
fbg13 Posted November 24, 2016 Author Share 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? Link to comment Share on other sites More sharing options...
Robin S Posted November 24, 2016 Share 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 Link to comment Share on other sites More sharing options...
fbg13 Posted November 25, 2016 Author Share 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. Link to comment Share on other sites More sharing options...
fbg13 Posted November 25, 2016 Author Share 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. Link to comment Share on other sites More sharing options...
fbg13 Posted January 2, 2017 Author Share 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. Link to comment Share on other sites More sharing options...
fbg13 Posted January 4, 2017 Author Share 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; } Link to comment Share on other sites More sharing options...
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