Easily integrate custom-made NPS (Net Promoter Score) into your application

Overview

Social Card of Laravel NPS

Laravel NPS

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Easily integrate custom-made NPS (Net Promoter Score) to your application.

Installation

You can install the package via composer:

composer require maize-tech/laravel-nps

You can publish and run the migrations with:

php artisan vendor:publish --tag="nps-migrations"
php artisan migrate

You can publish the config file with:

php artisan vendor:publish --tag="nps-config"

This is the contents of the published config file:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Nps model
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the nps model class.
    |
    */

    'nps_model' => Maize\Nps\Models\Nps::class,

    /*
    |--------------------------------------------------------------------------
    | Nps answer model
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the nps answer
    | model class.
    |
    */

    'nps_answer_model' => Maize\Nps\Models\NpsAnswer::class,

    /*
    |--------------------------------------------------------------------------
    | Nps finder
    |--------------------------------------------------------------------------
    |
    | Here you may specify the fully qualified class name of the nps finder class.
    |
    */

    'nps_finder' => Maize\Nps\DefaultNpsFinder::class,

    /*
    |--------------------------------------------------------------------------
    | Nps visibility
    |--------------------------------------------------------------------------
    |
    | Here you may associate a custom visibility class to a name, which is then
    | used as a reference in the nps model.
    |
    */

    'visibility' => [
        'default' => Maize\Nps\DefaultNpsVisibility::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Nps range
    |--------------------------------------------------------------------------
    |
    | Here you may associate a custom range class to a name, which is then
    | used as a reference in the nps model.
    |
    */

    'range' => [
        'default' => Maize\Nps\DefaultNpsRange::class,
        'minimal' => Maize\Nps\MinimalNpsRange::class,
        'emoji' => Maize\Nps\EmojiNpsRange::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Route configurations
    |--------------------------------------------------------------------------
    |
    | Here you may specify whether routes should be enabled or not.
    | You can also customize the routes prefix and middlewares.
    |
    */

    'routes' => [
        'enabled' => true,
        'prefix' => '',
        'name' => 'nps',
        'middleware' => ['auth:api'],
        'endpoints' => [
            'show' => [
                'middleware' => [],
            ],
            'answer' => [
                'middleware' => [],
            ],
            'delay' => [
                'middleware' => [],
            ],
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Cache
    |--------------------------------------------------------------------------
    |
    | Here you may specify the amount of time, in seconds, where each nps
    | is cached to avoid multiple database queries.
    |
    */

    'cache' => [
        'nps_ttl' => 3600,
        'nps_answer_ttl' => 3600,
    ],
];

Usage

Basic

To use the package, add the Maize\Nps\CanAnswerNps trait to the User model.

Here's an example model including the CanAnswerNps trait:

<?php

namespace App\Models;

use Maize\Nps\CanAnswerNps;

class User extends Model
{
    use CanAnswerNps;

    protected $fillable = [
        'fist_name',
        'last_name',
        'email',
    ];
}

You can then create one or multiple NPS from the DB or, if you wish, you could handle the creation with a CMS.

Here are the fields who should be filled:

  • question: the question that identifies the NPS
  • starts_at: the start date of the NPS
  • ends_at: the end date of the NPS
  • range: the value ranges accepted for the given NPS. This value must be equal to one of the keys defined in the range list from config/nps.php. Defaults to default.
  • visibility: the visibility for the given NPS. This value must be equal to one of the keys defined in the visibility list from config/nps.php. Defaults to default.

Let's say we create a NPS which starts on 2021-01-01 and ends after a week: here's the model entity we would have:

$nps = [
    "id" => 1,
    "question" => "How would you rate our platform?",
    "starts_at" => "2021-01-01",
    "ends_at" => "2021-01-31",
    "range" => "default", // default range is 1-5
    "visibility" => "default", // by default a NPS is always visible
    "updated_at" => "2021-01-01",
    "created_at" => "2021-01-01",
];

You can now call the custom API to retrieve, reply or delay the current NPS, which can be customized in config/nps.php:

GET - /nps

This endpoint retrieves the current NPS using the given criteria:

  • the starts_at date must be earlier than now()
  • the ends_at date must be older than now()
  • the NPS must be visible (defaults to true)

The NPS entries are then filtered by their ends_at date in order to pick the first one expiring.

The response contains the NPS id (used for the POST route), the question, and the accepted values. Here is a sample response body:

{
    "data": {
        "id": 1,
        "values": [
            1,
            2,
            3,
            4,
            5
        ],
        "question": "How would you rate our platform?"
    }
}

POST - /nps/{id}

This endpoint stores the answer for the given NPS from the currently authenticated user. The request requires the following attributes:

  • value: the value chose by the user
  • answer: the (optional) answer written by the user

There are some basic validation rules applied to the request:

  • the value attribute must be an integer
  • the value attribute should be between the range defined in the given NPS model
  • a user should not be able to submit the answer if value is null
  • a user should be able to decline their submission for the NPS. In this case, both value and answer attributes should be null

POST - /nps/{id}/delay

This endpoint marks the NPS answered in cache for the currently authenticated user, but only for a limited time.

This way, the hasAnsweredCurrentNps and hasAnsweredNps methods will return true even if the answer is not stored in the database.

The user will then be able to see again the NPS only after that amount of time has expired.

The amount of time (in seconds) can be configured in the nps_answer_ttl attribute from config/nps.php.

Custom range class

If you wish to define a custom range of values for a NPS, you can define a new class which extends the NpsRange abstract class and contains a $values array.

class MyCustomNpsRange extends NpsRange
{
    protected static array $values = [2, 4, 6, 8, 10];
}

You can then associate the class with a name used as identified for the range attribute of the NPS model. This can be easily done by adding the key-value pair in the range list from config/nps.php:

'range' => [
    'default' => Maize\Nps\DefaultNpsRange::class,
    'minimal' => Maize\Nps\MinimalNpsRange::class,
    'emoji' => Maize\Nps\EmojiNpsRange::class,
    'custom' => Path\To\MyCustomNpsRange::class,
]

You can also define an associative array in case you want the values to be an array of strings. In this case, the key should contain the string, whereas the value is the associated integer which should be sent from the POST endpoint.

class EmojiNpsRange extends NpsRange
{
    protected static array $values = [
        '😡' => 1,
        '🙁' => 2,
        '😐' => 3,
        '😉' => 4,
        '😍' => 5,
    ];
}

Custom visibility class

If you wish to define a custom visibility for a NPS, you can define a new class which extends the NpsVisibility abstract class and implement the __invoke abstract method.

For example, let's say we want a NPS to be visible for a user when they performed at least 5 logins. Here is the custom visibility class we should have:

class MinLoginsVisibility extends NpsVisibility
{
    public function __invoke(Nps $nps): bool
    {
        return auth()->user()->accessLogs()->count() >= 5;
    }
}

You can then associate the class with a name used as identified for the visibility attribute of the NPS model. This can be easily done by adding the key-value pair in the visibility list from config/nps.php:

'visibility' => [
    'default' => Maize\Nps\DefaultNpsVisibility::class,
    'min_logins' => Path\To\MinLoginsVisibility::class,
]

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

You might also like...
Airbrake.io & Errbit integration for Symfony 3/4/5. This bundle plugs the Airbrake API client into Symfony project

AmiAirbrakeBundle Airbrake.io & Errbit integration for Symfony 3/4/5. This bundle plugs the Airbrake API client into Symfony project. Prerequisites Th

Quickly and easily expose Doctrine entities as REST resource endpoints with the use of simple configuration with annotations, yaml, json or a PHP array.

Drest Dress up doctrine entities and expose them as REST resources This library allows you to quickly annotate your doctrine entities into restful res

Laravel package to easily send events to Google Analytics

Laravel Analytics Event Tracking https://twitter.com/pascalbaljet/status/1257926601339277312 Laravel package to easily send events to Google Analytics

Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application

CORS Middleware for Laravel Implements https://github.com/asm89/stack-cors for Laravel About The laravel-cors package allows you to send Cross-Origin

Use middleware to decorate method calls within your application code.
Use middleware to decorate method calls within your application code.

Laravel Middlewarize 🎀 Chain of Responsibility Design Pattern In Laravel Apps 🎀 You can use middlewares to decorate any method calls on any object.

The 1Password Connect PHP SDK provides your PHP applications access to the 1Password Connect API hosted on your infrastructure and leverage the power of 1Password Secrets Automation

1Password Connect PHP SDK The 1Password Connect PHP SDK provides your PHP applications access to the 1Password Connect API hosted on your infrastructu

application/hal builder / formatter for PHP 5.4+

Nocarrier\Hal This is a library for creating documents in the application/hal+json and application/hal+xml hypermedia formats It requires PHP 5.4 or l

Zoho CRM API SDK is a wrapper to Zoho CRM APIs. By using this sdk, user can build the application with ease

Archival Notice: This SDK is archived. You can continue to use it, but no new features or support requests will be accepted. For the new version, refe

This API provides functionality for creating and maintaining users to control a simple To-Do-List application. The following shows the API structure for users and tasks resources.
This API provides functionality for creating and maintaining users to control a simple To-Do-List application. The following shows the API structure for users and tasks resources.

PHP API TO-DO-LIST v.2.0 This API aims to present a brief to consume a API resources, mainly for students in the early years of Computer Science cours

Comments
Releases(2.0.0)
Owner
H-FARM Innovation
H-FARM Innovation
PHP implementation of JSON schema. Fork of the http://jsonschemaphpv.sourceforge.net/ project

JSON Schema for PHP A PHP Implementation for validating JSON Structures against a given Schema with support for Schemas of Draft-3 or Draft-4. Feature

Justin Rainbow 3.4k Dec 26, 2022
The perfect starting point to integrate Algolia within your PHP project

⚡️ A fully-featured and blazing-fast PHP API client to interact with Algolia.

Algolia 629 Jan 4, 2023
Bundle to integrate Tactician with Symfony projects

TacticianBundle Symfony2 Bundle for the Tactician library https://github.com/thephpleague/tactician/ Installation Step 1: Download the Bundle Open a c

The League of Extraordinary Packages 240 Jan 4, 2023
Raidbots API wrapper which incorporates existing reports and static data into your project.

Raidbots API Raidbots API wrapper which incorporates existing reports and static data into your project. Usage use Logiek\Raidbots\Client; $client =

Logiek 2 Dec 23, 2021
Laravel library to convert your models into API responses.

Laravel Scene Laravel library to convert your models into API responses. Why a transformation library? By default you can use the default implementati

Ahmed Azaan 27 Nov 23, 2022
Laravel package to easily update business KPI monitors for your software or service

Laravel package to easily update business KPI monitors for your software or service. Monitors can be exposed to your user community via mobile app or embedded into your own application.

Heinz Seldte 2 Dec 12, 2022
A collection of custom Arcanist linters

Arcanist Linters This is a collection of custom Arcanist linters that we've written at Pinterest. Apache Thrift Apache Thrift Generated Black Checksty

Pinterest 64 May 7, 2022
All this is a ready-made solution for the VK api.

Instructions for VK API ?? Instructions using my ready-made solution ?? Table of Contents Introduction Users users.get users.getFollowers users.getSub

Dima Gashuk 3 Dec 11, 2021
Provides a Middleware to integration Tideways into Symfony Messenger Processing

Tideways Middleware for Symfony Messenger This package is currently under development and might be moved into the Tideways PHP Extension or stay indep

Tideways 6 Jul 5, 2022
Http-kernel - The HttpKernel component provides a structured process for converting a Request into a Response.

HttpKernel Component The HttpKernel component provides a structured process for converting a Request into a Response by making use of the EventDispatc

Symfony 7.8k Jan 9, 2023