Doctrine JOIN ... ON ... in annotations - php

I'm searching how to have an entity history (or versioning) using Doctrine.
Here are my tables (the column "code" identifies the entity and the "flag" identifies the last version):
User
+--------+-------------+------+
| Column | Type | PK |
+--------+-------------+------+
| id | integer | true |
| code | integer | |
| flag | boolean | |
| name | string(255) | |
+--------+-------------+------+
Post
+----------+----------+------+
| Column | Type | PK |
+----------+----------+------+
| id | integer | true |
| code | integer | |
| flag | boolean | |
| userCode | integer | |
| content | longtext | |
+----------+----------+------+
Here are my values :
User
+----+------+------+------+
| id | code | flag | name |
+----+------+------+------+
| 1 | 1 | true | foo |
| 2 | 2 | true | bar |
+----+------+------+------+
Post
+----+------+-------+----------+----------------+
| id | code | flag | userCode | content |
+----+------+-------+----------+----------------+
| 1 | 1 | false | 1 | First version |
| 2 | 1 | false | 1 | Second version |
| 3 | 1 | true | 2 | Third version |
+----+------+-------+----------+----------------+
In this case, I have 3 version of my post, it was edited twice.
Using Doctrine (and Symfony), I would have a joinColumns with the ON specified in my User class :
class User{
/**
* #ManyToMany(targetEntity="Post", inversedBy="author")
* #JoinTable(name="user_posts",
* joinColumns={JoinColumn(name="user_code", referencedColumnName="code")
* inversedJoinColumns={#JoinColumn(name="post_code", referencedColumnName="code", on="flag=true")} <-- My ON parameter
* )
*/
private $posts
Is there a simple way to have this condition?

i have a history for all my entities and log them in a entityLog entity. I use a entity subscriber and when any entity update i insert a row with the entity name, timestamp, login user etc. Then just i just filter this rows like last 5 changes, by user or by entity for statistics reasons.
You can set one such external subscriber to listen to all entity changes and run your code like documentation suggest or (for changes in a properties of a specific entity only) create a function with annotation in your entity class to use the Lifecycle Callback. For the second case don't forget the annotation #ORM\HasLifecycleCallbacks() in your class otherwise it is not going to work.

Related

How to model belongsToMany relation where pivot table does not contain id

I'm rewriting an old application and I'm using Eloquent to handle the db layer.
I have these two tables:
+----------------+
| core_users |
| |
| id name |
|----------------|
| 1 John Doe |
| 2 Jane Doe |
+----------------+
+---------------------+
| core_access |
| |
| id user_id access |
|---------------------|
| 1 1 users |
| |
| 2 1 stores |
| |
| 3 2 stores |
+---------------------+
This is a belongsToMany relation since a user can have many access roles and access roles can belong to many users. But the core_access table is not a true pivot table, which have proven cumbersome when I wan't to attach and detach access roles to users.
An alternative, that I hesitate from doing, is to alter the table structure with a true pivot table like this:
+------------------------+
| core_user_core_access |
| |
| id user_id access_id |
|------------------------|
| 1 1 1 |
| |
| 2 1 2 |
| |
| 3 2 2 |
+------------------------+
But rather is there a way to setup the current table structure with Eloquent Models with a belongsToMany approach?

Laravel 5.8 - How to give permission to users to read,create,update,delete?

How to define permission in controller,to access the function
For example, USER -> Joe can use the function read create update delete
,but USER -> dog can use the function only read.
In which table permission can increase continuously, and define permission dynamic.
I know roles & permissions spatie but it makes the default table, which I want to use my table.
I have table permission
________________________________________________________
| id | APP | read | create | update | delete | group |
|------+------+------+--------+--------+--------+-------|
| 1 | aa | 1 | 1 | 1 | 1 | admin |
| 2 | bb | 1 | 0 | 0 | 0 | user |
| 3 | cc | 1 | 1 | 1 | 1 | admin |
|______|______|______|________|________|________|_______|
and i have table role
_______________________
| id | user | group |
|------+------+-------|
| 1 | joe | admin |
| 2 | dog | user |
| 3 | cat | admin |
|______|______|_______|
Perhaps you could look into policies: https://laravel.com/docs/5.8/authorization#generating-policies

Doctrine orm one to many with reference key also containing strings

I have an entity called books and another one users.
Each book can have many authors(users).
So when I add a book I select the users that are registered on the site.
But if the author of the book doesn't have an account on the site I want to type his name by hand.
+----+---------+-----------+--+
| id | book_id | author_id | |
+----+---------+-----------+--+
| 1 | 1 | 1 | |
| 2 | 1 | Mr.Paul | |
+----+---------+-----------+--+
See how the author_id is a string but also an reference key to an user?
Can I do this with doctrine or I will have to manage the inserts myself?
Edit:I have no idea what the right title should be
Edit2:A possible solution will be to make another table containing only authors that don't have an account on the website.
I would recommend following approach
You have a table books a table accounts and the following:
authors_books
+----+---------+-----------+--+
| id | book_id | author_id | |
+----+---------+-----------+--+
| 1 | 1 | 1 | |
| 2 | 1 | 2 | |
+----+---------+-----------+--+
authors
+----+---------+------------+--+
| id | name | account_id | |
+----+---------+------------+--+
| 1 | Mr. Paul | 1 | |
| 2 | Simon | (empty) | |
+----+---------+-------------+--+
the account_id can be empty

Symfony2 + Doctrine, find in relations

I'm thinking over to design an API to filter objects using fos_rest bundle in Symfony2 and Doctrine with MySQL.
Let's say I have a Master Entity, which has relations with different entities which have some properties.
Now in frontend I would like to create a filter, where one can filter the Master Entity by the properties of the related Entities. How would that be doable?
say we have
+---------------+
| Master Entity |
+----+----------+
| id | name |
+----+----------+
| 1 | Apple |
+----+----------+
| 3 | Berry |
+----+----------+
+-------------------+
| Property Entity |
+----+------+-------+
| id | id_m | value |
+----+------+-------+
| 1 | 1 | green |
+----+------+-------+
| 2 | 1 | yello |
+----+------+-------+
| 3 | 1 | red |
+----+------+-------+
| 4 | 3 | pink |
+----+------+-------+
And I want to have a filter, where I filter by the values in Property Entity
I would like to do something like
$em->getRepository('AcmeBundle\MasterEntity')->findBy(array("PropertyEntity:value" => "red","PropertyEntity:value" => "yello"))
so it would return the object collection of Master Entity with ID=1 (apple) - because both parameters would match Apple
You can create a query builder instead of use findBy
$qb->select('m')
->from('AcmeBundle\MasterEntity', 'm')
->join('m.PropertyEntity', 'p')
->where('p.value IN (:values)')
->setParameter('values',['red','yellow']);

Manage multiple tables relationed in CakePHP

So, i have three tables
Table: Users
_________________
| id | user |
-------------------
| 1 | Roy |
| 2 | Ben |
|________|________|
Table: Hability_lists // Where i set the list with all habilities available
___________________________________
| id | category | subcategory |
------------------------------------
| 1 | Programmer | PHP |
| 2 | Programmer | ASP |
|________|____________|_____________|
Table: Habilities // Where i set the habilities from all users
________________________________________
| id | user_id | hability_list_id |
-----------------------------------------
| 1 | 2 | 1 |
| 2 | 1 | 2 |
|________|____________|__________________|
By this, we can see that:
Roy are a ASP Programmer and Ben are a PHP Programmer
But, how to set relative models like this using CakePHP?
I know how by using two models but not using three models.
There is some way to do this? Or maybe a better way to do?
Thanks in advance.
When working with an MVC framework it's highly recommended to follow its conventions. So a few changes may be beneficial for you.
What you are looking for its the HABTM (Has And Belongs To Many) association between the "users" table and the "habilities" table *. I'm guessing, by the design of your table, that a user can have multiple habilities, otherwise you should check the hasMany association.
It should be something like this:
Table habilities:
select * from habilities;
+----+------------+----------------------+----------+
| id | category | subcategoy | created | modified |
+----+------------+------------+---------+----------+
| 1 | Programmer | ASP | | |
| 2 | Programmer | PHP | | |
| 3 | Musician | Classical | | |
+----+------------+------------+---------+----------+
Table users:
select * from users;
+----+-------+---------------------+---------------------+
| id | name | created | modified | **
+----+-------+---------------------+---------------------+
| 1 | Roy | 2012-08-15 02:52:18 | 2013-01-17 03:25:28 |
| 2 | Ben | 2012-11-10 03:36:12 | 2012-11-10 03:36:12 |
+----+-------+---------------------+---------------------+
Relational table for HABTM:
select * from habilities_users;
+----+-------------+-------------------+----------+
| id | hability_id | user_id | created | modified |
+----+-------------+---------+---------+----------+
| 1 | 1 | 2 | | |
| 2 | 2 | 1 | | |
+----+-------------+---------+---------+----------+
Look the reference columns in habilities_users, they're singular with a _id suffix to work with CakePHP.
Defining the models classes it's also important, since it's where you define all their associations.
app/Model/User.php
<?php
class User extends AppModel {
public $hasAndBelongsToMany = array('Hability');
}
app/Model/Hability.php
<?php
class Hability extends AppModel {
public $hasAndBelongsToMany = array('User');
}
The table habilities_users doesn't need a model file, its behaviours and properties are implicit in the declaration of its associated models.
* using those names it's also the CakePHP way. [link]
** adding "created" and "modified" in each table will store those events for each record automatically.
You'll want to use HasAndBelongsToMany (HABTM).
This allows you to have two models - User and Hability that are joined by a "tweener" table.

Categories