PHPackages                             64robots/webforms - 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. 64robots/webforms

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

64robots/webforms
=================

Backend for 64 Robots webforms.

0.1.1(5y ago)73MITPHPPHP ^7.4

Since Oct 1Pushed 5y ago6 watchersCompare

[ Source](https://github.com/64robots/webforms)[ Packagist](https://packagist.org/packages/64robots/webforms)[ Docs](https://github.com/64robots/webforms)[ RSS](/packages/64robots-webforms/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (11)Versions (10)Used By (0)

Backend for 64 Robots webforms
==============================

[](#backend-for-64-robots-webforms)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2bf893f1ae315c0d21fa695eae779b598d73ffd6ff95e2d0da5a1adb1f09f835/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f3634726f626f74732f776562666f726d732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/64robots/webforms)[![MIT Licensed](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![GitHub Tests Action Status](https://camo.githubusercontent.com/94a7e5a0e482993900b340b04cbd90d969aab311c6ffae7bf39813fa0a06da86/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f3634726f626f74732f776562666f726d732f72756e2d74657374733f6c6162656c3d7465737473)](https://github.com/64robots/webforms/actions?query=workflow%3Arun-tests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/8b5f452d1f0b4067c8d258f446f42ab3469f373700e6ff3553bb149a2753110a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f3634726f626f74732f776562666f726d732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/64robots/webforms)

Package to rapidly create custom forms. This package provides you an easy way to start the backend for an SPA Form. You could create forms, form steps and questions. Your users could respond to these forms. Made by [64 Robots](https://64robots.com).

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

[](#installation)

You can install the package via composer:

```
composer require 64robots/webforms
```

You can publish and run the migrations with:

```
php artisan vendor:publish --provider="R64\Webforms\WebformsServiceProvider" --tag="migrations"
php artisan migrate
```

You can publish the config file with:

```
php artisan vendor:publish --provider="R64\Webforms\WebformsServiceProvider" --tag="config"
```

This is the contents of the published `webforms.php` config file:

```
use R64\Webforms\QuestionTypes\EmailType;
use R64\Webforms\QuestionTypes\PhoneType;

return [
    'date_format' => 'Y-m-d',
    'year_month_format' => 'Y-m',
    'fields_to_be_confirmed' => [
        EmailType::TYPE,
        PhoneType::TYPE,
    ],
    'user_model' => 'App\User',
];
```

Usage
-----

[](#usage)

1 - Add Routes

At the moment, the package doesn't work with anonymous users. Please, add that to your routes file under an auth middleware:

```
Route::webforms('webforms');
```

If you want routes to create Forms, FormSteps and Questions, add that under the appropriate middleware in your routes file:

```
Route::webformsAdmin('webforms-admin');
```

2 - Add `HasWebForms` trait in your user entity.

3 - Create Seeders for Form, FormSteps and Question.

Example
-------

[](#example)

Let's start a new form to collect info about coffee in your app:

We will add in `routes/api.php`:

```
Route::webforms('webforms');
```

We will also add in `routes/api_admin.php`:

```
Route::webformsAdmin('webforms-admin');
```

The next step is to add a new Form. Just create a new Seeder.

```
php artisan make:seeder CoffeeSeeder

```

Now in the Seeder file `database/seeders/CoffeeSeeder` we'll include the creation of the form, form steps and questions.

Let's start with the form creation:

```
use R64\Webforms\Models\Form;

$coffeeForm = Form::build('Coffee Form')
    ->save();
```

Once we have the `form` we'll need to add, at least, a form step:

```
use R64\Webforms\Models\FormStep;

$coffeeStep = FormStep::build($coffeeForm, 'Coffee')
    ->save();
```

Then we can add `questions` to this step:

```
use R64\Webforms\Models\Question;
use R64\Webforms\QuestionTypes\OptionsType;

$whatKindOfCoffeeDoYouLikeQuestion = Question::build($coffeeStep, 'What kind of coffee do you like?')
    ->type(OptionsType::TYPE)
    ->options([
        'black' => 'Black',
        'latte' => 'Latte',
        'capuccino' => 'Cappucino',
        'americano' => 'Americano',
        'red-eye' => 'Red Eye',
        'flat-white' => 'Flat White',
     ])
    ->save();

$whatTypeOfBeansDoYouLikeQuestion = Question::build($coffeeStep, 'What type of coffee beans do you like the most?')
    ->type(OptionsType::TYPE)
    ->options([
        'arabica' => 'Arabica',
        'robusta' => 'Robusta',
    ])
    ->save();
```

Add now a new step to collect some personal info. We'll encrypt that info in the database:

```
use R64\Webforms\Models\FormStep;

$personalInfoStep = FormStep::build($coffeeForm, 'Personal info')
    ->isPersonalData(1)
    ->save();
```

Then add the questions:

```
use R64\Webforms\Models\Question;
use R64\Webforms\QuestionTypes\IntegerType;

$firstNameQuestion = Question::build($personalInfoStep, 'First Name')
    ->save();

$lastNameQuestion = Question::build($personalInfoStep, 'Last Name')
    ->save();

$ageQuestion = Question::build($personalInfoStep, 'Birth Year')
    ->type(IntegerType::TYPE)
    ->save();
```

Once we have that, we can add the questions steps to users:

```
User::all()->each->addFormSteps([$coffeeStep, $personalInfoStep]);
```

If we want to add all the formSteps to the users we can also use:

```
User::all()->each->addFormSteps();
```

When the users ask for the forms they will get only the forms they had steps on it. We need to do an authenticated request to:

`/webforms/forms`

We'll get something like:

```
{
    "data": [
        {
            "id": 1,
            "sort": 1,
            "slug": "coffee-form",
            "menu_title": null,
            "title": "Coffee Form",
            "description": null,
            "completed": false
        }
    ]
}
```

Let's say the form is the one with id 1. Then we can make another one to:

`/webforms/form-steps?form=1`

We'll obtain all the forms steps info:

```
{
    "data": [
        {
            "id": 1,
            "form": {
                "id": 1,
                "sort": 1,
                "slug": "coffee-form",
                "menu_title": "",
                "title": "Coffee Form",
                "description": "",
                "completed": false
            },
            "sort": 1,
            "slug": "coffee",
            "menu_title": null,
            "title": "Coffee",
            "description": "",
            "completed": false
        },
        {
            "id": 2,
            "form": {
                "id": 1,
                "sort": 1,
                "slug": "coffee-form",
                "menu_title": null,
                "title": "Coffee Form",
                "description": null,
                "completed": false
            },
            "sort": 2,
            "slug": "personal-info",
            "menu_title": null,
            "title": "Personal info",
            "description": null,
            "completed": false
        }
    ]
}
```

For each form step we need to ask for the questions using:

`/webforms/questions?form_step=1`

```
{
    "data": [
        {
            "id": 1,
            "form_step": {
                "id": 1,
                "sort": 1,
                "slug": "coffee",
                "menu_title": null,
                "title": "Coffee",
                "description": "",
                "completed": false
            },
            "sort": 1,
            "depends_on": null,
            "shown_when": null,
            "required": false,
            "slug": "what-kind-of-coffee-do-you-like",
            "group_by": null,
            "group_by_description": null,
            "label_position": "left",
            "help_title": null,
            "help_body": null,
            "type": "options",
            "post_input_text": null,
            "title": "What kind of coffee do you like?",
            "description": null,
            "error_message": null,
            "default_value": null,
            "min": null,
            "max": null,
            "options": [
                {
                    "label": "Black",
                    "value": "black"
                },
                {
                    "label": "Latte",
                    "value": "latte"
                },
                {
                    "label": "Cappucino",
                    "value": "capuccino"
                },
                {
                    "label": "Americano",
                    "value": "americano"
                },
                {
                    "label": "Red Eye",
                    "value": "red-eye"
                },
                {
                    "label": "Flat White",
                    "value": "flat-white"
                }
            ],
            "answer": {}
        },
        {
            "id": 2,
            "form_step": {
                "id": 1,
                "sort": 1,
                "slug": "coffee",
                "menu_title": null,
                "title": "Coffee",
                "description": "",
                "completed": false
            },
            "sort": 2,
            "depends_on": null,
            "shown_when": null,
            "required": false,
            "slug": "what-type-of-coffee-beans-do-you-like-the-most",
            "group_by": null,
            "group_by_description": null,
            "label_position": "left",
            "help_title": null,
            "help_body": null,
            "type": "options",
            "post_input_text": null,
            "title": "What type of coffee beans do you like the most?",
            "description": null,
            "error_message": null,
            "default_value": null,
            "min": null,
            "max": null,
            "options": [
                {
                    "label": "Arabica",
                    "value": "arabica"
                },
                {
                    "label": "Robusta",
                    "value": "robusta"
                }
            ],
            "answer": {}
        }
    ]
}
```

We need to do the same with the personal info step:

`/webforms/questions?form_step=2`

```
{
    "data": [
        {
            "id": 3,
            "form_step": {
                "id": 2,
                "sort": 2,
                "slug": "personal-info",
                "menu_title": null,
                "title": "Personal info",
                "description": "",
                "completed": false
            },
            "sort": 3,
            "depends_on": null,
            "shown_when": null,
            "required": false,
            "slug": "first-name",
            "group_by": null,
            "group_by_description": null,
            "label_position": "left",
            "help_title": null,
            "help_body": null,
            "type": "text",
            "post_input_text": null,
            "title": "First Name",
            "description": null,
            "error_message": null,
            "default_value": null,
            "min": null,
            "max": null,
            "options": null,
            "answer": {}
        },
        {
            "id": 4,
            "form_step": {
                "id": 2,
                "sort": 2,
                "slug": "personal-info",
                "menu_title": null,
                "title": "Personal info",
                "description": "",
                "completed": false
            },
            "sort": 4,
            "depends_on": null,
            "shown_when": null,
            "required": false,
            "slug": "last-name",
            "group_by": null,
            "group_by_description": null,
            "label_position": "left",
            "help_title": null,
            "help_body": null,
            "type": "text",
            "post_input_text": null,
            "title": "Last Name",
            "description": null,
            "error_message": null,
            "default_value": null,
            "min": null,
            "max": null,
            "options": null,
            "answer": {}
        },
        {
            "id": 5,
            "form_step": {
                "id": 1,
                "sort": 1,
                "slug": "coffee",
                "menu_title": null,
                "title": "Coffee",
                "description": "",
                "completed": false
            },
            "sort": 4,
            "depends_on": null,
            "shown_when": null,
            "required": false,
            "slug": "birth-year",
            "group_by": null,
            "group_by_description": null,
            "label_position": "left",
            "help_title": null,
            "help_body": null,
            "type": "integer",
            "post_input_text": null,
            "title": "Birth Year",
            "description": null,
            "error_message": null,
            "default_value": null,
            "min": null,
            "max": null,
            "options": null,
            "answer": {}
        }
    ]
}
```

When a user needs to send an answer to a question, we will need to make a POST request to:

`/webforms/answers`

With the following payload:

```
{
    "question_id": 2,
    "text": "arabica"
}
```

We will receive the question but now with an answer on it:

```
{
    "data": {
        "id": 2,
        "form_step": {
            "id": 1,
            "sort": 1,
            "slug": "coffee",
            "menu_title": null,
            "title": "Coffee",
            "description": "",
            "completed": false
        },
        "sort": 2,
        "depends_on": null,
        "shown_when": null,
        "required": false,
        "slug": "what-type-of-coffee-beans-do-you-like-the-most",
        "group_by": null,
        "group_by_description": null,
        "label_position": "left",
        "help_title": null,
        "help_body": null,
        "type": "options",
        "post_input_text": null,
        "title": "What type of coffee beans do you like the most?",
        "description": null,
        "error_message": null,
        "default_value": null,
        "min": null,
        "max": null,
        "options": [
            {
                "label": "Arabica",
                "value": "arabica"
            },
            {
                "label": "Robusta",
                "value": "robusta"
            }
        ],
        "answer": {
            "id": 123,
            "user_id": 10,
            "question_id": 2,
            "text": "arabica",
            "confirmed": true
        }
    }
}
```

Testing
-------

[](#testing)

Copy `phpunit.xml.dist` to `phpunit.xml`

```
cp phpunit.xml.dist phpunit.xml
```

Adapt or change the values in the next portion of code to your preferences:

```

```

Create the database, in this case `r64_webforms`.

Execute:

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

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

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [64 Robots](https://github.com/64Robots)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

Acknowledgments
---------------

[](#acknowledgments)

Thanks to [Spatie](https://spatie.be/) for the [Package Skeleton Laravel](https://github.com/spatie/package-skeleton-laravel).

###  Health Score

24

—

LowBetter than 30% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.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 ~5 days

Total

2

Last Release

1876d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/88e19e84d31e5f50eb2e338915669ae04f507a643fa24f88afc870520d8bef23?d=identicon)[64robots](/maintainers/64robots)

---

Top Contributors

[![mmanzano](https://avatars.githubusercontent.com/u/1055699?v=4)](https://github.com/mmanzano "mmanzano (85 commits)")[![NtimYeboah](https://avatars.githubusercontent.com/u/8011922?v=4)](https://github.com/NtimYeboah "NtimYeboah (1 commits)")

---

Tags

laravelWebForms

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/64robots-webforms/health.svg)

```
[![Health](https://phpackages.com/badges/64robots-webforms/health.svg)](https://phpackages.com/packages/64robots-webforms)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k57.2M683](/packages/laravel-scout)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9922.4M146](/packages/roots-acorn)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

265.2k](/packages/aedart-athenaeum)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[forjedio/inertia-table

Backend-driven dynamic tables for Laravel + Inertia.js

272.0k](/packages/forjedio-inertia-table)

PHPackages © 2026

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