Views join on custom table with file_managed table - drupal

I have custom table with a field called image_id.
image_id is an integer which represents a file id of the managed_file table.
I've read many tutorials on how to expose this field to views, and how to make a join with the managed file table. All examples just show joins with node table, but none of them make joins with file_managed.
I tried something like this:
$data['my_table']['table']['join'] = [
'file_managed' => [
'left_field' => 'fid',
'field' => 'image_id',
],
];
$data['my_table']['image_id']['relationship'] = [
'handler' => 'views_handler_relationship',
'base'=>'file_managed',
'field'=>'image_id',
'label' => 'Managed files',
];
Right now my field is exposed, but the relation with the file_managed table doesn't work. I can't see fields from the managed files table, therefore I can't render my images with all formatters available.
Please help me!

Related

Dynamically generate a Drupal page for each row in a table

Is there a way in Drupal 8 to dynamically generate a page for each row in a table in a database?
If I have a database named School, with a table Students, with these columns and rows:
ID |FirstName |LastName |Email |User |HiddenField
-------------------------------------------------------------------------
1 |Adam |Johnson |ajohnson#example.com |ajohn1 |Blah
2 |Bob |Smith |bsmith#example.com |bsmith0 |Foo
Is there a module or setting to create simple pages with these URLs with content like this:
http://mywebpage.com/students/1
First name: Adam
Last name: Johnson
Email address: ajohnson#example.com
Username: ajohn1
http://mywebpage.com/students/2
First name: Bob
Last name: Smith
Email address: bsmith#example.com
Username: bsmith0
Note that there is a HiddenField that isn't displayed, so this solution should include the ability to exclude certain columns.
I've tried using the Views module to create a new page type, but I don't see in there where to specify a table or anything like that.
To fetch data to an associative array with the keys named as the fields, you can write the following:
$query = \Drupal::database()->select('students')
->fields('students', [
'id',
'firstname',
'lastname',
'email',
'user'
]);
$results = $query->execute()->fetchAllAssoc();
After that, you can iterate through $results and create the pages:
foreach ($results as $result) {
// Create node object.
$node = Node::create([
'type' => 'page',
'title' => 'whatever you want',
'field_machine_name' => 'field_value',
'firstname' => $result['firstname'],
]);
$node->save();
}
Please keep in mind to use dependency injection wherever you can. Also you can check for errors like is there a bundle called 'page', and run it only if there is.

How can I obtain the values of an Entity in Laravel-Backpack?

While I was trying to show pictures I made this pleasant discovery in backpack:
$this->crud->addFields([
[ // Upload
'name' => 'pictures', //<-- this is an Entity
'label' => 'Photos',
'type' => 'upload_multiple',
'upload' => true,
'disk' => 'uploads'
]
]);
This fragment of code gives me this:
My questions is:
What am I doing wrong?
How can get the value 'file' of this two vectors? I need this for display the images.
You probably forgot to add 'photos' to the cast array.
Based on the documentation:
Step 3. Since the filenames are stored in the database as a JSON array, we're going to use attribute casting on your model, so every time we get the filenames array from the database it's converted from a JSON array to a PHP array:
protected $casts = [
'photos' => 'array'
];
https://laravel-backpack.readme.io/docs/crud-fields#upload_multiple

Symfony2: Two owning sides on many-to-many?

Let's say I have an Person entity and a ResearchArea entity. There is a ManyToMany Doctrine relationship between them with simple join table, a Person can have multiple ResearchAreas and a ResearchArea can have multiple Persons.
In my database, there are thousands of Persons, but only around 10 ResearchAreas.
On the Person edit form, I want to present a checkbox list for each ResearchArea. This is easy in a form builder:
->add('researchAreas', 'entity', array(
'label' => false,
'class' => 'AcmeDemoBundle:ResearchArea',
'property' => 'title',
'required' => false,
'multiple' => true,
'expanded' => true,
))
When submitting the form and binding the request data, this works well and the ManyToMany is handled nicely.
However, when editing a ResearchArea entity, I want to also provide a way to manage the Persons associated with that area. However, I can't use the same entity form type as I did above because there are so many Person entities.
Instead what I want is a collection form type, where the user can add/remove Person entities. I can do this by rendering text fields for each "row" and accept an ID of the person to add.
To support an approach like that, I need to change the relationship from a ManyToMany to a OneToMany -> ManyToOne and make the join table its own entity. But in doing that, then I can no longer use the nice checkboxes on the Person form which would only work with a direct ManyToMany.
Am I just making this all too complicated? Is there a solution to this?
For a similar use case I simply used the entity field type, rendered as a multiselect (multiple => true, expanded => false) and improved with a jquery plugins. This worked quite well, but I didn't have thousands of entities.
->add('persons', 'entity', array(
'label' => false,
'class' => 'AcmeDemoBundle:Person',
'required' => false,
'multiple' => true,
'expanded' => false,
))
I used a jquery plugin (like Chosen) to improve the multiselect and make it more user friendly. With chosen you can simply use:
$(".chosen-select").chosen();
With a bit of custom css you might be able to style it to fit your needs.
I too, would advocate the entity approach, but I used select2 (http://ivaynberg.github.io/select2/) instead.
In Many-to-Many Ajax Forms (Symfony2 Forms) I have some fairly detailed implementation examples.
Select2 can support ajax loading and searching, so the 3000 researchers is not a big deal.

symfony doctrine with two entity managers manually bind select tag

I googled a lot trying to find an answer for my problem, but no luck.
I have two tables in two different db db1.pages and db2.layouts I have defined the two entity managers and I can successfully manage the two as unrelated entities.
My problem is on table db1.pages, I have a layout_id column which contains a reference to the db2.layouts.id column, I didn't created an association between the two because, from my understanding, is not supported by doctrine. I successfully managed to display a selection list of possible layouts on the PageType using the following code:
$builder
->add('name', null, array('label' => 'Name'))
->add('label', null, array('label' => 'Title'))
->add('home', null, array('label' => 'Homepage'))
->add('layoutId', 'entity', array(
'class' => 'USGMCMSBundle:Layouts',
'property' => 'label',
'label' => 'Layout',
))
but it doesn't select the correct layout matched by the value stored into layoutId. Is there a way to select the current selected item and keep it in sync when the user choose a different one?
Maybe using an EventSubscriber? but on which stage? Or is there a better solution?
Hope I made myself clear (sorry for my english)

Symfony 2, how to persist join table entities?

This is such a trivial problem that I can't believe I couldn't find an answer.
Symfony 2, doctrine 2.1. I've got two entities and one intermediate entity (join table). User, Pref, and UsersPrefs. Pref table is dictionary table, so that I could change pref name in one place only. Ok, let's see the picture:
infographic http://dl.dropbox.com/u/22495762/infographic.png
As You can see, I want to have a checkbox group, with all the possible choices (prefs) and preferred choices checked. So, if there are 3 prefs, and only 2 selected by the user, there should be 3 checkboxes, 2 selected.
It's simple, if done plain PHP - query database twice to get list of all prefs and user prefs, render checkboxes depending on values, add some actions to handle form submit, done.
But for the life of God I can't get this to work using symfony & doctrine. I was able to get to the point where I can update relationships in doctrine and further in database, but I'm using raw query values for that:
$data = $request->request->get('some_form');
and this supposedly isn't the way it should be done?
Morevoer, I'm completely stuck as to how should I display checkbox list. I either get list of all options, none checked, or only user options, all checked. Or 'left joined' result set with checkboxes for all cases, useless anyway.
I've come to the point where I tried to overload twig checkbox template, but I couldn't pass variables to the form template, and that was the last straw...
EDIT:
This way I'm getting group of checkboxes, not connected to user choices:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\Pref',
'expanded' => 'true',
'multiple' => 'true',
'property' => 'name'
))
And this way I'm getting only user choices, all checked:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\UserPrefs',
'multiple' => 'false',
'expanded' => 'false',
'property' => 'pref.name',
'query_builder' => function(EntityRepository $er) use ($id) {
return $er->createQueryBuilder('u')
->where("u.user = :id")
->setParameter('id', $id)
;
},
))
And I tried left joins and other options, but at best I could get list of all possible options for all possible users, checked accordingly.
EDIT (POSSIBLE SOLUTION):
I'm displaying checkbox group:
->add('pref_ids', 'choice', array(
'choices' => array(
'1' => 'pref one',
'2' => 'pref two',
'3' => 'pref three',
),
'expanded' => 'true',
'multiple' => 'true'
))
I've added $pref_ids array in User entity. Now I just need to set values in array according to preferences chosen by user:
public function setPrefIds()
{
$prefs = $this->getPrefs();
$this->pref_ids = array();
foreach($prefs as $pref){
array_push($this->pref_ids, $pref->getPref()->getId());
}
return $this;
}
This way I get appropriate checkboxes checked.
Writing values to database is reversal of the process. I'm getting input values from request:
$data = $request->request->get('edit_form');
var_dump($data['pref_ids']);
Removing all user prefs:
foreach ($userPrefs as $pref){
$em->remove($pref);
}
And setting actual associations in doctrine from ids:
$entity->setPrefsById($em, $data['pref_ids']);
Here I'm passing entity manager to entity itself, but I need to refactor it, because it looks kinda messy this way.
Then $em->flush(); and that's it.
That's the best I could come up with. Probably it's overcomplicated and should be done entirely different way. Unfortunately couldn't figure out this "other way".
You need the choice field type: http://symfony.com/doc/current/reference/forms/types/choice.html
In your builder, it will be something like
$builder->add('prefs', 'choice', array('multiple' => true, 'expanded' => true, 'choices' => fetch the available prefs from the database here);
Edit: Sorry I'm mistaken, you need the "Entity" type, which fetches automatically the choices from the database: http://symfony.com/doc/current/reference/forms/types/entity.html
You must still put multiple => true expanded => true to get checkboxes.

Resources