Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nathanrobjohn's avatar

Edit post by user and admin approval

Hi Guys,

I am trying to think of a way that a user can edit a post on the frontend but a admin has to approve before the update is made? i can't seem to figure out the best solution for this, does anyone have any suggestions on how to make this work?

Regards Nathan

0 likes
24 replies
mstnorris's avatar

Set an extra boolean column on the posts table of approved. When a User edits the Post, you set the value of approved back to false.

When a Post is created (if you want it to be approved from the start), then set the initial value to false. Of course, you can use true/false, _1/0_ etc. It just depends on what data type you prefer to work with.

An Admin can then see all Posts that need approval, and you can implement this accordingly.

To protect the routes, you'd need to look into Middleware.

Kryptonit3's avatar

create a temporary table identical to your post table so you can store the existing in post and edited in temp table. create a foreign key in post table edited_id that references id from temp table. add a flag on the post table like @mstnorris says to see if the post has been edited, once you review the edited post (maybe side by side? current | edited) click a link to "approve" the change and use logic to grab content from temp table to overwrite existing post table content.

and maybe a hasOne\belongsTo relation on the Post table to the temp table so you can check the boolean, and then grab the temp data.

then you could add a counter to notify you like TempTable::all()->count() that will let you know there are posts that have been edited then grab them with $edited = Posts::where('boolean_column',true)->get();

then just grab the data from the relation in a loop

something along those lines I would think.

mstnorris's avatar

@Kryptonit3 that sounds overly complicated. I'm not saying it wouldn't work but @nathanrobjohn didn't specify that they needed to compare the edits so in my opinion you'd be better off explaining your approach and the reasons why.

There are always multiple ways to implement anything, of course we could always ask the OP for more information. But based on the information given, setting an extra column on the posts table is definitely the better (simpler) way to go.

Kryptonit3's avatar

@mstnorris - My example is so you can store the edited data while maintaining the existing data and giving you the power to see if you want to approve the edit. Where else would you store the temporary edited data? I am assuming you do not want to overwrite the existing data without approving it first.

If approved, overwrite existing with temp edit data. if not, delete temp edit data and set boolean back to false.

mstnorris's avatar

I understood your approach, but I thought you should make it clear to the OP (and others), why they should choose your approach. Yes, it would be great to be able to review the edit and take action accordingly.

1 like
nathanrobjohn's avatar

Thank you @mstnorris that is currently how i have it set up but obviously the post will disappear on the front end , this is probably my fault as i didn't explain properly i want to be able to keep the post live and make a duplicate of the "live" post and then copy the edits across if the admin approves the changes.

@Kryptonit3 Thank you for your answer this is how i want it so work but would i be able to have multiple edits? from different users?

Kryptonit3's avatar

@mtnorris I agree. But just adding a boolean column will just be a way of notifying that an edit was made. OP stated they wanted a "way that a user can edit a post on the frontend but a admin has to approve before the update is made".

With your approach there is no option to store updated content, thus nothing to approve or update.

1 like
Kryptonit3's avatar

@nathanrobjohn is your intention to only have one working "temporary" edit? if so, then a hasOne\belongsTo is the way to go. If you want to store all edits then you would need a hasMany\belongsTo and then a reference to the current approved post on the thread and write logic to view all edits. But once an approved edit is made in my opinion, there is no need for previous edits unless you need that for your project. Who knows. :)

mstnorris's avatar

I'm just thinking aloud here, but another approach would be to create a new Post each time you edit it, that way you can keep all revisions.

You could add another column to the posts table to link to the "new" Post. Each time you create a new one, you grab the new ID and save it to the previous version of the Post. Or, each time you update a Post (by creating a new one) you link back to the previous version. Both accomplish essentially the same thing.

1 like
Kryptonit3's avatar

@mstnorris that is a good idea if he wants to keep all revisions. no need for extra table or relation. Just a referencing id on the thread to the latest post, and backend logic to view all edits.

mstnorris's avatar

@Kryptonit3 yes that is what I am referring to. I've never been a fan of creating two essentially identical tables. Just another column to link the IDs of the different revisions of the post.

jekinney's avatar

It would be kinda confusing if you had multiple posts of the (essentially) same post. You would eliminate any unique checks etc. Having a post table, edited and possibly and archive table could be equally confusing too.

Good question though, and good answers. Has me thinking....

mstnorris's avatar

@jekinney I don't think it would be confusing to store multiple revisions of a post within the same table.

| id | previous_id | title                      | body                                        | approved |
|----|-------------|----------------------------|---------------------------------------------|----------|
| 1  | 1           | First Post Title           | This is my first post.                      | true     |
| 2  | 1           | Title of my First Post     | This is an edited version of my first post. | true     |
| 3  | 3           | This Is A Second Post      | This is a second post.                      | true     |
| 4  | 1           | The Title Of My First Post | Oops I did it again! This is another edit.  | true     |
| 5  | 3           | This Is My Second Post     | This is a second post. Just edited.         | true     |
| 6  | 6           | A Third Post               | You get the idea.                           | true     |
| 7  | 6           | Blah Blah Blah             | You get the idea. HFKDHFKSDFHKSDH           | false    |

I hope the above is clear, whenever a new post is created, approved can either default to true or false. When an edit is approved, it is then used.

4 likes
nathanrobjohn's avatar

@Kryptonit3 Would you recommend maybe having a revisions model with a revisions table?

thank you for all the help and replies

mstnorris's avatar

@nathanrobjohn I wouldn't recommend that. Post and Revision would be the same. Think about it this way (it's kinda philosophical but)

A Post with no Revisions is the first Revision. Ergo they are the same.

1 like
Kryptonit3's avatar

do you just want the thread starter post to be held in moderation for its edits or all posts on that thread as well?

@nathanrobjohn

nathanrobjohn's avatar

@mstnorris i get what your saying but obviously there will be a post and won;t be any revisions until a frontend user edit's a post as a admin would always update the active posts. How else would you go about it if not creating a model for revisions? i am going to go with the way @Kryptonit3 explained but i would of created a Revisions model and table and have the table like explained above? then when a front end user edits a post then it will go into the revisions table for an admin to approve and once approved will find the current post id inside of the revisions column and then post the new content to the current post? in my head the current post would never change id etc it would just update the content from the revision

mstnorris's avatar

You set the revision to the same id, see my previous table. Having two tables for the same thing is not wise, it goes against data normalisation and one of the fundamental programming principles.

nathanrobjohn's avatar

@Kryptonit3 its not like a forum this is what i have currently

blog post model admin can edit , create blog post user can create blog post which then a admin must approve a user can edit a blog post

the last part i want the user to edit the blog post which they then submit and will be entered into a revisions table with the blog post id they have edited an admin would then review the edit and once the admin clicks accept edit it would then find the live blog post from the post_id column in the revisions table and copy the content from the row in the revisions table to the current blog post

i might be saying it wrong but wouldn't it be easier to have the following:

Blog post model : has many revisions

| id  | title |
| ------------- | ------------- |
| 1  | title  |
| 2  | title  |

Revisions model : belongs to post

| id  | title | post_id |
| ------------- | ------------- | ------------- |
| 1  | title  | 2 |
| 2  | title  | 2 |

@mstnorris

nathanrobjohn's avatar

@mstnorris they are the same basically would you suggest something like this then? inside my blog posts model:

class BlogPosts extends Eloquent {

    public function __construct($posts , array $attributes = array())
    {
        parent::__construct($attributes);

        $this->table = $posts;
    }

}

then when creating post have :

$post = new BlogPosts('posts');

and when creating revision have :

$revisions = new BlogPosts('revisions');
mstnorris's avatar

Well, in my head at least I would think that when you create a new Post (please bear in mind this is semi-pseudo code and I haven't tested it and it's just to give you an idea of how I'm thinking about it).

$post = Post::create([
    ...
    'title' => '...',
    ...
]);
$post->revision_id = $post->id;
$post->save();

When you update a Post, you are effectively creating a new one, and setting the revision_id to the previous revision.

Does that make sense?

nathanrobjohn's avatar

@mstnorris thank you for the help so far i don't think that would work only using one table as you would then be creating a new post with a new id everytime that you accept a revision which then would obviously change id and won't index in google properly. kind of stumped with this i might go with what @Kryptonit3 suggested and change a few things and have two tables seems the most sensible for what i am looking for.

Kryptonit3's avatar
Level 11
Models: User, Thread, Post, Revision
User hasMany Thread
Thread belongsTo User
Thread hasMany Post
Post belongsTo Thread
Post hasMany Revision
Revision belongsTo Post

Table Design (example)
Thread: id,title,user_id,timestamps()
Post: id,thread_id,user_id,text,timestamps() (no need for a boolean as we only want to check if they edit, not initial post)
Revision: id,post_id,text,approved(boolean, default false),timestamps()

Then when displaying the thread you will loop over posts to display (or extract logic to repo), in that loop you can check $post->revision->count() and if it is greater than 0 check if any of the revision have their column approved set to true, then grab the latest() one with approved column set to true. That is what I would do.

This is a raw example

// mysite.com/thread/{id}
// $posts = Thread->posts->oldest() // you will want to show oldest first, like any site forum

foreach($posts as $post)
{
    if($post->revision->where('approved',true)->count() > 0) // show latest approved post content
    {
        $updated = $post->revision->where('approved',true)->latest()->first(); //sort by a timestamp column desc (latest) and just grab the first approved one
            // display post
            $updated->text
    } else {
        // there are no revisions, or no approved revisions so display original post content
        $post->text
    }
}

This is just a general example. It may or may not be ideal code design. Just showing a general idea on how I would go about it. You could then have a ticker with $count = Revision::where('approved',false)->count() that shows if there are any posts that have been edited that you need to approve. If you approve it, change approved to true, if not, delete post all together.

If you do not want to delete the revision even if you deny it then add a seen boolean column to revision table and mark that as true and change the counter logic to this $count = Revision::where(['approved' => false, 'seen' => false])->count()

That way, if you seen it, and deny it, the approved column stays false, and seen counter updates to true and you are no longer notified about it. @nathanrobjohn

Please or to participate in this conversation.