Repository: jijunair/laravel-referral
Branch: main
Commit: 3fab42b5fe5b
Files: 18
Total size: 29.7 KB
Directory structure:
gitextract_ks4k398i/
├── .github/
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── composer.json
├── config/
│ └── referral.php
├── database/
│ └── migrations/
│ └── 2023_05_28_135232_create_referrals_table.php
├── routes/
│ └── web.php
├── src/
│ ├── Controllers/
│ │ └── ReferralController.php
│ ├── Models/
│ │ └── Referral.php
│ ├── Providers/
│ │ └── ReferralServiceProvider.php
│ └── Traits/
│ └── Referrable.php
└── tests/
└── ReferralControllerTest.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Before creating a new bug report**
Please check if there isn't a similar issue on [the issue tracker](https://github.com/jijunair/laravel-referral/issues) or in [the discussions](https://github.com/jijunair/laravel-referral/discussions).
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .gitignore
================================================
/vendor/
node_modules/
npm-debug.log
yarn-error.log
# Laravel 4 specific
bootstrap/compiled.php
app/storage/
# Laravel 5 & Lumen specific
public/storage
public/hot
# Laravel 5 & Lumen specific with changed public path
public_html/storage
public_html/hot
storage/*.key
.env
Homestead.yaml
Homestead.json
/.vagrant
.phpunit.result.cache
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to the "jijunair/laravel-referral" package will be documented in this file.
## [1.0.0] - 2023-07-14
### Added
- Initial release of the "jijunair/laravel-referral" package.
[1.0.0]: https://github.com/jijunair/laravel-referral/releases/tag/v1.0.0
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Laravel Referral Package
Thank you for your interest in contributing to the Laravel Referral Package! We welcome your contributions and appreciate your efforts to improve the project. Please follow these guidelines when contributing:
- Report any issues or bugs on the [GitHub issue tracker](https://github.com/jijunair/laravel-referral/issues).
- Submit bug fixes or new features by forking the repository, making changes, and opening a pull request against the `main` branch.
- Follow the project's coding standards, including the PSR-12 coding style.
- Be open to feedback and respond to any questions or suggestions from the maintainers.
We value your contributions and appreciate your help in making the Laravel Referral Package even better!
## License
By contributing to the Laravel Referral Package, you agree that your contributions will be licensed under the project's [MIT](LICENSE) license.
Thank you for your contributions!
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Jiju Nair
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
The **Laravel Referral** package (`jijunair/laravel-referral`) is a powerful and easy-to-use package for adding referral system functionality to your Laravel applications. With this package, you can effortlessly generate referral codes, track user referrals, and reward users based on their referrals.
## Key Features
✅ Generate unique referral codes for users
✅ Track referrals and associate them with users
✅ Retrieve referrers and their referred users
✅ Customizable referral code length, cookie tracking, and redirection
✅ Simple trait-based integration with your `User` model
- [Installation](#installation)
- [Configuration](#configuration)
- [Migration](#migration)
- [Add Trait](#add-trait)
- [Usage](#usage)
- [Generate Referral Accounts for Existing Users](#generate-referral-accounts-for-existing-users)
- [Get the Referrer of a User](#get-the-referrer-of-a-user)
- [Get Referrer by Referral Code](#get-referrer-by-referral-code)
- [Check if a User has a Referral Account](#check-if-a-user-has-a-referral-account)
- [Create a Referral Account for a User](#create-a-referral-account-for-a-user)
- [Get All Referrals of a User](#get-all-referrals-of-a-user)
- [Get the Referral Link of a User](#get-the-referral-link-of-a-user)
- [Changelog](#changelog)
- [Contribution](#contributing)
- [License](#license)
## Installation
You can install the package via Composer by running the following command:
```bash
composer require jijunair/laravel-referral
```
#### Configuration
The package provides a configuration file that allows you to customize its behavior. You should publish the migration and the config/referral.php config file with:
```php
php artisan vendor:publish --provider="Jijunair\LaravelReferral\Providers\ReferralServiceProvider"
```
After publishing, you can find the configuration file at config/referral.php.
| Configuration Key | Description |
|---------------------|---------------------------------------------------------------------------------------------------------------|
| `cookie_name` | The name of the cookie that tracks referrals. |
| `cookie_expiry` | How long the referral cookie will be valid. (Default: 1 year) |
| `route_prefix` | The prefix used for referral links. |
| `ref_code_prefix` | The prefix added to the unique referral code for each user. |
| `redirect_route` | The page where users will go after clicking on a referral link. |
| `user_model` | The model class for the user. |
| `referral_length` | The length of the referral code for each user. (Default: 8 characters) |
These configuration options help customize the behavior of the referral system in your Laravel application. Feel free to adjust these values according to your preferences and requirements!
#### Migration
After the config and migration have been published and configured, you can create the tables for this package by running:
```php
php artisan migrate
```
#### Add Trait
Add the necessary trait to your User model:
```php
use Jijunair\LaravelReferral\Traits\Referrable;
class User extends Model
{
use Referrable;
}
```
## Usage
#### Generate Referral Accounts for Existing Users
To generate referral accounts for existing users, you can visit the following URL:
```plaintext
http://localhost:8000/generate-ref-accounts
```
This will generate referral codes for all existing users in your application.
#### Get the Referrer of a User
To get the referrer of a user, you can use the following code:
```php
use Illuminate\Support\Facades\Auth;
$user = Auth::user();
$referrer = $user->referralAccount->referrer;
```
This retrieves the referrer associated with the user.
#### Get Referrer by Referral Code
To get the referrer by referral code, you can use the following code:
```php
use Jijunair\LaravelReferral\Models\Referral;
use Illuminate\Support\Facades\Cookie;
$referralCode = Cookie::get(config('referral.cookie_name'));
$referrer = Referral::userByReferralCode($referralCode);
```
This retrieves the referrer based on the referral code stored in the cookie.
#### Check if a User has a Referral Account
To check if a user has a referral account, you can use the following code:
```php
$user->hasReferralAccount();
```
This returns `true` if the user has a referral account, and `false` otherwise.
#### Create a Referral Account for a User
To create a referral account for a user, you can use the following code:
```php
$user->createReferralAccount($referrer->id);
```
This associates the user with the provided referrer by creating a referral account.
#### Get All Referrals of a User
To get all referrals under a user, you can use the following code:
```php
$referrals = $user->referrals;
```
This retrieves all the referrals associated with the user.
#### Get the Referral Link of a User
To get the referral link of a user, you can use the following code:
```php
$referralLink = $user->getReferralLink();
```
This returns the referral link associated with the user.
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Thank you for considering contributing to the Laravel Referral Package! If you have any suggestions, bug reports, or pull requests, please feel free to open an issue or submit a pull request on the GitHub repository.
## License
The Laravel Referral Package is open-source software licensed under the [MIT](LICENSE) license.
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
Please refer to the following table to see the currently supported versions of the Laravel Referral Package with security updates:
| Version | Supported |
| ------- | ------------------ |
| 1.0.x | :white_check_mark: |
Note: It is highly recommended to use the latest stable version whenever possible.
## Reporting a Vulnerability
To report a security vulnerability, please follow these steps:
1. Go to the [GitHub Issues](https://github.com/jijunair/laravel-referral/issues) page of the this repository.
2. Click on the "New Issue" button.
3. Provide a clear and descriptive title for the vulnerability report.
4. In the issue description, include detailed information about the vulnerability, including steps to reproduce and potential impact.
5. If possible, include any relevant code snippets or examples.
6. Submit the issue.
We will review your vulnerability report as soon as possible and provide updates on its progress. We appreciate your responsible disclosure of security vulnerabilities and your contribution to the security of this package.
Thank you for helping us maintain a secure package!
================================================
FILE: composer.json
================================================
{
"name": "jijunair/laravel-referral",
"description": "Laravel package for a referral system",
"keywords": [
"jijunair",
"laravel",
"referral",
"affiliate",
"package",
"laravel-referral",
"referral-system",
"user-referral"
],
"homepage": "https://github.com/jijunair/laravel-referral",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Jiju Nair",
"email": "hello@jijunair.com"
}
],
"require": {
"php": "^7.2|^7.3|^7.4|^8.0|^8.1|^8.2",
"illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0",
"illuminate/auth": "^8.0|^9.0|^10.0|^11.0|^12.0"
},
"require-dev": {
"phpunit/phpunit": "^9.4|^10.0|^11.0|^12.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Jijunair\\LaravelReferral\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Jijunair\\LaravelReferral\\Tests\\": "tests"
}
},
"extra": {
"laravel": {
"providers": [
"Jijunair\\LaravelReferral\\Providers\\ReferralServiceProvider"
]
}
}
}
================================================
FILE: config/referral.php
================================================
'mysite_ref',
// Expiry time for the referral cookie in minutes
'cookie_expiry' => 525600, // 1 year
// The prefix used for referral links
'route_prefix' => 'save20',
// The prefix used for referral code
'ref_code_prefix' => 'ref_',
// The route where users will be redirected after clicking on a referral link
'redirect_route' => 'orders.create',
// The model class for the user
'user_model' => 'App\Models\User',
// The length of the referral code generated for each user
'referral_length' => 8,
];
================================================
FILE: database/migrations/2023_05_28_135232_create_referrals_table.php
================================================
id();
$table->unsignedBigInteger('user_id');
$table->string('referral_code')->unique();
$table->unsignedBigInteger('referrer_id')->nullable();
$table->timestamps();
$table->foreign('referrer_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->index('referral_code');
$table->index('user_id');
$table->index('referrer_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('referrals');
}
}
================================================
FILE: routes/web.php
================================================
group(function () {
Route::get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])
->name('referralLink');
Route::get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers'])
->name('generateReferralCodes');
});
================================================
FILE: src/Controllers/ReferralController.php
================================================
route(config('referral.redirect_route'));
} else {
// Create a referral code cookie and redirect to configured route
$ck = Cookie::make($refCookieName, $referralCode, $refCookieExpiry);
return redirect()->route(config('referral.redirect_route'))->withCookie($ck);
}
}
/**
* Generate referral codes for existing users.
*
* @return JsonResponse
*/
public function createReferralCodeForExistingUsers()
{
$userModel = resolve(config('referral.user_model'));
$users = $userModel::cursor();
foreach ($users as $user) {
if (!$user->hasReferralAccount()) {
$user->createReferralAccount();
}
}
return response()->json(['message' => 'Referral codes generated for existing users.']);
}
}
================================================
FILE: src/Models/Referral.php
================================================
belongsTo(config('referral.user_model'), 'user_id');
}
/**
* Get the referrer associated with the referral.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function referrer()
{
return $this->belongsTo(config('referral.user_model'), 'referrer_id');
}
/**
* Retrieve the user by referral code.
*
* @param string $code
* @return mixed|null
*/
public static function userByReferralCode($code)
{
$referrer = self::where('referral_code',$code)->first();
if ($referrer) {
return App::make(config('referral.user_model'))->find($referrer->user_id);
}
return null;
}
}
================================================
FILE: src/Providers/ReferralServiceProvider.php
================================================
mergeConfigFrom(__DIR__.'/../../config/referral.php', 'referral');
}
/**
* Bootstrap package services.
*
* @return void
*/
public function boot()
{
// Load package migrations
$this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
if ($this->app->runningInConsole()) {
// Publish package's configuration file
$this->publishes([
__DIR__.'/../../config/referral.php' => config_path('referral.php'),
], 'laravel-referral-config');
// Publish package's migration files
$this->publishes([
__DIR__.'/../../database/migrations' => database_path('migrations'),
], 'laravel-referral-migrations');
}
// Load package's routes
$this->loadRoutesFrom(__DIR__.'/../../routes/web.php');
// Bind the ReferralController to the application container
$this->app->bind('Jijunair\LaravelReferral\Controllers\ReferralController', function ($app) {
return new \Jijunair\LaravelReferral\Controllers\ReferralController();
});
}
}
================================================
FILE: src/Traits/Referrable.php
================================================
hasMany(Referral::class, 'referrer_id');
}
/**
* Get the referral account of the user.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function referralAccount()
{
return $this->belongsTo(Referral::class, 'id', 'user_id');
}
/**
* Check if the user has a referral account.
*
* @return bool
*/
public function hasReferralAccount()
{
return !is_null($this->referralAccount);
}
/**
* Get the referral link for the user.
*
* @return string
*/
public function getReferralLink()
{
if ($this->hasReferralAccount()) {
return url('/') . "/" . config('referral.route_prefix') . "/" . $this->getReferralCode();
}
return "";
}
/**
* Get the referral code of the user's referral account.
*
* @return string|null
*/
public function getReferralCode()
{
if ($this->hasReferralAccount()) {
return $this->referralAccount->referral_code;
}
return null;
}
/**
* Create a referral account for the user.
*
* @param int|null $referrerID
* @return void
*/
public function createReferralAccount(int $referrerID = NULL)
{
$prefix = config('referral.ref_code_prefix');
$length = config('referral.referral_length');
$referralCode = $this->generateUniqueReferralCode($prefix, $length);
$ref = new Referral;
$ref->user_id = $this->getKey();
$ref->referrer_id = $referrerID;
$ref->referral_code = $referralCode;
$ref->save();
}
/**
* Generate a unique referral code.
*
* @param string $prefix
* @param int $length
* @return string
*/
private function generateUniqueReferralCode($prefix, $length)
{
$prefix = strtolower($prefix);
// Generate an initial referral code
$code = $prefix . strtolower(Str::random($length));
// Check if the generated code already exists in the database
while (Referral::where('referral_code', $code)->exists()) {
// If code already exists, generate a new one until a unique code is found
$code = $prefix . strtolower(Str::random($length));
}
return $code;
}
}
================================================
FILE: tests/ReferralControllerTest.php
================================================
get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])
->name('referralLink');
// Call the route with the referral code
$response = $this->get(route('referralLink', ['referralCode' => $referralCode]));
// Assert that the response redirects to the configured route
$response->assertRedirect(config('referral.redirect_route'));
}
public function testAssignReferrerWithoutExistingCookie()
{
// Create a dummy referral code
$referralCode = 'ABC123';
// Define the route for assigning a referrer
Route::middleware('web')->get(config('referral.route_prefix') . '/{referralCode}', [ReferralController::class, 'assignReferrer'])
->name('referralLink');
// Call the route with the referral code
$response = $this->get(route('referralLink', ['referralCode' => $referralCode]));
// Assert that the response redirects to the configured route
$response->assertRedirect(config('referral.redirect_route'));
// Assert that the referral code cookie has been set
$this->assertTrue(Cookie::has(config('referral.cookie_name')));
}
public function testCreateReferralCodeForExistingUsers()
{
// Create some dummy users
$users = factory(config('referral.user_model'), 5)->create();
// Define the route for generating referral codes for existing users
Route::middleware('web')->get('generate-ref-accounts', [ReferralController::class, 'createReferralCodeForExistingUsers'])
->name('generateReferralCodes');
// Call the route to generate referral codes for existing users
$response = $this->get(route('generateReferralCodes'));
// Assert that the response is a JSON response
$response->assertJson(['message' => 'Referral codes generated for existing users.']);
// Assert that referral codes have been created for all existing users
foreach ($users as $user) {
$this->assertTrue($user->hasReferralAccount());
$this->assertNotNull($user->getReferralCode());
}
}
}