Lock records: A step-by-step guide

There has been a major change on 2019/09/22 in the events_lock_record()-function. This function has to return FALSE to skip overwriting membership after events_after_insert() call.

In Step 2 please have a look at lines 24 – 27 and change your code.

It has been requested many times: this is a step-by-step guide for conditionally locking records in AppGini applications.

This example will show how to lock a record and make fields readonly depending on the status of the record. I’m using the well known “OCMS” (clinic management) which is an AppGini demo project available here: http://bigprof.com/appgini/applications/online-clinic-management-system .

To illustrate the necessary changes I’m going to change the existing events-table (“Appointments”).

Whenever the user changes the status to Closed the record will be locked.

Due to the limits of AppGini 5.7x, not every field type can be locked. For example dropdowns, date-pickers and richtext editors will still look like editable and still be editable even if user has no permission to edit or insert.

What we can do is locking most of the field types and deny saving.

Locking all controls is a different story which will be told another day. See my last comment at the bottom of this page.


Ensure that you have a separate user-group with at least one member for testing purposes. I’m going to create a group doctors with one member doctor1 for this example.

Create Group

Go to Admin-Area

Create a group (if you don’t have one already) and grant the following permissions:

Create User

Create a new group-member (if you don’t have one already)

Now check if you can login as the newly created user. Also check if you can enter the table which you like to lock later on. In this example it is table events.


Step 1: Changes in AppGini project

1.1 Add a new status “Closed”

First we need a field which will be used to control the locking state. In this example we can use the already existing field status.

Before we change the field, let’s have a look at the form:

There is only these two options available. We are going to add Closed as third option now:

The status field is an “Options list” fields with list values “Active;;Cancelled”:

Available list options:

Add ;;Closed

1.2 Add a new field “created_by”

Create a new field which will will hold the creator of the record.

We will need this field later on whenever we need to unlock the record again.

1.3 Hide “Save As Copy”

1.4 Save and generate

Let us check the result: Now we can see all three options.

Step 2: Code changes in hooks/events.php

Whenever a user saves the record we have to check the status and lock it if status = "Closed".

This check shall be executed after insert and after update.

I am going to write a re-usable function named events_lock_record() for this to avoid redundant code. This new function will be called after insert and after update

Let’s open hooks/events.php in our code editor and insert some code.

// file: hooks/events.php

// add this:
function events_lock_record($data, $memberInfo, &$args)
	$status = $data["status"];
	$table = "events";

	// PHP 5
	$id = $data["selectedID"] ? $data["selectedID"] : $data["id"];
	$creator = $data["created_by"] ? $data["created_by"] : $memberInfo["username"];

	// in PHP 7 you can write
	// $id = $data["selectedID"] ?? $data["id"];
	// $creator = $data["created_by"] ?? $memberInfo["username"];

	$owner = "admin";
	if ($status === "Closed") {
		set_record_owner($table, $id, $owner);
	} else {
		set_record_owner($table, $id, $creator);

	// update 2019/09/22
	// by returning FALSE we exit the AppGini function
	// BEFORE AppGini overwrites our ownership-setting
	return FALSE; 

// ...

// change this existing function
function events_after_insert($data, $memberInfo, &$args)
	return events_lock_record($data, $memberInfo, $args);

// ...

// change this existing function
function events_after_update($data, $memberInfo, &$args)
	return events_lock_record($data, $memberInfo, $args);

Step 3: Login and test


Solved issues

At this point we have reached the following:

  1. Users can insert and edit records as long as status is not Closed
  2. As soon as status = "Closed" users will still be able to see the record but not able to save changes any more

Open issues at this point

  • some fields are not locked, yet. As metioned at the beginning, certain fields like dropdowns, richtext-aread or datepickers are still editable.

Solving open issues

We are currently working on a couple of new cool features for our AppGini Helper JavaScript library.

One feature will help us on the open issues mentioned here: .readonly()-function which will work even for dropdons, datepickers or richtext fields.

Jan Setzer

Jan Setzer, Jahrgang 1972, ist Wirtschaftsinformatiker (BA) und gelernter Verwaltungsfachangestellter mit über 20 jähriger Berufserfahrung in Software-Entwicklung und IT-Projektgeschäft. Viele Jahre war er als Abteilungsleiter tätig und für Produktentwicklungen und Softwareprojekte zuständig. Als selbständiger Software- und IT-Berater arbeitet er für Behörden und Unternehmen in Schleswig-Holstein und Hamburg.