#how to get difference between two timestamps in laravel
Explore tagged Tumblr posts
codehunger · 4 years ago
Text
Laravel-find days between two dates in laravel
Laravel-find days between two dates in laravel
In this blog, we will learn about how to find days between two dates in laravel, This tutorial will give you a simple example of getting days difference in laravel. if you want to see an example of how to get days difference in laravel then you are in the right place. Follow the below tutorial step of laravel 8 gets last week’s records from the database. If you want to see what all carbon does…
Tumblr media
View On WordPress
1 note · View note
programmingbiters-blog · 7 years ago
Photo
Tumblr media
New Post has been published on https://programmingbiters.com/file-uploads-with-laravel-5-and-dropzone-drag-and-drop/
File Uploads with Laravel 5 and Dropzone drag and drop
File uploads with Laravel is incredibly easy, thanks to the powerful file systemabstraction that it comes bundled with. Couple that up with Dropzone’s drag and drop feature, and you have a robust file upload mechanism. Not only these are easy to implement, they provide a great number of features in very few lines of code.
# Setting up the uploads
We’ll create a database table that contains information about each of the uploads. Of course we are not going to store our file in the database itself, rather we’d store only some metadata of the file. So let’s create a schema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function up()
             Schema::create(‘uploads’, function (Blueprint $table)
            $table->increments(‘id’);
            $table->integer(‘user_id’)->unsigned()->index();
            $table->string(‘filename’);
            $table->bigInteger(‘size’);
            $table->softDeletes();
            $table->timestamps();
            $table->foreign(‘user_id’)->references(‘id’)->on(‘users’)->onDelete(‘cascade’);
        );
     Here only metadata we are storing are  filename  and size . filename  would be used to store and retrieve the file later. We add a foreign keyuser_id  to keep track of who uploaded the file. This can also be used to check the owner of a file. We are also going to use  SoftDeletes  to mark a file as deleted rather than actually delete the file from storage, when a user deletes a file.
Now, let’s  php artisan make:model Upload  to create a Upload  model for this table.
Next, we define the relationship between a user and an uploaded file – a user may upload many files and each uploaded file will belong to a user. Therefore, let’s define a one-to-many relationship in our User  and Upload  models.  In theUser model:
1
2
3
4
5
6
public function uploads()
    return $this->hasMany(Upload::class);
and the inverse relationship is defined in our Upload model:
1
2
3
4
5
6
public function user()
return $this->belongsTo(User::class);
Also while we are at it, let’s update the fillable  columns for our Upload  model.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Illuminate\Database\Eloquent\SoftDeletes;
use App\User;
class Upload extends Model
    use SoftDeletes;
    protected $fillable = [
        ‘filename’, ‘size’,
    ];
    public function user()
          return $this->belongsTo(User::class);
     That’s all! Our Upload  model is now ready.
# Setting up dropzone
Now that our uploads backend is ready, let’s setup dropzone for drag and drop file uploads.
First we need to install dropzone, so let’s do a npm install dropzone —save . Next, we need to load the dropzone library. Since we are going to use Laravel Mix to compile our frontend assets, we can load the library withinresources/assets/js/bootstrap.js :
1
2
3
4
5
6
// Dropzone
window.Dropzone = require(‘dropzone’);
Dropzone.autoDiscover = false;
This will set Dropzone  to the window object. We are disabling the autoDiscover�� option, which is used to automatically attach dropzone with any file input, which we do not need.
Now let’s add the styling for this (otherwise it’s going to look uglier than Voldemort’s face, trust me). We can do this in ourresources/assets/sass/app.scss .
1
2
3
4
5
6
7
8
@import “~dropzone/src/dropzone.scss”;
.dropzone
margin-bottom: 20px;
min-height: auto;
All set. So we can now compile the assets using npm run dev .
# Setting up routes
Before we start uploading any files, we need to define some routes. Here we’d create two routes, one for receiving the uploads and one for deleting the uploads, should a user choose to delete one.
1
2
3
4
5
Route::post(‘/upload’, ‘UploadController@store’)->name(‘upload.store’);
Route::delete(‘/upload/upload’, ‘UploadController@destroy’);
Let’s php artisan make:controller UploadController  to create the controller. We will use this UploadController  to process the uploads in the backend.
# Uploading files
Now that we have pulled in dropzone and attached it to the window object, we need to integrate dropzone within a view to start file uploads. We can simple do this using an id  tag.
1
2
3
<div id=“file” class=“dropzone”></div>
class=“dropzone”  is used to style the dopzone upload box. We can use the#file  to inject dropzone on this element. (tip: it is a best practice in laravel to create javascript snippets in separate partials and then including them in whichever blade template they are needed)
1
2
3
4
5
6
7
8
9
let drop = new Dropzone(‘#file’,
    addRemoveLinks: true,
    url: ‘ route(‘upload.store‘) ’,
    headers:
        ‘X-CSRF-TOKEN’: document.head.querySelector(‘meta[name=”csrf-token”]’).content
     );
We are instantiating the Dropzone  class on our #file and then passing in some addition configuration. addRemoveLinks  will add a remove link to every uploaded file, so a user can remove a file after uploading it. The url option is used to let dropzone know where to post the uploaded file to, in case we are not using a form. If we are using a form, by default dropzone would use the action attribute of the form as the post url (I’m not quite sure about this though, so please don’t take my words as is, and do correct me if I am wrong). We are using the upload.store  route which we have defined earlier.
headers are used to send additional headers to the server. Because we are posting our uploads, we need to send a  X–CSRF–TOKEN  header, otherwise our app will throw a  TokenMismatchException (this is used by laravel to protect our app against CSRF attacks). By default, the meta information in head contains a meta with the name  csrf–token . Therefore we select the meta and extract the content which gives us the token .
Dropzone provide’s a huge number of configuration options. Check out the documentation for all the available options. (Also don’t forget to thank the developer of dropzone )
Now that we are able to post files from the frontend, let’s work on our controller to receive and process the uploads on backend.
In the UploadController , let’s define a method storeUploadedFile() which receives a Illuminate\Http\UploadedFile and store all the metadata in our database.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected function storeUploadedFile(UploadedFile $uploadedFile)
    $upload = new Upload;
    $upload->fill([
        ‘filename’ => $uploadedFile->getClientOriginalName(),
        ‘size’ => $uploadedFile->getSize(),
    ]);
    $upload->user()->associate(auth()->user());
    $upload->save();
    return $upload;
getClientOriginalName() gives us the original name of the file that has been uploaded. getSize() returns the size of the uploaded file in bytes. We thenassociate()  the upload with the currently logged in user. Finally we save the file and return the model instance.
In the  store() method, we accept a Request and then from that request, we extract the file.
1
2
3
4
5
6
public function store(Request $request)
    $uploadedFile = $request->file(‘file’);
We are going to store this file in our local filesystem. Of course you can upload it to Amazon S3 or any other cloud storage services and laravel provides an excellent documentation on how to configure different storage services. However, I’m going to store the uploads on our local disk only.
Next we need to save the file metadata like name, size and the user who uploaded it to our database. For this, we can use thestoreUploadedFile() method we implemented above.
1
2
3
$upload = $this->storeUploadedFile($uploadedFile);
This returns us an instance of the Upload model. We can now use this to store the file.
1
2
3
4
5
6
7
Storage::disk(‘local’)->putFileAs(
    ‘uploads/’ . $request->user()->id,
    $uploadedFile,
    $upload->filename
);
The Storage facade is used to interact with the disk in which we are going to store the file. Storage::disk(‘local’)  gives us an instance of the local disk. The default local storage root is storage/app .
putFileAs() method is used to automatically stream a given file to a storage location. The first argument ‘uploads/’ . $request->user()->id is the upload path. We are creating a new directory uploads and within that directory creating another directory using user’s id  and storing the file there, so that all files uploaded by a user goes to the same location. For example, if a user’s id is 7, any file he uploads will be stored at storage/app/uploads/7/ .
The second argument in putAsFile() method is theIlluminate\Http\UploadedFile instance and the last argument is the filename that will be used to store the file. Because at this point, we already have stored the file’s metadata in our database, we can simply get the name of the file by  $upload->filename .
At this point, file storing is complete. Finally we send back a JSON  response with the uploaded file’s id.
1
2
3
4
5
return response()->json([
    ‘id’ => $upload->id
]);
That’s all. The file has been stored on our local disk.
# Deleting files
To remove a file, Dropzone provides a removedfile event, which we can listen to and then send a delete request. We will use axios to send the request.
We can register to any dropzone event by calling .on(eventName,callbackFunction) on our dropzone instance. Check this documentation for a list of different dropzone events and when they are triggered.
Now we need to use the id of the uploaded file in order to send the delete request. But from the frontend how could we possibly know what’s the id of a uploaded file? Well, this is where the JSON response from thestore() method is useful. When we uploaded a file successfully, we are sending back the id of the file from the backend. On a successful upload, we can therefore associate this id  with the file on the frontend.
1
2
3
4
5
drop.on(‘success’, function(file, response)
file.id = response.id;
);
When a file has been uploaded successfully, dropzone triggers a success  event. We can register to this event to get the file instance and theresponse from the backend inside the callback function. We simple assign theresponse.id to file.id . Therefore, for every file that we have successfully uploaded, now we have an identifier associated with it to be used on the frontend. Great!
Now that we have an id associated with each file, deleting files is easy. We listen for removedfile  event and then use axios from the global window object to fire a delete request to the backend.
1
2
3
4
5
6
7
8
9
10
11
drop.on(‘removedfile’, function(file)
axios.delete(‘/upload/’ + file.id).catch(function(error)
drop.emit(‘addedfile’,
id: file.id,
name: file.name,
size: file.size,
);
);
);
Notice how we are chaining the catch() method. This to catch any error when removing a file. If an error occurs that prevented the file deletion, we want to add it back so that the user knows the deletion failed and they may try again. We do that simply by calling the emit() method and passing in the details of the file. This will call the default addedfile event handler and add the file back.
Okay. So our frontend is ready to delete files. Let’s start working on thedestroy()  controller method.
Because we are injecting the file id on our delete request, we can therefore accept the file we trying to delete , destroy(Upload $upload) , using  laravel’s route model binding.   The next thing we need to do is verify if the delete request is actually coming from the owner of the file. Let’s create a policy,UploadPolicy  for that.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use App\User, Upload;
use Illuminate\Auth\Access\HandlesAuthorization;
class UploadPolicy
    use HandlesAuthorization;
    public function touch(User $user, Upload $upload)
             return $user->id === $upload->user_id;
     In the touch()  method, we are checking if the ids of the user who uploaded it and the user who is sending the delete request is same. In our destroy()  method, we can now use this touch()  method to authorize the request.
1
2
3
$this->authorize(‘touch’, $upload);
Finally we can delete the file.
1
2
3
4
5
6
7
8
public function destroy(Upload $upload)
$this->authorize(‘touch’, $upload);
$upload->delete();
Since we are using SoftDeletes , this will mark the file as deleted in the database.
That’s all folks.
The complete UploadController looks like this.
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
<?php
namespace App\Http\Controllers;
use Storage;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use App\Upload;
class UploadController extends Controller
    public function __construct()
             $this->middleware(‘auth’);
         public function store(Request $request)
          $uploadedFile = $request->file(‘file’);
        $upload = $this->storeUploadedFile($uploadedFile);
        Storage::disk(‘local’)->putFileAs(
            ‘uploads/’ . $request->user()->id,
            $uploadedFile,
            $upload->filename
        );
        return response()->json([
            ‘id’ => $upload->id
        ]);
         public function destroy(Upload $upload)
             $this->authorize(‘touch’, $upload);
        $upload->delete();
         protected function storeUploadedFile(UploadedFile $uploadedFile)
             $upload = new Upload;
        $upload->fill([
            ‘filename’ => $uploadedFile->getClientOriginalName(),
            ‘size’ => $uploadedFile->getSize(),
        ]);
        $upload->user()->associate(auth()->user());
        $upload->save();
        return $upload;
       # Conclusion
There can be so many different ways of implementing file uploads. Dropzone’s documentation includes an example section that have quite a few in-depth excellent examples. Don’t forget to check that out!
0 notes
mbaljeetsingh · 8 years ago
Text
Implement a Favoriting Feature Using Laravel and Vue.js
These days, various web applications are in one way or the other implementing a kind of favorite/like/recommend feature on the websites. These can be seen on sites like Medium, Facebook, Laracasts, and even here on scotch.io and school.scotch.io.
In this tutorial, I'll be showing you how to implement a favorites feature using Vue.js in your Laravel application. Though we'll be using the term favorites in this tutorial, this can be replaced with likes, recommends depending on your application.
What We'll Be Building
We'll be building a simple Posts app. This app will comprise of users and posts. Users will be able to create posts and as well mark posts as favorites. Finally, users will be able to see all the posts they marked as favorites.
The app will have a User model and a Post model, there will be an authentication system which will allow only authenticated users mark/unmark posts as favorites. We'll make use of VueJs and Axios to make marking/un-marking posts as favorites dynamic, that is without reloading the page.
Before we start building, let's take a quick look at what the Posts app will look like when we are done.
Let's Get started
We'll start by creating a new Laravel project, the name of the project will be laravel-vue-favorite.
laravel new laravel-vue-favorite
This will create a new Laravel 5.4 (which is the current version as at the time of this tutorial) project.
Installing NPM Dependencies
In a fresh installation of Laravel, Laravel provides some frontend frameworks and libraries with some basic setup to integrate these packages together. Among the frameworks and libraries are Bootstrap, VueJs and Axios, which we will be using in this tutorial. But we still need to install these dependencies through NPM:
npm install
Also, we'll make use of Laravel Mix to compile and build our CSS and JavaScript. The command above will also install all Laravel Mix dependencies.
Models And Migrations
For our Posts app, we'll need a User model (which comes with Laravel), a Post model and a Favorite model and their respective migration files.
php artisan make:model Post -m php artisan make:model Favorite -m
These will create a Post model and a Favorite model along with their migration files respectively. Open the posts table migration file and update the up() with:
/** * Define posts table schema */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->string('title'); $table->text('body'); $table->timestamps(); }); }
The posts table will contain an id, user_id (ID of the user that created the post), title, body, and some timestamps columns.
Next, open the favorites table migration file and update the up() with:
/** * Define favorites table schema */ public function up() { Schema::create('favorites', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->integer('post_id')->unsigned(); $table->timestamps(); }); }
The favorites table will be a pivot table. It will contain two columns: user_id which will hold the ID of the user that favorited a post and post_id which will the ID of the post that was favorited.
For the users table migration, we'll be using the default Laravel provided.
Before we run our migrations, let's setup our database. Add your database details to the .env file:
DB_DATABASE=laravue DB_USERNAME=root DB_PASSWORD=root
Remember to update with your own database details. Now we can go on and run our migrations:
php artisan migrate
Database Seeder
We'll also generate some seed data which we can test our app with. To generate dummy data, we'll make use of Laravel Model Factories. Laravel model factories make use of the Faker PHP library.
We'll generate dummy data of Users and Posts. When you open the database/factories/ModelFactory.php file, you will see that Laravel provides a User model factory, which means we only need to create a Post model factory. Add the snippets below to database/factories/ModelFactory.php just after the User model factory:
// database/factories/ModelFactory.php $factory->define(App\Post::class, function (Faker\Generator $faker) { // Get a random user $user = \App\User::inRandomOrder()->first(); // generate fake data for post return [ 'user_id' => $user->id, 'title' => $faker->sentence, 'body' => $faker->text, ]; });
Let's quickly run through the code. Remember from our posts table migration, we defined that a post must have a user ID. So, we get a random user and assign the user_id of a post to the ID of the random user, then we use Faker to generate the title and body of the post.
With our model factories done, let's move on to create our database seeder classes by running these commands:
php artisan make:seeder UsersTableSeeder php artisan make:seeder PostsTableSeeder
Open database/seeds/UsersTableSeeder.php and update the run() with:
// database/seeds/UsersTableSeeder.php /** * Run the database seeds to create users. * * @return void */ public function run() { factory(App\User::class, 5)->create(); }
This will create 5 different users with dummy data when the seeder is run. We'll do the same for Posts. Open database/seeds/PostsTableSeeder.php and update the run() with:
// database/seeds/PostsTableSeeder.php /** * Run the database seeds to create posts. * * @return void */ public function run() { factory(App\Post::class, 10)->create(); }
This will create 10 different posts with dummy data when the seeder is run.
Before we run the database seeders, let's update the database/seeds/DatabaseSeeder.php which is provided by default:
// database/seeds/DatabaseSeeder.php /** * Run the database seeds. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); $this->call(PostsTableSeeder::class); }
Now we can run the database seeders:
php artisan db:seed
You should now see some dummy data in your database.
Authenticating Users
Before a user can mark a post has favorite, the user must be logged in. So we need a kind of authentication system. Luckily for us, Laravel got our back on this. We'll use the artisan make:auth command to scaffold an authentication system.
php artisan make:auth
This will create all of the necessary routes and views for authentication. We can go and register as a user, which we will use to test the functionality of the application we are building.
Defining Our Routes
Let's define the routes of our application. Open routes/web.php and update with below:
// routes/web.php Auth::routes(); Route::get('/', 'PostsController@index'); Route::post('favorite/{post}', 'PostsController@favoritePost'); Route::post('unfavorite/{post}', 'PostsController@unFavoritePost'); Route::get('my_favorites', 'UsersController@myFavorites')->middleware('auth');
The routes are pretty straightforward. Auth routes that Laravel created when we ran the make:auth command. A route to the homepage that will list all posts, two other routes for favoriting and unfavoriting posts. Lastly, a route that displays all posts that have been marked as favorites by a user. This route will be accessible to only authenticated users.
When a user registers or login, Laravel will redirect them to the /home route by default. Since we have removed the /home route that Laravel created when we ran make:auth. We need to update the redirectTo property of both app/Http/Controllers/Auth/LoginController.php and app/Http/Controllers/Auth/RegisterController.php to:
protected $redirectTo = '/';
Defining Users To Favorite Posts Relationship
Since a user can mark many posts as favorites and a post can be marked as favorites by many users, the relationship between users and favorite posts will be a many to many relationships. To define this relationship, open the User model and add a favorites():
// app/User.php /** * Get all of favorite posts for the user. */ public function favorites() { return $this->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id')->withTimeStamps(); }
Laravel will assume the pivot table is post_user but since we gave the pivot table a different name (favorites), we have to pass in some additional arguments. The second argument is the name of the pivot table (favorites). The third argument is the foreign key name (user_id) of the model on which you are defining the relationship (User), while the fourth argument is the foreign key name (post_id) of the model that you are joining to (Post).
Noticed we chained withTimeStamps() to the belongsToMany(). This will allow the timestamps (create_at and updated_at) columns on the pivot table be affected whenever a row is inserted or updated.
Posts Controller
Let's create a new controller that will handle displaying posts, marking a post as favorite and unfavorite a post.
php artisan make:controller PostsController
Open the newly created app/Http/Controllers/PostsController.php and add the snippet below to it:
// app/Http/Controllers/PostsController.php // remember to use the Post model use App\Post; /** * Display a paginated list of posts. * * @return Response */ public function index() { $posts = Post::paginate(5); return view('posts.index', compact('posts')); }
The index() will get all posts and paginate them into 5 per page. Then render a view file (that we are yet to create) along with the posts, which will do the actual displaying of the posts.
Remember when we ran make:auth command that Laravel created some views. We'll be using the resources/views/layouts/app.blade.php that was created and make some few additions to it. Add the code below just after the <title>:
// resources/views/layouts/app.blade.php <link rel="stylesheet" href="http://ift.tt/2mrbfp2; />
Then add this just before the Logout list item:
// resources/views/layouts/app.blade.php <li> <a href="http://ift.tt/1uaQUM0">My Favorites</a> </li>
Now let's create the index view. Create a new posts folder within views directory and create a new index.blade.php file within the newly created folder. Paste the code below into resources/views/posts/index.blade.php:
// resources/views/posts/index.blade.php @extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="page-header"> <h3>All Posts</h3> </div> @forelse ($posts as $post) <div class="panel panel-default"> <div class="panel-heading"> </div> <div class="panel-body"> </div> </div> @empty <p>No post created.</p> @endforelse </div> </div> </div> @endsection
Pretty simple markup that displays a paginated list of posts. Open the homepage in your browser, you should see page like the image below:
Next, let's go back to PostsController and add the methods that will handle marking a post as favorite and unfavorite a post. Add the code below to PostsController:
// app/Http/Controllers/PostsController.php // remember to use use Illuminate\Support\Facades\Auth; /** * Favorite a particular post * * @param Post $post * @return Response */ public function favoritePost(Post $post) { Auth::user()->favorites()->attach($post->id); return back(); } /** * Unfavorite a particular post * * @param Post $post * @return Response */ public function unFavoritePost(Post $post) { Auth::user()->favorites()->detach($post->id); return back(); }
The favoritePost() takes a post as an argument. Using the favorites relationship we defined above, we attach the post ID to the ID of the authenticated user then insert into the favorites table. Finally, return back to the previous page.
The unFavoritePost() is the reverse of favoritePost() which simply remove the ID of the authenticated user along with the post ID from the favorites table.
Integrating With VueJs
It's time to integrate Vue into our application. We'll make the favorite button/icon a Vue component. Making it a Vue component will allow for reuse in multiple places with our application.
Once the favorite button/icon is clicked, we'll mark the post as favorite or unfavorite without reloading the page, that is through AJAX. For this, we'll make use of Axios which is a Promise based HTTP client for the browser and node.js.
Creating The Favorite Component
Create a new Favorite.vue file within the resources/assets/js/components folder and paste the code below into it:
// resources/assets/js/components/Favorite.vue <template> <span> <a href="#" v-if="isFavorited" @click.prevent="unFavorite(post)"> <i class="fa fa-heart"></i> </a> <a href="#" v-else @click.prevent="favorite(post)"> <i class="fa fa-heart-o"></i> </a> </span> </template> <script> export default { props: ['post', 'favorited'], data: function() { return { isFavorited: '', } }, mounted() { this.isFavorited = this.isFavorite ? true : false; }, computed: { isFavorite() { return this.favorited; }, }, methods: { favorite(post) { axios.post('/favorite/'+post) .then(response => this.isFavorited = true) .catch(response => console.log(response.data)); }, unFavorite(post) { axios.post('/unfavorite/'+post) .then(response => this.isFavorited = false) .catch(response => console.log(response.data)); } } } </script>
The Favorite component has two sections: template and script. In the template section, we defined the markup that will be rendered when the component is used. We are using conditional rendering to show the appropriate button/icon. That is, if isFavorited is true, the button/icon should be marked as favorite and on click of the button/icon should trigger unFavorite(). Else the button/icon should be marked as unfavorite and on click of the button/icon should trigger favorite().
Moving on to the script section, we defined some properties for the component; post (will be the ID of the post) and favorited (will either be true or false depending on if the post has been favorited by the authenticated user). We also defined an isFavorited data which will be used for the conditional rendering from above.
When the component is mounted, we set the value of isFavorited to the value of isFavorite computed property. That is, the isFavorite computed property will return the value of favorited prop which will either be true or false. We use a computed property so as to reactively get the value of the favorited prop instead using the value of favorited prop that was passed directly.
Lastly, we defined two methods: favorite() and unFavorite() which both accepts the post prop as arguments. Using Axios, we make a POST request to the routes we defined earlier. For the favorite(), once the POST request is successful, we set isFavorited to true and otherwise console log the errors. Same is applicable to the unFavorite() just that we set isFavorited to false.
Registering The Favorite Component
Before we can start to use the Favorite component, we need to first register it on our Vue root instance. Open resources/assets/js/app.js, you will see that Laravel register an Example component. We are going to replace that with the Favorite component:
// resources/assets/js/app.js Vue.component('favorite', require('./components/Favorite.vue'));
Now we can compile and build our styles and scripts:
npm run dev
Using The Favorite Component
We can now use the Favorite component. Open resources/views/posts/index.blade.php and add the snippets below to it after the closing div of the panel-body:
// resources/views/posts/index.blade.php @if (Auth::check()) <div class="panel-footer"> <favorite :post= :favorited= ></favorite> </div> @endif
The favorite button/icon will only be displayed to authenticated users. As you can see, we passed to the Favorite component the props that we defined when we created the component. To know if a post is has been favorited by the authenticated user, we call a favorited() (which we are yet to create) on the post.
To create favorited(), open app/Post.php and add the code below to it:
// app/Post.php // remember to use use App\Favorite; use Illuminate\Support\Facades\Auth; /** * Determine whether a post has been marked as favorite by a user. * * @return boolean */ public function favorited() { return (bool) Favorite::where('user_id', Auth::id()) ->where('post_id', $this->id) ->first(); }
This gets and casts to boolean the first result where the user_id is equal to that of the authenticated user and where the post_id is equal to the ID of the post the method is called on.
If you visit the homepage of the application in the browser and login, you should get something similar to:
As you can see I have marked some posts as favorites.
Displaying User Favorite Posts
Won't it be nice for users to be able to see all the posts they have marked as favorites? Sure it will be. Remember we defined a my_favorites route that will be accessible to only authenticated users, this is where users will be able to see the posts they've marked as favorites.
Let's create a UsersController that will handle this route.
php artisan make:controller UsersController
Open app/Http/Controllers/UsersController.php and add the code below to it:
// app/Http/Controllers/UsersController.php // remember to use use Illuminate\Support\Facades\Auth; /** * Get all favorite posts by user * * @return Response */ public function myFavorites() { $myFavorites = Auth::user()->favorites; return view('users.my_favorites', compact('myFavorites')); }
The myFavorites() uses the favorites relationship we defined earlier, get all the posts that the authenticated user has marked as favorites. Then return a view along with favorites posts.
Now let's create the view. Create a new users folder within the resources/views directory and within the users folder, create a new file my_favorites.blade.php and paste the code below to it:
// resources/views/users/my_favorites.blade.php @extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="page-header"> <h3>My Favorites</h3> </div> @forelse ($myFavorites as $myFavorite) <div class="panel panel-default"> <div class="panel-heading"> </div> <div class="panel-body"> </div> @if (Auth::check()) <div class="panel-footer"> <favorite :post= :favorited= ></favorite> </div> @endif </div> @empty <p>You have no favorite posts.</p> @endforelse </div> </div> </div> @endsection
The markup is similar to that of index.blade.php. As you can see, we also used the Favorite component. When viewed in the browser, you should see something similar to:
Conclusion
That's it, we are done building the Post app and seen how to allow only authenticated users mark/unmark posts as favorites without reloading the page using VueJs and Axios. I hope you find this tutorial useful. If you encounter any problems following this tutorial or have questions/suggestions, kindly drop them in the comment section below. Also, I have made a vue-favorite component based on this tutorial which can be installed through NPM.
via Scotch.io http://ift.tt/2mptpr0
0 notes
mbaljeetsingh · 8 years ago
Text
Quick Tip: Display Dates Relatively in Laravel
We have previously looked at the Carbon package by Brian Nesbitt as well as all the functionality it adds to PHP's DateTime class.
In this article, we will take a look at how Laravel takes advantage of this package.
Introduction
As already mentioned, The carbon class does not rebuild PHP's DateTime class from scratch, it builds upon it.
<?php namespace Carbon; class Carbon extends \DateTime { // code here }
This means that you can access the default functionality of PHP's DateTime class on top of the awesomeness that is Carbon.
Laravel already includes the Carbon class by default so we do not need to install it separately. To get started with Carbon in Laravel, simply create a new project using the laravel command.
$ laravel new scotch-dates
Carbon Dating in Laravel
See what I did there? Turns out Brian Nesbitt had the same idea in mind while creating the Carbon package.
Now by default, if the timestamps variable in a Laravel model class is not explicitly set to false, then it is expected that it's corresponding table should have the created_at and updated_at columns.
We can however go ahead and add our own date columns such as activated_at, dob or any other depending on the type of application or the nature of the Laravel model we are working on.
But how does laravel know that these fields should be cast to date?
Simple. Add all the date fields to the protected dates variable in the model class.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = [ 'created_at', 'updated_at', 'activated_at', 'dob' ]; }
Setup
In our scotch-dates application that we just created, we already have a our first migration setup for the user's table. We will need to have some user records to work with, so let's seed some data in our database with the factory helper method on tinker.
$ php artisan tinker >>> factory('App\User', 10)->create()
To get started, we'll go ahead and create a new UserController class to get all the user's from the user's table into a view and add a /users route.
/routes/web.php
Route::get('/', function () { return view('welcome'); }); Route::get('/users', 'UserController@users');
I have gone ahead to add a few helper variables courtesy of the Carbon class to give me access to a few dates such as now, yesterday, today and tomorrow.
/app/Http/Controllers/UserController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; use Carbon\Carbon; class UserController extends Controller { public function users() { return view('users', [ 'users' => User::all(), 'now' => Carbon::now(), 'yesterday' => Carbon::yesterday(), 'today' => Carbon::today(), 'tomorrow' => Carbon::tomorrow() ]); } }
Let's play around with Carbon dates on the user's view.
Displaying Absolute Dates
Having setup our user's details and passed them on to the users view, we can now display each of the users with the following blade template.
<table> <tr> <th>Name</th> <th>Created</th> </tr> @foreach($users as $user) <tr> <td></td> <td></td> </tr> @endforeach </table>
With this, we should have the following.
Displaying Dates Relatively
Displaying dates relatively is quite popular since it is easier for humans to read out a post as created 30 minutes ago as opposed to 2017-01-08 19:15:20.
Let's play around with the Carbon class to see how we can display the dates relatively in different ways.
When comparing a value in the past to default now:
This comes in handy when you want to display a date in the past with reference to the current time. This would be something like:
A few seconds ago
30 minutes ago
2 days ago
1 year ago
To achieve this, we simply use the diffForHumans method.
$user->created_at->diffForHumans() // 1 hour ago
When comparing a value in the future to default now:
You'd probably want to use this in cases where you need to publish a post in the future or show an expiration date.
1 hour from now
5 months from now
$user->created_at->addDays(5)->diffForHumans() //5 days from now
When comparing a value in the past to another value:
1 hour before
5 months before
$yesterday->diffForHumans($today) //1 day before
When comparing a value in the future to another value:
1 hour after
5 months after
$tomorrow->diffForHumans($today) //1 day after
More About Diffs
While it may be nice to display to the user fully quallified diffs such as 2 hours ago, you may at times simply want to show the user the value without the text.
This may come in handy where you have many comments coming in and the text is just too repetitive. diffInSeconds() in particular can be used in cases where the difference in time between two entities, say, lap times, is of significance.
This can achieved by the diffInYears, diffInMonths(), diffInWeeks(), diffInDays(), diffInWeekdays(), diffInWeekendDays() diffInHours(), diffInMinutes() and diffInSeconds() methods.
$user->created_at->diffInHours(); //2 $user->created_at->diffInMinutes(); //134 $user->created_at->diffInSeconds(); //8082
The carbon class also come with methods that return the number of seconds since midnight or to the end of the day (midnight) which can be used to create a countdown, say, for a product sale.
$now->secondsSinceMidnight() //77825 $now->secondsUntilEndOfDay() //8574
Conclusion
There's alot you can achieve with the Carbon class and sometimes you will not find out about a functionality that it provides until you need it.
Take a look at the documentation here. Happy Carbon dating!
via Scotch.io http://ift.tt/2koKYn4
0 notes