PHPackages                             rougin/weasley - 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. rougin/weasley

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

rougin/weasley
==============

Helpers and utilities for Slytherin.

v0.7.1(11mo ago)02.9k1MITPHPPHP &gt;=5.3.0CI passing

Since Jan 5Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/rougin/weasley)[ Packagist](https://packagist.org/packages/rougin/weasley)[ Docs](https://roug.in/weasley/)[ RSS](/packages/rougin-weasley/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (5)Versions (21)Used By (1)

Weasley
=======

[](#weasley)

[![Latest Version on Packagist](https://camo.githubusercontent.com/423a511ecf60d6b6dc7278f956425b061c259dc5a78c1020a9335a6bd56521b4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f726f7567696e2f776561736c65792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rougin/weasley)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/rougin/weasley/blob/master/LICENSE.md)[![Build Status](https://camo.githubusercontent.com/733a4b52594c970a9e977f90a81b5dac60e98c909f6056c55f8a0370e42c7b5c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f726f7567696e2f776561736c65792f6275696c642e796d6c3f7374796c653d666c61742d737175617265)](https://github.com/rougin/weasley/actions)[![Coverage Status](https://camo.githubusercontent.com/bc8837fc6fe7095ee97fd63c645d6465b49bf759e3f2fedca0096238ef8647b9/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f726f7567696e2f776561736c65793f7374796c653d666c61742d737175617265)](https://app.codecov.io/gh/rougin/weasley)[![Total Downloads](https://camo.githubusercontent.com/25a55acd2bdb530c0f9b93083f2230842a0e6f3a108d119c328ae6f8b4a8b24e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f726f7567696e2f776561736c65792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rougin/weasley)

`Weasley` is a PHP package that provides generators, helpers, and utility classes for the [Slytherin](https://roug.in/slytherin/). Its goal is to improve the overall productivity when writing web applications based on `Slytherin` by reducing in writing code related to [CRUD operations](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete).

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

[](#installation)

Install `Weasley` through [Composer](https://getcomposer.org/):

```
$ composer require rougin/weasley
```

Basic usage
-----------

[](#basic-usage)

`Weasley` is built on a layered architecture where each domain delegates to a dedicated package:

PackagePurpose[Slytherin](https://github.com/rougin/slytherin)Simple, extensible PHP micro-framework.[Onion](https://github.com/rougin/onion)HTTP middlewares for Slytherin.[Valla](https://github.com/rougin/valla)A simple validation package in PHP.[Blueprint](https://github.com/rougin/blueprint)A bootstrap for PHP console projects.[Classidy](https://github.com/rougin/classidy)Create PHP classes using PHP.Code generators
---------------

[](#code-generators)

`Weasley` provides commands that generate code for Slytherin components. These commands allow `Slytherin` to be a rapid prototyping tool when creating web-based applications.

Use the `weasley` command to access the list of its available commands:

```
$ vendor/bin/weasley
```

### Available commands

[](#available-commands)

CommandDescription`make:check`Creates a new validation (`Check`) class`make:handler`Creates a new [HTTP Middleware](https://github.com/rougin/slytherin/wiki/Middleware) class`make:package`Creates a new [Slytherin Integration](https://github.com/rougin/slytherin/wiki/IntegrationInterface-Implementation) class`make:route`Creates a new [HTTP route](https://github.com/rougin/slytherin/wiki/Defining-HTTP-Routes) classEach command accepts the following options:

```
$ vendor/bin/weasley make:check UserCheck --path src/Checks --namespace App\Checks --author "John Doe"
```

OptionDefaultDescription`--path``src/Checks`Directory where the file will be created`--namespace``App\Checks`Namespace for the generated class`--author`*(empty)*Author name in the class docblockHTTP routes
-----------

[](#http-routes)

`Weasley` provides classes for creating HTTP routes in the [RESTful](https://en.wikipedia.org/wiki/REST) style. In other PHP frameworks, these are also known as *Controllers*.

### `HttpRoute`

[](#httproute)

A simple HTTP route class that provides a `json()` helper for returning JSON responses:

```
use Rougin\Weasley\Route;

class Welcome extends Route
{
    public function index()
    {
        $data = array('message' => 'Hello world!');

        return $this->json($data);
    }
}
```

The `Route` class is a root-namespace alias for `Rougin\Weasley\Routes\HttpRoute`. It accepts the PSR-07 request and response through its constructor:

```
/** @var \Psr\Http\Message\ServerRequestInterface */
$request = /** ... */;

/** @var \Psr\Http\Message\ResponseInterface */
$response = /** ... */;

$route = new Welcome($request, $response);

/** @var \Psr\Http\Message\ResponseInterface */
$result = $route->index();
```

### `JsonRoute`

[](#jsonroute)

Extends `HttpRoute` with built-in CRUD operations backed by an Eloquent model and a validator:

```
use Rougin\Weasley\Routes\JsonRoute;

class UsersRoute extends JsonRoute
{
    protected $model = 'Acme\Models\User';

    protected $mutator = 'Rougin\Weasley\Mutators\RestMutator';

    protected $validator = 'Acme\Checks\UserCheck';
}
```

Once defined, the following methods become available:

MethodHTTP EquivalentDescription`index()``GET /users`Returns all records (paginated when `illuminate/pagination` is installed)`show($id)``GET /users/{id}`Returns a single record`store()``POST /users`Creates a new record from the parsed request body`update($id)``PUT /users/{id}`Updates an existing record`delete($id)``DELETE /users/{id}`Deletes a recordThe `$model` must be an Eloquent model with `$fillable` defined. The `$validator` must be a `Check` subclass. Both are validated at construction time and will throw `UnexpectedValueException` if missing.

HTTP handlers
-------------

[](#http-handlers)

`Weasley` provides HTTP middlewares (handlers) that process incoming requests and outgoing responses. Each handler implements `Rougin\Slytherin\Middleware\MiddlewareInterface`.

Note

Starting v0.8, all handler classes are thin wrappers over [Onion](https://github.com/rougin/onion) (`rougin/onion`). Every feature described below originates from Onion's classes.

### `AllowCrossOrigin`

[](#allowcrossorigin)

Adds [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) headers to every response:

```
use Rougin\Weasley\Handlers\AllowCrossOrigin;

// Default: allows all origins, allows GET/POST/PUT/DELETE/OPTIONS
$cors = new AllowCrossOrigin;

// Restrict to specific origins and methods via constructor
$cors = new AllowCrossOrigin(
    array('https://example.com', 'https://api.example.com'),
    array('GET', 'POST')
);

// Or configure fluently
$cors = (new AllowCrossOrigin)
    ->allowed(array('https://example.com'))
    ->methods(array('GET', 'POST', 'DELETE'));
```

Note

If the incoming request method is `OPTIONS`, the handler returns an empty response immediately (preflight support).

### `EmptyStringToNull`

[](#emptystringtonull)

Converts empty, `"null"`, and `"undefined"` string values from query parameters and parsed body to actual `null`:

```
use Rougin\Weasley\Handlers\EmptyStringToNull;

$handler = new EmptyStringToNull;
// query params: ?age=&name=null&role=undefined
// becomes:      ['age' => null, 'name' => null, 'role' => null]
```

### `JsonContentType`

[](#jsoncontenttype)

Sets the `Content-Type` header to `application/json` on every response that does not already have one:

```
use Rougin\Weasley\Handlers\JsonContentType;

$handler = new JsonContentType;
// Response header: Content-Type: application/json
```

### `MutateRequest`

[](#mutaterequest)

An extensible base class for transforming request values. Extend it and override the `transform()` method:

```
use Rougin\Weasley\Handlers\MutateRequest;

class SanitizeHtml extends MutateRequest
{
    protected function transform($value)
    {
        return is_string($value) ? strip_tags($value) : $value;
    }
}
```

The `transform()` method is called recursively on every value in query parameters and the parsed body. Arrays are recursed into automatically.

### `SpoofHttpMethod`

[](#spoofhttpmethod)

Replaces the HTTP verb of the request with the value of a configurable key from the parsed body, enabling HTML forms to simulate `PATCH`, `PUT`, or `DELETE`:

```
use Rougin\Weasley\Handlers\SpoofHttpMethod;

// Default key is "_method"
$spoof = new SpoofHttpMethod;

// Use a custom key
$spoof = new SpoofHttpMethod('_action');
// or fluently: $spoof->key('_action');
```

When the request body contains `['_method' => 'PATCH']`, the request method becomes `PATCH`.

### `TrimStringValue`

[](#trimstringvalue)

Trims whitespace from all string values in query parameters and the parsed body:

```
use Rougin\Weasley\Handlers\TrimStringValue;

$handler = new TrimStringValue;
// query params: ?name=  Rougin
// becomes:      ['name' => 'Rougin']
```

Validation
----------

[](#validation)

`Weasley` provides the `Check` class for validating data. It is built on [Valla](https://github.com/rougin/valla) (`rougin/valla`) and supports all rules from Valla's rule engine (e.g., `required`, `email`, and more):

```
$check = new UserCheck;

$data = /* e.g., from request */;

if ($check->valid($data))
{
    // Data passed validation
}
else
{
    // Get all errors: array
    $errors = $check->errors();

    // Get the first error only
    echo $check->firstError(); // e.g., "Age is required"
}
```

Error messages are built from the label and the rule description. For example, a missing `email` field with the label `"Email"` produces `"Email is required"`.

### Method-based style (recommended)

[](#method-based-style-recommended)

The method-based style is recommended when rules depend on the submitted data (e.g., conditionally requiring a field):

```
use Rougin\Weasley\Check;

class UserCheck extends Check
{
    /**
     * @return array
     */
    public function labels()
    {
        return array(
            'name' => 'Name',
            'email' => 'Email',
            'age' => 'Age',
        );
    }

    /**
     * @param array $data
     *
     * @return array
     */
    public function rules(array $data)
    {
        $rules = array(
            'name' => 'required',
            'email' => 'required|email',
            'age' => 'required|numeric|min:18',
        );

        return $rules;
    }
}
```

### Property-based style (legacy)

[](#property-based-style-legacy)

This can also define rules and labels as protected properties for simple, static rule sets:

```
use Rougin\Weasley\Check;

class SimpleCheck extends Check
{
    protected $labels = array(
        'name' => 'Name',
        'email' => 'Email',
    );

    protected $rules = array(
        'name' => 'required',
        'email' => 'required|email',
    );
}
```

Mutators
--------

[](#mutators)

Mutators transform data into a specified output format (e.g., PSR-07 responses, API payloads). They implement `Rougin\Weasley\Contract\Mutator`.

### `JsonMutator`

[](#jsonmutator)

Encodes data as JSON and returns a PSR-07 response:

```
use Rougin\Weasley\Mutators\JsonMutator;

$mutator = new JsonMutator($response);
$result = $mutator->mutate(array('status' => 'success'));
// Content-Type: application/json
// Body: {"status":"success"}
```

A second argument accepts [JSON encoding options](https://www.php.net/manual/en/json.constants.php):

```
$mutator = new JsonMutator($response, JSON_PRETTY_PRINT);
```

### `RestMutator`

[](#restmutator)

Formats paginated results following [PayPal's API Style Guide](https://web.archive.org/web/20220114091735/https://github.com/paypal/api-standards/blob/master/api-style-guide.md):

```
use Rougin\Weasley\Mutators\RestMutator;

$mutator = new RestMutator;
$result = $mutator->mutate($paginator);

// $result becomes:
// [
//     'total_items' => 100,
//     'total_pages' => 10,
//     'items' => [...],
// ]
```

When the data is not a `LengthAwarePaginator`, the mutator wraps it as `['items' => $data]`.

Third-party packages
--------------------

[](#third-party-packages)

`Weasley` provides `IntegrationInterface` implementations for wiring third-party packages into Slytherin's container.

### `Laravel\Eloquent`

[](#laraveleloquent)

Enables [Eloquent ORM](https://laravel.com/docs/eloquent) from [Laravel](https://laravel.com):

```
$ composer require illuminate/database
```

```
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Weasley\Packages\Laravel\Eloquent;

$config = new Configuration;
$config->set('database.default', 'sqlite');
$config->set('database.sqlite.driver', 'sqlite');
$config->set('database.sqlite.database', ':memory:');

$container = new Container;
(new Eloquent)->define($container, $config);

// Eloquent models are now available globally
$users = User::all();
```

### `Laravel\Blade`

[](#laravelblade)

Enables [Blade](https://laravel.com/docs/blade) templating:

```
$ composer require illuminate/view
```

```
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Weasley\Packages\Laravel\Blade;

$config = new Configuration;
$config->set('illuminate.view.templates', __DIR__ . '/templates');
$config->set('illuminate.view.compiled', __DIR__ . '/cache');

$container = new Container;
(new Blade)->define($container, $config);

// Resolve the renderer from the container
$renderer = $container->get('Rougin\Weasley\Renderers\BladeRenderer');
echo $renderer->render('welcome', array('name' => 'Rougin'));
```

### `Laravel\Paginate`

[](#laravelpaginate)

Adds pagination support to Eloquent models:

```
$ composer require illuminate/pagination
```

```
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Weasley\Packages\Laravel\Paginate;

// Assuming Eloquent is already booted (see above)
$container = new Container;
(new Paginate)->define($container, new Configuration);

// Eloquent models now have a paginate() method
$paginator = User::paginate(10); // 10 per page

echo $paginator->total();      // total records
echo $paginator->currentPage(); // current page number
```

### `Session`

[](#session)

Provides session management through `SessionHandlerInterface`:

```
use Rougin\Slytherin\Container\Container;
use Rougin\Slytherin\Integration\Configuration;
use Rougin\Weasley\Packages\Session;

$config = new Configuration;
$config->set('session.cookies', array());
$config->set('session.expiration', 3600);
$config->set('session.path', __DIR__ . '/sessions');

$container = new Container;
(new Session)->define($container, $config);

// Resolve the session from the container ---
$class = 'Rougin\Weasley\Contract\Session';

$session = $container->get($class);
// ------------------------------------------

$session->set('user_id', 42);
echo $session->get('user_id'); // 42

$session->regenerate();      // rotate session ID
$session->delete('user_id'); // remove a key
```

Contracts
---------

[](#contracts)

`Weasley` defines interfaces for its extensible components:

### `Contract\Mutator`

[](#contractmutator)

```
namespace Rougin\Weasley\Contract;

interface Mutator
{
    /**
     * @param mixed $data
     * @return mixed
     */
    public function mutate($data);
}
```

Implement this interface to create custom mutators. `JsonMutator` and `RestMutator` are built-in implementations.

### `Contract\Session`

[](#contractsession)

```
namespace Rougin\Weasley\Contract;

interface Session
{
    /**
     * @param string $key
     * @param mixed  $default
     * @return mixed
     */
    public function get($key, $default = null);

    /**
     * @param string $key
     * @param mixed  $value
     * @return self
     */
    public function set($key, $value);

    /**
     * @param string $key
     * @return boolean
     */
    public function delete($key);

    /**
     * @param boolean $delete
     * @return boolean
     */
    public function regenerate($delete = false);
}
```

Utilities
---------

[](#utilities)

### `Random`

[](#random)

Generates cryptographically secure random strings:

```
use Rougin\Weasley\Assorted\Random;

$token = Random::make(32); // e.g., "a7f3b9c2d1e8..."
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](https://github.com/rougin/weasley/blob/master/CHANGELOG.md) for more recent changes.

Upgrade Guide
-------------

[](#upgrade-guide)

As `Weasley` continues to evolve, there might be some breaking changes in its internal code during development. The said changes can be found in [UPGRADING](https://github.com/rougin/weasley/blob/master/UPGRADING.md).

Contributing
------------

[](#contributing)

See [CONTRIBUTING](https://github.com/rougin/weasley/blob/master/CONTRIBUTING.md) on how to contribute.

License
-------

[](#license)

The MIT License (MIT). Please see [LICENSE](https://github.com/rougin/weasley/blob/master/LICENSE.md) for more information.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance75

Regular maintenance activity

Popularity18

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity57

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 ~145 days

Recently: every ~665 days

Total

20

Last Release

340d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c7721589a958a1fbcef1b527c794d820d75b82988f14b2ed86a1c6904d76a59e?d=identicon)[rougin](/maintainers/rougin)

---

Top Contributors

[![rougin](https://avatars.githubusercontent.com/u/6078637?v=4)](https://github.com/rougin "rougin (429 commits)")

---

Tags

php-generatorphp-helpersslytherinweasleyworkflowhelperutilitygeneratorworkflow

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/rougin-weasley/health.svg)

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

###  Alternatives

[bocharsky-bw/arrayzy

A native PHP arrays easy manipulation library in OOP way.

38427.7k](/packages/bocharsky-bw-arrayzy)[bocharsky-bw/file-naming-resolver

A lightweight library which helps to resolve a file/directory naming of uploaded files using various naming strategies.

1134.9k](/packages/bocharsky-bw-file-naming-resolver)

PHPackages © 2026

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