Skip to content

Commit 795f374

Browse files
committed
first commit
0 parents  commit 795f374

File tree

11 files changed

+1125
-0
lines changed

11 files changed

+1125
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.github/workflows/tests.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v3
10+
- name: Setup PHP
11+
uses: shivammathur/setup-php@v2
12+
with:
13+
php-version: '8.2'
14+
- name: Install dependencies
15+
run: composer install
16+
- name: Run tests
17+
run: vendor/bin/phpunit

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea/
2+
vendor/
3+
composer.lock
4+
.phpunit.result.cache

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Ali Tolouei
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# Laravel RepoMate
2+
3+
**A modern, flexible, and filterable Eloquent repository base for Laravel.**
4+
5+
RepoKit simplifies your data access layer by providing a reusable, testable, and maintainable repository structure. It includes filtering, chainable queries, pagination, CRUD operations, soft deletes, and batch inserts—all with Laravel Eloquent.
6+
7+
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8+
[![Tests](https://github.com/mrtolouei/laravel-repo-mate/actions/workflows/tests.yml/badge.svg)](https://github.com/mrtolouei/laravel-repo-mate/actions/workflows/tests.yml)
9+
[![Latest Stable Version](https://poser.pugx.org/mrtolouei/laravel-repo-mate/v/stable)](https://packagist.org/packages/mrtolouei/laravel-repo-mate)
10+
11+
12+
---
13+
14+
## Table of Contents
15+
16+
1. [Installation](#installation)
17+
2. [Creating a Repository](#creating-a-repository)
18+
3. [Filterable Trait](#filterable-trait)
19+
4. [Using Filters](#using-filters)
20+
5. [Basic Query Methods](#basic-query-methods)
21+
6. [Chainable Queries](#chainable-queries)
22+
7. [Custom Queries](#custom-queries)
23+
8. [Persisting Queries](#persisting-queries)
24+
9. [CRUD Operations](#crud-operations)
25+
10. [Advance Usages](#advanced-usage)
26+
11. [Testing](#testing)
27+
12. [Contributing](#contributing)
28+
13. [License](#license)
29+
30+
---
31+
32+
## Installation
33+
34+
Install via composer:
35+
36+
```bash
37+
composer require mrtolouei/laravel-repository
38+
```
39+
40+
---
41+
42+
## Creating a Repository
43+
44+
To create a new repository, extend BaseRepository and pass the model in the constructor:
45+
46+
```php
47+
use App\Models\User;
48+
use RepoKit\Repositories\BaseRepository;
49+
50+
class UserRepository extends BaseRepository
51+
{
52+
public function __construct(User $model)
53+
{
54+
parent::__construct($model);
55+
}
56+
}
57+
```
58+
59+
---
60+
61+
## Filterable Trait
62+
63+
To create a new repository, extend BaseRepository and pass the model in the constructor:
64+
65+
Key properties:
66+
- `$activeFilters`: Parameters set at runtime.
67+
- `$filterDefinitions`: Define how filters are applied (column, type, operator, relation).
68+
- `$filtersApplied`: Internal flag to prevent applying filters multiple times.
69+
70+
Filter definition structure:
71+
72+
```php
73+
[
74+
'filter_name' => [
75+
'column' => 'db_column', // DB column name
76+
'type' => 'string|integer|boolean|array|datetime', // Type of filter
77+
'operator' => '=', // Optional, defaults to '='
78+
'relation' => 'relationName', // Optional, for whereHas
79+
]
80+
]
81+
```
82+
83+
---
84+
85+
## Using Filters
86+
87+
Filters are defined in your repository as an array:
88+
89+
```php
90+
use App\Models\User;
91+
use RepoKit\Repositories\BaseRepository;
92+
93+
class UserRepository extends BaseRepository
94+
{
95+
protected array $filterDefinitions = [
96+
'email' => [
97+
'column' => 'email',
98+
'type' => 'string'
99+
],
100+
'roles' => [
101+
'column' => 'id',
102+
'type' => 'array',
103+
'operator' => '=',
104+
'resource' => 'roles' //Relation name in User model
105+
],
106+
'age' => [
107+
'column' => 'age',
108+
'type' => 'integer',
109+
'operator' => '>='
110+
],
111+
'is_active' => [
112+
'column' => 'is_active',
113+
'type' => 'boolean',
114+
]
115+
];
116+
}
117+
```
118+
119+
You can apply filters dynamically at runtime using the repository’s `setFilter()` method. This is especially useful in a controller, where you can use query parameters from the HTTP request:
120+
121+
```php
122+
public function index(Request $request)
123+
{
124+
$userRepo = new UserRepository(new User());
125+
126+
// Apply filters from query parameters
127+
$users = $userRepo->setFilter($request->query())->all();
128+
129+
return response()->json($users);
130+
}
131+
```
132+
133+
Explanation:
134+
135+
- `setFilter()` accepts an array of filter parameters (e.g., from `request()->query()`).
136+
- The repository automatically applies the filters according to the `filterDefinitions` you defined in your repository.
137+
- This approach keeps your controller clean and leverages the repository’s built-in filtering system.
138+
139+
---
140+
141+
## Basic Query Methods
142+
143+
| Method | Description | Example |
144+
| ------------------ | ------------------------------------------------ | -------------------------------------------------- |
145+
| `query(): Builder` | Get the query builder instance for customization | `$query = $userRepo->query();` |
146+
| `where(...)` | Add a `where` clause | `$userRepo->where('is_active', true)->all();` |
147+
| `with([...])` | Eager load relations | `$userRepo->with(['posts', 'profile'])->all();` |
148+
| `orderBy(...)` | Order results | `$userRepo->orderBy('created_at', 'desc')->all();` |
149+
| `limit(int)` | Limit results | `$userRepo->limit(10)->all();` |
150+
151+
---
152+
153+
## Chainable Queries
154+
155+
All query-building methods return `$this` for chaining:
156+
157+
```php
158+
$users = $userRepo
159+
->where('is_active', true)
160+
->orderBy('created_at', 'desc')
161+
->limit(5)
162+
->all();
163+
```
164+
165+
---
166+
167+
## Custom Queries
168+
169+
Get the underlying query builder for advanced queries:
170+
171+
```php
172+
$query = $userRepo->query();
173+
174+
$query->where('role_id', 2)
175+
->orWhere('is_active', false)
176+
->get();
177+
```
178+
179+
---
180+
181+
## Persisting Queries
182+
183+
Use `persistQuery()` to reuse the same query for multiple operations:
184+
185+
```php
186+
$query = $userRepo->persistQuery()
187+
->where('role_id', 2)
188+
->orderBy('created_at');
189+
190+
$firstUser = $query->first();
191+
$allUsers = $query->all();
192+
```
193+
194+
Without `persistQuery()`, queries are reset after each operation.
195+
196+
---
197+
198+
## CRUD Operations
199+
200+
```php
201+
// Create
202+
$newUser = $userRepo->create([
203+
'name' => 'Ali',
204+
'email' => '[email protected]',
205+
]);
206+
207+
// Update
208+
$updatedUser = $userRepo->update($newUser->id, ['name' => 'Ali Tolouei']);
209+
210+
// Delete
211+
$deletedCount = $userRepo->delete($newUser->id);
212+
213+
// Restore
214+
$restoredCount = $userRepo->restore($newUser->id);
215+
216+
// Bulk insert
217+
$userRepo->insert([
218+
['name' => 'User1', 'email' => '[email protected]'],
219+
['name' => 'User2', 'email' => '[email protected]'],
220+
]);
221+
```
222+
223+
---
224+
225+
## Advanced Usage
226+
227+
```php
228+
$users = $userRepo
229+
->setFilter(['role' => 2])
230+
->where('is_active', true)
231+
->orderBy('created_at', 'desc')
232+
->with(['profile', 'posts'])
233+
->paginate(10);
234+
```
235+
236+
- Combines filters, chainable queries, and pagination.
237+
- Supports eager loading relations.
238+
239+
---
240+
241+
## Testing
242+
243+
```bash
244+
composer test
245+
```
246+
247+
---
248+
249+
## Contributing
250+
251+
1. Fork the repository
252+
2. Create a feature branch (`feature/awesome-feature`)
253+
3. Commit your changes (`git commit -m 'Add new feature'`)
254+
4. Push to the branch (`git push origin feature/awesome-feature`)
255+
5. Open a Pull Request
256+
257+
---
258+
259+
## License
260+
261+
This package is open-sourced software licensed under the [MIT license](LICENSE).

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "mrtolouei/laravel-repo-mate",
3+
"description": "A clean and flexible base repository package for Laravel that simplifies data access, enforces the repository pattern, and keeps your code organized and testable.",
4+
"type": "library",
5+
"minimum-stability": "stable",
6+
"license": "MIT",
7+
"authors": [
8+
{
9+
"name": "Ali Tolouei",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"require": {
14+
"php": ">=8.0",
15+
"illuminate/support": ">=9.0",
16+
"illuminate/database": ">=9.0",
17+
"illuminate/pagination": ">=9.0"
18+
},
19+
"require-dev": {
20+
"phpunit/phpunit": "^10.0",
21+
"mockery/mockery": "^1.6"
22+
},
23+
"autoload": {
24+
"psr-4": {
25+
"RepoMate\\": "src/"
26+
}
27+
},
28+
"autoload-dev": {
29+
"psr-4": {
30+
"RepoMate\\Tests\\": "tests/"
31+
}
32+
}
33+
}

phpunit.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
>
7+
<testsuites>
8+
<testsuite name="Test Suite">
9+
<directory suffix="Test.php">./tests</directory>
10+
</testsuite>
11+
</testsuites>
12+
<source>
13+
<include>
14+
<directory suffix=".php">./src</directory>
15+
</include>
16+
</source>
17+
</phpunit>

0 commit comments

Comments
 (0)