0

I have a simple DB with user data table, a controller data table and user_controller table that have the controllerID and the userId.

In my PHP OOP (first time) implementation i have a class User and a class Controller.

The functionality for the user is simple - he can login and logout and see a table of all his controllers. I have an admin user who can see all users and their controllers, he can add/delete/edit controller to a user and also can add\delete\edit users.

The Login functionality is implemented (DB class, user class and helpers class)

My problem is how and where should i build the functionality to add a controller to a user. Controller has an id (unique), a name(not unique) and password.

User private fields are:

private $_db,
        $_data, //all of this user data
        $_sessionName,
        $_cookieName,
        $_isLoggedIn;

and controller class:

private $_db,
        $_data; //all of this controller data

I tried to implement function Create in controller:

public function create($fields = array()){
        if(!$this->_db->insert('controllers',$fields)){
            throw new Exception("Problem creating new controller");}}

and function createController in the user:

public function addController($pass,$controller_name,$lat='',$lon=''){
    if ($pass && $controller_name){
        $controller = new Controller();

        $salt = Hash::salt(32);

        try{
            $controller->create(array(
                    'pass' => Hash::make($pass,$salt),
                    'salt' => $salt,
                    'controller_name' => $controller_name,
                    'lat' => $lat,
                    'lon' => $lon
                    ));
        //if success then we update user-controller table
            $controller_id = $controller->find($controller_name)->data()->id;
            $userID = $this->data()->ID;
            $fields = array(
                'UserID' => $userID,
                'ControllerID' => $controller_id
                );

            if(!$this->_db->insert('user_controllers',$fields)){
                throw new Exception("Problem creating controller for user");
            }
        }
        catch(Exception $e){
            throw new Exception('There was a problem creating new controller'); 
        }
    } else {
        throw new Exception('No name or password had been given');
    }

Generally it is working. But there have been couple problems:

  1. The id of the controller is created automatically by the DB so i dont know it when i create it. I cant later find the controller by name because i can have a lot of controllers with this name

  2. I am not sure this is the proper way to handle the relationship between user and controller

  3. i have trouble of implementing "show me all your controllers" for the user.

Can you please tell me what is the correct way to implement this relationship and how to make the createController and ShowControllers of the user?

tereško
  • 58,060
  • 25
  • 98
  • 150
alexandra
  • 1
  • 3
  • I've done something similar where I created a UserTools class that handles anything a user can do. Maybe you could do something similar? – magnified Jul 24 '14 at 20:57
  • You would want to use something like last_insert_id() or if your ORM has a similar function, to get the id of the controller you just created. – Jestep Jul 24 '14 at 21:01
  • Thank you Jestep, it sounds interesting... Just a function that returns max(ID) from a specific table- i can see how it solves this particular problem – alexandra Jul 24 '14 at 21:04
  • magnified - UserTools suppose to handle all the functions of create\edit\delete controllers? And what class supposed to delete the user itself (from the admin)? The user class or also the usertools? – alexandra Jul 24 '14 at 21:05

1 Answers1

0

Your structure seems to be correct. You need a users table, a controllers table and a user_controller table as you mentioned which maps the relationships between the two (user has many controllers).

Solutions for your problems:

  1. When you insert data, you need to retrieve the inserted ID of the new record to use in your mapping relationship. I'm not sure in your example if you're written this MVC structure yourself or otherwise; it looks a little like CodeIgniter. If it is a CI application, here's an example of how to get the last insert ID. If it's a bespoke application, you can use $mysqli->insert_id (mysqli) or $pdo->lastInsertId(); for PDO.

  2. What you're doing is correct.

  3. In a "show me all your controllers" for the user scenario, you will query the user_controller table to get a list of all the controller relationships, and you'll use a join (inner might suit, for a mandatory successful join). You specify that you want to return controller.* in your select fields, and you'll end up with a record for each controller and ignore the user controller fields (if you don't need them). An example SQL query might look like this:

    SELECT controller.* FROM user_controller UC
    INNER JOIN controller ON controller.id = user_controller.controller_id
    WHERE user_controller.user_id = [YOUR_USER_ID_HERE]
Community
  • 1
  • 1
scrowler
  • 24,273
  • 9
  • 60
  • 92
  • Thanks for the explanation. I know how to query the tables. I was just sure which class should handle this functionality. And no - i dont use frameworks or MVC pattern. For now i just have classes and views that work with them. Later maybe i will go for the MVC but now i just need a working solution – alexandra Jul 24 '14 at 21:07
  • OK - this line `$controller_id = $controller->find($controller_name)->data()->id;` which is getting a controller ID based on the (non-unique) name should be replaced by `$controller->insert_id` or `$controller->lastInsertID()` depending on which database driver you're using (might pay to mention this) and if you've written the DB class yourself, you might need to create another wrapper to call these properties/functions, unless the class references the database connection already. If you can provide an example of your DB class, I can help you further. – scrowler Jul 24 '14 at 21:10
  • I am using PDO and Mysql. I will implement a function as you suggested: LastId($table,$field) - that will return the max id in some table. So this is a solution - thanks. The remaining question is - where should i implement the show\create\edit\delete controller - in a user class or in a new class? – alexandra Jul 24 '14 at 21:14
  • @alexandra it would be technically incorrect to return the max(id) from MySQL, you really want to use `$pdo->lastInsertID()` to return the last ID that your query inserted, it's a built in resource, easy to use and will give you a consistent result. As for your other question, a RESTful approach would tell you to put all of those methods (show, create, edit, delete) into your controller class. If you mean deleting links between user and controller, put them in the user class e.g. `user/deleteController/CONTROLLERID` or `user/controller/delete/CONTROLLERID` – scrowler Jul 24 '14 at 21:17
  • @alexandra - I should also clarify the last insert idea. You **do not** need to pass any parameters into your function. You should use the existing PDO resource that you used to **insert** data, which will internally already store the new ID and that function will simply return it. Your DB class should be storing the DB resource as an internal property so that you can access it again and again within a request. – scrowler Jul 24 '14 at 21:19
  • thanks, i understand now that it is a build in function. So you dont agree with "magnified" that it should be a different class? – alexandra Jul 24 '14 at 21:27
  • My DB class is implemented as a singleton – alexandra Jul 24 '14 at 21:28
  • You can structure your classes however you like, but the actions you request should be methods of the controller that the data applies, to if you're viewing, creating, editing or deleting a **controller**, then those actions should belong to the controller class. If they are affecting a link between a user and a controller, they belong to the user and should be in the user class. You could create a user_controller class to manage those links too if you wanted to. It's how long is a piece of string sometimes... – scrowler Jul 24 '14 at 21:37