Record Tracking

Archived from the Xataface Users forum.

ADobkin — Mon Oct 22, 2007 7:47 pm

What is the correct procedure to track the creator and creation time of a record, as well as the last updated time? Specifically, what field names and data types should be defined in the database, and what other settings (i.e. fields.ini, etc.) are necessary to make this information display properly in the record view?

Thanks,

Alan


shannah — Tue Oct 23, 2007 12:52 am

  1. Tracking creator.
Code: Select all
function beforeInsert(&$record){     $auth =& Dataface_AuthenticationTool::getInstance();     $username =& $auth->getLoggedInUsername();     $record->setValue('creator', $username); }

This assumes that you have a field called ‘creator’ in your table.

  1. Tracking creation time.

There are many ways to do this but I generally do this.
a. Create a datetime field and allow null values, let’s say its name is ‘date_created’.
b. In the fields.ini file:

Code: Select all
[date_created]     widget:type=hidden     timestamp=insert
  1. Tracking modification time

a. Create a datetime field and allow null values, let’s say its name is ‘date_modified’
b. In the fields.ini file:

Code: Select all
[date_modified]     widget:type=hidden     timestamp=update

-Steve


ADobkin — Tue Oct 23, 2007 6:37 am

Thanks for the info! I have a couple of follow-up questions:

1) Is it preferred to let Dataface handle the timestamps, or to use type TIMESTAMP fields in MySQL and have them updated automatically by the database (on the back-end)?

2) If I have other datetime or timestamp fields in the table, how do I ensure that Dataface uses the right one when showing the “Last updated” statement at the top of the current record view? I noticed the functions getCreated and getLastModified (referencing $createdField and $lastModifiedField respectively) in Record.php. Should my field names be specified to override these values, and if so, where should this be defined?

Thanks,

Alan


Tue Oct 23, 2007 7:43 am

Is it preferred to let Dataface handle the timestamps, or to use type TIMESTAMP fields in MySQL and have them updated automatically by the database (on the back-end)?

All things being equal I would say ‘yes’ it is better to do it in the database. However I have personally had a lot of trouble getting mysql to track both the creation time and the modified time. You can only have one timestamp field per table, and this field can either track the modified time or the creation time, not both.
Of course, if you are using MySQL 5 you could write a trigger.

If I have other datetime or timestamp fields in the table, how do I ensure that Dataface uses the right one when showing the “Last updated” statement at the top of the current record view? I noticed the functions getCreated and getLastModified (referencing $createdField and $lastModifiedField respectively) in Record.php. Should my field names be specified to override these values, and if so, where should this be defined?

Dataface tries to guess which field is your update time based on the field name. Currently you cannot override this field name, but you can override the modified time value using the getLastModified() delegate class method.

e.g.

Code: Select all
function getLastModified(&$record){      return strtotime( $record->strval('last_updated') ); }

Note that this method should return a unix timestamp.

-Steve


ADobkin — Tue Oct 23, 2007 11:19 am

I decided to try abstracting the user name by using user IDs instead from the users table. I am also keeping track of both the user who added the record and the one who last modified it, like this:

Code: Select all
`function beforeInsert(&$record){
                $auth =& Dataface_AuthenticationTool::getInstance();
                $user =& $auth->getLoggedInUser();
                $record->setValue(‘_uidAdd’, $user);
        }

        function beforeUpdate(&$record){
                $auth =& Dataface_AuthenticationTool::getInstance();
                $user =& $auth->getLoggedInUser();
                $record->setValue(‘_uidMod’, $user);
        }`

Then, I have a definition in valuelists.ini to display the actual user name:

Code: Select all
[Users] __sql__ = "SELECT _user_ID, userName FROM users ORDER BY userName"

Do you see any problems with this approach? For example, will I be losing out on certain features by not using a “creatorField” that Dataface can “guess” (since “uidMod” doesn’t match the hard-coded patterns)?

Thanks,

Alan


shannah — Tue Oct 23, 2007 11:43 am

This looks like a pretty good approach to me. Can’t think of any down-sides off the top of my head.

-Steve


ADobkin — Wed Oct 24, 2007 2:53 am

I am noticing some weird behavior with this:

[quote=”shannah”]3. Tracking modification time

a. Create a datetime field and allow null values, let’s say its name is ‘date_modified’
b. In the fields.ini file:

Code: Select all
[date_modified]     widget:type=hidden     timestamp=update

shannah — Wed Oct 24, 2007 8:01 am

Likely a bug in dataface… will look into it.


ADobkin — Wed Oct 24, 2007 8:10 am

Thanks. In case you are not able to confirm the bug, I realized after I posted this message that I had converted my fields from timestamp to datetime in MySQL rather than creating them from scratch. I don’t think that should make a difference, especially for new records, but I thought I’d mention it just in case….


ADobkin — Mon Nov 05, 2007 2:39 pm

I am having a problem with my user logging example above:

Code: Select all
function beforeUpdate(&$record){         $auth =& Dataface_AuthenticationTool::getInstance();         $user =& $auth->getLoggedInUser();         $record->setValue('_uidMod', $user); }

The value is set to 1 no matter which user is logged in. Is there a different function I should be using other than getLoggedInUser()? Or, do I need to create my own function for this? I poked around a bit in the AuthenticationTool source file, and it looks like it doesn’t keep track of the actual numeric user ID (primary key). Please confirm.

Thanks,

Alan


shannah — Mon Nov 05, 2007 2:58 pm

Your problem is that $user is a Dataface_Record object and not a string.

You have 2 options here:

  1. Use the getLoggedInUsername() method instead of getLoggedInUser()

e.g.

Code: Select all
$user = $auth->getLoggedInUsername(); $record->setValue('_uidMod', $user);

or

  1. Use the value of the username field in the setValue() call:
    e.g.
Code: Select all
$user = $auth->getLoggedInUser(); $record->setValue('_uidMod', $user->val('username'));

Note that the above assumes that the column you use to store usernames is called ‘username’.

-Steve


shannah — Mon Nov 05, 2007 2:58 pm

Your problem is that $user is a Dataface_Record object and not a string.

You have 2 options here:

  1. Use the getLoggedInUsername() method instead of getLoggedInUser()

e.g.

Code: Select all
$user = $auth->getLoggedInUsername(); $record->setValue('_uidMod', $user);

or

  1. Use the value of the username field in the setValue() call:
    e.g.
Code: Select all
$user = $auth->getLoggedInUser(); $record->setValue('_uidMod', $user->val('username'));

Note that the above assumes that the column you use to store usernames is called ‘username’.

-Steve