Yii: Find in Active Record by a PHP Expression - php

Say you have an Active Record model which contains a set of records:
id | name
---------
1 | Record1
2 | Record2
3 | Record3
Users who has the permission to see each records are stored in another table, using a foreign key to represent the record, in a comma separated way:
foreignId | users
-----------------
1 | joe, doe, zoe
2 | joe
3 | doe, zoe
There is an authentication manager bizRule which checks if current user has the permission to see a record. You give it the record id and it checks the permissions table to see if the user is in the comma separeted field.
Yii::app()->authManager->checkAccess('seeRecord', $id);
Is there an easy way using CActiveRecord to pass a PHP Expression "query"? Something like:
Record::model()->findByPHPExpression('Yii::app()->authManager->checkAccess('seeRecord', array('id' => 'id'));
If the expression returns true for the current record, that record would be added.
Thank you

You have some serious non-yii related issue, your database schema is wrong, please read some about database normalization.
You should have an intermediate table, if a user can see various records, and a record can be seen by various users, then you need an intermediate table.
Users, Users_cansee_Records, Records
The intremediate table will have 2 primary keys, that are the user_id and record_id respectively
for your example this table will have something like:
user | record
--------------
1 | joe
1 | doe
1 | zoe
2 | joe
3 | doe
3 | zoe
Yii supprots this "Many many" relationships out of the box. but please read about database normalization, its an important topic, database design is a critical step in any project development.

Related

How do I use multiple tables to create a user profile?

I made a firm to add a user to my database now I want to have two tables. One table keeps track of the languages the user knows and the other table the design software the user uses.
Would I create 3 tables (profile, languages, software) each with an I'd field and when I add a user add a row to each table?
As you begin to add several many-to-many relationships, you need more tables to 'link' the information together. Here's how I would tackle the problem:
Note The IDs should all be unique indexed columns. Consider using AUTO_INCREMENT.
Table 1: Contains user's profile information
| ProfileID |UserInfo |
|=======================|
| 0 | Info |
|-----------------------|
| 1 | Info2 |
|-----------------------|
Table 2: Stores the possible languages
|LanguageID |LanguageName|
|========================|
| 50 | Python |
|------------------------|
| 51 | Java |
|------------------------|
and so on...
Table 3: Stores the Profile links to the languages
|ProfileID |LanguageID |
|========================|
| 0 | 50 |
|------------------------|
| 0 | 51 |
|------------------------|
| 1 | 50 |
|------------------------|
Every time you wanted to add a language to a user's profile, you'd create an entry in this table.
You would add two more tables for the software a user knows. One table for all the possible types of software, and another to store the links.
When you want to retrieve the information, you would do an operation such as the one below:
SELECT * FROM Table3
LEFT JOIN Table2
ON Table3.LanguageID = Table2.LanguageID
WHERE ProfileID = [TheProfileIDToSearch]
This structure uses JOIN to link tables together to return information from several tables at once. Here is a W3Schools quick explanation about SQL JOINS.

Composite key ID generator in Symfony

I'm building a multi-tenant application using Symfony3, Doctrine and PostgreSQL.
I want that each entity have two primary keys: tenantId and entityId. This way, each tenant has each data with id's starting with 1.
So, user 'Xyz' from tentant 1 is http://example.com/users/1, and user 'Zzz' from tenant 2 is also http://example.com/users/1. The tenantId is stored in the session, so it's not represented in the URL (and yes, I know that this is incorrect RESTful).
I already know how to work with composite keys with Doctrine, adding #Id annotation to all the fields, but I don't know how to generate these id's.
Is there any automatic way to have this behavior, or I need to create a custom generator in Doctrine and find the MAX(id) + 1 for the given entity, using a WHERE tenantId = :TENANT_ID?
Thanks for your help.
Example of what I'm looking for:
Tenants table:
tenantId | tenantName
1 | First company
2 | Second company
Users table:
tenantId | userId | userName
1 | 1 | Mr Foo Bar
1 | 2 | Mrs Bar Foo
2 | 1 | Mr John Doe
2 | 2 | Mrs Mary Doe
As you can see, the primary key of the users' table is a composite key (tenantId, userId). What I'm looking for is for a simple, automathic method to generate userId. In a table with only a PK, this method can be a simple generator or a SERIAL field, but as this is a composite PK, I need that the userId value depends on the tenantId field.

Dynamic Multiple dropdown select options from MySQL using PHP

I'm trying to come up with some sort solution to a problem where I have to provide a user with dynamic dropdowns depending on the options they choose.
Currently I have 3 tables that are normalized as such.
Currently this works well with my HTML select elements, where if I select John Doe I would get Paul, Kevin and Dick as my second options and if I were to choose Kevin I would get Drake and Kanye as a third option.
My issue is that I do not want to keep creating tables since I would like to add more layers of staff_level in my application.
How would I approach this and have a fully dynamic table structure using PHP and MySQL?
Thank you for taking your time to read this.
You want an association table between the people. Put all of them in one table with unique IDs like so:
Table Staff
id | Name | <Other fields>
----+-------------+----------
1 | John Doe |
2 | Sam Smith |
3 | John Johns |
4 | Paul Pete |
5 | Kevin Mayor |
6 | Dick Ross |
...
Then the association table named whatever you like - maybe StaffHeirarchy:
Table StaffRelationships
id | ManagerId | SubordinateId
---+-----------+--------------
* | Null | 1 # Has no manager
* | 2 | 6 # Dick Ross is subordinate to Sam Smith
This table should have an id field for unique keys, but you don't have to care about what it is (it's not used as a Foreign Key as the Staff.id field is), which is why I put * there - in reality it would be some integer id.
I haven't seen your PHP for pulling values out of the database, but it is basically the same - query the association table filtering for the id of the manager you are looking for and you will get the ids of the subordinates (which you can JOIN on the staff table to get the names).

Associate two MySQL rows

This is a bit confusing. I cant find how to word it for google and I just cant wrap my head around the logic to do this.
I have "contacts" and "sites" tables that I am storing data for in a database. We need to have a page showing the contacts information and what "sites" they are associated with AND have a page for information about a "site" and show what contacts are associated with it.
Right now I have a field for "contacts" that has comma separated ids of each site that its associated with and a field for "sites" that also has comma separated ids of each contact associated with that site.
When I create a new site with an associated contact. how should the logic go that will update the "associated sites" field on the contacts row in MySQL while also updating its own "associated contacts" field?
I think, you are speaking about many-to-many relationships.
I assume you have a table design like this:
tbl_contacts tbl_sites
id | full_name id | label
1 | John Doe 1 | my website
3 | Maria Doe 2 | super website
You need a table to "link" the tables. this is a many-to-many-table:
tbl_contacts2sites
id | contact_id | site_id
1 | 1 | 2
5 | 1 | 1
3 | 3 | 2
So, John Doe is assigned to both sites, but Maria only to the "super site".
This is the common way to design your relationships. You should avoid any comma seperated lists for this kind of relationships.
The best solution would be when you create a third table (contacts2sites) in this table you have three columns called: id, siteid, contactid.
In this table you can add every connection between sites and contacts. To query the data out of it you can use the mysql query with joins over all tables.
little example:
solution with joins

MySQL Table Setup

Hey all,
I am setting up a PHP web app that will make use of subdomains for accounts. I am storing subdomains in a MySQL table with the following fields:
subdomain_id | owner_id | name | date_created
owner_id maps back to user_id in the user table The user table has the following fields:
user_id | email_address | etc...
Now I am trying to figure out what is the best way to store which users have access to which subdomain. Is the best to set up another table with the following fields?
id | subdomain_id | user_id
That would contain data such as the following (showing user #6 has access to subdomains 4 & 7):
id | sudomain_id | user_id
1 | 4 | 6
2 | 4 | 23
3 | 7 | 6
Is there a more efficient way?
That is the correct way to model a many-to-many relationship, but the id column is entirely unnecessary. You don't need to give every table an artificial identifier. The primary key of that table is simply (subdomain_id, user_id).

Categories