PHPackages                             ssnepenthe/metis - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. ssnepenthe/metis

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ssnepenthe/metis
================

Pimple, with some helpful tweaks for working in WordPress

0.7.0(8y ago)41.3k[2 issues](https://github.com/ssnepenthe/metis/issues)3GPL-2.0PHPPHP &gt;=5.3

Since Mar 30Pushed 8y ago1 watchersCompare

[ Source](https://github.com/ssnepenthe/metis)[ Packagist](https://packagist.org/packages/ssnepenthe/metis)[ Docs](https://github.com/ssnepenthe/metis)[ RSS](/packages/ssnepenthe-metis/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (2)Versions (10)Used By (3)

metis
=====

[](#metis)

[Pimple](https://pimple.sensiolabs.org/), with some some helpful tweaks for working in WordPress.

Requirements
------------

[](#requirements)

PHP 5.3 or later and Composer.

**Note:** Metis should continue to work down to 5.3 but is no longer tested below 5.4.

Installation
------------

[](#installation)

```
$ composer require ssnepenthe/metis

```

Usage
-----

[](#usage)

This is basically Pimple but you will use `Metis\Container` instead of `Pimple\Container`.

The following features have been added:

**Handle activation and deactivation logic within your service providers**

```
class Some_Provider implements Pimple\ServiceProviderInterface {
    public function activate( Pimple\Container $container ) {
        // Handle activation here.
    }

    public function deactivate( Pimple\Container $container ) {
        // Handle deactivation here.
    }

    // ...
}
```

And then call the corresponsing method on your container instance.

```
$container = new Metis\Container;
$container->register( new Some_Provider );

register_activation_hook( __FILE__, array( $container, 'activate' ) );
register_deactivation_hook( __FILE__, array( $container, 'deactivate' ) );
```

**Handle boot logic (add\_action/add\_filter calls) within your service providers**

```
class Another_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'init', array( $container['service'], 'init' ) );
    }

    // ...
}
```

And then call the corresponding method on your container instance.

```
$container = new Metis\Container;
$container->register( new Another_Provider );

add_action( 'plugins_loaded', array( $container, 'boot' ) );
```

**Service Proxies**

One of the many benefits of a dependency injection container like Pimple is that objects are created on demand as you access their container entries.

This can be especially useful for functionality that is only needed on a limited number of requests (e.g. admin, cron, etc.).

Unfortunately this doesn't always work the way you might want in WordPress:

```
class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', array( $container['admin_page'], 'do_something' ) );
    }

    // ...
}
```

Since the `boot()` method is typically attached to the `plugins_loaded` hook, the admin page object will always be created regardless of whether `admin_init` has been triggered.

A sensible approach would be to verify that the current request is for an admin page before calling `add_action()`:

```
class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        if ( is_admin() ) {
            add_action( 'admin_init', array( $container['admin_page'], 'do_something' ) );
        }
    }

    // ...
}
```

But this results in a boot method littered with conditionals.

An alternative would be to access the `admin_page` entry within an anonymous function:

```
class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', function() use ( $container ) {
            $container['admin_page']->do_something();
        }
    }

    // ...
}
```

But that gets tedious quickly and can result in a large number of unnecessary `Closure` objects floating around.

Instead, you might choose to extend `Metis\Base_Provider` and use the `proxy()` method:

```
class Admin_Provider extends Metis\Base_Provider {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', array( $this->proxy( $container, 'admin_page' ), 'do_something' ) );
    }

    // ...
}
```

This will create a `Metis\Proxy` object to be used in place of the admin page object. This object will correctly proxy all method calls to the underlying service from the container while holding off on creation of that service until it is actually needed.

**Access WordPress globals from the container**

Use the `WordPress_Provider` class to get access to frequently used WordPress globals from the container.

```
$container = new Metis\Container;
$container->register( new Metis\WordPress_Provider );

$container['wp'] === $GLOBALS['wp']; // true
```

`$wp`, `$wpdb`, `$wp_query`, `$wp_rewrite`, `$wp_filesystem` and `$wp_object_cache` are all added to the container.

Be careful about timing when using these - each will return null if it has not yet been defined.

###  Health Score

27

—

LowBetter than 47% of packages

Maintenance10

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~70 days

Recently: every ~103 days

Total

9

Last Release

3172d ago

PHP version history (3 changes)0.1.0PHP &gt;=7.0

0.1.1PHP &gt;=5.4

0.6.0PHP &gt;=5.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10903810?v=4)[ssnepenthe](/maintainers/ssnepenthe)[@ssnepenthe](https://github.com/ssnepenthe)

---

Top Contributors

[![ssnepenthe](https://avatars.githubusercontent.com/u/10903810?v=4)](https://github.com/ssnepenthe "ssnepenthe (125 commits)")

---

Tags

dependency-injectionphppimplewordpresswordpress-php-library

### Embed Badge

![Health badge](/badges/ssnepenthe-metis/health.svg)

```
[![Health](https://phpackages.com/badges/ssnepenthe-metis/health.svg)](https://phpackages.com/packages/ssnepenthe-metis)
```

###  Alternatives

[oat-sa/tao-core

TAO core extension

66140.1k108](/packages/oat-sa-tao-core)[jaxon-php/jaxon-core

Jaxon is an open source PHP library for easily creating Ajax web applications

73147.2k29](/packages/jaxon-php-jaxon-core)[ckfinder/ckfinder-laravel-package

CKFinder 3 package for Laravel

159517.6k67](/packages/ckfinder-ckfinder-laravel-package)[ckfinder/ckfinder-symfony-bundle

CKFinder bundle for Symfony

42448.0k](/packages/ckfinder-ckfinder-symfony-bundle)[inpsyde/wp-app-container

DI Container and related tools to be used at website level.

41267.6k](/packages/inpsyde-wp-app-container)[rockettheme/toolbox

RocketTheme Toolbox Library

22535.0k4](/packages/rockettheme-toolbox)

PHPackages © 2026

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