Moving MAX and MIN calculation into a sub query to preserve the full result set in the outer query
Since you have aggregate functions in your SELECT clause, you need to specify what groups to apply them to. If you add:

GROUP BY   p.id
 , p.date
 , p.title
 , v.total_views
 , r.total_rating
 , r.module
 , r.module_id


before ORDER BY in your query, you will get 1 row per such group.

Without a GROUP BY clause, MySQL will randomly pick 1 row for you. This is a well-known bug in older MySQL versions.