FOSUserBundle or PUGXMultiUserBundle to have two different user profiles (Symfony2) - php

I'm doubtful about how to approach this problem:
My Symfony2 app for this issue has two different profiles, name 'em "Seller" and "Buyer". The goal is to keep a bunch of attributes about a "Seller", and, on the other hand, not much about the "Buyer" (email and password would do it).
I realise that it's not easy to have two different entities log in and register using FOSUserBundle. There are quite some other bundles, such as PUGXMultiUserBundle that 'hack' FOSUserBundle, and are not easy to config/implement.
So my quiestion is: Is it more correct to use the hack PUGXMultiUserBundle proposes, dealing with its implementation and config, or is it better to stick to FOSUserBundle, have a User entity, and a one-to-one relation with a "Seller" entity that represents the attributes of a Seller different from a buyer? There would be another problem with that approach, with the registration form, that should be splitted in two, for Seller and Buyer register (which I don't know if it is possible/advisable using FOSUserBundle)
I hope you guys help me get it right. Cheers :)

I would definitely use the PUGXMultiUserBundle for that. I don't think it's a hack, it just implements a discrimination table that will be like:
1User Table
----------------------------------------
| id | username | type |------------
|-----|-----------|--------|------------
| 1 | mgdepoo | buyer |------------
| 2 | Sydney_o9 | seller |------------
----------------------------------------
2Buyer Table
----------------------------------------
| id | buyer_specific_field_1
|-----|---------------------------------
| 1 |
----------------------------------------
3Seller Table
----------------------------------------
| id | seller_specific_field_1
|-----|---------------------------------
| 2 |
----------------------------------------
That's all there is really.
I think that's exactly what you need especially if you wish to have different profiles for your users. You will have 2 registration forms as well (but you can make one with a choice box buyer/seller if you want to).
I personally use this bundle and it works great for me. Now, one of the question you might want to ask yourself is what if a buyer wants to be a seller as well. Does he want to have another email address? That is a choice that you'll have to make.

Related

Best way to create relational database model for different Customer modals in Laravel

In my Laravel project i have 3 kind of types, Vehicle Owner, Driver and Customer models.
When I'm adding credits and debts for all kind. It's working but I'm not happy with solution
Because:
There are several common fields repeates.
When user will add credit/invoice which joins with 3 tables.
Financial table seems more complex
Finance
userType | userID | amouth
------ | ------ |-----------
VehicleOwner | 5 | -500
Driver | 5 | 200
Customer | 5 | 200
Maybe there is a solution could be relate all 3 tables with one table:
In my case i have many related info between these type and would like to use in common instead of joining the data in each table.
1.Driver (extend driving license info)
2.Customer (extend corporate info)
3.Vehicle Owner (extend driver info)
I'm new in Laravel and looking for best practice? I'm waiting for only laravel code practices.
You can have a user_type field (tinyint (1)) in users table.
All kind of users will be in this table.
Customer will have user type of 1, drivers 2 and vehicle owners 3 etc.
You can store amount in User model and add field user_id in Driver, Customer and Vihacle owner models.

Create a lookup table with Doctrine2

I have recently installed Doctrine2 on my web server and all works great. I have setup all my entities but now I'm at the point where I want to create a lookup table and I'm a bit confused how to do that. I want a table which looks like this:
tbl_Role tbl_User
+--------+----------+ +--------+----------+--------------+----------+
| id | Name | | id | Name | Password | Role |
+--------+----------+ +--------+----------+--------------+----------+
| 1 | Admin |
| 2 | User |
| 3 | Free |
+--------+----------+
Between the Role and the User table consists a OneToMany relation (one Role has many Users) and this table does not change in future. I do not want to use Enums because of the update or reorder problem with them (if nevertheless something changed)
My question now is how I can represent this lookup table as a Doctrine entity? Normally if I want to create a new User I have to get the fitting Role from the DB and set it as a reference in the User entity. This seems a bit expensive to me. It would be great if I could have only the Role IDs in static PHP fields so I can set them as reference for the User. Is this possible?
Another problem is how I get the lookup values into the database. Can I implement a method into the Role entity itself which is executed after the Role table is created? This way it would be possible to mark the constructor as private and all values are present after a migration.
First of all, it won't be too expensive, because Doctrine2 has a few cache layers and these queries will be efficiently cached since the Role table won't change.
Anyway, if Role table won't change, I'm not sure if it should be kept in database. You could create a "static" factory service for it to create simple value objects as a part of your domain layer.

Multi-Table User Authentication

I am currently developing a Student Information System that is going to be used by educational group to provide students & teachers a portal.
I am using Laravel4 which has a good authentication driver built in but can use only one table for authentication. I am unable to figure out how to authenticate them because I have users in multiple tables. Example :
SchoolOne_students
SchoolOne_teachers
SchoolTwo_students
SchoolTwo_teachers
and so on....
A significantly better way, rather than multiple users tables, would be to link each user to their school and status (teacher or student). You certainly can twist Laravel into doing what you want, but in order to prevent conflicts between the four different user types, you'll probably end up having to rewrite a large part of the entire authentication package.
What I would do is, in your users table, have an ENUM column, with the options student and teacher. Then, have an integer column, school_id (with a separate table for school data, if needed). This will allow much more flexibility, and when your design requirements change (yes, they will change), you'll be able to take them in stride.
Using this method, you should not have to modify any of Laravel's own code.
if all the tables have identical schemas, you could create a view that does a UNION of all the tables and then use that view as your Laravel auth table. I am not saying this is an ideal solution, but if you have restrictions on altering the existing tables and must use them as is, this could work.
The view would not be update-able (I don't believe so, at least) so adding or updating users would require specific add/update code, but for Auth, this may do the trick.
CREATE VIEW users_combined_view
AS
SELECT id, username, password
FROM schoolOne_students
UNION
SELECT id, username, password
FROM schoolOne_teachers
UNION
...
note - this method would be somewhat useless (ok, totally useless) if username was not unique across the tables
A good database design is scalable.
This is particularly a bad idea:
SchoolOne_students
SchoolOne_teachers
SchoolTwo_students
SchoolTwo_teachers and so on...
There should be only one table for all the users, in your case for students.
There should be another table for Schools where all the school information will be stored.
Then you should join the students table with schools table by adding a school_id field to the schools table where the school_id will be stored for the corresponding students row.
===Students Table===
+-----------------------------------------
+ id | name |school_id | ... | ... |
+----+--------+----------+-----------+----
+ 1 |Student1| 5 | ... | ... |
+----+--------+----------+-----------+----
+ 2 |Student1| 3 | ... | ... |
===Schools Table===
+-----------------------------------------
+ id | name | ... | ... | ... |
+----+--------+----------+-----------+----
+ 3 |School 3| ... | ... | ... |
+----+--------+----------+-----------+----
+ 5 |School 5| ... | ... | ... |
+----+--------+----------+-----------+----
This way you can add as many schools as you may want and students for them
I hope this will help

Dynamic survey application logic PHP/MSSQL

Firstly I think this question can be related to any language, but I specified what I was using.
Excuse me if I start to bore also, but I am trying to find out the best way to build a dynamic survey management system.
My client basically has said to me that the data has to be stored in MS SQL as his client has only got MS SQL connector for SAS, which is going to do reporting.
My logic so far is this:
1st. Setup the survey itself, i.e. ask for title, quick overview, etc, etc.
2nd. Define your questions.
3rd. Publish survey.
Now what I have done so far is that when they "publish survey", I have created a dedicated database table for this survey which will house the responses.
From the admin side of this, they will not be able to modify the questions, maybe the question title but that is about it. They cant add/remove questions.
Question is, is creating individual database tables a good thing? My only worry really is that say the admin creates like 30 questions, I will have 30 columns in that dedicated table. To go with that, this way might be easy for the SAS system to pull in data for reporting. The administrator will not see the survey responses in the admin panel btw.
I have done something similar for a language grading exam. I opted for a more flexible approach with the following tables
+------+ +-------------+ +-------------+ +-------------+ +----------+
| Exam | | Question | | Choice | | Answer | | User |
+------+ +-------------+ +-------------+ +-------------+ +----------+
| id | | id | | id | | id | | id |
| name | | questionNb | | choice | | user_id | | name |
+------+ | question | | question_id | | exam_id | | email |
| exam_id | | isAnswer | | question_id | | password |
+-------------+ +-------------+ | choice_id | +----------+
| isGood |
+-------------+
This model allowed me to easilly have a 15 questions exam, a 30 questions exam and a 50 questions exam. To adapt this model for survey, you might just have to remove the isAnswer and isGood part and you should be good and replace users data with anonymous general data like age, income, sex.
Creating a column for each question is totally wrong, altering the database at runtime for business oriented purpose is a "never ever do".
Read something about "relational databases" things should look like this:
table_surveys
id
survey_name
table_questions
id
fk_survey (foreign key to table_surveys)
question_text
(question value? maybe)
table_questions_options
id
question_id(foreign key to table_questions)
option_value (this can be true/false for a test or a numeric value for a survey)
option_label
table_users
id
username
pass
name
table_answers
id
options_fk (foreign key to table_question_options)
users_fk (foreign key to table_users)
This way everything is linked together (No reusing of options,or questions or stuff into different surveys)
According to the comments in the documentation, MS SQL Support in PHP is iffy at best. Is PHP the only language you are allowed to use for the project? If not, you might want to consider using C#, VB.Net or something more compatible with SQL Server. Otherwise, you could initially store the data in MySQL, and export it to MS SQL Server when you needed to do analysis.
Dont know, if I really understand your question. But I once built such a survey system. And it came out pretty quick and easy with about the following tables (if I remember right):
USER, SURVEYS, QUESTIONS, ANSWERS, [some mapping tables]
The SAS will fetch the data from virtual any table. If everything in one or two tables, it will even be easier.
With all due respect to Kibbee, PHP/MSSQL support is actually VERY good. We do it quite often, and the performance bests PHP/MySQL and matches compiled C#/MSSQL (in our very limited and unscientific testing). This is assuming you're running PHP on a Win machine. Running PHP with a TLS connector to a separate MSSQL box is another ball of wax and can be a pain to configure.
Anyway, we had a similar scenario and went with one table to manage forms (Forms w/ FormID as the primary), another to manage fields/questions (Fields w/FieldID, FieldType such as Y/N, text, select, etc.), and another to "assign" a field to a form (FormFields w/ FormFieldID, FormID, FieldID, parameters in an array for select items, etc.). Then yet another set of tables to deal with the answering of the questions.
I agree with the rest of the group. Make sure to normalize and don't create a separate column for each question. It'll be more work initially, but you'll appreciate it when you simply have to add a few rows to a table instead of re-writing your queries and re-designing your tables.

What is the efficient way to make a permission system?

Currently I'm just using something like this in the DB Table:
access: home,register,login
And then in each page:
if(!Functions::has_rights('content'))
{
Functions::noAccess();
}
is there more efficient way to do it with php & MySQL? I may want to gain access even to several parts a page, for example, user can read a page, but doesn't comments to it, and I don't want to build a separate system to each module.
I believe what you are looking for is Access Control List where you model your problem into two things: objects and roles.
Incomplete list of examples one may use, or be inspired from if writing a custom one from scratch:
Zend provides Zend_Acl
Symphony 3.x has ACL, for Symphony 4.x you can use ACL Bundle and the Voters.
The CakePHP has an ACL plugin
I built one using a "*NIX-type" permission system.
I have different type of permissions for a page (read, modify, delete, comment, vote) and I assign a bit to each of those.
So for instance I have
define ('USER_CANREAD', 1);
define ('USER_CANMODIFY', 2);
define ('USER_CANDELETE', 4);
define ('USER_CANINSERT', 8);
define ('USER_CANCOMMENT', 16);
define ('USER_CANVOTE', 32);
Then if the user can read, comment and vote the permission will be 1+16+32 = 49
To check for permissions I just do a bitwise AND with those values.
For instance user->permissions & USER_CANDELETE to check if the user can delete the page (obviously I have a canDelete function for that)
If you are using some kind of routing it will make sense to make your ACL (Access Control List) depend on the routing that you have defined.
I usually run with a permissions table and a permissions_users table in a HABTM relationship. This way when the routing is matches, a permission can be looked up. If the user doesn't have the permission he is denied access.
This can be improved with checking for the different types of methods GET, POST, PUT and DELETE.
This is because I like the opportunity to edit the permissions and settings from the web interface, and allow for non-it people to do the same (i.e. marketing people).
Here is the layout:
+-----------------------+
| permissions |
+-----------------------+
| id | pattern | method |
+-----------------------+
| 1 | | GET | # => Will hit the root of your application
| 2 | users | GET | # => Will hit users/, usually listing the users
| 3 | users | PUT | # => Will hit anyone trying to insert a new user into the system.
| 4 | users/:id | GET | # => Will hit anyone who tries to view a specific user
| 5 | users/:id | POST | # => Will hit anyone trying to update a user
+-----------------------+
+-------------------------+
| permissions_users |
+-------------------------+
| user_id | permission_id |
+-------------------------+
| 1 | 1 | # => Will allow to view the root of the application
| 1 | 2 | # => Will allow to view the users list
+-------------------------+
So user 1 doesn't have any rights that could alter the records. And since the routing defines where the different request methods go, you cant simply POST to the /users to view the list.

Categories