Welcome Guest, Not a member yet? Register   Sign In
Controller + Model vs Ultra-slim controller that barely does anything + Library
#1

(I'll apologize in advance, because the number of problems increased from the basic one mentioned in the title to some more while writing this post...)

Hey guys.

I've been trying to implement a small action-logging system directly coupled with a notification system today.
What I want(ed) to achieve: Every failure or success of a specific action (Logging in) corresponds to an "Action": For example, you could have "LoggedIn", "LoggedOut", "LoginFail", "CreatePost" or whatever really as action. (I spent some time thinking about if it would make sense to have a different action for failure and success, but I came to the conclusion, that, while messier, it would be easier to implement that way)
Also, most actions will be coupled with notifications - I guess just like flash messages, just without the session-coupled part (I wanted to be able to manage everything from one place) - that will be displayed to the user until (s)he deletes them (Which, I just noticed, may be quite annoying for simple notifications like "Successfully logged in!", but letting some be displayed until deleted and others only once like a flash message would be quite bothersome to implement... I need to think about that.)

At first, I implemented everything as a straight-forward library, with methods such as "logAction" and "makeNotification", and the following database structure:

Code:
ActionTypes
-----------
ATID -> ActionType ID
Name -> Action Type name
UserMessage -> Message displayed to user for that type of action, with %1 and %2 being replaced by specific data
AdminMessage -> Same for admins
-----------

Actions
-------
AID -> Action ID
ActionType -> Type of this action
UserID -> User the action applies to
Data1 -> Specific action data
Data2 -> Specific action data (I was too lazy to couple that stuff with yet another table to make the amount of data variable)
-------

Notifications
-------------
NID -> Notification ID
UserID -> User the notification should be displayed to
ActionID -> The action mapped to that specific notification
Apart from the main problem of this thread, there are already a few within the above database design.
1. I have a maximal amount of two action specific data fields, instead of a variable one. Not really important, but something I should maybe reconsider.
2. While the Action and Notification system is one and the same, the Action system should still be usable without notifications. Which is currently not the case, as the messages shown in the notifications are defined in "ActionTypes". I honestly do not really know how I would go about this while keeping the amount of tables to a minimum.

But, while writing the library, which's code I'll include below, I noticed that if I want users to click away the notification to get rid of it, I'll need some kind of supplementary controller that will be called by JavaScript code. Which would render a library a little redundant, since a controller with a model would also do the job. On the other hand, always needing to call HMVC's Modules::run('Notification/create/arguments') in my own code to create a notification or action instead of simply calling the library $this->notifications->create(arguments) seems annoying too.
So I am currently undecided between using a reaaaally slim controller that barely does anything than forward a call + library or a real controller with a model - Or even a library for the action system (Since that one does not need any user input), plus a controller and model for notifications.

In addition to this "main" problem, there are a few more secondary ones: Mostly, guests.
I can't really save a notification with a guest as target user, since it would get displayed to lots of other guests too. And it would stay and need to be deleted, too. Which basically leads me back to flash_messages and a lot of if and elses in my library. So, yeah, I'm a little confused on how to approach this.

Here's the unfinished code I currently have:
PHP Code:
<?php
defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Notifications {

    private 
$CI;

    function 
__construct(){
        
$this->CI = &get_instance();

        
//Load all action types and store them as variables for easier action creation outside of the library
        
$res $this->CI->db->select('ATID, Name, UserMessage, AdminMessage')->from('actiontypes')->get()->result_array();
        foreach(
$res as $actionType){
            
$actionName $actionType['Name'];
            
$this->$actionName = new ActionType($actionType['ID'], $actionName$actionType['UserMessage'], $actionType['AdminMessage']);
        }
    }

    
//TODO CACHE actions and notifications
    //TODO Finish this

    
function getUserNotifications($userID){
        
$notifications = array();
        
$res = array();

        if(
$userID == $this->CI->userystem->GUEST_ID){ //Get actions by ActionID saved for this specific guest instead of by User ID
            
$res $this->CI->db->select('actions.ActionType, actions.Data1, actions.Data2, actiontypes.UserMessage')->from('actions')
            ->
join('actiontypes''actions.ActionType = actiontypes.ATID')->where("actions.AID IN ({$this->CI->session->flashdata('light_notifs')})")->get()->result_array();
        }else{ 
//Get notifications by user ID
            
$res $this->CI->db->select('notifications.NID, actions.ActionType, actions.Data1, actions.Data2, actiontypes.UserMessage')
            ->
from('notifications')->join('actions''actions.AID = notifications.ActionID')->join('actiontypes''actions.ActionType = actiontypes.ATID')
            ->
where('notifications.UserID', (int) $userID)->get()->result_array();
        
//TODO Use the already loaded Action Types instead of joining that shit again
                
}

        
        
//$res = $this->CI->db->select('notifications.NID, actions.ActionType, actions.Data1, actions.Data2')
        //->from('notifications')->join('actions', 'actions.AID = notifications.ActionID')->where('notifications.UserID', (int) $userID)->get()->result_array();

        
foreach($res as &$notification)
            
array_push($notificationsstr_replace(array('%1''%2'), array($notification['Data1'], $notification['Data2']), $notification['UserMessage']));

        return 
$notifications;
    }

    function 
logAction($actionType$actioner$data1 ''$data2 ''){
        if(! 
$this->CI->db->insert('actions', array('ActionType' => $actionType->ID'UserID' => $actioner'IP' => $_SERVER['REMOTE_ADDR'], 'Data1' => $data1'Data2' => $data2)) ){
            
// $this->db->error(); TODO Log error
            
return false;
        }
        return 
$this->CI->db->insert_id();
    }

    
/**
     * If user is a guest, save the ActionID in a temporary array
    **/
    
function makeNotification($actionID$targetUser){
        if(
$targetUser == $this->CI->usersystem->GUEST_ID){
            
array_push($this->lightNotifications$actionID);
            
$this->CI->session->set_flashdata('light_notifs'$this->lightNotifications);
            return 
false//TODO I don't know about this... Damned be the guests
        
}
        if(! 
$this->CI->db->insert('notifications', array('UserID' => $targetUser'ActionID' => $actionID))){
            return 
false;
        }
        return 
$this->CI->db->insert_id();
    }

    function 
deleteNotification($NID){
        
//TODO controller?
    
}

    function 
getAdminNotificationsByUser($userID){

    }



    private 
$lightNotifications = array();

}

class 
ActionType {
    public 
$ID$name$userMesage$adminMessage;

    function 
__construct($ID$name$userMessage$adminMessage){
            
$this->ID $ID;
            
$this->name $name;
            
$this->userMessage $userMessage;
            
$this->adminMessage $adminMessage;
    }



Thank you very much for reading! 
Help is greatly appreciated Smile


Kind regards
Reply


Messages In This Thread
Controller + Model vs Ultra-slim controller that barely does anything + Library - by Call-Me-Captain - 08-19-2016, 09:04 AM



Theme © iAndrew 2016 - Forum software by © MyBB