You need to have PHP, NodeJS and MySQL to run this project. We recommend using Laravel Valet in local development.
$ cd exercise-repo
$ composer install
$ cp .env.example .env
$ php artisan key:generate
Note: Do not forget to start your database!
Make sure to update your .env
file:
DB_DATABASE={your-database}
APP_URL={your-url}
Once you're done, you can seed the database with data:
$ php artisan migrate --seed
You can run application tests with Artisan:
$ php artisan test
- Any user can sign up and create their own blog (back office)
- Any visitor can see all posts (front)
- Need to register, be logged in login.
- email, unique and valid
- password, 8 characters mini and some special characters
- username, unique with no special characters. Slug
- Order by published_at, from now to older (reverse chronological)
- Need pagination (8 per page).
- Permalink page
<site>/<username>/<post_unique_slug_from_title>
. - Each post view should include a link back to the user's author
<site>/<username>
- title, slug
- author_id, id of the user who has made the post
- body, text
- published_at, datetime (when a post is published)
- Updated packages using
composer update
. - Checked unit tests by running
php artisan test
. (cmt: composer update and unit tests checked)- fixed
could not find driver (SQL: PRAGMA foreign_keys = ON;)
issue by enabling thepdo_sqlite
extension.
- fixed
- Created an account and tested everything that is written down in the "Initial requirements" section. (cmt: initial review of application)
- During this process, I was able to replicate the permission issue (#2) by replacing the post's slug in my post's edit page URL with other post slug created by another user.
- The permission issue #1 doesn't exist - The user can't edit content without logging in.
- Strategy: While it is an existing project, I decided to maintain the existing style and make as few changes as I can.
- Issue #1: Stronger passwords. (br: stronger-passwords-issue-1)
- Found the
PasswordValidationRules
trait with the methodpasswordRules
used in password-related validations. - Updated rules, added:
'min:8'
,'regex:/[^\w]/'
. - Added a new method
passwordCustomMessages
for specifying that the regex error is related to special characters. - Passed custom messages (using unpacking
...
operator) as a second parameter in every action which uses thepasswordRules
method. (cmt) - Added the new
test_registration_fails_with_invalid_password
test case. (cmt) - Created PR and merged.
- Found the
- Issue #2: Permissions. (br: post-permissions-fix)
- Found
PostPolicy
and post's update and store requests, which are used in the posts controller. - Registered
PostPolicy
inAuthServiceProvider
. - Added try/catch block in PostController's
update
method to authorize the user and return an error message. (cmt) - Added the new
test_user_cannot_edit_other_users_post
test case. (cmt) - Created PR and merged.
- Found
- Issue #3: Performance. (br: performance-issues)
- Reviewed code and found out:
- The
posts
query seems nice and could be optimized in some small details, but it isn't critical. - The
authors
query needs a lot of optimizations and has critical issues.
- The
- Optimizing
authors
query used in the sidebar component ("Random authors"):- Moved the take method before the
get
method in the query chain. - The method
with
was replaced with thewithCount
method and addedis_active = true
condition to replicate the logic used in theauthors.blade.php
template - Updated the
authors.blade.php
template to useposts_count
property - Updated the
@include
directives - passing the authors variable to make obvious, which data is used by the component (increases readability) - Tested, worked - centralized the updated query as a scope to reuse in other controllers (cmt)
- Moved the take method before the
- Considerations about the
posts
query:- Posts query is a pretty good one. I would consider with PM to disable the future publishing (
'published_at', '<=', Carbon::now()
) check in the Post'spublished
scope (if it isn't planned), because it is useful with publish scheduling feature and we haven't it in this project. - I would consider adding caching by pages here, but this change adds the "delay" in displaying new posts on the front, so it needs some discussion too.
- Also, indexing some columns (author_id, published_at) could be helpful.
- Posts query is a pretty good one. I would consider with PM to disable the future publishing (
- Created PR and merged.
- Reviewed code and found out: