Handling Users

Spoova creates a User-Database relationship which makes its easier to control user accounts. This relationship makes it possible to perform simple operations like login and logout, account auto redirection, account information e.t.c just in a few number of lines. The User class is an extension of the Session class. Hence, it has access to most of the Session class static methods. However, it also handles the User session account using some specific static methods that will be discussed below.

In order for the User class to be able to link to database, it is important to configure the init file with require user details. The init file contains some basic user information that is neccessary for the User class to use to connect to the proper user database column in the default database name set in the dbconfig.php file. This means that both the dbconfig.php and init must be properly configured in order for the User class to be able to pick up some basic User information from the database.

Although, part of this have been discussed on the session setup documentation, Some of the earlier discussed may be referenced on this page with the assumption that the configuration files have been properly set.


Helper Methods

Assuming that we have properly set up our configuration files, the User class provides us with certain useful static method that can be used to either obtain the User information from the database or perform queries on the database itself.

  • User::config()
  • User::tableName()
  • User::id()
  • User::auth()
User::config()
This method returns certain important user configuration data details such as:
DBNAME => current database name.
USER_TABLE => the user table name.
SESSION_NAME => current session key name.
COOKIE_NAME => current cookie name.
USER_ID_FIELD_NAME => current user id field name in user database table (i.e USER_TABLE).
COOKIE_FIELD_NAME => current cookie field name in database table (i.e USER_TABLE).

User::tableName()
This is an helper method that quickly returns the currently connected User default table name which contains all user information. which is equivalent to "USER_TABLE" discussed earlier under the User::config() method

User::id()
This method returns the current user id for a logged in user. It is important that in order for a userid to be returned, the following must have occurred:

  1. The USER_TABLE must have been previously set in the configuration
  2. The USER_ID_FIELD_NAME must have been previously set in the configuration
  3. A userid must be stored when logging in whose value exists in USER_ID_FIELD_NAME in the database USER_TABLE
  4. A user session must be active based on the predefined configurations

User::auth()
This method returns some basic user information which includes current user id, primary user id and current user connection. This method returns the UserAuth class. Hence the following can be chained on this method:
  • User::auth()->db() : This returns the DB class
  • User::auth()->dbh() : This returns the DBHandler class with its current user connection
  • User::auth()->id() : This returns the currently authenticated user id for a session user account if called as a string
  • User::auth()->id()->main() : This returns the currently authenticated user primary id for a session account.
  • User::auth()->id()->primary() : This returns the current authenticated user primary id for a session account. This can only be obtained if each user has an auto generated primary "id" field in the user's database table.
Rather than setting up a new connection, the User::auth() method returns the default user connection if not previously modified using the same method. This method only reflects that the Framework handles the entire User connection using the default connection parameters set in the dbconfig.php file. This means that, provided all default configurations are set, running queries will be as simple as :

  if($authdb = User::auth()->dbh()){
  
      $authdb->query('select * from users')->read();
      $results = $authdb->results();
  
  }
    

Session Setup


Since spoova supports multi-sessions, session class requires a session key and an optional cookie key to run sucessfully. This should be set at the top of your application or project file.

  new Session('session_key', 'cookie_key');
            


Once the Session class is set, then the User class will become active for use. This is because the User class depends on the session class to function properly. Since the User class is an extension of the Session class, we can also initialize session from the user class.

  new User('session_key', 'cookie_key');
            



Session accounts


Session accounts may be separated using Frames. Frames are container classes for window files hence may contain data that are specific to certain window files which may not necessarily be available in other window files. Since Frames a extensions of Windows, they have access to all window methods. The super() method is a window method that contains all logic that must occur before a window is loaded. This gives us access to configure our session keys within the a specific session frame which can then be extended to by our window classes. Since only one top level key session can be attached to a user account, each separate user account can be controlled by its own key separately, for example, you can have a user account and a separate admin account. The user account will obtain its data from its own user session group while the admin account will obtain its data from the admin's separate group. In order to do this, two separate session (user) files or frames must be created with their own unique keys such as the example below:

File 1 - UserFrame.php
    <?php

    namespace spoova\mi\windows\Frames;
    
    use Window;

    class UserFrame extends Window {

        function super() {

            new Session('user', 'user_cookie');

        }

    }
            


File 2 - AdminFrame.php
    <?php

    namespace spoova\mi\windows\Frames;
    
    use Window;

    class AdminFrame extends Window {

        function super() {

            new Session('admin', 'admin_cookie');

        }

    }
            


In the above examples, two different session (channel) files were created. User related pages (or routes) will be can be extended to the UserFrame.php file while admin related pages can be connected to the AdminFrame.php files. Session files may be separated from other frame files to keep track of where session files are declared. The major known issue with the super() method is that it can be overridden by a child class. This issue is fixed starting from version 2.5+ where the frame() method can be used to replace the super() method to keep the state of frame classes.

User Session Control


The User class can be used to control the activity and response of a session which includes storing of data and user redirection. The setting up of a user account system involve three(3) main steps:

  • Data Storage and Retrieval
  • Session storage
  • Session redirection
  • Session auto redirection
Data Storage and Retrieval

Data storage is mostly handled through the Model and Form class. The Form is supplied a model which contains authentication rules for form inputs and mapping of form inputs to database columns. Once the form is authenticated, the data can be saved using the Form::isSaved() method which saves the data to the model's defined database table.

Once a data is stored, then it can be fetched through using a database model. The Model class is the root database model handler that is used to communicate with the database through the use of a structure that depends on database relationships. These database relationships include "one-to-one", "one-to-many" and "many-to-many" relationships. More information on database model is provided here.


Session Storage
When a session is authenticated, the data of the user is expected to be stored in the session which can be retrieved later. In most cases only specific essential data which is required to keep a session active is mostly stored in the session. This data is expected to be authenticated before each request sent can obtain a session's data. The User::login() method allows us to store our data into the session by simply supplying the user data in the format:
  $userdata = ['userid' => 'someid'];

  User::login( $userdata );
            


In the above code format, the someid is a unique id that must be found in the init-defined "USER_ID_FIELDNAME". If the corresponding column set in the init file does not contain the someid, the data is never stored if such session is defined as secured. This is explained in the session setup documentation. The User::login() method also manages the storage of a cookie_key which is binded to the session.


Session redirection

A session redirection occurs in two format. This includes logging in and logging out of a session account. While the User::login() stores the user data in the session storage, it is also capable of redirecting the user to a new url once the session data is successfully stored. This is done by supplying the redirection url as a second parameter on the login() method. For example, the code syntax: User::login(['userid'=>'someid'], 'home') would mean that a session data should be stored and a redirection to the home should be made. This would be applied only when the user data has been validated and retrieved from the database.

The User::login() also take a third parameter which defineds the maximum lifetime of a cookie. By default, this is set as 86400 which is equivalent to 1 day. This can be modified as desired. For example User::login(data, url, 60) would mean that the cookie generated or retrieved from database should only last for 60 seconds. Cookies are used in the user class to setup a "remember-me" feature which can help to re-initialize a session once it has ended. This re-initialization is controlled automatically through the Session::onauto() or User::onauto() method. Other information about User::onauto() method is discussed under autoredirection.

Also, the User::logout() method ensures that an active session is terminated. Once this method is called on an active session, the session will be terminated. The User::logout() not only ensures that the session is terminated, it also terminates the cookie key if it exists and supplying a url within the logout() method will ensure that a redirection is made to the defined url once the session is terminated.

As an added feature to the User::logout() method, a session cookie can be revoked from the database. In this case, any stored cookie which is binded to the user data in the database will be nullified and a new one generated once a user logs in and the "remember-me" feature is used. In order to achieve this, the User::logout() method must be supplied a logout url followed by a true argument. For example, User::logout('index', true) will revoke the cookie key, terminate a session and redirect the user to index page.

Lastly, it is important to note that the User::login() or User::logout() are used when a certian condition is expected to be met. For example, it can be used when it requires that a login or logout button is clicked or after a user authentication has been done.


Session auto redirection

A session automatic redirection is usually being defined through the use of Session::onauto() or User::onauto() methods. This does not require that a condition is defined before a redirection occurs but rather, it checks if a condition is met before an automatic redirection is made. The auto redirection is based on two conditions which are when an session is active (login) or when it is not active (logout). The User::onauto('login') will ensure that a page is not redirected unless the session is active. This rule is usually applied on guest pages which are not required to be viewed when a session account is active. Once a session becomes active, these pages will force an automatic redirection to another specified page. The User::onauto('logout') are mostly applied on account related pages which must not be view once a session becomes inactive. When this condition is used on user account related pages, the session will ensure that a redirection is forced to another page if the session becomes inactive. An example is shown below:

AppSession (parent session)
    <?php 

    namespace sppova\mi\windows\sessions;

    use Window;
    use Session;

    class AppSession extends Window {

        static function frame(){

            new Session('user', 'user_cookie');

        }

    }
                                

Assumming that we have a base session as shown above, we can extend this session to a GuestSession and UserSession such that the GuestSession is owned by guest routes and the User session is owned by User related pages.

GuestSession
    <?php 

    namespace spoova\mi\windows\sessions;

    use spoova\mi\windows\sessions\AppSession;

    use Window;
    use Session;

    class GuestSession extends AppSession {

        static function frame(){

            Session::onauto('login', 'home'); //auto redirect to home

        }

    }
                                

UserSession
    <?php 

    namespace sppova\mi\windows\sessions;

    use spoova\mi\windows\sessions\AppSession;

    use Window;
    use Session;

    class UserSession extends AppSession {

        static function frame(){

            Session::onauto('logout', 'login'); //auto redirect to login

        }

    }
                                

Assuming that a Login route is extended to the GuestSession while an Home route is extended to the UserSession, for the Login route, once the account becomes active, it will redirect to the Home route while for the Home route, it will redirect to the login once the session becomes inactive. If not specified, the default redirection url for User::login() is "home" while the default for User::logout() is "index". We can also ensure that a redirection is never made by setting the second argument as false instead of a string url.


Running queries from User class

User class returns an authentication class from its auth() which is the UserAuth class. This class has a method dbh() which returns the database handler class only if a session is active. If a session is not active, the dbh() method will return null. The DBhandler class returned is always specfic to the current user session. Hence, rather than opening a new connection, we can retrieve the current user connection from the User::dbh() method and perform our queries through that DBHandler class returned.

  $auth = User::auth();

  if($db = $auth->dbh()) {

    Session is active, run query

  }
                


Some of the actions that can be performed on the User class include :

  • Modify the default dbconfig.php connection of a User through the use of User::auth() directive by creating new database connection and supplying it as argument just as shown below:

      $db = ($dbc = new DB)->openDB('db','user','pass','port','server');
        
      $auth = User::auth($db, $dbc); // use a new connection 
        


    In the code above, the DB class is used to update the default connections of the User class set in dbconfig.php file. Every other subsequent connections will obtain their configuration from the last update instead of the default config file.
  • Return the specific database connection a currently authenticated user uses through the dbcon() directive
  • Return the authenticated user database handler class when dbh() method is called upon it.
  • Find data related to the defined user table by using the find() directive
      $db = $auth->dbh();
    
      $db->where('userid = ?', [1])->find('username'); //returns username from the user database table name