How to create an Entity with multiple tables? (Doctrine2) - php

There is a legacy project, which I would like to refactor. I would like to handle all database related stuff with Doctrine.
Unfortunately the user data is in two tables. There is a x_users and a x_userdata table. Both have a user_id field, but store different type of information. I would like to use all the columns from both tables in my User entity. How is it possible?
I was searching for a solution, but I haven't found any answer yet.
One solution would be to create a User and a UserData entity, and have a one to one relationship. But maybe there is a better solution

Related

How to save relations (many-to-many) between local data and an API?

I'm looking for a proper way to handle and store relations between data in my DB and data from a third party API. I use Laravel 5.
For example, I have a Project model (id, name). Also, I have an API which I can call from PHP and get back a JSON with Articles list.
I need to save a many-to-many relation with a junction table between Projects and Articles.
Because Articles data comes from API I do not have a local table with Articles so I can't use Eloquent to deal with relations.
My question is how to do it right.
I've thought of 2 possible solutions:
1.) Use some lib that can "map" an API as an Eloquent model. But I've only found abandoned projects. And overall this solution looks like overkill in such simple situation.
2.) Use query builder and manually handle this situation to save data about relations between Projects and Articles in the junction table.
But if I'll use this option it will be hard to deal with updates etc.

Three way Eloquent relationship

The project that I am working on requires a sort of sharing functionality meaning that when a person creates an exercise they can choose to share that exercise with another person and append a certain permission to that exercise (i.e read, write, or execute).
I have three tables(all of which have models): users, exercises, and permissions. In the middle I have an exercise_permission_user table that only has three columns: exercise_id, permission_id, and user_id all of which are foreign keys that point back to their respective tables.
The problem comes with establishing a three way many to many relationship among these tables in Laravel 5. More specifically, when a person shares an exercise, I need to input the id's of the exercise being shared, the user it is being shared with, and the permission that is being appended into the exercise_permission_user table. I then need to be able to query the user_id of this table and see all exercises that are being shared with a certain user. If the user Mike has an ID of 3, then I would like to query the middle table for that ID and find the exercise he has access to as well as the permission that he is being granted.
I am still in the learning process when it comes to eloquent so any help would be greatly appreciated. I am not necessarily looking for someone to build this for me, just some help that will give me the information necessary to do it on my own. Thanks to all that help!
I've struggled with this issue a couple of times. As far as I could research, I didn't find a Laravel native way of coding this kind of three way many to many relationship. What I generally do is to create a model for the pivot table. So, a SharedExercise model (or the name you want to use) with a protected $table property set as 'exercises_permission_user'. Inside that model you set the relationships with user, exercises and permissions. Then, you can write:
$sharedExercises = SharedExercise::where('user_id', $userId)->get();
Pay attention to the table and model naming. I usually name tables using laravel's conventions, but when I have this 3 way many to many, I try to find a more describing name than the convention. So, for example instead of exercises_permission_user and ExercisePermissionUser model, maybe shared_exercises and SharedExercise names are better.
Note that this isn't THE way to do it. It's how I do it as a result of not finding a convention in the documentation.

Finding all columns with same names across multiple tables with Symfony2/Doctrine

I'm thinking of implementing blameable fields to couple of my tables using https://github.com/stof/StofDoctrineExtensionsBundle bundle to know which user created some of database objects.
What I want to achieve and cannot find right answers to do that is following:
As admin user I would like to be able to transfer all blameable objects from one user to another one. This could happen in cases when I want to delete existing user or just want that those objects belongs to another user.
Theoretically I can connect to MySQL.INFORMATION_SCHEMA to find all tables which have fields "createdBy" and deal with those tables, but I cannot connect to that database using doctrine (or can I???).
Can someone suggest approach of transferring all blameable objects to different user?
P.S. I don't need to set default user or to enable null values for createdBy column like answered here: How to disable Blameable-behaviour programmatically in Symfony2

Where should filtering with an Acl be performed?

Let's say I have three tables: users, books, and users_books.
In one of my views, I want to display a list of all the books the current user has access to. A user has access to a book if a row matching a user and a book exists in users_books.
There are (at least) two ways I can accomplish this:
In my fetchAll() method in the books model, execute a join of some sort on the users_books table.
In an Acl plugin, first create a resource out of every book. Then, create a role out of every user. Next, allow or deny users access to each resource based on the users_books table. Finally, in the fetchAll() method of the books model, call isAllowed() on each book we find, using the current user as the role.
I see the last option as the best, because then I could use the Acl in other places in my application. That would remove the need to perform duplicate access checks.
What would you suggest?
I'd push it all down into the database:
Doing it in the database through JOINs will be a lot faster than filtering things in your PHP.
Doing it in the database will let you paginate things properly without having to jump through hoops like fetching more data than you need (and then fetching even more if you end up throwing too much out).
I can think of two broad strategies you could employ for managing the ACLs.
You could set up explicit ACLs in the database with a single table sort of like this:
id: The id of the thing (book, picture, ...) in question.
id_type: The type or table that id comes from.
user: The user that can look at the thing.
The (id, id_type) pair give you a pseudo-FK that you can use for sanity checking your database and the id_type can be used to select a class to provide the necessary glue to interact the the type-specific parts of the ACLs and add SQL snippets to queries to properly join the ACL table.
Alternatively, you could use a naming convention to attach an ACL sidecar table to each table than needs an ACL. For table t, you could have a table t_acl with columns like:
id: The id of the thing in t (with a real foreign key for integrity).
user: The user the can look at the thing.
Then, you could have a single ACL class that could adjust your SQL given the base table name.
The main advantage of the first approach is that you have a single ACL store for everything so it is easy to answer questions like "what can user X look at?". The main advantage of the second approach is that you can have real referential integrity and less code (through naming conventions) for gluing it all together.
Hopefully the above will help your thinking.
I would separate out your database access code from your models by creating a finder method in a repository class with an add method like getBooksByUser(User $user) to return a collection of book objects.
Not entirely sure you need ACLs from what you describe. I maybe wrong.

MySQL: Inheritance

I read about an inheritance feature in PostgreSQL that seemed pretty neat. Unfortunately I am forced to use MySQL. How would you do something similar in a clean way?
Say you for example had the two following classes that you want to work with:
User
˪ Id
˪ Name
˪ Password
Employee : User
˪ Pay
How would you store those in a MySQL database so that they can be fetched from for example PHP in a fairly clean way? I need to for example be able to fetch all users including employees, only employees, find if a user is also an employee, et cetera.
Looking for general advice and not a specific solution to this case. I for example see that I could simply add a nullable Pay column to a Users table, but I don't really like that idea as it would quickly become very messy if more sub-classes were needed.
Add a field to Employee which is a foreign key to User. You'd still have to perform a join across the tables, but it's better than nothing.

Categories