PHPackages                             itsmill3rtime/listify - 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. [Database &amp; ORM](/categories/database)
4. /
5. itsmill3rtime/listify

ActiveLibrary[Database &amp; ORM](/categories/database)

itsmill3rtime/listify
=====================

Turn any Eloquent model into a list! http://lookitsatravis.github.io/listify

1.2.3(6y ago)08MITPHPPHP &gt;=5.5.0

Since Dec 21Pushed 6y agoCompare

[ Source](https://github.com/itsmill3rtime/listify)[ Packagist](https://packagist.org/packages/itsmill3rtime/listify)[ RSS](/packages/itsmill3rtime-listify/feed)WikiDiscussions master Synced yesterday

READMEChangelog (1)Dependencies (7)Versions (15)Used By (0)

Listify
=======

[](#listify)

Turn any Eloquent model into a list!

Description
-----------

[](#description)

`Listify` provides the capabilities for sorting and reordering a number of objects in a list. The class that has this specified needs to have a `position` column defined as an integer on the mapped database table. `Listify` is an Eloquent port of the highly useful Ruby gem `acts_as_list` ([https://github.com/swanandp/acts\_as\_list](https://github.com/swanandp/acts_as_list)).

[![Build Status](https://camo.githubusercontent.com/0022fb5acb8484e7b4ffebfca9ea9dc6864000c9fcf6db9316cbb500aa00281f/68747470733a2f2f7472617669732d63692e6f72672f6c6f6f6b697473617472617669732f6c6973746966792e7376673f6272616e63683d6d6173746572)](https://secure.travis-ci.org/lookitsatravis/listify)[![Coverage Status](https://camo.githubusercontent.com/d60da86aefd10a7760a1a759dc1b043f9b55f733c2464898764844f1309b8937/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6c6f6f6b697473617472617669732f6c6973746966792f62616467652e706e67)](https://coveralls.io/r/lookitsatravis/listify)

[![Latest Stable Version](https://camo.githubusercontent.com/b9baf243f6cd058b9990f5cfe6de70d3951f5d319a27bd68cc4d697df52e02cb/68747470733a2f2f706f7365722e707567782e6f72672f6c6f6f6b697473617472617669732f6c6973746966792f762f737461626c652e706e67)](https://packagist.org/packages/lookitsatravis/listify)

- [Requirements](#requirements)
- [Installation](#installation)
- [Quick Start](#quickstart)
- [Overview](#overview)
- [Configuration](#configuration)
- [Notes](#notes)
- [Future Plans](#futureplans)
- [Contributing](#contributing)
- [Copyright](#copyright)

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

[](#requirements)

- `Listify` currently requires php &gt;= 5.5 (`Listify` is implemented via the use of traits).
- Laravel 5.0 or higher

> For use with Laravel 4, please use version 1.0.6.

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

[](#installation)

`Listify` is distributed as a composer package, which is how it should be used in your app.

Install the package using Composer. Edit your project's `composer.json` file to require `lookitsatravis/listify`.

```
  "require": {
    "laravel/framework": "~5.0",
    "lookitsatravis/listify": "~1.2"
  }
```

Once this operation completes, the final step is to add the service provider. Open `app/config/app.php`, and add a new item to the providers array.

```
    'Lookitsatravis\Listify\ListifyServiceProvider'
```

Optionally, you can define an alias to the `Listify` trait. Open `app/config/app.php`, and add a new item to the aliases array.

```
    'Listify' => 'Lookitsatravis\Listify\Listify'
```

Quickstart
----------

[](#quickstart)

First things first, you'll need to add a column to store the position. From the command line, use the migration generator:

```
php artisan listify:attach {table_name} {position_column_name}
php artisan migrate
```

> `{table_name}` is a required argument. `{position_column_name}` is optional and the default value is "position".

Then, in your model:

```
class User extends Eloquent
{
    use \Lookitsatravis\Listify\Listify;

    public function __construct(array $attributes = array(), $exists = false) {

        parent::__construct($attributes, $exists);

        $this->initListify();
    }
}
```

> Make sure that the `initListify()` method is called *after* `parent::__construct()` of your model.

That's all it takes to get access to the `Listify` hotness.

Overview
--------

[](#overview)

### Instance Methods Added To Eloquent Models

[](#instance-methods-added-to-eloquent-models)

You'll have a number of methods added to each instance of the Eloquent model to which `Listify` is added.

In `Listify`, "higher" means further up the list (a lower `position`), and "lower" means further down the list (a higher `position`). That can be confusing, so it might make sense to add tests that validate that you're using the right method given your context.

#### Methods That Change Position and Reorder List

[](#methods-that-change-position-and-reorder-list)

- `eloquentModel.insertAt(2)`
- `eloquentModel.moveLower()` will do nothing if the item is the lowest item
- `eloquentModel.moveHigher()` will do nothing if the item is the highest item
- `eloquentModel.moveToBottom()`
- `eloquentModel.moveToTop()`
- `eloquentModel.removeFromList()`

#### Methods That Change Position Without Reordering List Immediately

[](#methods-that-change-position-without-reordering-list-immediately)

###### Note: a changed position will still trigger updates to other items in the list once the model is saved

[](#note-a-changed-position-will-still-trigger-updates-to-other-items-in-the-list-once-the-model-is-saved)

- `eloquentModel.incrementPosition()`
- `eloquentModel.decrementPosition()`
- `eloquentModel.setListPosition(3)`

#### Methods That Return Attributes of the Item's List Position

[](#methods-that-return-attributes-of-the-items-list-position)

- `eloquentModel.isFirst()`
- `eloquentModel.isLast()`
- `eloquentModel.isInList()`
- `eloquentModel.isNotInList()`
- `eloquentModel.isDefaultPosition()`
- `eloquentModel.higherItem()`
- `eloquentModel.higherItems()` will return all the items above `eloquentModel` in the list (ordered by the position, ascending)
- `eloquentModel.lowerItem()`
- `eloquentModel.lowerItems()` will return all the items below `eloquentModel` in the list (ordered by the position, ascending)

\##Configuration

There are a few configuration options available. You'll need to pass these in as an array argument for `initListify()` in your model's constructor. Here are the options:

- `top_of_list` sets the integer position for the top of the list (default: `1`).
- `column` sets the name of your position column that you chose during installation (default: `'position'`).
- `add_new_at` sets the name of your position column that you chose during installation (default: `'bottom'`, options: `'top'` or `'bottom'`).
- `scope` allows you to scope the items in your list. This one requires a bit of elaboration. There are three posible values accepted:
    - `string`
    - `Illuminate\Database\Eloquent\Relations\BelongsTo` object
    - `Illuminate\Database\Query\Builder` object

---

\###String

If `string` is passed in, a raw string is passed in as a `whereRaw` to the scope. This allows you to do something like `'custom_foreign_key = 42'` and have all of the items scoped to that result set. You can pass as complicated of a where clause as you want, and it will be passed straight into each DB operation.

Example:

```
class User extends Eloquent
{
    use \Lookitsatravis\Listify\Listify;

    public function __construct(array $attributes = array(), $exists = false) {

        parent::__construct($attributes, $exists);

        $this->initListify([
            'scope' => 'answer_to_ltuae = 42'
        ]);
    }
}
```

Results in a scope of:

`WHERE answer_to_ltuae = 42`

---

\###Illuminate\\Database\\Eloquent\\Relations\\BelongsTo

If `Illuminate\Database\Eloquent\Relations\BelongsTo` is passed in, `Listify` will match up the foreign key of the scope to the value of the corresponding foreign key of the model instance.

Example:

```
class ToDoListItem extends Eloquent
{
    use \Lookitsatravis\Listify\Listify;

    public function __construct(array $attributes = array(), $exists = false) {

        parent::__construct($attributes, $exists);

        $this->initListify([
            'scope' => $this->toDoList()
        ]);
    }

    public function toDoList()
    {
        $this->belongsTo('ToDoList');
    }
}
```

Results in a scope of:

`WHERE to_do_list_id = {{value of toDoListItem.to_do_list_id}}`

---

\###Illuminate\\Database\\Query\\Builder

And lastly, if `Illuminate\Database\Query\Builder` is passed in, `Listify` will extract the where clause of the builder and use it as the scope of the `Listify` items. This scope type was added in an attempt to keep parity between the `acts_as_list` version and `Listify`; **however, due to differences in the languages and in ActiveRecord versus Eloquent, it is a limited implementation so far and needs impovement to be more flexible and secure. This is a big limitation and will be the first thing addressed in upcoming releases.**

This one is tricky, because in order for it to work the query objects `where` array is prepared with the bindings *outside of PDO* and then passed in as a raw string. So, please keep in mind that this route can open your application up to abuse if you are not careful about how the object is built. If you use direct user input, please sanitize the data before using this as a scope for `Listify`.

Example:

```
class ToDoListItem extends Eloquent
{
    use \Lookitsatravis\Listify\Listify;

    public function __construct(array $attributes = array(), $exists = false) {

        parent::__construct($attributes, $exists);

        $this->initListify([
            'scope' => DB::table($this->getTable())->where('type', '=', 'Not A List of My Favorite Porn Videos')
        ]);
    }
}
```

Results in a scope of:

`to_do_list_items.type = 'Not A List of My Favorite Porn Videos'`

---

### Changing the configuration

[](#changing-the-configuration)

You may also change any configuration value during runtime by using `$this->setListifyConfig('key', 'value');`. For example, to change the scope, you can do this:

```
$this->setListifyConfig('scope', 'what_does_the_fox_say = "ring ding ding ding"');
```

When an update is processed, the original scope will be used to remove the record from that list, and insert it into the new list scope. *Be careful here*. Changing the configuration during processing can have unpredictable effects.

Notes
-----

[](#notes)

All `position` queries (select, update, etc.) inside trait methods are executed without the default scope, this will prevent nasty issues when the default scope is different from `Listify` scope.

The `position` column is set after validations are called, so you should not put a `presence` validation on the `position` column.

Future Plans
------------

[](#future-plans)

- Add support for using a closure as a scope
- Update `Illuminate\Database\Query\Builder` scope to be more secure and flexible
- Additional features for the install command. Things like:
    - update the model with trait automatically (including init method in constructor)
    - generate (or add to) a controller with actions for each public method for `Listify`, including adding necessary routes. This would make it easy to, say, call something like `http://localhost:8000/foos/1/move_lower` through an AJAX-y front end.

Aside from that, I hope to just keep in parity with the Ruby gem `acts_as_list` ([https://github.com/swanandp/acts\_as\_list](https://github.com/swanandp/acts_as_list)) as necessary.

Contributing to `Listify`
-------------------------

[](#contributing-to-listify)

- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Composer.json, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
- I would recommend using Laravel 5.0 and higher for testing the build before a pull request.

Copyright
---------

[](#copyright)

Copyright (c) 2013-2017 Travis Vignon, released under the MIT license

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 83.7% 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 ~174 days

Recently: every ~398 days

Total

13

Last Release

2426d ago

PHP version history (2 changes)1.0.0PHP &gt;=5.4.0

1.2.0PHP &gt;=5.5.0

### Community

Maintainers

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

---

Top Contributors

[![lookitsatravis](https://avatars.githubusercontent.com/u/606978?v=4)](https://github.com/lookitsatravis "lookitsatravis (41 commits)")[![jwpage](https://avatars.githubusercontent.com/u/52687?v=4)](https://github.com/jwpage "jwpage (2 commits)")[![adamgoose](https://avatars.githubusercontent.com/u/611068?v=4)](https://github.com/adamgoose "adamgoose (2 commits)")[![vlczero](https://avatars.githubusercontent.com/u/2276235?v=4)](https://github.com/vlczero "vlczero (1 commits)")[![itsmill3rtime](https://avatars.githubusercontent.com/u/2539808?v=4)](https://github.com/itsmill3rtime "itsmill3rtime (1 commits)")[![stevendesu](https://avatars.githubusercontent.com/u/1384974?v=4)](https://github.com/stevendesu "stevendesu (1 commits)")[![jordanlev](https://avatars.githubusercontent.com/u/149992?v=4)](https://github.com/jordanlev "jordanlev (1 commits)")

---

Tags

laravelmodeleloquentlistorderpositionrailsacts\_as\_list

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/itsmill3rtime-listify/health.svg)

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

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[cybercog/laravel-ban

Laravel Ban simplify blocking and banning Eloquent models.

1.1k651.8k11](/packages/cybercog-laravel-ban)[pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

145360.2k4](/packages/pdphilip-elasticsearch)

PHPackages © 2026

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