{"id":24732739,"url":"https://github.com/gonzalo123/ionic2_to_s3","last_synced_at":"2025-10-10T01:32:49.402Z","repository":{"id":66582106,"uuid":"95381099","full_name":"gonzalo123/ionic2_to_s3","owner":"gonzalo123","description":"Taking photos with a ionic2 and upload to S3 Bucket with SAP's Cloud Foundry, Silex and Lumen","archived":false,"fork":false,"pushed_at":"2017-08-17T21:31:04.000Z","size":1659,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-03T12:21:39.826Z","etag":null,"topics":["aws","ionic2","lumen","php","s3","sap","sap-cloud-foundry","scp","silex"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gonzalo123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-25T19:26:09.000Z","updated_at":"2019-09-18T16:53:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"4430bc06-e339-469f-81b8-4f0e519b5b3d","html_url":"https://github.com/gonzalo123/ionic2_to_s3","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gonzalo123/ionic2_to_s3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fionic2_to_s3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fionic2_to_s3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fionic2_to_s3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fionic2_to_s3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gonzalo123","download_url":"https://codeload.github.com/gonzalo123/ionic2_to_s3/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gonzalo123%2Fionic2_to_s3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002406,"owners_count":26083374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","ionic2","lumen","php","s3","sap","sap-cloud-foundry","scp","silex"],"created_at":"2025-01-27T17:53:50.762Z","updated_at":"2025-10-10T01:32:49.397Z","avatar_url":"https://github.com/gonzalo123.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Taking photos with a ionic2 and upload to S3 Bucket with SAP's Cloud Foundry, Silex and Lumen\n======\n\nToday I want to play with an experiment. When I work with mobile applications, I normally use ionic and on-premise backends. Today I want play with cloud based backends. In this small experiment I want to use an ionic2 application to take pictures and upload them to an S3 bucket. Let's start.\n\nFirst I've created a simple ionic2 application. It's a very simple application. Only one page with a button to trigger the device's camera.\n\n```html\n\u003cion-header\u003e\n    \u003cion-navbar\u003e\n        \u003cion-title\u003e\n            Photo\n        \u003c/ion-title\u003e\n    \u003c/ion-navbar\u003e\n\u003c/ion-header\u003e\n\n\u003cion-content padding\u003e\n    \u003cion-fab bottom right\u003e\n        \u003cbutton ion-fab (click)=\"takePicture()\"\u003e\n            \u003cion-icon  name=\"camera\"\u003e\u003c/ion-icon\u003e\n        \u003c/button\u003e\n    \u003c/ion-fab\u003e\n\u003c/ion-content\u003e\n```\n\nThe controller uses @ionic-native/camera to take photos and later we use @ionic-native/transfer to upload them to the backend.\n\n```js\nimport {Component} from '@angular/core';\nimport {Camera, CameraOptions} from '@ionic-native/camera';\nimport {Transfer, FileUploadOptions, TransferObject} from '@ionic-native/transfer';\nimport {ToastController} from 'ionic-angular';\nimport {LoadingController} from 'ionic-angular';\n\n@Component({\n    selector: 'page-home',\n    templateUrl: 'home.html'\n})\nexport class HomePage {\n    constructor(private transfer: Transfer,\n                private camera: Camera,\n                public toastCtrl: ToastController,\n                public loading: LoadingController) {\n    }\n\n    takePicture() {\n        const options: CameraOptions = {\n            quality: 100,\n            destinationType: this.camera.DestinationType.FILE_URI,\n            sourceType: this.camera.PictureSourceType.CAMERA,\n            encodingType: this.camera.EncodingType.JPEG,\n            targetWidth: 1000,\n            targetHeight: 1000,\n            saveToPhotoAlbum: false,\n            correctOrientation: true\n        };\n\n        this.camera.getPicture(options).then((uri) =\u003e {\n            const fileTransfer: TransferObject = this.transfer.create();\n\n            let options: FileUploadOptions = {\n                fileKey: 'file',\n                fileName: uri.substr(uri.lastIndexOf('/') + 1),\n                chunkedMode: true,\n                headers: {\n                    Connection: \"close\"\n                },\n                params: {\n                    metadata: {foo: 'bar'},\n                    token: 'mySuperSecretToken'\n                }\n            };\n\n            let loader = this.loading.create({\n                content: 'Uploading ...',\n            });\n\n            loader.present().then(() =\u003e {\n                let s3UploadUri = 'https://myApp.cfapps.eu10.hana.ondemand.com/upload';\n                fileTransfer.upload(uri, s3UploadUri, options).then((data) =\u003e {\n                    let message;\n                    let response = JSON.parse(data.response);\n                    if (response['status']) {\n                        message = 'Picture uploaded to S3: ' + response['key']\n                    } else {\n                        message = 'Error Uploading to S3: ' + response['error']\n                    }\n                    loader.dismiss();\n                    let toast = this.toastCtrl.create({\n                        message: message,\n                        duration: 3000\n                    });\n                    toast.present();\n                }, (err) =\u003e {\n                    loader.dismiss();\n                    let toast = this.toastCtrl.create({\n                        message: \"Error\",\n                        duration: 3000\n                    });\n                    toast.present();\n                });\n            });\n        });\n    }\n}\n```\n\nNow let's work with the backend. We'll use SAP's Cloud Foundry tenant (using a free account). In this tenant we'll create a PHP application using the PHP buildpack with nginx\n\n\n```yaml\napplications:\n- name:    myApp\n  path: .\n  memory:  128MB\n  buildpack: php_buildpack\n```\n\nThe PHP application is a simple Silex application to handle the file uploads and post the pictures to S3 using the official AWS SDK for PHP (based on Guzzle)\n\n```php\ninclude __DIR__ . \"/../vendor/autoload.php\";\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Silex\\Application;\nuse Aws\\S3\\S3Client;\n\nrequire 'vendor/autoload.php';\n\n$app = new Application([\n    'debug'        =\u003e false,\n    'aws.config'   =\u003e [\n        'debug'       =\u003e false,\n        'version'     =\u003e 'latest',\n        'region'      =\u003e 'eu-west-1',\n        'credentials' =\u003e [\n            'key'    =\u003e $_ENV['s3key'],\n            'secret' =\u003e $_ENV['s3secret'],\n        ],\n    ],\n]);\n\n$app['aws'] = function () use ($app) {\n    return new S3Client($app['aws.config']);\n};\n\n$app-\u003epost('/upload', function (Request $request, Application $app) {\n    $metadata = json_decode($request-\u003eget('metadata'), true);\n    $token    = $request-\u003eget('token');\n\n    if ($token === $_ENV['token']) {\n        $fileName = $_FILES['file']['name'];\n        $fileType = $_FILES['file']['type'];\n        $tmpName  = $_FILES['file']['tmp_name'];\n\n        /** @var \\Aws\\S3\\S3Client $s3 */\n        $s3 = $app['aws'];\n        try {\n            $key = date('YmdHis') . \"_\" . $fileName;\n            $s3-\u003eputObject([\n                'Bucket'      =\u003e $_ENV['s3bucket'],\n                'Key'         =\u003e $key,\n                'SourceFile'  =\u003e $tmpName,\n                'ContentType' =\u003e $fileType,\n                'Metadata'    =\u003e $metadata,\n            ]);\n            unlink($tmpName);\n\n            return $app-\u003ejson([\n                'status' =\u003e true,\n                'key'    =\u003e $key,\n            ]);\n        } catch (Aws\\S3\\Exception\\S3Exception $e) {\n            return $app-\u003ejson([\n                'status' =\u003e false,\n                'error'  =\u003e $e-\u003egetMessage(),\n            ]);\n        }\n    } else {\n        return $app-\u003ejson([\n            'status' =\u003e false,\n            'error'  =\u003e \"Token error\",\n        ]);\n    }\n});\n\n$app-\u003erun();\n```\n\nI just wanted a simple prototype (a working one). Enough for a Sunday morning hacking.\n\nUPDATE\n\nI had this post ready weeks ago but something has changed. Silex is dead so, as an exercise I'll migrate current Silex application to Lumen.\n\nThat's the main application.\n\n```php\nuse App\\Http\\Middleware;\nuse Aws\\S3\\S3Client;\nuse Illuminate\\Http\\Request;\nuse Laravel\\Lumen\\Application;\n\nrequire 'vendor/autoload.php';\n\n(new Dotenv\\Dotenv(__DIR__ . \"/../env\"))-\u003eload();\n\n$app = new Application();\n\n$app-\u003erouteMiddleware([\n    'auth' =\u003e Middleware\\AuthMiddleware::class,\n]);\n\n$app-\u003eregister(App\\Providers\\S3ServiceProvider::class);\n\n$app-\u003egroup(['middleware' =\u003e 'auth'], function (Application $app) {\n    $app-\u003epost('/upload', function (Request $request, Application $app, S3Client $s3) {\n        $metadata = json_decode($request-\u003eget('metadata'), true);\n        $fileName = $_FILES['file']['name'];\n        $fileType = $_FILES['file']['type'];\n        $tmpName  = $_FILES['file']['tmp_name'];\n\n        try {\n            $key = date('YmdHis') . \"_\" . $fileName;\n            $s3-\u003eputObject([\n                'Bucket'      =\u003e getenv('s3bucket'),\n                'Key'         =\u003e $key,\n                'SourceFile'  =\u003e $tmpName,\n                'ContentType' =\u003e $fileType,\n                'Metadata'    =\u003e $metadata,\n            ]);\n            unlink($tmpName);\n\n            return response()-\u003ejson([\n                'status' =\u003e true,\n                'key'    =\u003e $key,\n            ]);\n        } catch (Aws\\S3\\Exception\\S3Exception $e) {\n            return response()-\u003ejson([\n                'status' =\u003e false,\n                'error'  =\u003e $e-\u003egetMessage(),\n            ]);\n        }\n    });\n});\n\n$app-\u003erun();\n```\n\nProbably we can find a S3 Service provider, but I've built a simple one for this example.\n\n```php\nnamespace App\\Providers;\n\nuse Illuminate\\Support\\ServiceProvider;\nuse Aws\\S3\\S3Client;\n\nclass S3ServiceProvider extends ServiceProvider\n{\n    public function register()\n    {\n        $this-\u003eapp-\u003ebind(S3Client::class, function ($app) {\n            $conf = [\n                'debug'       =\u003e false,\n                'version'     =\u003e getenv('AWS_VERSION'),\n                'region'      =\u003e getenv('AWS_REGION'),\n                'credentials' =\u003e [\n                    'key'    =\u003e getenv('s3key'),\n                    'secret' =\u003e getenv('s3secret'),\n                ],\n            ];\n\n            error_log(json_encode($conf));\n            return new S3Client($conf);\n        });\n    }\n}\n```\n\nAnd also I'm using a middleware for the authentication\n\n```php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Request;\n\nclass AuthMiddleware\n{\n    public function handle(Request $request, Closure $next)\n    {\n        $token = $request-\u003eget('token');\n        if ($token === getenv('token')) {\n            return response('Admin Login', 401);\n        }\n\n        return $next($request);\n    }\n}\n```\n\nOk. I'll post this article soon. At least before Lumen will be dead also, and I need to rewrite it too :)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fionic2_to_s3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgonzalo123%2Fionic2_to_s3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgonzalo123%2Fionic2_to_s3/lists"}