Introduction

QCache is primarily designed to help with caching things site-wide, that are presented the same to all users. But that doesn't mean you can't use it in more advanced ways.

Here is an example of using QCache to prevent re-calculating a menu, even though the menu changes dynamically for different clients, roles, and role permissions.

Data Model

We have the following data model:

client
id
name

User
id
role_id
client_id
name

Role
id
name

Permission
id
name

Role Permissions
role_id
permission_id
client_id

Example Setup

Our menu should show everything the user can do, based on the permissions assigned to their role for the appropriate client.

Data

eg:

  • Bill is part of ACME, and has Sys Admin role
  • Joe is part of ACME, and has Team Lead role
  • George is part of StampsRUs, and has Sys Admin role
  • Phil is part of StampsRUs, and has Team Lead role
  • Shawn is part of StampsRUs, and has Team Lead role
  • Sys Admin is assigned User Admin permissions for ACME
  • Sys Admin is assigned Role Admin permissions for ACME
  • Sys Admin is assigned User Admin permissions for StampsRUs
  • Sys Admin is assigned Role Admin permissions for StampsRUs
  • Team Lead is assigned User Admin permissions for ACME
  • Team Lead is assigned User Admin permissions for StampsRUs
  • Team Lead is assigned Role Admin permissions for StampsRUs

(So Team Lead is the same as Sys Admin, except that in ACME, Team Leads can't admin Roles)

Result

So these are the menus we expect to see:

  • Bill: User Admin, Role Admin
  • Joe: User Admin
  • George: User Admin, Role Admin
  • Phil: User Admin, Role Admin
  • Shawn: User Admin, Role Admin

Code

Now, since we're smart, we realize that user 4 and 5 have the same circumstances, and re-checking permissions when they need a menu is a waste.

So here's what we do:

<?PHP
$thisUser = session['User'];

$cache = new QCache('Menu '.$thisUser->RoleId, $thisUser->ClientId);
$cachedMenu = $cache->GetData();

if(false !== $cachedMenu && '' != $cachedMenu)
{
	print($cachedMenu);
	return;
}

ob_start();

/**** BUILD MENU HERE ****/
$rolePermissionArray = RolePermission::QueryArray(QQ::AndCondition(
    QQ::Equal(QQN::RolePermission()->RoleId, $thisUser->RoleId),
    QQ::Equal(QQN::RolePermission()->ClientId, $thisUser->ClientId)
  ),
  QQ::Clause(QQ::Expand(QQN::RolePermission()->Permission))
  ));
foreach($rolePermissionArray as $rolePermission)
  echo $rolePermission->Permission->Name.', ';
/**** END MENU BUILDING ****/

$contents = ob_get_contents();
ob_end_clean();
//cache the menu
$cache->SaveData($contents);
print($contents);
?>

Pretty simple. We've gone and cached the menu for each role, specific to each client.

But once it's cached, what if something changes?

That's not too bad either: In RolePermission?.class.php

public function Save($blnForceInsert = false, $blnForceUpdate = false) {
	//wipe the cached menus, since they may have been affected by this change
	QCache::ClearNamespace('Menu '.$this->RoleId);
	
	return parent::Save($blnForceInsert, $blnForceUpdate);
}