Adding Uploads Module categories dynamically

Just recently i was faced with a task of creating a per Registered User based Download area. My first thought was, oh thats easy simply connect FrontEndUsers Module with Uploads Module and done.

But as we all know, there are always small issues that come along in each Project. So the issue with my thought was, that Uploads module does communicate with FrontEndUsers Module but not in a way i needed it.
If you need to allow Upload/Download area access by Group it is simple, each Category has a option to specify which group is allowed to view it, but unfortunatelly there is no way to have a per User control, one of the downsides of FronteEndUsers module. 

Facing this per User challenge i had to think of a UDT to manage this task. Luckly CMSMS comes with "EventManager" which makes it very easy to run specific tasks on particular Events.

First thing i did is having a look at EventManager, making sure there is a Event triggered which i could use for a UDT and yes there was one in FronteEndUsers Module called "OnCreateUser".

This brought me to a plan that a UDT could be ran on this Event creating a category for each user, still having control over Categories to manage by "Group", which i needed to allow access for "Clients" and "Managers" where second would have access to all files, managing Uploads and being able to delete these via Frontend.  

My conclusion was that i need a UDT that communicates with Uploads and FronteEndUsers module, that reads User Information when one is being created, creates a Uploads Module category based on username, creates a folder based on FrontEndUser extra field value and saves all that information in Uploads module per Category as needed. 

The UDT (i named it add_uploads_category) :

$db        = cmsms()->getDb(); // get databse
$catid     = $db->GenID(cms_db_prefix() . "module_uploads_categories_seq"); // category id
$FEU       = cms_utils::get_module('FrontEndUsers'); // get FEU module instance
$Uploads   = cms_utils::get_module('Uploads'); // get Uploads module instance

// get user properties
foreach ($FEU->GetUserProperties($params['id']) as $prop) {
     $user_props[$prop['title']] = $prop['data'];

$folder = "downloads/" . $user_props['folder']; //define var for user property called folder
$name   = $params['name']; // get user username
$groups = $FEU->GetMemberGroupsArray($params['id']); // get user id

// get group id from this user
$gid = array();
    foreach($groups as $group) {
        $gid[] = $group['groupid'];
    $groups = implode(',', $gid);

// create directory from "folder" userprop
$dir = $Uploads->_categoryPath($folder);
    if(!file_exists($folder)) {
        $result = cge_dir::mkdirr($dir);
    if($Uploads->GetPreference('create_dummy_index_html') ) {
        touch( $dir.DIRECTORY_SEPARATOR."index.html" ); // if Uploads pref is create index.html
// query database
$query    = "SELECT upload_category_id FROM " . cms_db_prefix() . "module_uploads_categories WHERE upload_category_name = " . $name . ";";
$dbresult = $db->Execute($query);
if ($dbresult && $row = $dbresult->FetchRow()) {
    return; // category already exists. stop.
// if table doesn't exist, insert all into Uploads table
$query = "INSERT INTO " . cms_db_prefix() . "module_uploads_categories
(upload_category_id, upload_category_name, upload_category_description,upload_category_path, upload_category_listable, upload_category_deletable,upload_category_expires_hrs,upload_category_scannable,upload_category_groups)
VALUES (?,?,?,?,?,?,?,?,?)"; // execute $dbresult = $db->Execute($query, array($catid, $name, "Upload category for user " . $name . "", $folder, 1, 0, 0, 1, $groups));

So the above UDT would check for FrontEndUsers user properties like "folder" which was my extra field i have created in FEU Module to specify a folder for each user. The reason for this was that i didn't like the fact that category folders were simply created in CMSMS /uploads folder.
I have used /downloads folder for that and creating Category folders inside of it.
Then from user properties a check for username and group is done. Each Uploads module category is created based on Username (this makes it simple to output category for each user based on logged in username and as we need a FEU group access check the group id is needed.

When these conditions are checked the UDT creates a folder based on path specified, where also a check for Module preference is made if blank index.html file  should be created.

After that a Database query is done, if category doesn't exist (which actually shouldn't, usernames should be unique) values are inserted into Uploads module table "module_uploads_categories".

Note: make sure you do not forget to add this UDT in "Extensions » EventManager" to FEU event called "OnCreateUser" and do not blame me if you brake something. Play with this in a developement environment not on live site.

To all of above you will need a decent Smarty template logic, displaying correct results to different users, but this is something i might write about some other time, but i shouldn't make it that easy for you either.