├── .travis.yml
├── bin
└── console
├── composer.json
├── config
├── db.sql
├── parameters.yml.dist
└── services.yml
├── log
└── touch
├── phpunit.xml
├── readme.md
├── src
└── IngoWalther
│ └── ImageMinifyApi
│ ├── Command
│ ├── AddUserCommand.php
│ ├── ListUserCommand.php
│ └── SetupCommand.php
│ ├── Compressor
│ ├── Compressor.php
│ ├── GifsicleCompressor.php
│ ├── MozJpegCompressor.php
│ ├── PngquantCompressor.php
│ └── SVGOCompressor.php
│ ├── Database
│ ├── AbstractRepository.php
│ └── UserRepository.php
│ ├── DependencyInjection
│ ├── CompilerPass
│ │ ├── CommandPass.php
│ │ └── CompressorPass.php
│ └── ContainerBuilder.php
│ ├── Error
│ └── ErrorHandler.php
│ ├── File
│ ├── FileHandler.php
│ ├── FileSizeFormatter.php
│ └── SavingCalculator.php
│ ├── Minify
│ └── Minify.php
│ ├── Response
│ └── CompressedFileResponse.php
│ ├── Security
│ ├── ApiKeyCheck.php
│ ├── ApiKeyGenerator.php
│ └── RandomStringGenerator.php
│ ├── Test
│ ├── Error
│ │ └── ErrorHandlerTest.php
│ ├── File
│ │ ├── FileSizeFormatterTest.php
│ │ └── SavingCalculatorTest.php
│ ├── Minify
│ │ └── MinifyTest.php
│ ├── Security
│ │ ├── ApiKeyCheckTest.php
│ │ └── ApiKeyGeneratorTest.php
│ └── Validator
│ │ └── RequestValidatorTest.php
│ └── Validator
│ └── RequestValidator.php
└── web
├── .htaccess
└── index.php
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.6
4 | - 7.0
5 | - hhvm
6 | - nightly
7 |
8 | matrix:
9 | allow_failures:
10 | - php: nightly
11 |
12 | before_script:
13 | - composer install --no-dev
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | build(realpath(__DIR__ . '/../'));
10 |
11 | /** @var \Symfony\Component\Console\Application $console */
12 | $console = $container->get('console');
13 | $console->run();
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ingowalther/image-minify-api",
3 | "homepage": "https://github.com/ingowalther/image-minify-api",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Ingo Walther",
8 | "email": "ingowalther@iwebspace.net"
9 | }
10 | ],
11 | "require": {
12 | "silex/silex": "~1.3",
13 | "adambrett/shell-wrapper": "0.6",
14 | "symfony/dependency-injection": "2.7.6",
15 | "symfony/yaml": "2.7.6",
16 | "symfony/config": "2.7.6",
17 | "symfony/console": "2.7.6",
18 | "doctrine/dbal": "2.5.2",
19 | "monolog/monolog": "1.17.2",
20 | "incenteev/composer-parameter-handler": "~2.1"
21 | },
22 | "require-dev": {
23 | "phpunit/phpunit": "5.0.*"
24 | },
25 | "scripts": {
26 | "post-install-cmd": [
27 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
28 | "php bin/console image-minify-api:setup"
29 | ],
30 | "post-update-cmd": [
31 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"
32 | ]
33 | },
34 | "extra": {
35 | "incenteev-parameters": {
36 | "file": "config/parameters.yml"
37 | }
38 | },
39 | "autoload": {
40 | "psr-0": {
41 | "IngoWalther\\ImageMinifyApi\\": "src/"
42 | }
43 | },
44 | "minimum-stability": "dev"
45 | }
--------------------------------------------------------------------------------
/config/db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.2.2 MySQL dump
2 |
3 | SET NAMES utf8;
4 | SET time_zone = '+00:00';
5 | SET foreign_key_checks = 0;
6 | SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
7 |
8 | SET NAMES utf8mb4;
9 |
10 | CREATE TABLE `user` (
11 | `id` int(11) NOT NULL AUTO_INCREMENT,
12 | `name` varchar(32) NOT NULL,
13 | `api_key` varchar(32) NOT NULL,
14 | PRIMARY KEY (`id`)
15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
16 |
17 |
18 | -- 2015-11-03 22:22:52
--------------------------------------------------------------------------------
/config/parameters.yml.dist:
--------------------------------------------------------------------------------
1 | parameters:
2 | db_config.database: image-minify-api
3 | db_config.user: root
4 | db_config.password: root
5 | db_config.host: localhost
6 | compressor.mozjpeg.binary_path: '/opt/mozjpeg/bin/cjpeg'
7 | compressor.mozjpeg.command: '%compressor.mozjpeg.binary_path% -quality 82 %s > %s'
8 | compressor.gifsicle.binary_path: 'gifsicle'
9 | compressor.gifsicle.command: '%compressor.gifsicle.binary_path% -O3 %s -o %s'
10 | compressor.pngquant.binary_path: 'pngquant'
11 | compressor.pngquant.command: '%compressor.pngquant.binary_path% --quality=60-90 %s --ext=%s -s1'
12 | compressor.svgo.binary_path: 'svgo'
13 | compressor.svgo.command: '%compressor.svgo.binary_path% %s %s'
--------------------------------------------------------------------------------
/config/services.yml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: 'parameters.yml' }
3 |
4 | parameters:
5 | db:
6 | url: mysql://%db_config.user%:%db_config.password%@%db_config.host%/%db_config.database%
7 | configPath: %basePath%/config
8 | logPath: %basePath%/log
9 |
10 | services:
11 | minify:
12 | class: IngoWalther\ImageMinifyApi\Minify\Minify
13 | arguments: [@fileHandler, @logger]
14 |
15 | mozJpegCompressor:
16 | class: IngoWalther\ImageMinifyApi\Compressor\MozJpegCompressor
17 | arguments: ['%compressor.mozjpeg.binary_path%', '%compressor.mozjpeg.command%']
18 | tags:
19 | - { name: image.compressor, alias: jpeg}
20 |
21 | pngquantCompressor:
22 | class: IngoWalther\ImageMinifyApi\Compressor\PngquantCompressor
23 | arguments: ['%compressor.pngquant.binary_path%', '%compressor.pngquant.command%']
24 | tags:
25 | - { name: image.compressor, alias: png}
26 |
27 | svgoCompressor:
28 | class: IngoWalther\ImageMinifyApi\Compressor\SVGOCompressor
29 | arguments: ['%compressor.svgo.binary_path%', '%compressor.svgo.command%']
30 | tags:
31 | - { name: image.compressor, alias: svgo}
32 |
33 | gifsicleCompressor:
34 | class: IngoWalther\ImageMinifyApi\Compressor\GifsicleCompressor
35 | arguments: ['%compressor.gifsicle.binary_path%', '%compressor.gifsicle.command%']
36 | tags:
37 | - { name: image.compressor, alias: gif}
38 |
39 | fileHandler:
40 | class: IngoWalther\ImageMinifyApi\File\FileHandler
41 |
42 | randomStringGenerator:
43 | class: IngoWalther\ImageMinifyApi\Security\RandomStringGenerator
44 |
45 | apiKeyCheck:
46 | class: IngoWalther\ImageMinifyApi\Security\ApiKeyCheck
47 | arguments: [@userRepository]
48 |
49 | apiKeyGenerator:
50 | class: IngoWalther\ImageMinifyApi\Security\ApiKeyGenerator
51 | arguments: [@userRepository, @randomStringGenerator]
52 |
53 | userRepository:
54 | class: IngoWalther\ImageMinifyApi\Database\UserRepository
55 | arguments: [@dbConnection]
56 |
57 | dbConfig:
58 | class: Doctrine\DBAL\Configuration
59 |
60 | dbConnection:
61 | class: Doctrine\DBAL\Connection
62 | factory_class: Doctrine\DBAL\DriverManager
63 | factory_method: getConnection
64 | arguments: [%db%, @dbConfig]
65 |
66 | errorHandler:
67 | class: IngoWalther\ImageMinifyApi\Error\ErrorHandler
68 | arguments: [@logger]
69 |
70 | logger:
71 | class: Monolog\Logger
72 | arguments: ['ImageMinifyApi']
73 | calls:
74 | - [pushHandler, [@logHandler]]
75 |
76 | logHandler:
77 | class: Monolog\Handler\RotatingFileHandler
78 | arguments: [%logPath%/app.log, 7]
79 |
80 | console:
81 | class: Symfony\Component\Console\Application
82 |
83 | addUserCommand:
84 | class: IngoWalther\ImageMinifyApi\Command\AddUserCommand
85 | calls:
86 | - [setApiKeyGenerator, [@apiKeyGenerator]]
87 | tags:
88 | - { name: console.command, alias: user}
89 |
90 | listUserCommand:
91 | class: IngoWalther\ImageMinifyApi\Command\ListUserCommand
92 | calls:
93 | - [setUserRepository, [@userRepository]]
94 | tags:
95 | - { name: console.command, alias: listUser}
96 |
97 | setupCommand:
98 | class: IngoWalther\ImageMinifyApi\Command\SetupCommand
99 | calls:
100 | - [setConnection, [@dbConnection]]
101 | - [setConfigPath, [%configPath%]]
102 | tags:
103 | - { name: console.command, alias: setup}
104 |
--------------------------------------------------------------------------------
/log/touch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ingowalther/image-minify-api/8e69699d7f45659a03dabfa5d07e0c95bb5a27cc/log/touch
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | src
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Image Minify API
2 |
3 | Install an Image-Compression-Service (like TinyPng, JPEGMini) on your own Server!
4 |
5 | [](https://travis-ci.org/ingowalther/image-minify-api)
6 |
7 | - [Image Minify API](#)
8 | - [Installation](#installation)
9 | - [Create Database](#create-database)
10 | - [Install Project](#install-project)
11 | - [Set permissions for files](#set-permissions-for-files)
12 | - [Setup Webserver](#setup-webserver)
13 | - [Usage](#usage)
14 | - [Create API-Key](#create-api-key)
15 | - [Compress an Image](#compress-an-image)
16 | - [Response](#response)
17 | - [List all user](#list-all-user)
18 | - [Clients](#api-clients)
19 | - [PHP](#api-clients)
20 | - [Grunt-Task](#api-clients)
21 | - [TODO](#todo)
22 |
23 | Currently supports:
24 | - jpeg (mozJpeg, Installation Instructions: http://mozjpeg.codelove.de/binaries.html)
25 | - png (pngquant, https://pngquant.org/)
26 | - svg (SVGO, https://github.com/svg/svgo)
27 | - gif (Gifsicle, https://www.lcdf.org/gifsicle/)
28 |
29 | ## Installation
30 |
31 | ### Create Database
32 | You should create a database first. In this database Image Minify API will create all necessary tables during composer install.
33 |
34 | ### Install Project
35 | ```sh
36 | composer create-project ingowalther/image-minify-api %installation-folder-name%
37 | ```
38 |
39 | ### Set permissions for files
40 | ```sh
41 | chmod a+rw log
42 | ```
43 |
44 | ### Setup Webserver
45 | ```
46 | vHost DocRoot -> web/
47 | ```
48 |
49 | ## Usage
50 |
51 | ### Create API-Key
52 | ```sh
53 | bin/console user:add
54 | ```
55 | Enter a Username.
56 | If the user is created correctly you will see the API-Key in your Terminal.
57 |
58 | ### Compress an Image
59 |
60 | POST with Params "api_key" and File with Name "image" to http://yourserver/minify
61 |
62 | Example:
63 | ```sh
64 | curl --form "image=@test.jpg" --form api_key=VVDFNNflLIQdCH5vnx0RkmCxxjhHIL6 http://localhost/minify > result.json
65 | ```
66 |
67 | #### Response
68 | You will get a Json-Response like this:
69 | ```json
70 | {
71 | "success":true,
72 | "oldSize":539,
73 | "newSize":394,
74 | "saving": 26,
75 | "image":"\/9j\/4AAQSkZJRgABAQAAAQABAAD\/\/gATQ3JlYXRlZCB3aXRoIEdJTVD\/2wCEAAoKCgoKCgsMDAsPEA4QDxYUExMUFiIYGhgaGCIzICUgICUgMy03LCksNy1RQDg4QFFeT0pPXnFlZXGPiI+7u\/sBCgoKCgoKCwwMCw8QDhAPFhQTExQWIhgaGBoYIjMgJSAgJSAzLTcsKSw3LVFAODhAUV5PSk9ecWVlcY+Ij7u7+\/\/CABEIAAEAAQMBIgACEQEDEQH\/xAAUAAEAAAAAAAAAAAAAAAAAAAAH\/9oACAEBAAAAAGb\/xAAUAQEAAAAAAAAAAAAAAAAAAAAA\/9oACAECEAAAAH\/\/xAAUAQEAAAAAAAAAAAAAAAAAAAAA\/9oACAEDEAAAAH\/\/xAAUEAEAAAAAAAAAAAAAAAAAAAAA\/9oACAEBAAE\/AH\/\/xAAUEQEAAAAAAAAAAAAAAAAAAAAA\/9oACAECAQE\/AH\/\/xAAUEQEAAAAAAAAAAAAAAAAAAAAA\/9oACAEDAQE\/AH\/\/2Q=="
76 | }
77 | ```
78 | | Parameter | Description |
79 | | ------------- | ------------- |
80 | | success | true or false |
81 | | oldSize | ImageSize before compressing (in Byte) |
82 | | newSize | ImageSize after compressing (in Byte) |
83 | | saving | The saving of bytes in percent |
84 | | image | The binarydata of the compressed image (base64 encoded) |
85 |
86 | ### List all user
87 | ```sh
88 | bin/console user:list
89 | ```
90 | Output:
91 |
92 | 
93 |
94 | ## API-Clients
95 |
96 | PHP: https://github.com/ingowalther/image-minify-php-client
97 |
98 | Grunt-Task: https://github.com/yannicstadler/image-minify-api-grunt-task
99 |
100 | ## TODO
101 | - Quota
102 |
103 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Command/AddUserCommand.php:
--------------------------------------------------------------------------------
1 | apiKeyGenerator = $apiKeyGenerator;
26 | }
27 |
28 |
29 | protected function configure()
30 | {
31 | $this
32 | ->setName('user:add')
33 | ->setDescription('Creates a new User/API-Key')
34 | ->addArgument(
35 | 'name',
36 | InputArgument::OPTIONAL,
37 | 'Username?'
38 | );
39 | }
40 |
41 | /**
42 | * @param InputInterface $input
43 | * @param OutputInterface $output
44 | * @throws \Exception
45 | */
46 | protected function execute(InputInterface $input, OutputInterface $output)
47 | {
48 | if(!$this->apiKeyGenerator) {
49 | throw new \Exception('ApiKeyGenerator is not set!');
50 | }
51 |
52 | $name = $input->getArgument('name');
53 |
54 | if(!$name) {
55 | /** @var QuestionHelper $helper */
56 | $helper = $this->getHelper('question');
57 | $question = new Question('Username? ');
58 |
59 | $name = $helper->ask($input, $output, $question);
60 | }
61 |
62 | $key = $this->apiKeyGenerator->generate($name);
63 |
64 | $output->writeln(sprintf('User "%s" succesfully created', $name));
65 | $output->writeln(sprintf('API-Key: %s', $key));
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Command/ListUserCommand.php:
--------------------------------------------------------------------------------
1 | userRepository = $userRepository;
24 | }
25 |
26 | protected function configure()
27 | {
28 | $this
29 | ->setName('user:list')
30 | ->setDescription('Lists all user');
31 | }
32 |
33 | /**
34 | * @param InputInterface $input
35 | * @param OutputInterface $output
36 | */
37 | protected function execute(InputInterface $input, OutputInterface $output)
38 | {
39 | $table = new Table($output);
40 | $table->setHeaders(['ID', 'Username', 'API-Key'])
41 | ->addRows($this->userRepository->findAll());
42 |
43 | $table->render();
44 | }
45 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Command/SetupCommand.php:
--------------------------------------------------------------------------------
1 | configPath = $configPath;
28 | }
29 |
30 | /**
31 | * @param Connection $connection
32 | */
33 | public function setConnection(Connection $connection)
34 | {
35 | $this->connection = $connection;
36 | }
37 |
38 | protected function configure()
39 | {
40 | $this
41 | ->setName('image-minify-api:setup')
42 | ->setDescription('Setups the project');
43 | }
44 |
45 | /**
46 | * @param InputInterface $input
47 | * @param OutputInterface $output
48 | * @throws \Exception
49 | */
50 | protected function execute(InputInterface $input, OutputInterface $output)
51 | {
52 | $dump = file_get_contents($this->configPath . '/db.sql');
53 |
54 | $statement = $this->connection->prepare($dump);
55 | $statement->execute();
56 |
57 | if ($statement->errorCode() != 0) {
58 | throw new \Exception('Error while creating Database');
59 | }
60 |
61 | $output->writeln('Database created successfully');
62 | }
63 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Compressor/Compressor.php:
--------------------------------------------------------------------------------
1 | binaryPath = $binaryPath;
35 | $this->command = $command;
36 | }
37 |
38 | /**
39 | * @return string
40 | */
41 | public function getFileTypeToHandle()
42 | {
43 | return 'image/gif';
44 | }
45 |
46 | /**
47 | * @param UploadedFile $file
48 | * @return string
49 | */
50 | public function compress(UploadedFile $file)
51 | {
52 | $shell = new Exec();
53 |
54 | $command = new Command(
55 | sprintf($this->command, $file->getRealPath(), $file->getRealPath() . 'compressed')
56 | );
57 |
58 | $shell->run($command);
59 |
60 | if (!file_exists($file->getRealPath() . 'compressed')) {
61 | throw new \RuntimeException('No compressed Image created!');
62 | }
63 |
64 | return $file->getRealPath() . 'compressed';
65 | }
66 |
67 | /**
68 | * @return bool
69 | */
70 | public function checkLibaryIsInstalled()
71 | {
72 | $shell = new Exec();
73 |
74 | $command = new Command($this->binaryPath);
75 | $command->addFlag(new Command\Flag('-version'));
76 |
77 | $shell->run($command);
78 |
79 | if ($shell->getReturnValue() === 0) {
80 | return true;
81 | }
82 |
83 | return false;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Compressor/MozJpegCompressor.php:
--------------------------------------------------------------------------------
1 | binaryPath = $binaryPath;
33 | $this->command = $command;
34 | }
35 |
36 | /**
37 | * @return string
38 | */
39 | public function getFileTypeToHandle()
40 | {
41 | return 'image/jpeg';
42 | }
43 |
44 | /**
45 | * @param UploadedFile $file
46 | * @return string
47 | */
48 | public function compress(UploadedFile $file)
49 | {
50 | $shell = new Exec();
51 |
52 | $command = new Command(
53 | sprintf($this->command, $file->getRealPath(), $file->getRealPath() . 'compressed')
54 | );
55 |
56 | $shell->run($command);
57 |
58 | if (!file_exists($file->getRealPath() . 'compressed')) {
59 | throw new \RuntimeException('No compressed Image created!');
60 | }
61 |
62 | return $file->getRealPath() . 'compressed';
63 | }
64 |
65 | /**
66 | * @return bool
67 | */
68 | public function checkLibaryIsInstalled()
69 | {
70 | $shell = new Exec();
71 |
72 | $command = new Command($this->binaryPath);
73 | $command->addFlag(new Command\Flag('version'));
74 |
75 | $shell->run($command);
76 |
77 | if ($shell->getReturnValue() === 0) {
78 | return true;
79 | }
80 |
81 | return false;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Compressor/PngquantCompressor.php:
--------------------------------------------------------------------------------
1 | binaryPath = $binaryPath;
33 | $this->command = $command;
34 | }
35 |
36 | /**
37 | * @return string
38 | */
39 | public function getFileTypeToHandle()
40 | {
41 | return 'image/png';
42 | }
43 |
44 | /**
45 | * @param UploadedFile $file
46 | * @return string
47 | */
48 | public function compress(UploadedFile $file)
49 | {
50 | $shell = new Exec();
51 |
52 | $command = new Command(
53 | sprintf($this->command, $file->getRealPath(), 'compressed')
54 | );
55 |
56 | $shell->run($command);
57 |
58 | if (!file_exists($file->getRealPath() . 'compressed')) {
59 | throw new \RuntimeException('No compressed Image created!');
60 | }
61 |
62 | return $file->getRealPath() . 'compressed';
63 | }
64 |
65 | /**
66 | * @return bool
67 | */
68 | public function checkLibaryIsInstalled()
69 | {
70 | $shell = new Exec();
71 |
72 | $command = new Command($this->binaryPath);
73 | $command->addArgument(new Command\Argument('version'));
74 |
75 | $shell->run($command);
76 |
77 | if ($shell->getReturnValue() === 0) {
78 | return true;
79 | }
80 |
81 | return false;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Compressor/SVGOCompressor.php:
--------------------------------------------------------------------------------
1 | binaryPath = $binaryPath;
33 | $this->command = $command;
34 | }
35 |
36 | /**
37 | * @return string
38 | */
39 | public function getFileTypeToHandle()
40 | {
41 | return 'image/svg+xml';
42 | }
43 |
44 | /**
45 | * @param UploadedFile $file
46 | * @return string
47 | */
48 | public function compress(UploadedFile $file)
49 | {
50 | $shell = new Exec();
51 |
52 | $command = new Command(
53 | sprintf($this->command, $file->getRealPath(), $file->getRealPath() . 'compressed')
54 | );
55 |
56 | $shell->run($command);
57 |
58 | if (!file_exists($file->getRealPath() . 'compressed')) {
59 | throw new \RuntimeException('No compressed Image created!');
60 | }
61 |
62 | return $file->getRealPath() . 'compressed';
63 | }
64 |
65 | /**
66 | * @return bool
67 | */
68 | public function checkLibaryIsInstalled()
69 | {
70 | $shell = new Exec();
71 |
72 | $command = new Command($this->binaryPath);
73 | $command->addFlag(new Command\Flag('v'));
74 |
75 | $shell->run($command);
76 |
77 | if ($shell->getReturnValue() === 0) {
78 | return true;
79 | }
80 | return false;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Database/AbstractRepository.php:
--------------------------------------------------------------------------------
1 | connection = $connection;
24 | $this->setTableName();
25 | }
26 |
27 | /**
28 | * @param int $fetchType
29 | */
30 | public function findAll($fetchMode = \PDO::FETCH_ASSOC)
31 | {
32 | $query = sprintf('SELECT * FROM `%s`', $this->tableName);
33 | return $this->fetch($query, array(), $fetchMode);
34 | }
35 |
36 | /**
37 | * @param $query
38 | * @param array $params
39 | * @param int $fetchMode
40 | * @return array
41 | * @throws \Doctrine\DBAL\DBALException
42 | */
43 | protected function fetch($query, $params = array(), $fetchMode= \PDO::FETCH_ASSOC)
44 | {
45 | $statement = $this->connection->prepare($query);
46 | $statement->execute($params);
47 |
48 | return $statement->fetchAll($fetchMode);
49 | }
50 |
51 | protected abstract function setTableName();
52 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Database/UserRepository.php:
--------------------------------------------------------------------------------
1 | tableName = 'user';
14 | }
15 |
16 | /**
17 | * @param string $userName
18 | * @return bool|array
19 | */
20 | public function findUserByName($userName)
21 | {
22 | $query = 'SELECT * FROM `user` WHERE `name` = ?';
23 |
24 | $result = $this->fetch($query, array($userName));
25 | if (count($result) == 0) {
26 | return false;
27 | }
28 | return array_pop($result);
29 | }
30 |
31 | /**
32 | * @param string $key
33 | * @return bool|array
34 | */
35 | public function findUserByKey($key)
36 | {
37 | $query = 'SELECT * FROM `user` WHERE `api_key` = ?';
38 |
39 | $result = $this->fetch($query, array($key));
40 | if (count($result) == 0) {
41 | return false;
42 | }
43 | return array_pop($result);
44 | }
45 |
46 | /**
47 | * @param $username
48 | * @param $key
49 | */
50 | public function addUser($username, $key)
51 | {
52 | $statement = $this->connection->prepare('INSERT INTO `user` (`id`, `name`, `api_key`) VALUES (NULL, ?, ?)');
53 | $statement->execute(array($username, $key));
54 | }
55 |
56 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/DependencyInjection/CompilerPass/CommandPass.php:
--------------------------------------------------------------------------------
1 | has('console')) {
18 | return;
19 | }
20 |
21 | $definition = $container->findDefinition('console');
22 | $taggedServices = $container->findTaggedServiceIds('console.command');
23 |
24 | foreach ($taggedServices as $id => $tags) {
25 | foreach ($tags as $attributes) {
26 | $definition->addMethodCall(
27 | 'add',
28 | array(new Reference($id))
29 | );
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/DependencyInjection/CompilerPass/CompressorPass.php:
--------------------------------------------------------------------------------
1 | has('minify')) {
18 | return;
19 | }
20 |
21 | $definition = $container->findDefinition('minify');
22 | $taggedServices = $container->findTaggedServiceIds('image.compressor');
23 |
24 | foreach ($taggedServices as $id => $tags) {
25 | foreach ($tags as $attributes) {
26 | $definition->addMethodCall(
27 | 'addCompressor',
28 | array(new Reference($id))
29 | );
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/DependencyInjection/ContainerBuilder.php:
--------------------------------------------------------------------------------
1 | addCompilerPass(new CompressorPass());
25 | $container->addCompilerPass(new CommandPass());
26 | $container->setParameter('basePath', $basePath);
27 | $loader = new YamlFileLoader($container, new FileLocator($basePath .'/config'));
28 | $loader->load('services.yml');
29 | $container->compile();
30 |
31 | return $container;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Error/ErrorHandler.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
26 | }
27 |
28 | /**
29 | * @param \Exception $e
30 | * @param $code
31 | * @return \Symfony\Component\HttpFoundation\JsonResponse
32 | */
33 | public function handle(\Exception $e, $code)
34 | {
35 | switch ($code) {
36 | case 404:
37 | $data = array(
38 | 'success' => false,
39 | 'code' => '404',
40 | 'message' => 'The requested page could not be found.',
41 | );
42 | break;
43 | default:
44 | $data = array(
45 | 'success' => false,
46 | 'code' => $code,
47 | 'message' => $e->getMessage(),
48 | );
49 | }
50 |
51 | $this->logger->error(
52 | sprintf('%s: %s', get_class($e), $e->getMessage())
53 | );
54 |
55 | return new JsonResponse($data, $code);
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/File/FileHandler.php:
--------------------------------------------------------------------------------
1 | file($path);
19 | }
20 |
21 | /**
22 | * @param $path
23 | * @return int
24 | */
25 | public function getFileSize($path)
26 | {
27 | return filesize($path);
28 | }
29 |
30 | /**
31 | * @param $path
32 | * @return string
33 | */
34 | public function getFileContent($path)
35 | {
36 | return file_get_contents($path);
37 | }
38 |
39 | /**
40 | * @param $path
41 | * @return bool
42 | */
43 | public function delete($path)
44 | {
45 | return unlink($path);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/File/FileSizeFormatter.php:
--------------------------------------------------------------------------------
1 | fileHandler = $fileHandler;
41 | $this->logger = $logger;
42 | }
43 |
44 | /**
45 | * @param Compressor $compressor
46 | */
47 | public function addCompressor(Compressor $compressor)
48 | {
49 | $this->compressors[] = $compressor;
50 | }
51 |
52 | /**
53 | * Minifies the given Image
54 | *
55 | * @param UploadedFile $file
56 | * @param array $user
57 | * @return CompressedFileResponse
58 | */
59 | public function minify(UploadedFile $file, $user)
60 | {
61 | $fileType = $this->fileHandler->getFileType($file->getRealPath());
62 |
63 | $compressorToUse = $this->getCompressorToUse($fileType);
64 | $path = $compressorToUse->compress($file);
65 |
66 | $oldSize = $this->fileHandler->getFileSize($file->getRealPath());
67 | $newSize = $this->fileHandler->getFileSize($path);
68 |
69 | if ($newSize < $oldSize) {
70 | return $this->handleSuccess($file, $user, $path, $oldSize, $newSize);
71 | }
72 |
73 | return $this->handleNewFileBigger($file, $user, $path, $oldSize, $newSize);
74 | }
75 |
76 | /**
77 | * @param $fileType
78 | * @return Compressor
79 | */
80 | private function getCompressorToUse($fileType)
81 | {
82 | foreach ($this->compressors as $compressor) {
83 | if ($compressor->getFileTypeToHandle() == $fileType) {
84 | if ($compressor->checkLibaryIsInstalled()) {
85 | return $compressor;
86 | }
87 | }
88 | }
89 |
90 | throw new \InvalidArgumentException(
91 | sprintf('Filetype "%s" not supported', $fileType)
92 | );
93 | }
94 |
95 | /**
96 | * @param UploadedFile $file
97 | * @param $user
98 | * @param $path
99 | * @param $oldSize
100 | * @param $newSize
101 | * @return CompressedFileResponse
102 | */
103 | private function handleSuccess(UploadedFile $file, $user, $path, $oldSize, $newSize)
104 | {
105 | $binaryContent = $this->fileHandler->getFileContent($path);
106 | $this->fileHandler->delete($path);
107 |
108 | $savingCalculator = new SavingCalculator();
109 | $saving = $savingCalculator->calculate($oldSize, $newSize);
110 |
111 | $fomatter = new FileSizeFormatter();
112 |
113 | $this->logger->info(
114 | sprintf('[%s] Succesfully compressed Image (%s) - Old: %s, New: %s, Saving: %d%%',
115 | $user['name'],
116 | $file->getClientOriginalName(),
117 | $fomatter->humanReadable($oldSize),
118 | $fomatter->humanReadable($newSize),
119 | $saving)
120 | );
121 |
122 | return new CompressedFileResponse($oldSize, $newSize, $saving, $binaryContent);
123 | }
124 |
125 | /**
126 | * @param UploadedFile $file
127 | * @param $user
128 | * @param $oldSize
129 | * @param $newSize
130 | * @param $path
131 | * @return CompressedFileResponse
132 | */
133 | private function handleNewFileBigger(UploadedFile $file, $user, $path, $oldSize, $newSize)
134 | {
135 | $savingCalculator = new SavingCalculator();
136 | $saving = $savingCalculator->calculate($oldSize, $newSize);
137 |
138 | $fomatter = new FileSizeFormatter();
139 |
140 | $this->logger->info(
141 | sprintf('[%s] New image is bigger than the original one - returning original image (%s) - Old: %s, New: %s, Saving: %d%%',
142 | $user['name'],
143 | $file->getClientOriginalName(),
144 | $fomatter->humanReadable($oldSize),
145 | $fomatter->humanReadable($newSize),
146 | $saving)
147 | );
148 |
149 | $binaryContent = $this->fileHandler->getFileContent($file->getRealPath());
150 | $this->fileHandler->delete($path);
151 | $newSize = $oldSize;
152 | $saving = 0;
153 |
154 | return new CompressedFileResponse($oldSize, $newSize, $saving, $binaryContent);
155 | }
156 |
157 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Response/CompressedFileResponse.php:
--------------------------------------------------------------------------------
1 | true,
17 | 'oldSize' => $oldSize,
18 | 'newSize' => $newSize,
19 | 'saving' => $saving,
20 | 'image' => base64_encode($binaryContent)
21 | ];
22 |
23 | parent::__construct($data, $status, $headers);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Security/ApiKeyCheck.php:
--------------------------------------------------------------------------------
1 | userRepository = $userRepository;
26 | }
27 |
28 | /**
29 | * Checks for valid API-Key
30 | * @param string $apiKey
31 | */
32 | public function check($apiKey)
33 | {
34 | $user = $this->isKeyValid($apiKey);
35 | return $user;
36 | }
37 |
38 | /**
39 | * Checks if API-Key is valid
40 | * @param string $apiKey
41 | */
42 | private function isKeyValid($apiKey)
43 | {
44 | $user = $this->userRepository->findUserByKey($apiKey);
45 |
46 | if(!$user) {
47 | throw new AccessDeniedHttpException('Your API key is not valid');
48 | }
49 | return $user;
50 | }
51 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Security/ApiKeyGenerator.php:
--------------------------------------------------------------------------------
1 | userRepository = $userRepository;
31 | $this->randomStringGenerator = $randomStringGenerator;
32 | }
33 |
34 | /**
35 | * @param $username
36 | * @return string
37 | */
38 | public function generate($username)
39 | {
40 | $this->checkUsername($username);
41 |
42 | do {
43 | $key = $this->randomStringGenerator->generate();
44 | } while (!$this->checkKey($key));
45 |
46 | $this->userRepository->addUser($username, $key);
47 | return $key;
48 | }
49 |
50 | /**
51 | * @param $username
52 | */
53 | private function checkUsername($username)
54 | {
55 | $user = $this->userRepository->findUserByName($username);
56 | if ($user) {
57 | throw new Exception('This username is taken');
58 | }
59 | }
60 |
61 | private function checkKey($key)
62 | {
63 | $user = $this->userRepository->findUserByKey($key);
64 | if($user) {
65 | return false;
66 | }
67 | return true;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Security/RandomStringGenerator.php:
--------------------------------------------------------------------------------
1 | characters) - 1;
24 | for ($i = 0; $i < $length; $i++) {
25 | $string .= $this->characters[rand(0,$max)];
26 | }
27 | return $string;
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/Error/ErrorHandlerTest.php:
--------------------------------------------------------------------------------
1 | getMockBuilder('Monolog\Logger')
17 | ->disableOriginalConstructor()
18 | ->getMock();
19 |
20 | $this->object = new ErrorHandler($logger);
21 | }
22 |
23 | public function testWith404()
24 | {
25 | $exception = new \Exception();
26 | $response = $this->object->handle($exception, '404');
27 |
28 | $this->assertEquals(404, $response->getStatusCode());
29 |
30 | $data = array(
31 | 'success' => false,
32 | 'code' => '404',
33 | 'message' => 'The requested page could not be found.',
34 | );
35 |
36 | $expected = json_encode($data);
37 | $this->assertEquals($expected, $response->getContent());
38 | }
39 |
40 | public function testDefault()
41 | {
42 | $message = 'This is my test error';
43 |
44 | $exception = new \Exception($message);
45 | $response = $this->object->handle($exception, '500');
46 |
47 | $this->assertEquals(500, $response->getStatusCode());
48 |
49 | $data = array(
50 | 'success' => false,
51 | 'code' => '500',
52 | 'message' => $message,
53 | );
54 |
55 | $expected = json_encode($data);
56 | $this->assertEquals($expected, $response->getContent());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/File/FileSizeFormatterTest.php:
--------------------------------------------------------------------------------
1 | 800, 'expected' => '800.00B'],
13 | ['test' => 1200, 'expected' => '1.17kB'],
14 | ['test' => 8000000, 'expected' => '7.63MB'],
15 | ['test' => 8000000000, 'expected' => '7.45GB'],
16 | ['test' => 0, 'expected' => '0.00B'],
17 | ];
18 |
19 | $fomatter = new FileSizeFormatter();
20 |
21 | foreach($testData as $entry) {
22 | $result = $fomatter->humanReadable($entry['test']);
23 | $this->assertEquals($entry['expected'], $result);
24 | }
25 | }
26 |
27 | public function testHumanReadableWithBytesSmallerZero()
28 | {
29 | $fomatter = new FileSizeFormatter();
30 | $this->setExpectedException('InvalidArgumentException');
31 | $fomatter->humanReadable(-1);
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/File/SavingCalculatorTest.php:
--------------------------------------------------------------------------------
1 | object = new SavingCalculator();
17 | }
18 |
19 | public function testWithOldAndNewSizeZero()
20 | {
21 | $result = $this->object->calculate(0, 0);
22 | $this->assertEquals(0, $result);
23 | }
24 |
25 | public function testWithOldSizeZeroAndNewSizeSet()
26 | {
27 | $result = $this->object->calculate(0, 50);
28 | $this->assertEquals(0, $result);
29 | }
30 |
31 | public function testWithOldSizeSetAndNewSizeZero()
32 | {
33 | $result = $this->object->calculate(50, 0);
34 | $this->assertEquals(0, $result);
35 | }
36 |
37 | public function testWithOldAndNewSizeSet()
38 | {
39 | $result = $this->object->calculate(100, 50);
40 | $this->assertEquals(50, $result);
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/Minify/MinifyTest.php:
--------------------------------------------------------------------------------
1 | fileHandler = $this->getMock(
18 | 'IngoWalther\ImageMinifyApi\File\FileHandler',
19 | array(),
20 | array(),
21 | '',
22 | false
23 | );
24 |
25 | $logger = $this->getMockBuilder('Monolog\Logger')
26 | ->disableOriginalConstructor()
27 | ->getMock();
28 |
29 | $this->object = new Minify($this->fileHandler, $logger);
30 | }
31 |
32 | public function testWithNoCompressor()
33 | {
34 | $this->fileHandler->expects($this->once())
35 | ->method('getFileType')
36 | ->with('/tmp/foobar')
37 | ->will($this->returnValue('image/jpeg'));
38 |
39 | $this->setExpectedException('InvalidArgumentException');
40 | $this->object->minify($this->createMockFile(), ['name' => 'foobar']);
41 | }
42 |
43 | public function testWithNoMatchingCompressor()
44 | {
45 | $this->fileHandler->expects($this->once())
46 | ->method('getFileType')
47 | ->with('/tmp/foobar')
48 | ->will($this->returnValue('image/png'));
49 |
50 | $this->setExpectedException('InvalidArgumentException');
51 |
52 | $this->object->addCompressor($this->createMockCompressor('image/jpeg'));
53 | $this->object->minify($this->createMockFile(), ['name' => 'foobar']);
54 | }
55 |
56 | public function testWithNoCompressorButLibaryNotInstalled()
57 | {
58 | $this->fileHandler->expects($this->once())
59 | ->method('getFileType')
60 | ->with('/tmp/foobar')
61 | ->will($this->returnValue('image/png'));
62 |
63 | $this->setExpectedException('InvalidArgumentException');
64 |
65 | $this->object->addCompressor($this->createMockCompressor('image/jpeg', $installed = false));
66 | $this->object->minify($this->createMockFile(), ['name' => 'foobar']);
67 | }
68 |
69 | public function testWithMatchingCompressor()
70 | {
71 | $image = $this->createMockFile();
72 |
73 | $this->fileHandler->expects($this->once())
74 | ->method('getFileType')
75 | ->with('/tmp/foobar')
76 | ->will($this->returnValue('image/jpeg'));
77 |
78 | $compressor = $this->createMockCompressor('image/jpeg');
79 |
80 | $compressor->expects($this->once())
81 | ->method('compress')
82 | ->with($image)
83 | ->will($this->returnValue('/tmp/foobar_compressed'));
84 |
85 | $this->fileHandler->expects($this->at(1))
86 | ->method('getFileSize')
87 | ->with('/tmp/foobar')
88 | ->will($this->returnValue(1000));
89 |
90 | $this->fileHandler->expects($this->at(2))
91 | ->method('getFileSize')
92 | ->with('/tmp/foobar_compressed')
93 | ->will($this->returnValue(500));
94 |
95 | $this->fileHandler->expects($this->at(3))
96 | ->method('getFileContent')
97 | ->with('/tmp/foobar_compressed')
98 | ->will($this->returnValue('Foobar'));
99 |
100 | $this->fileHandler->expects($this->at(4))
101 | ->method('delete')
102 | ->with('/tmp/foobar_compressed');
103 |
104 | $this->object->addCompressor($compressor);
105 | $result = $this->object->minify($image, ['name' => 'foobar']);
106 |
107 | $this->assertEquals('IngoWalther\ImageMinifyApi\Response\CompressedFileResponse', get_class($result));
108 | }
109 |
110 | public function testWithMatchingCompressorAndNewFileBigger()
111 | {
112 | $image = $this->createMockFile();
113 |
114 | $this->fileHandler->expects($this->once())
115 | ->method('getFileType')
116 | ->with('/tmp/foobar')
117 | ->will($this->returnValue('image/jpeg'));
118 |
119 | $compressor = $this->createMockCompressor('image/jpeg');
120 |
121 | $compressor->expects($this->once())
122 | ->method('compress')
123 | ->with($image)
124 | ->will($this->returnValue('/tmp/foobar_compressed'));
125 |
126 | $this->fileHandler->expects($this->at(1))
127 | ->method('getFileSize')
128 | ->with('/tmp/foobar')
129 | ->will($this->returnValue(1000));
130 |
131 | $this->fileHandler->expects($this->at(2))
132 | ->method('getFileSize')
133 | ->with('/tmp/foobar_compressed')
134 | ->will($this->returnValue(1001));
135 |
136 | $this->fileHandler->expects($this->at(3))
137 | ->method('getFileContent')
138 | ->with('/tmp/foobar')
139 | ->will($this->returnValue('Foobar'));
140 |
141 | $this->fileHandler->expects($this->at(4))
142 | ->method('delete')
143 | ->with('/tmp/foobar_compressed');
144 |
145 | $this->object->addCompressor($compressor);
146 | $result = $this->object->minify($image, ['name' => 'foobar']);
147 |
148 | $this->assertEquals('IngoWalther\ImageMinifyApi\Response\CompressedFileResponse', get_class($result));
149 |
150 | $resultData = json_decode($result->getContent());
151 |
152 | $this->assertEquals(1000, $resultData->newSize);
153 | $this->assertEquals(0, $resultData->saving);
154 | }
155 |
156 | private function createMockFile()
157 | {
158 | $file = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile')
159 | ->setConstructorArgs(array('/tmp/test', 'test', null, null, 'test'))
160 | ->getMock();
161 |
162 | $file->expects($this->any())
163 | ->method('getRealPath')
164 | ->will($this->returnValue('/tmp/foobar'));
165 |
166 | return $file;
167 | }
168 |
169 | private function createMockCompressor($type, $installed = true)
170 | {
171 | $compressor = $this->getMockBuilder('IngoWalther\ImageMinifyApi\Compressor\MozJpegCompressor')
172 | ->disableOriginalConstructor(true)
173 | ->getMock();
174 |
175 | $compressor->expects($this->any())
176 | ->method('getFileTypeToHandle')
177 | ->will($this->returnValue($type));
178 |
179 | $compressor->expects($this->any())
180 | ->method('checkLibaryIsInstalled')
181 | ->will($this->returnValue($installed));
182 |
183 | return $compressor;
184 | }
185 |
186 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/Security/ApiKeyCheckTest.php:
--------------------------------------------------------------------------------
1 | userRepository = $this->getMockBuilder('IngoWalther\ImageMinifyApi\Database\UserRepository')
23 | ->disableOriginalConstructor(true)
24 | ->getMock();
25 |
26 | $this->object = new ApiKeyCheck($this->userRepository);
27 | }
28 |
29 | public function testCheckWithInvalidAPIKey()
30 | {
31 | $this->userRepository->expects($this->once())
32 | ->method('findUserByKey')
33 | ->with('invalid')
34 | ->will($this->returnValue(false));
35 |
36 | $this->setExpectedException('Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException');
37 | $this->object->check('invalid');
38 | }
39 |
40 | public function testWithValidAPIKey()
41 | {
42 | $fakeUser = array('fakeuser' => true);
43 |
44 | $this->userRepository->expects($this->once())
45 | ->method('findUserByKey')
46 | ->with('valid')
47 | ->will($this->returnValue($fakeUser));
48 |
49 | $result = $this->object->check('valid');
50 | $this->assertEquals($fakeUser, $result);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/Security/ApiKeyGeneratorTest.php:
--------------------------------------------------------------------------------
1 | userRepository = $this->getMockBuilder('IngoWalther\ImageMinifyApi\Database\UserRepository')
27 | ->disableOriginalConstructor(true)
28 | ->getMock();
29 |
30 | $this->randomStringGenerator = $this->getMockBuilder('IngoWalther\ImageMinifyApi\Security\RandomStringGenerator')
31 | ->getMock();
32 |
33 | $this->object = new ApiKeyGenerator($this->userRepository, $this->randomStringGenerator);
34 | }
35 |
36 | public function testWithTakenUsername()
37 | {
38 | $username = 'taken';
39 |
40 | $this->userRepository->expects($this->once())
41 | ->method('findUserByName')
42 | ->with($username)
43 | ->will($this->returnValue(array('user' => 'peter')));
44 |
45 | $this->setExpectedException('Exception');
46 | $this->object->generate($username);
47 | }
48 |
49 | public function testWithFreeUsername()
50 | {
51 | $username = 'free';
52 |
53 | $this->userRepository->expects($this->at(0))
54 | ->method('findUserByName')
55 | ->with($username)
56 | ->will($this->returnValue(false));
57 |
58 | $this->randomStringGenerator->expects($this->at(0))
59 | ->method('generate')
60 | ->will($this->returnValue('taken1'));
61 |
62 | $this->randomStringGenerator->expects($this->at(1))
63 | ->method('generate')
64 | ->will($this->returnValue('taken2'));
65 |
66 | $this->randomStringGenerator->expects($this->at(2))
67 | ->method('generate')
68 | ->will($this->returnValue('freeKey'));
69 |
70 | $this->userRepository->expects($this->at(1))
71 | ->method('findUserByKey')
72 | ->with('taken1')
73 | ->will($this->returnValue(array('user' => 'peter')));
74 |
75 | $this->userRepository->expects($this->at(2))
76 | ->method('findUserByKey')
77 | ->with('taken2')
78 | ->will($this->returnValue(array('user' => 'peter2')));
79 |
80 | $this->userRepository->expects($this->at(3))
81 | ->method('findUserByKey')
82 | ->with('freeKey')
83 | ->will($this->returnValue(false));
84 |
85 | $this->userRepository->expects($this->at(4))
86 | ->method('addUser')
87 | ->with('free', 'freeKey');
88 |
89 | $key = $this->object->generate($username);
90 |
91 | $this->assertEquals('freeKey', $key);
92 | }
93 |
94 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Test/Validator/RequestValidatorTest.php:
--------------------------------------------------------------------------------
1 | object = new RequestValidator();
18 | }
19 |
20 | public function testWithOnePostFieldNotSet()
21 | {
22 | $this->object->setRequiredPostFields(['foo', 'bar', 'baz']);
23 | $this->object->setRequiredFileFields([]);
24 |
25 | $request = new Request();
26 | $request->request->set('foo', '1');
27 | $request->request->set('bar', '2');
28 |
29 | $this->setExpectedException('InvalidArgumentException');
30 | $this->object->validateRequest($request);
31 | }
32 |
33 | public function testWithAllPostFieldSetAndNoFileFieldRequired()
34 | {
35 | $this->object->setRequiredPostFields(['foo', 'bar', 'baz']);
36 | $this->object->setRequiredFileFields([]);
37 |
38 | $request = new Request();
39 | $request->request->set('foo', '1');
40 | $request->request->set('bar', '2');
41 | $request->request->set('baz', '3');
42 |
43 | $this->object->validateRequest($request);
44 | }
45 |
46 | public function testWithAllPostFieldSetAndRequiredFileFieldNotSet()
47 | {
48 | $this->object->setRequiredPostFields(['foo', 'bar', 'baz']);
49 | $this->object->setRequiredFileFields(['file', 'file2']);
50 |
51 | $request = new Request();
52 | $request->request->set('foo', '1');
53 | $request->request->set('bar', '2');
54 | $request->request->set('baz', '3');
55 |
56 | $request->files->set('file', array());
57 |
58 | $this->setExpectedException('InvalidArgumentException');
59 | $this->object->validateRequest($request);
60 | }
61 |
62 | public function testWithAllPostFieldSetAndAllFileFieldsSet()
63 | {
64 | $this->object->setRequiredPostFields(['foo', 'bar', 'baz']);
65 | $this->object->setRequiredFileFields(['file', 'file2']);
66 |
67 | $request = new Request();
68 | $request->request->set('foo', '1');
69 | $request->request->set('bar', '2');
70 | $request->request->set('baz', '3');
71 |
72 | $request->files->set('file', array());
73 | $request->files->set('file2', array());
74 |
75 | $this->object->validateRequest($request);
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/src/IngoWalther/ImageMinifyApi/Validator/RequestValidator.php:
--------------------------------------------------------------------------------
1 | validatePostFields($request);
29 | $this->validateFileFields($request);
30 | }
31 |
32 | /**
33 | * @param Request $request
34 | */
35 | private function validatePostFields(Request $request)
36 | {
37 | foreach($this->requiredPostFields as $field) {
38 | $this->validatePostField($request, $field);
39 | }
40 | }
41 |
42 | /**
43 | * @param Request $request
44 | * @param $field
45 | */
46 | private function validatePostField(Request $request, $field)
47 | {
48 | if (!$request->request->has($field)) {
49 | throw new \InvalidArgumentException(sprintf('Postfield "%s" must be set', $field));
50 | }
51 | }
52 |
53 | /**
54 | * @param Request $request
55 | */
56 | private function validateFileFields(Request $request)
57 | {
58 | foreach($this->requiredFileFields as $field) {
59 | $this->validateFileField($request, $field);
60 | }
61 | }
62 |
63 | /**
64 | * @param Request $request
65 | * @param $field
66 | */
67 | private function validateFileField(Request $request, $field)
68 | {
69 | if (!$request->files->has($field)) {
70 | throw new \InvalidArgumentException(sprintf('Filefield "%s" must be set', $field));
71 | }
72 | }
73 |
74 | /**
75 | * @param array $requiredFileFields
76 | */
77 | public function setRequiredFileFields($requiredFileFields)
78 | {
79 | $this->requiredFileFields = $requiredFileFields;
80 | }
81 |
82 | /**
83 | * @param array $requiredPostFields
84 | */
85 | public function setRequiredPostFields($requiredPostFields)
86 | {
87 | $this->requiredPostFields = $requiredPostFields;
88 | }
89 | }
--------------------------------------------------------------------------------
/web/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Options -MultiViews
3 |
4 | RewriteEngine On
5 | RewriteCond %{REQUEST_FILENAME} !-f
6 | RewriteRule ^ index.php [QSA,L]
7 |
--------------------------------------------------------------------------------
/web/index.php:
--------------------------------------------------------------------------------
1 | build(realpath(__DIR__ . '/../'));
13 |
14 | $app->post('/minify', function(Request $request) use ($container) {
15 |
16 | $validator = new RequestValidator();
17 | $validator->validateRequest($request);
18 |
19 | $apiKeyCheck = $container->get('apiKeyCheck');
20 | $user = $apiKeyCheck->check($request->request->get('api_key'));
21 |
22 | $minify = $container->get('minify');
23 | $result = $minify->minify($request->files->get('image'), $user);
24 |
25 | return $result;
26 | });
27 |
28 | $app->error(function (\Exception $e, $code) use ($container) {
29 | $errorHandler = $container->get('errorHandler');
30 | return $errorHandler->handle($e, $code);
31 | });
32 |
33 | $app->run();
34 |
--------------------------------------------------------------------------------