PHPackages                             unionofrad/li3\_behaviors - 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. unionofrad/li3\_behaviors

ActiveLithium-library[Framework](/categories/framework)

unionofrad/li3\_behaviors
=========================

Model behaviors for the li₃ PHP framework

v2.2.3(6y ago)41.0k14BSD-3-ClausePHPPHP ^5.4 || ^7

Since Apr 2Pushed 3y ago7 watchersCompare

[ Source](https://github.com/UnionOfRAD/li3_behaviors)[ Packagist](https://packagist.org/packages/unionofrad/li3_behaviors)[ RSS](/packages/unionofrad-li3-behaviors/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (2)Versions (17)Used By (4)

li₃ Behaviors
=============

[](#li-behaviors)

This library provides base classes for implementing model behaviors. Model behaviors provide a simple way to extend models. This pattern allow common logic to be encapsulated inside behaviors for keeping models light and composed only by its own business logic.

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

[](#installation)

The preferred installation method is via composer. You can add the library as a dependency via:

```
composer require unionofrad/li3_behaviors

```

li₃ plugins must be registered within your application bootstrap phase as they use a different (faster) autoloader.

```
Libraries::add('li3_behaviors')
```

The official manual has more information on [how to register the plugin](http://li3.me/docs/book/manual/1.x/installation/plugins)with the app or use alternative installation methods (i.e. via Git).

Usage
-----

[](#usage)

### Managing and Loading Behaviors

[](#managing-and-loading-behaviors)

First to add the ability of using behaviors in a model, use the behaviors trait in your model. After that define all behaviors you plan to use in the `$_actsAs` property of the model class.

```
// ...
class Posts extends \lithium\data\Model {

   use li3_behaviors\data\model\Behaviors;

   protected $_actsAs = [
       'Sluggable' => ['field' => 'slug', 'label' => 'title']
   ];

   // ...
```

The `Behaviors` trait also makes some static methods available in the model, which allows to manage behaviors as follows.

```
// Bind the sluggable behavior with configuration.
Posts::bindBehavior('Sluggable', ['field' => 'slug', 'label' => 'title']);

// Accessing configuration.
Posts::behavior('Sluggable')->config();
Posts::behavior('Sluggable')->config('field');

// Updating configuration.
Posts::behavior('Sluggable')->config('field', 'alt');

// Unbinding it again.
Posts::unbindBehavior('Sluggable');
```

### Creating a Behavior

[](#creating-a-behavior)

Now that we are able to load and manage behaviors we can create our own behavior which must extend the `Behavior` base class. In the following example we create a `Sluggable` behavior in `extensions/data/behavior/Sluggable.php`.

```
namespace app\extensions\data\behavior;

use lithium\util\Inflector;

class Sluggable extends \li3_behaviors\data\model\Behavior {

	protected static $_defaults = [
		'field' => 'slug',
		'label' => 'title'
	];

	protected static function _filters($model, $behavior) {
		Filters::apply($model, 'save', function($params, $next) use ($behavior) {
			$params['data'][$behavior->config('field')] = static::_generate(
				$params['data'][$behavior->config('label')]
			);
			return $next($params);
		});
	}

	protected static function _generate($value) {
		return strtolower(Inflector::slug($value));
	}
}
```

### Behavior Configuration

[](#behavior-configuration)

The configuration of each behavior can be accessed from within the behavior via `config()`. By default configuration for the behavior will be set automatically using the user provided configuration from the `$_actsAs`property of the model and the defaults provided in the behavior as `$_defaults`.

The defaults are merged with the provided configuration using simple array addition (`$config += $defaults`). If you want to change the way configuration is merged read further.

#### Providing Custom Configuration Logic

[](#providing-custom-configuration-logic)

Behaviors often come with different requirements towards configuration. In some cases just a 1-dimensional array needs to be merged in other cases nested multi-dimensional arrays must be merged or even normalized in a custom way.

That's why merging the defaults with the provided configuration can be controlled easily by yourself - the implementer. By default we do a simple one-dimensional merge adding defaults and configuration to eachother. To control configuration merging overwrite the `_config()` method of the base class.

In the following example we will normalize certain configuration options while merging with the behavior's defaults.

```
// ...

class Serializable extends \li3_behaviors\data\model\Behavior {

	protected static $_defaults = [
		'fields' => []
	];

	protected static function _config($model, $behavior, $config, $defaults) {
		$config += $defaults;
		$config['fields'] = Set::normalize($config['fields']);

		foreach ($config['fields'] as $field => &$pass) {
			if (!$pass) {
				$pass = 'json';
			}
		}
		return $config;
	}

	// ...
```

The `_config()` method gets the configuration and the defaults as defined in `$_defaults` as the 3rd and 4th parameters. The method must finally return the configuration that should be used for the behavior instance.

### Exposing Static Methods to the Model

[](#exposing-static-methods-to-the-model)

Any public static method present in the behavior is automically exposed on the model. This allows for adding methods to the model easily. Each static method that is exposed gets the name of the current model class as its first and the instance of the behavior as a second parameter.

This is useful if you i.e. need to query the model for results or when you want to retrieve configuration from the behavior.

The example below shows how we expose a token generation method to the model.

```
// ...

class TokenGenerator extends \li3_behaviors\data\model\Behavior {

	protected static $_defaults = [
		'short' => false
	];

	// Generates a random token either short (8 chars) or long (16 chars) and
	// returns it. Default expiration is one year.
	public static function token($model, $behavior) {
		$token = substr(md5(Random::generate(32)), 0, $behavior->config('short') ? 8 : 16);
		$expires = date('Y-m-d H:i:s', strtotime('+1 year'));

		return compact('token', 'expires');
	}

	// ...
```

### Exposing Instance Methods to the Model

[](#exposing-instance-methods-to-the-model)

Analog to exposing static methods, instance methods can also be exposed to the model easily. Any concrete method implemented in the behavior will be exposed. Each behavior method will in addition to the `$entity`parameter also receive the name of the model and an instance of the behavior as a second parameter i.e. to access configuration.

```
// ...

class Publishable extends \li3_behaviors\data\model\Behavior {

	protected static $_defaults = [
		'field' => 'is_published'
	];

	public function publish($model, $behavior, $entity) {
		$field = $behavior->config('field');
		$entity->{$field} = true;
	}

	// ...
```

#### Dynamically Adding Model Instance Methods

[](#dynamically-adding-model-instance-methods)

Sometimes you need to dynamically add methods to a model instance. I.e. when a field name of a behavior is user configurable and needs to be added as a method on the entity.

This can be achived by overwriting the `_methods()` method and returning an array of methods keyed by their alias on the model instance.

```
// ...

class Taggable extends \li3_behaviors\data\model\Behavior {
    // ...

	protected static function _methods($model, $behavior) {
		return [
			$behavior->config('field') => function() { /* ... */  }
		]
	}

	// ...
```

The above exemplaric behavior would then enable the following methods on each entity returned from the model.

```
Posts::bindBehavior('Taggable', ['field' => 'taxonomy']);
$item = Posts::create();
$item->taxonomy();
```

### Attaching Filters to the Model

[](#attaching-filters-to-the-model)

To modify existing model methods, filters should be used. If your behavior needs to use filters a good place to attach them is the behavior's `_filters()`method. Overwrite it to attach filters to the model during initialization phase.

```
// ...

class Timestamp extends \li3_behaviors\data\model\Behavior {
	// ...

	protected static function _filters($model, $behavior) {
		Filters::apply($model, 'save', function($params, $next) use ($behavior) {
			$params['data'] = static::_timestamp($behavior, $params['entity'], $params['data']);

			return $next($params);
		});
	}

	protected static function _timestamp($behavior, $entity, $data) {
		// ...
	}

	// ...
```

### Attaching Finders to the Model

[](#attaching-finders-to-the-model)

To add finders to the model's find method, finders should be used. If your behavior needs to use finders a good place to attach them is the behavior's `_finders()`method. Overwrite it to add finders to the model during initialization phase.

```
// ...

class Taggable extends \li3_behaviors\data\model\Behavior {
	// ...

	protected static function _finders($model, $behavior) {
		$model::finder('tag', function($params, $next) use ($behavior) {
			// ...
			return $next($params);
		});
	}

	// ...
```

Copyright &amp; License
-----------------------

[](#copyright--license)

Copyright 2010 Union of RAD. All rights reserved. This library is distributed under the terms of the BSD 3-Clause License. The full license text can be found in the LICENSE.txt file.

Credits for previous Implementations
------------------------------------

[](#credits-for-previous-implementations)

- David Persson, [https://github.com/davidpersson/li3\_behaviors](https://github.com/davidpersson/li3_behaviors)
- Nate Abele, [https://github.com/nateabele/li3\_behaviors](https://github.com/nateabele/li3_behaviors)
- Simon Jaillet, [https://github.com/jails/li3\_behaviors](https://github.com/jails/li3_behaviors)

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 84.2% 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 ~132 days

Recently: every ~108 days

Total

16

Last Release

2480d ago

Major Versions

v1.1.0 → v2.0.0-alpha2015-03-24

PHP version history (3 changes)v1.0.0PHP &gt;=5.4

v2.1.1PHP ^5.4

v2.1.2PHP ^5.4 || ^7

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/29702?v=4)[Marius Wilms](/maintainers/mariuswilms)[@mariuswilms](https://github.com/mariuswilms)

---

Top Contributors

[![mariuswilms](https://avatars.githubusercontent.com/u/29702?v=4)](https://github.com/mariuswilms "mariuswilms (85 commits)")[![jails](https://avatars.githubusercontent.com/u/1306941?v=4)](https://github.com/jails "jails (12 commits)")[![djordje](https://avatars.githubusercontent.com/u/1223357?v=4)](https://github.com/djordje "djordje (2 commits)")[![jamesgol](https://avatars.githubusercontent.com/u/6788517?v=4)](https://github.com/jamesgol "jamesgol (1 commits)")[![nateabele](https://avatars.githubusercontent.com/u/18288?v=4)](https://github.com/nateabele "nateabele (1 commits)")

---

Tags

pluginpluginlithiummodelBehaviorli3

### Embed Badge

![Health badge](/badges/unionofrad-li3-behaviors/health.svg)

```
[![Health](https://phpackages.com/badges/unionofrad-li3-behaviors/health.svg)](https://phpackages.com/packages/unionofrad-li3-behaviors)
```

###  Alternatives

[unionofrad/lithium

The li₃ PHP framework

1.2k181.9k49](/packages/unionofrad-lithium)[october/rain

October Rain Library

1601.7M73](/packages/october-rain)[helsingborg-stad/municipio

A bootstrap theme for creating municipality sites.

4028.3k10](/packages/helsingborg-stad-municipio)[offline/oc-mall-plugin

E-commerce solution for October CMS

1744.7k2](/packages/offline-oc-mall-plugin)[unionofrad/framework

The li₃ standard distribution, including overarching directory layout, starting application, and a copy of the framework.

1932.9k](/packages/unionofrad-framework)[lorenzo/linkable

CakePHP Linkable Behavior

2754.5k](/packages/lorenzo-linkable)

PHPackages © 2026

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