article

Monday, March 24, 2025

Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication

Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication

Download Laravel App

https://laravel.com/docs/12.x/installation

Connecting our Database

open .env file root directory.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel12dev
DB_USERNAME=root
DB_PASSWORD=root

Database Migration
php artisan migrate

myapp>php artisan migrate
Migration table created successfully.
check database table
Create Controller
myapp>php artisan make:controller PostController

app\Http\Controllers\PostController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//app\Http\Controllers\PostController.php
<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Pagination\LengthAwarePaginator;
 
class PostController extends Controller
{
    public function index()
    {
        $response = Http::get(getenv("WP_JSON_Wordpress_URL"));
 
        if ($response->successful()) {
 
            $posts = $response->json();
 
            $postArr = collect($posts)->map(function ($post) {
                return [
                    'id' => $post['id'],
                    'title' => $post['title']['rendered'],
                    'content' => $post['content']['rendered'],
                ];
            })->toArray();
 
            return view('Home', compact('postArr'));
        } else {
            // Handle error if the request was not successful
            $error = $response->status(); // Get the HTTP status code
        }
    }
 
    public function create()
    {
        return view('Create');
    }
 
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'content' => 'required',
            'status' => 'required',
        ]);
 
        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . getenv("WP_JWT_AUTH_TOKEN"),
            'Content-Type' => 'application/json',
        ])
            ->post(getenv("WP_JSON_Wordpress_URL"), [
                'title' => $request->title,
                'content' => $request->content,
                'status' => $request->status,
            ]);
 
        // response
        if ($response->successful()) {
 
            $post = $response->json();
 
            return redirect()->route('posts.index')->with('success', 'Post has been created successfully.');
        } else {
            // errors
            $error = $response->json();
 
            return redirect()->route('posts.create')->with('error', 'Failed to create post');
        }
    }
 
    public function show(Request $request)
    {
        $postId = $request->post;
 
        $url = getenv("WP_JSON_Wordpress_URL") . "/" . $postId;
 
        $response = Http::get($url);
 
        if ($response->successful()) {
            $post = $response->json();
            return view('Read', compact('post'));
        } else {
            return $response->status();
        }
    }
 
    public function edit(Request $request)
    {
        $postId = $request->post;
 
        $url = getenv("WP_JSON_Wordpress_URL") . "/" . $postId;
 
        $response = Http::get($url);
 
        if ($response->successful()) {
            $post = $response->json();
            return view('Edit', compact('post'));
        } else {
            return $response->status();
        }
    }
 
    public function update(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'content' => 'required',
            'status' => 'required',
        ]);
 
        // ID of the post to update
        $postId = $request->post;
 
        $updateData = [
            'title' => $request->title,
            'content' => $request->content,
            'status' => $request->status
        ];
 
        $response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . getenv("WP_JWT_AUTH_TOKEN"),
        ])->put(getenv("WP_JSON_Wordpress_URL") . "/" . $postId, $updateData);
 
        if ($response->successful()) {
            $updatedPost = $response->json();
            return redirect()->route('posts.index')->with('success', 'Post Has Been updated successfully');
        } else {
            // Handle error
            $error = $response->status();
            return redirect()->route('posts.index')->with('error', 'Failed to update post');
        }
    }
 
    public function destroy(Request $request)
    {
        $postId = $request->post;
 
        $response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer ' . getenv("WP_JWT_AUTH_TOKEN"),
        ])->delete(getenv("WP_JSON_Wordpress_URL") . "/" . $postId);
 
        if ($response->successful()) {
            $deletedPost = $response->json();
            return redirect()->route('posts.index')->with('success', 'Post has been deleted successfully');
        } else {
            $error = $response->status(); // Get the HTTP status code
            return redirect()->route('posts.index')->with('success', 'Failed to delete post');
        }
    }
 
    public function pagination(Request $request)
    {
 
        //First resolve the current page
        $page = LengthAwarePaginator::resolveCurrentPage();
        //Define how many items you want to display per page
        $perPage = 6;
 
        //Call the external API and retrieve the data passing the $page and the $perPage
        $response = Http::get(getenv("WP_JSON_Wordpress_URL"), [
            'page' => $page,
            'per_page' => $perPage,
        ]);
        $data = $response->json();
 
        $totalData = $response->header('X-WP-Total');
 
        //Create a new LengthAwarePaginator instance
        $paginator = new LengthAwarePaginator($data, $totalData,   $perPage, $page, [
           'path' => LengthAwarePaginator::resolveCurrentPath(),
        ]);
 
        //Pass the paginator instance to your Blade view
        //return $totalData;
        return view('Pagination', ['data' => $paginator]);
    }
}
View Blade File resources/views/Home.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//resources/views/Home.blade.php
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8"> <!--getbootstrap.com/docs/5.0/getting-started/introduction/ -->
    <title>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
 
<body>
    <div class="container mt-2">
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h3>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</h3>
                </div>
                <h4 class="text-center">Post List</h4>
                <div class="pull-right mb-2" style="float: right;">
                    <a class="btn btn-success" href="{{ route('posts.create') }}">Create Post</a>
                </div>
            </div>
        </div>
        @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
        @endif
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Post Title</th>
                    <th>Post Content</th>
                    <th width="280px">Action</th>
                </tr>
            </thead>
            <tbody>
                @foreach ($postArr as $post)
                <tr>
                    <td>{{ $post['id'] }}</td>
                    <td>{{ $post['title'] }}</td>
                    <td>{{ substr($post['content'], 0, 100) }}</td>
                    <td>
                        <form action="{{ route('posts.destroy',$post['id']) }}" method="Post">
                            <a class="btn btn-info" href="{{ route('posts.show',$post['id']) }}">Read</a>
                            <a class="btn btn-primary" href="{{ route('posts.edit',$post['id']) }}">Edit</a>
                            @csrf
                            @method('DELETE')
                            <button type="submit" onclick="return confirm('Are you sure want to delete?')" class="btn btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
    </div>
</body>
 
</html>
resources/views/Create.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//resources/views/Create.blade.php
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
 
<body>
    <div class="container mt-2">
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h3>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</h3>
                </div>
                <h4 class="text-center">Add Post</h4>
                <div class="pull-right" style="float: right;">
                    <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
                </div>
            </div>
        </div>
        @if(session('status'))
        <div class="alert alert-success mb-1 mt-1">
            {{ session('status') }}
        </div>
        @endif
        <form action="{{ route('posts.store') }}" method="POST">
            @csrf
            <div class="row">
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Title:</strong>
                        <input type="text" name="title" class="form-control" placeholder="Post Title">
                        @error('title')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Content:</strong>
                        <textarea class="form-control" name="content" rows="5" placeholder="Post Content"></textarea>
                        @error('content')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Status</strong>
                        <select name="status" class="form-control">
                            <option value="">-- Status --</option>
                            <option value="draft">Draft</option>
                            <option value="publish">Publish</option>
                        </select>
                        @error('status')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
 
                <button type="submit" class="btn btn-primary ml-3">Submit</button>
            </div>
        </form>
    </div>
</body>
 
</html>
resources/views/Read.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//resources/views/Read.blade.php
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication </title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
  
<body>
    <div class="container mt-2">
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h3>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</h3>
                </div>
                <h4 class="text-center">View Post</h4>
                <div class="pull-right" style="float: right;">
                    <a class="btn btn-primary" href="{{ route('posts.index') }}">
                        Back</a>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Title:</strong>
                    {{ $post['title']['rendered'] }}
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Content:</strong>
                    {!!html_entity_decode($post['content']['rendered'])!!}
                </div>
            </div>
        </div>
    </div>
</body>
 
</html>
resources/views/Edit.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//resources/views/Edit.blade.php
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication </title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
 
<body>
    <div class="container mt-2">
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h3>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</h3>
                </div>
                <h4 class="text-center">Edit Post</h4>
                <div class="pull-right" style="float: right;">
                    <a class="btn btn-primary" href="{{ route('posts.index') }}">
                        Back</a>
                </div>
            </div>
        </div>
        @if(session('status'))
        <div class="alert alert-success mb-1 mt-1">
            {{ session('status') }}
        </div>
        @endif
        <form action="{{ route('posts.update',$post['id']) }}" method="POST">
            @csrf
            @method('PUT')
            <div class="row">
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Title:</strong>
                        <input type="text" name="title" value="{{ $post['title']['rendered'] }}" class="form-control"
                            placeholder="Post Title">
                        @error('name')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Content:</strong>
                        <textarea class="form-control" name="content" rows="5">{{ $post['content']['rendered'] }}</textarea>
                        @error('address')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
                <div class="col-xs-12 col-sm-12 col-md-12">
                    <div class="form-group">
                        <strong>Status:</strong>
                        <select name="status" id="status" class="form-control">
                            <option value="">-- Status --</option>
                            <option {{ $post["status"] == "draft" ? "selected" : "" }} value="draft">Draft</option>
                            <option {{ $post["status"] == "publish" ? "selected" : "" }} value="publish">Publish</option>
                        </select>
                        @error('address')
                        <div class="alert alert-danger mt-1 mb-1">{{ $message }}</div>
                        @enderror
                    </div>
                </div>
 
                <button type="submit" class="btn btn-primary ml-3">Submit</button>
            </div>
        </form>
    </div>
</body>
 
</html>
resources/views/Edit.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//resources/views/Edit.blade.php
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        .custom-pagination {
            color: #0fb6cc;
            margin: 0 2px;
        }
 
        .custom-pagination .pagination {
            display: flex;
            justify-content: center;
            margin-top: 20px;
        }
    </style>
</head>
 
<body>
    <div class="container mt-2">
        <div class="row">
            <div class="col-lg-12 margin-tb">
                <div class="pull-left">
                    <h3>Laravel 12 CRUD (Create, Read, Update and Delete) with Pagination WordPress REST API with JWT Authentication</h3>
                </div>
                <h4 class="text-center">Post List</h4>
                <div class="pull-right mb-2" style="float: right;">
                    <a class="btn btn-success" href="{{ route('posts.create') }}">Create Post</a>
                </div>
            </div>
        </div>
 
        @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
        @endif
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Post Title</th>
                    <th>Post Content</th>
                    <th width="280px">Action</th>
                </tr>
            </thead>
            <tbody>
                @foreach ($data as $post)
                <tr>
                    <td>{{ $post['id'] }}</td>
                    <td>{{ $post['title']['rendered'] }}</td>
                    <td>{{ substr($post['content']['rendered'], 0, 100) }}</td>
                    <td>
                        <form action="{{ route('posts.destroy',$post['id']) }}" method="Post">
                            <a class="btn btn-info" href="{{ route('posts.show',$post['id']) }}">Read</a>
                            <a class="btn btn-primary" href="{{ route('posts.edit',$post['id']) }}">Edit</a>
                            @csrf
                            @method('DELETE')
                            <button type="submit" onclick="return confirm('Are you sure want to delete?')" class="btn btn-danger">Delete</button>
                        </form>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
 
        <!--
        {{ $data->links() }} -->
        <div class="d-flex custom-pagination">
            {{ $data->links('pagination::bootstrap-5') }}
        </div>
 
 
    </div>
</body>
 
</html>
Routes
routes/web.php
1
2
3
4
5
6
7
8
9
10
//routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
 
Route::get('/', function () {
    return view('welcome');
});
 
Route::resource('posts', PostController::class);
Route::get('/pagination', [PostController::class, 'pagination'])->name('pagination');
Install wordpress plugin JWT Authentication for WP-API and activate. wordpress org/plugins/jwt-authentication-for-wp-rest-api/

Configurate the Secret Key and enable the CORs Support
To add the secret key edit your wp-config.php file and add a new constant called JWT_AUTH_SECRET_KEY JWT_AUTH_CORS_ENABLE

define('JWT_AUTH_SECRET_KEY', 'cairocoders-ednalan0711');
define('JWT_AUTH_CORS_ENABLE', true);

Open laravel .env file from project folder, add token and json url
WP_JWT_AUTH_TOKEN="0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJod..."
WP_JSON_POST_URL="https://yourwordpresssite.com/wp-json/wp/v2/posts"

Related Post