0

I am currently working on a application with a edit button:

My edit button:

<th title="Edit task" class="edit" style="float: right; $color;">
    <?php
    echo "<a href=edit.php?id=" . $row["id"] . ">
              <i class=material-icons>edit</i>
          </a>";
    ?>      
</th>

My goal is that only one person can edit a article at a time. Is this even possible? If it is how can I do it?

Barry
  • 3,303
  • 7
  • 23
  • 42
J.vee
  • 623
  • 1
  • 7
  • 26

8 Answers8

2

If you only want to disable button to avoid concurrency editing then it is a terrible idea because users always can open the edit page by direct link. In fact, you need to implement concurrency control.

You can implement locking of record to concurrency control.

For example, you can use the following simple algorithm for the implementation of concurrency control:

  1. You add param that will contain an end time of locking to article
  2. On the edit page: you compare this time with current time if locking time greater then current time then you inform a user about the impossibility of article modified, else you show edit page to the user
  3. On the edit page: if you show edit page of an article to the user then you increase end time of locking param for example in increments of 5 minutes
  4. If the user finishes a record modification and saves it then you should reset end date of locking

But instead of this algorithm, you can implement optimistic locking.

Optimistic locking provides users open an edit page at the same time, but it forbids to save record in a parallel way. It is a better way to avoid troubles of parallel modification of a record

Optimistic locking consists in acceptance or rejection сhange of record to depend upon record version.

It works following: each article has a 'version' param that contains number of record modification. One user opens the edit page of an article that has version equal to 1 and another user opens it at the same time. Both of them save the same article. At first, you get one request for record modification and compare version of a stored record with version of an updated record if they equal one another then you should accept change and save an updated record in a storage and increase 'version' param in increments of 1 otherwise, you should reject change. As a result of this algorithm, the stored record will have version equal 2. Next, you get the second request and compare versions again, but since version of a stored record is equal 2 and version of an updated record from second request equal 1 this change is rejected. Of course, you must inform the user about the rejection of its change and give the user an ability to update the new variant of record

Maksym Fedorov
  • 6,383
  • 2
  • 11
  • 31
1

This is what I have done in my application:

When a user presses edit button, log the timestamp in database and redirect user to edit page. In edit page set a timer and show it to user that can edit record until timer runs out.

For example based on your record you can consider 2 minutes for user to edit a record. Time will start from 01':59'' and reach to 00':00''.

For other users when click on edit button, you should check if another user is editing that record and you can do this by calculating time from the log in database and now.

If user edits record under 2 minutes and saves it, you can remove edit log to let others users to edit.

Ali Farhoudi
  • 5,350
  • 7
  • 26
  • 44
0

it's not completely possible as of my point of view.

but try to do with below way.

you could add two columns in your database 'open' and 'time'

Set 'open' to 'true' or 'false' if someone is editing it. Also set a timestamp to the 'time' column. Replace the timestamp every so many seconds while editing takes place.

If someone else opens it, check the 'open' column and of it's 'true', calculate the time passed from the 'time' column. If it's over a certain time (say 2 or 3 minutes), assume the other user isn't editing anymore and allow this user to edit.

To make things clear,

you need to add one ajax call which is update your timestamp after every min/sec. if you are in edit page. so if someone close the browser then timestamp will not update and after next user is tried to edit then if timestamp is older then 2/3 min then allow to edit that user. beacuse we assume that user is close the tab or browser so flag is not updated but timestamp is older.

this is not perfect solution but you can try it.

Yagnik Detroja
  • 921
  • 1
  • 7
  • 22
0

There is the easy way and the hard way.

Easy way: Check concurrency on save with a timestamp.

You can simply add a timestamp (usually named update_at) in your database along with your data.

You put the timestamp in the page (or a $_SESSION variable which is safer) so that when you POST your changes you also post the timestamp. On the server side you verrify if the timestamp in your database is the same as the one you posted and if it's not you return a message saying that the post was editted.

If you care about what the user was typing (and most of the time you should) you can always display both edit side-by-side and allow him to choose/edit one of them.

Hard way: Store lock timestamp in your database

You can add a timestamp with your data the same way as in the easy way (but this time we'll call it last_edit_time).

When a user enters on the edit page you do this:

  • You check if the last_edit_time is 30 seconds away from the current time
    • If it's been less than 30 seconds you return a message saying the data is being editted
    • If it's greater than 30 seconds you set the value of your last_edit_time to the current time and show your edit page
  • Once the user is on the edit page you start a javascript interval of 15 seconds
    • Every 15 seconds you send an asynchronous request (Ajax) to the server telling it to update the last_edit_time to the current time. We send it every 15 seconds so that if the asynch call takes a long time the user comming to edit right on the 30th second doesn't load the page.

Doing this will assure you that only one user can access the page at the same time. If you want to make it even more secure you would add the user Id next to your last_edit_time to verrify on the moment of saving if it is the same user.

You can even set the last_edit_time to null once the user is done editting. This will unlock the data for everyone as soon as possible.

Of course there can be some edge cases where two users opens the page in the same second. To fix this you can always increase the precision of your timestamp (milliseconds instead of seconds).

Stefmachine
  • 382
  • 4
  • 11
0

You can do this very easily Please follow these step.

1)Create one table name as editLog where you column id,member_id/user_id,is_editable(default 1)

2)Now in initial stage table is empty first user came to edit fire AJAX when user click on edit at the same time check from the database if any data is not exiting in the table then allow him to make the changes(and when you save or update the data in table check with member id also to ensure member are same) and if data exit then give him the error of warning..

Follow these step if you still have confusion comment.

Bhanu Sengar
  • 372
  • 2
  • 10
0

The table from which you are getting $row["id"] add one more column in it and name that column as ipAddress with default value of null.

Now when user go to "/edit.php?id=$id" update the ipAddress column of table with user ip. You can easily get the user ip address by JS or by Server variables.

After that in edit.php you can easily check if current ip is equal to the ipAddress like:

    if($_SERVER['REMOTE_ADDR'] == $ipAddress){
      // Allow edit
    }
    else {
      // Donot allow edit
    }

And after edit is done or browser close you can set ipAddress to null.

Kunal
  • 603
  • 4
  • 13
-1

I did a little research and I found out that it is really hard to get this done... What you can do is run a check if there is a recent update on the article (same as pending edits on SO)

J.vee
  • 623
  • 1
  • 7
  • 26
-1

According to my understanding, the solution to your problem is very simple.

  • First, make a table or tables in which you will record the update queries made by users in your own way
  • Make a script which will execute the oldest query of the table which you made in the first step and then delete that query on success mean after updation is run successfully
  • Learn Cron Jobs
  • Create a cron job for that script for a certain interval of time

And enjoy your life :)

Zain Farooq
  • 2,956
  • 3
  • 20
  • 42