PHPackages                             aptoma/silex-extras - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. aptoma/silex-extras

AbandonedLibrary[Framework](/categories/framework)

aptoma/silex-extras
===================

Collection of common stuff for Silex powered applications

2.0.7(10y ago)2835.6k↓40%4[1 issues](https://github.com/aptoma/silex-extras/issues)MITPHP

Since Mar 27Pushed 8y ago7 watchersCompare

[ Source](https://github.com/aptoma/silex-extras)[ Packagist](https://packagist.org/packages/aptoma/silex-extras)[ Docs](https://github.com/aptoma/silex-extras)[ RSS](/packages/aptoma-silex-extras/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (20)Versions (28)Used By (0)

Silex Extras
============

[](#silex-extras)

[![Build Status](https://camo.githubusercontent.com/db3ecd231d012bfb7f3b5f8a111b3c407c601c032cbd996fae55a6780ae9aa10/68747470733a2f2f7472617669732d63692e6f72672f6170746f6d612f73696c65782d6578747261732e737667)](https://travis-ci.org/aptoma/silex-extras)[![Coverage Status](https://camo.githubusercontent.com/1ba59aee3da5fd88075b59cc5f9af441a733a652debe3c4ffd43f6779f9643f5/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f6170746f6d612f73696c65782d6578747261732e737667)](https://coveralls.io/r/aptoma/silex-extras)

Package consisting of reusable stuff for Silex powered applications.

It is collection of various services that will ease bootsrapping new Silex applications, keep best practices in sync across projects, and ensure we do stuff in a similar manner whenever we do something.

What's In It?
-------------

[](#whats-in-it)

- Log processor for adding extra context to logs
- ServiceProvider for rich logging in Logstash format
- Base Application class for doing common stuff we always do in Silex applications
- Error handler that outputs stuff as json if `Accept: application/json`
- TestToolkit to bootstrap functional testing of Silex applications
- API key user authentication
- Storage interface, with local file and Level3 implementations
- Ftp upload abstraction, basically a wrapper around native FTP functionality
- Level3 upload service, for uploading stuff to Level3
- ConsoleLoggerServiceProvider, for integrating the logger with the console
- CacheServiceProvider, for Memcached and Redis implementations of Doctrin Cache (can also be used standalone)
- GuzzleServiceProvider for extra Guzzle features
- Guzzle HttpCallInterceptorPlugin for testing with Guzzle services

### Aptoma\\Ftp

[](#aptomaftp)

Wraps native PHP FTP functions in an object oriented manner. It's designed for working with Level3 CDN, and thus has a concept of multiple paths for upload.

Usage:

```
$ftp = new Ftp($hostname, $username, $password, $logger);
$file = new File($pathToFile);

$destination = 'path/on/server/with/filename.txt';
// All directories needs to be created before upload
$ftp->preparePaths(array($destination));
$ftp->put($destination, $file->getRealPath());
```

The class has a few more features for validating upload integrity and moving the file to publish location after upload. Read the source :)

### Aptoma\\Service\\Level3Service

[](#aptomaservicelevel3service)

Provides an abstraction for uploading files to Level3. You need to provide a an `Ftp` instance and various paths, and can then simply do: `$service->upload($fileContents, $targetFileName, $relativeLocalTempDir);`.

After upload, the file will be renamed and put in a folder matching it's checksum, in order to avoid duplicate uploads, and to deal with Level3's (sensible) limitation of max number of files in a directory. The full public url is returned. Strictly speaking, this isn't actually Level3 specific, but more a two-step strategy for validated uploads.

There's also a bundled Level3ServiceProvider for simpler integration with Silex.

### Aptoma\\Log

[](#aptomalog)

This folder provides two classes:

- `ExtraContextProcessor` for always adding a predefined set of extra fields to log entries
- `RequestProcessor` for adding client ip, unique request token and username to all entries
- `MonologGuzzleLogAdapater` for integrating Monolog with Guzzle, to log request times and errors

Usage is simple:

```
use Monolog\Logger;
use Aptoma\Log\RequestProcessor;

$app = new \Silex\Application(...);

$app['logger']->pushProcessor(new RequestProcessor($app));
$app['logger']->pushProcessor(new ExtraContextProcessor(array('service' => 'my-service', 'environment' => 'staging')));
```

### Aptoma\\Silex\\Provider\\ExtendedLoggerServiceProvider

[](#aptomasilexproviderextendedloggerserviceprovider)

This is a service provider that automatically adds the above mentioned `RequestProcessor`, as well as a LogstashFormatter if you have specified `monolog.logstashfile`.

The LogstashFormatter can also add some extra context to each record:

```
$app['meta.service'] = 'drvideo-metadata-admin-gui'; // The name of the service, consult with AMP
$app['meta.customer'] = 'Aptoma'; // The name of customer for this record
$app['meta.environment'] = 'production'; // The environment of the current installation
```

These extra fields will help us classify records in our consolidated logging infrastructure (Loggly, Logstash and friends), and lead to great success.

### Aptoma\\Silex\\Provider\\ConsoleLoggerServiceProvider

[](#aptomasilexproviderconsoleloggerserviceprovider)

This service provider makes it easy to show log messages from services in the console, without having to inject an instance of `OutputInterface` into the services. This requires version ~2.4 of Symfony Components. More info about the change is at the [Symfony Blog](http://symfony.com/blog/new-in-symfony-2-4-show-logs-in-console).

In your console application, you can now do something like this:

```
use Symfony\Component\Console\Application;

$app = require 'app.php';
$console = new Application('My Console Application', '1.0');
// You should only register this service provider when running commands
$app->register(new \Aptoma\Silex\Provider\ConsoleLoggerServiceProvider());

$console->addCommands(
    array(
    //...
    )
);

$console->run($app['console.input'], $app['console.output']);
```

You will still use the normal `OutputInterface` instance for command feedback in your commands, but you will now also get output from anything your services are logging.

The console logger overrides the default `monolog.handler` in order to allow setting a custom log file. If defined, it will use `monolog.console_logfile`, and if not, it will fall back to `monolog.logfile`.

This Provider is also available as standalone package:

### Aptoma\\Silex\\Application

[](#aptomasilexapplication)

This is a base application you can extend. It will add a json formatter for errors, register `ServiceControllerServiceProvider` and `UrlGeneratorServiceProvider`, automatically log execution time for scripts (up until the response has been sent), and also exposes `registerTwig` and `registerLogger`, which you can use to set up those with one line of code.

This class should include functionality that we *always* use, meaning it's not a collection of "nice to haves".

### Aptoma\\JsonErrorHandler

[](#aptomajsonerrorhandler)

This class simply formats exceptions as `JsonResponse`s, provided the client has sent an `Accept: application/json` header. It will be loaded automatically by the base `Application` class mentioned above, or it can be registered manually:

```
$jsonErrorHandler = new Aptoma\JsonErrorHandler($app);
$app->error(array($jsonErrorHandler, 'handle'));
```

### Aptoma\\TestToolkit

[](#aptomatesttoolkit)

This includes a BaseWebTestCase you can use to bootstrap your test, and an associated `TestClient` with shortcuts for `postJson($url, $data)` and `putJson($url, $data)`.

To use it, you need to have your tests extend it, and probably also add the path to your bootstrap file:

```
class MyObjectTest extends TestToolkit\BaseWebTestCase
{
    public function setUp()
    {
        $this->pathToAppBootstrap = __DIR__.'/../../app/app.php';
        parent::setUp();
    }
}
```

### Aptoma\\Security

[](#aptomasecurity)

Component for API key user authentication.

All it requires is a UserProvider and an encoder to encode the API key. It'll typically be used in your app like this:

```
$app->register(
    new Aptoma\Silex\Provider\ApiKeyServiceProvider(),
    array(
        'api_key.user_provider' => new App\Specific\UserProvider(),
        'api_key.encoder' => new App\Specific\Encoder()
    )
);
```

It can then be attached to any firewall of your choice:

```
$app->register(
    new Silex\Provider\SecurityServiceProvider(),
    array(
        'security.firewalls' => array(
            // ...
            'secured' => array(
                'pattern' => '^.*$',
                'api_key' => true
                // more settings...
            )
        )
    )
);
```

### CacheServiceProvider

[](#cacheserviceprovider)

Registers services for `cache.memcached` and `cache.predis`, as well as a generic `cache`, which can be configured to return either of these (Memcached by default).

```
$app->register(new Aptoma\Silex\Provider\MemcachedServicerProvider());
$app->register(new Aptoma\Silex\Provider\CacheServicerProvider());

$app['cache']->save('mykey', 'myvalue');
```

See below for config options for Memcached.

### MemcachedServiceProvider

[](#memcachedserviceprovider)

Registers Memcached as a service, and takes care of prefixes and persistent connections. It returns an instance of \\Memcached.

```
$app['memcached.identifier'] = 'my_app';
$app['memcached.prefix'] = 'ma_';
$app['memcached.servers'] = array(
        array('host' => '127.0.0.1', 'port' => 11211),
    );

$app->register(new Aptoma\Silex\Provider\MemcachedServicerProvider());

$app['memcached']->set('mykey', 'myvalue');
```

### PredisServiceProvider

[](#predisserviceprovider)

Registers Predis as a service. It returns an instance of \\Predis\\Client.

```
$app['redis.host'] = '127.0.0.1';
$app['redis.port'] = 6379;
$app['redis.prefix'] = 'prefix::';
$app['redis.database'] = 0;

$app->register(new Aptoma\Silex\Provider\PredisClientServicerProvider());

$app['predis.client']->set('mykey', 'myvalue');
```

### GuzzleServiceProvider

[](#guzzleserviceprovider)

Extends the base GuzzleServiceProvider to allow registering global plugins, and also adds a few plugins:

- generic logging of each request
- logging of total requests
- adding of request token header to outgoing requests
- cache plugin for HTTP based caching

To configure which cache storage to use, define `$app['guzzle.default_cache']`, which should be a string referencing the cache service to use, ie. 'cache.memcached'.

```
$app->register(new GuzzleServiceProvider(), array('guzzle.services' => array()));
$app->finish(array($app['guzzle.request_logger_plugin'], 'writeLog'));

$app['guzzle.plugins'] = $app->share(
    function () use ($app) {
        return array(
            $app['guzzle.log_plugin'],
            $app['guzzle.request_logger_plugin'],
            $app['guzzle.request_token_plugin'],
            $app['guzzle.cache_plugin'],
        );
    }
);
```

### Guzzle HttpCallInterceptorPlugin

[](#guzzle-httpcallinterceptorplugin)

Guzzle plugin for use in unit testing to ensure there are no calls made to any external services. In your test setup, do something like this:

```
$this->app['guzzle.plugins'] = $this->app->share(
    $this->app->extend(
        'guzzle.plugins',
        function (array $plugins, $app) {
            $plugins[] = new HttpCallInterceptorPlugin($app['logger']);

            return $plugins;
        }
    )
);

// Intercept errors and fail tests, if you don't do this, you'll most often get
// a rather cryptic error message
$this->app->error(
    function (HttpCallToBackendException $e) use ($testCase) {
        $testCase->fail($e->getMessage());
    },
    10
);

$this->app->error(
    function (BatchTransferException $e) use ($testCase) {
        $testCase->fail($e->getMessage());
    },
    10
);
```

###  Health Score

40

—

FairBetter than 87% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity37

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 88.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~44 days

Recently: every ~84 days

Total

25

Last Release

3741d ago

Major Versions

0.0.1 → 1.0.02013-12-14

1.6.0 → 2.0.02015-03-12

### Community

Maintainers

![](https://www.gravatar.com/avatar/6814bf369d6df442037fc62c78ca37d85189df13400e924a8c384c846ab0e42f?d=identicon)[gunnarlium](/maintainers/gunnarlium)

---

Top Contributors

[![gunnarlium](https://avatars.githubusercontent.com/u/207556?v=4)](https://github.com/gunnarlium "gunnarlium (71 commits)")[![peterudo](https://avatars.githubusercontent.com/u/173796?v=4)](https://github.com/peterudo "peterudo (7 commits)")[![glensc](https://avatars.githubusercontent.com/u/199095?v=4)](https://github.com/glensc "glensc (1 commits)")[![tobsn](https://avatars.githubusercontent.com/u/109529?v=4)](https://github.com/tobsn "tobsn (1 commits)")

---

Tags

silex

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/aptoma-silex-extras/health.svg)

```
[![Health](https://phpackages.com/badges/aptoma-silex-extras/health.svg)](https://phpackages.com/packages/aptoma-silex-extras)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.6k509.9M17.0k](/packages/laravel-framework)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k235.4M9.6k](/packages/symfony-framework-bundle)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[silverstripe/framework

The SilverStripe framework

7213.5M2.5k](/packages/silverstripe-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
