Symfony data fixtures on ManyToMany relationship - php

I have two entities Categories and Criteria that are linked by ManyToMany relationship. It generated a new table named as criteria_categories in the database.
What i want to do is to use fixture to populate the entity Criteria and the table criteria_categories.
The categories table has already data in the database.
So my problem is, how to get the data from categories and insert them using fixtures into the criteria_categories table?
My code is as follow:
Criteria
class Criteria
{
/**
* #ORM\ManyToMany(targetEntity="Categories", inversedBy="criteria", cascade={"persist"})
* #ORM\JoinTable(name="criteria_categories")
**/
private $categories;
}
Categories
class Categories
{
/**
* #ORM\ManyToMany(targetEntity="Criteria", mappedBy="categories")
**/
private $criteria;
}
DataFixtures
class LoadCriteria extends Fixture
{
public function load(ObjectManager $manager)
{
$criteria = array(
array(
'label' => 'Test1'
),
array(
'label' => 'Test2'
)
);
$cat = new Categories();
foreach ($criteria as $critere) {
$ctr = new Criteria();
$ctr->setCriteriaLabel($critere['label']);
$manager->persist($ctr);
}
$manager->flush();
}
}
So the real question is how to get the data from categories and use them here in this fixture to populate the table criteria_categories?
Thanks in advance for your answer.

In doctrine you can forget on criteria_categories table. The class criteria has a collection of categories. Don't need to worry about additional tables used behind the scenes.
But to your question. To get all categories from the db, you have to define this fixture as a service and then inject an entity manager or your "wrapper" service.
class LoadCriteria extends Fixture
{
/**
* #var CategoriesRepository
*/
private $repository;
public function __construct(EntityManagerInterface $em)
{
$this->repository = $em->getRepository(Categories::class);
}
public function load(ObjectManager $manager)
{
$this->categories = $repository->findAll();
$criteria = array(
array(
'label' => 'Test1'
),
array(
'label' => 'Test2'
)
);
$cat = new Categories();
foreach ($criteria as $critere) {
$ctr = new Criteria();
$ctr->setCriteriaLabel($critere['label']);
$manager->persist($ctr);
}
$manager->flush();
}
}
If you use default service configuration from symfony 3.3+, your fixture is already a service.
If you don't use default service configuration, you have to define the fixture as service manually by.
#services.yml
App\DataFixtures\ORM\CriteriaFixture:
tags: [doctrine.fixture.orm]

Related

How to get methods properties values - PHP

I have this code and wonder get the methods properties values.
<?php
class framework{
// users table
function users(){
$username="VARCHAR (255)";
$email="VARCHAR (255)";
$password="VARCHAR (255)";
}
// product table
function produts(){
$title="VARCHAR (255)";
$price="INT ()";
$author="VARCHAR (255)";
}
//categories table
function categories(){
$category_name="VARCHAR (255)";
}
}
?>
I'm trying to create my own framework and in this particular code I'm trying to simplify database creation. The idea is to get the class name as the database name and the methods as tables names, and the last get the methods properties as cols.
I use get_class() to get the class name and add as table name;
get_class_methods to get the class methods and create the table.
So I have no idea of how to create the respective cols.
I am not recommending this approach because you are reinventing the wheel here, but you could expose your DDL info via public properties. Of course, you can make these private/protected and expose them via getters.
I also created a base model which your child models can inherit. This allows for IDE autocompletion in the DatabaseBuilder below.
<?php
namespace Bartolomeu;
// Base model
abstract class Model {
public $table;
public $columns;
}
class User extends Model
{
public $table = 'users';
public $columns = [
'username' => 'VARCHAR (255)',
'email' => 'VARCHAR (255)',
'password' => 'VARCHAR (255)',
];
}
class Product extends Model
{
public $table = 'products';
public $columns = [
'title' => 'VARCHAR (255)',
'price' => 'INT ()',
'author' => 'VARCHAR (255)',
];
}
class Category extends Model
{
public $table = 'categories';
public $columns = [
'category_name' => 'VARCHAR (255)',
];
}
Finally, you can create a class that will actually "read" the models and do the necessary work to create the tables themselves.
<?php
class DatabaseBuilder
{
public function createTables()
{
$models = [
new User(),
new Product(),
new Category(),
];
foreach ($models as $model) {
/* #var Model $model */
$table = $model->table;
$columns = $model->columns;
//...
}
}
}

Too many rows with Many To Many Relationship omines/datatables-bundle

I am using bundle omines/datatables-bundle to create tables in my Symfony application. When I create custom query that left joins with a field that has Many to Many relationship it returns too many rows.
I am using Symfony 4.2 and omines/datatables-bundle bundle. The end result it that I have wrong number of total results found and many blank pages in my table.
This is how my table is being created
class TestTableType implements DataTableTypeInterface
{
public function configure(DataTable $dataTable, array $options)
{
$dataTable
->add('id',
NumberColumn::class,
array(
'label' => 'ID',
'globalSearchable' => false
)
)
->createAdapter(ORMAdapter::class,
array(
'entity' => Test::class,
'query' => function (QueryBuilder $builder)
{
$builder
->distinct()
->select('t')
->from(Test::class, 't')
->leftJoin('t.products', 'prod');
}
)
)
;
}
}
and this is how Many to Many relationship is defined in my entity class.
**
* #ORM\ManyToMany(targetEntity="App\Entity\Product", inversedBy="tests")
* #ORM\JoinTable(name="product_has_test")
*/
private $products;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
along with getters and setters
public function addProduct(\App\Entity\Product $product)
{
$this->products[] = $product;
return $this;
}
public function removeProduct(\App\Entity\Product $product)
{
$this->products->removeElement($product);
}
public function getProducts()
{
return $this->products;
}
What might be the cause of it? And how can I fix it?

I want to acquire the relation value with the store when searching for a category in Laravel5.6

thank you view my question.
I would like to retrieve information on the tag table relation with the store with many-to-many when searching for a category
I created Store-table, Category-table, Tag-table.
The store-table and the category-table are connected by a many-to-many relation. The tag-table is the same.
I was able to search for categories and get information on businesses that are relation- ed, but I do not know how to get information on tags that are relations with stores.
So, I try this idea. search categories → get storeID from relation data→ storeID search → return shop data that hit.
However, I do not know how to get storeID in the store data acquired by category search
How can I write the code?
please help me.
sorry, bat my English.
App\Store
use Illuminate\Database\Eloquent\Model;
class Store extends Model
{
protected $fillable = ['name','location', 'price', 'open_time',
'closed_day'];
protected $table = 'stores';
public function photos(){
return $this->hasMany(StorePhoto::class);
}
public function categories(){
return $this->belongsToMany(Category::class,'category_store','category_id','store_id');
}
public function tags(){
return $this->belongsToMany(Tag::class, 'store_tag', 'tag_id', 'store_id');
}
}
App\Category
protected $fillable = ['store_id', 'category_id'];
public function stores()
{
return $this->belongsToMany(Store::class,'category_store','store_id','category_id');
}
App\Tag
protected $fillable = ['store_id', 'tag_id'];
public function stores()
{
return $this->belongsToMany(Store::class, 'store_tag', 'store_id', 'tag_id');
}
Resource/Category
class Category extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'store' => $this->stores,
];
}
}
web.php
use App\Category;
use App\Http\Resources\Category as CategoryResource;
Route::get("/store/api/category", function (Request $request) {
$search_category = $request->get('category_id');
return new CategoryResource(Category::find($search_category));
});
You can use dot notation to eager load nested relations:
$category = Category::with('stores.tags')->find($request->get('category_id'));
The tags will then be accessible on each Store model related to the Category:
// create a single flattened array of all the tags
$tags = $category->stores->flatMap->tags;

How to specify relationships between tables in ZF2 using ZFcBase

i'm new in Zend Framework. I'm working with an application that uses the following db pattern: Controler -> Service -> Mapper.
And i have an entity for each table and a hydrator file. What i need is to join tables in SQL query, but i don´t know how to access the results from the joined table, cause it only feeds the entity of the current table. Here´s my code:
Controller:
$userEntity = new \Portal\Entity\Iamuserdb();
$userEntity->setIamUserDbId($this->params('id'));
$service = $this->getServiceLocator()->get('Portal\Service\Reports');
$user = $service->getUserById($userEntity)
Service (Reports):
protected $iamuserMapper;
public function selectUsers(){
$usuarios = $this->getIamUserMapper()->fetchAllUsers();
return $usuarios;
}
protected function getIamUserMapper()
{
if ($this->iamuserMapper == null) {
$this->iamuserMapper = $this->getServiceManager()->get('Portal\Mapper\Iamuser');
}
return $this->iamuserMapper;
}
Mapper (Iamuser):
public function fetchAllUsers()
{
$select = $this->getSelect();
$select->from('IAMUser')
->join('IAMUser_IAMGroup', 'IAMUser.iamUserDbId=IAMUser_IAMGroup.IAMUser_iamUserDbId', array('IAMUser_iamUserDbId', 'iamGroups_iamGroupDbId'), 'left')
->join('IAMGroup', 'IAMGroup.iamGroupDbId=IAMUser_IAMGroup.iamGroups_iamGroupDbId', array(), 'left');
return $this->select($select);
}
Hydrator:
class Iamuser extends Hydrator
{
protected function getEntity()
{
return 'Portal\Entity\Iamuserdb';
}
protected function getMap()
{
return array(
);
}
}
In my Module.php from the module i have the factory:
'factories' => array(
'Portal\Mapper\Iamuser' => function($sm) {
$dbAdapter = new \Zend\Db\Adapter\Adapter($sm->get('Configuration')['db']);
$mapper = new Mapper\Iamuser();
$mapper->setEntityPrototype(new Entity\Iamuserdb())
->setHydrator(new Mapper\Hydrator\Iamuser())
->setDbSlaveAdapter($dbAdapter)
->setDbAdapter($dbAdapter);
return $mapper;
},
}
See in my mapper i'm joining two tables, but how to fetch these results, since they came from another table and is not feed in Entity class? Thanks in advance
I Solve my problem. All i have to do is return this statement:
return $this->select($select)->getDataSource();
So i skip the hydration results in entities and get raw PDO array, this way i can join tables.

Getting related user attributes in Phalcon

I'm new to Phalcon, just trying to write my first application, and facing an issue that the documentation isn't very clear on, which is in regards to getting related information.
At the moment I have 1 controller, the User controller.
<?php
class UserController extends Phalcon\Mvc\Controller
{
public function homeAction()
{
$users = Users::query()
->where('id = :id:')
->bind(array('id' => '1'))
->execute();
$user = $users->getFirst();
$this->view->setVar('user', $users->getFirst());
$primaryStatus = Status::query()
->where('userId = :id:')
->bind(array('id' => '1'))
->execute();
$this->view->setVar('primaryStatus', $primaryStatus->getFirst());
$status = Status::query()
->where('userId != :id:')
->bind(array('id' => '1'))
->execute();
$this->view->setVar('status', $status);
}
}
And I have some models setup, Users, Attributes and UsersAttributes
and my view setup in volt.
This is my Attributes model
<?php
class Attributes extends Phalcon\Mvc\Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany('id', 'UsersAttributes', 'attributesId');
}
}
My Users model
<?php
/**
* Users class
*
* Represents Holla users
*
*/
class Users extends Phalcon\Mvc\Model
{
public $id;
public $name;
public $username;
public $password;
public $email;
public $active;
public $createdDate;
public function getSource()
{
return 'users';
}
public function initialize()
{
$this->hasMany('id', 'UsersAttributes', 'userId');
$this->hasManyToMany(
'id',
'UsersAttributes',
'userId', 'attributeId',
'Attributes',
'id'
);
}
}
and my UsersAttributes model
<?php
/**
* Users attributes class
*
* Represents Holla users attributes
*
* #Source('usersAttributes');
*
*/
class UsersAttributes extends Phalcon\Mvc\Model
{
public $id;
public $userId;
public $attributeId;
public $attributeValue;
public function getSource()
{
return 'usersAttributes';
}
public function initialize()
{
$this->belongsTo('userId', 'Users', 'id');
$this->belongsTo('attributeId', 'Attributes', 'id');
}
}
I have 3 tables
users
id e.g. 1
name e.g. andre
username e.g. andrefigueira
attributes
id e.g. 1
attributeName e.g. profileImage
attributeDefaultValue e.g. placeholder.jpg
usersAttributes
id e.g. 1
userId e.g. 1
attributeId e.g. 1
attributeValue e.g. andre.jpg
In my controller I am doing a query and assigning the first result to a view property which is the user property, but I cannot figure out how to access specific user attributes from the get related method implementation.
I'd like to be able to in my volt do something like:
The name of the attributes is defined in the attributes table, then assigned a value and user in the usersAttributes table.
{{ user.userAttributes.profileImage }}
How would I go about accomplishing this? I have searched through a lot of different posts and the documentation with little luck...
Thanks in advance
One to many relation returns the container of zero or more records:
{% for r in user.userAttributes %}
{{ r.profileImage }}
{% endfor %}
I've realised my error, everything was working as it should, Phalcon simply won't map my structure database in this way as I define an attribute name in the attributes table, but the user defined value in the usersAttributes table. Hence no way to map it by the standard way so I had to create a new method and instantiate it elsewhere to pass the parameters to my view.
The code I've used to solve the problem is in the Users model and simply appends the attributes as an object to the user result object.
public static function fetchUserAttributes($userId)
{
$modelsManager = Phalcon\DI::getDefault()->getModelsManager();
$phql = '
SELECT name, attributeValue
FROM Attributes
LEFT JOIN UsersAttributes
ON UsersAttributes.userId = :userId:
AND Attributes.id = UsersAttributes.attributeId
';
$rows = $modelsManager->executeQuery($phql, array('userId' => $userId));
$attributesObj = new \stdClass();
foreach($rows as $row)
{
$attributesObj->{$row['name']} = $row['attributeValue'];
}
return $attributesObj;
}
public function afterFetch()
{
//Attach user attributes
$this->attributes = Users::fetchUserAttributes($this->id);
}

Categories