With Doctrine and Symfony 5, I want to change INDEX BY for my queries with findAll() and findBy() functions. I would like the keys of the result table to be simply the IDs.
// Current result
[
0 => Post {
'id' => 5,
'name' => 'Test 5',
},
1 => Post {
'id' => 6,
'name' => 'Test 6',
},
]
// Desired result :
[
5 => Post {
'id' => 5,
'name' => 'Test 5',
},
6 => Post {
'id' => 6,
'name' => 'Test 6',
},
]
I know that I can use createQueryBuilder('post', 'post.id'), but in this case I lose the fetch = EAGER since I make the queries myself.
Maybe the only solution is to do foreach () to change the keys of each findAll() and findBy() request, but I find it heavy.
You can alter the findBy method or findAll method:
Create a foreach ($results as $result) as follows:
$newResult = [];
$results = $repo->findAll();
foreach ($results as $result) {
$newResult[$result->getId()] = $result;
}
Related
I have a problem with GridFieldEditableColumns. I extended EditableOption with a list of files, and now I want the CMS columns to display an upload field. I took the EditableMultipleOptionField as a reference and implemented it like this:
$editableColumns = new GridFieldEditableColumns();
$editableColumns->setDisplayFields([
'Title' => [
'title' => 'Beschreibung',
'callback' => function ($record, $column, $grid) {
return TextField::create($column);
}
],
'Value' => [
'title' => 'Wert',
'callback' => function ($record, $column, $grid) {
return TextField::create($column);
}
],
'Default' => [
'title' => 'Standardmäßig aktiv?',
'callback' => function ($record, $column, $grid) {
return CheckboxField::create($column);
}
],
'Examples' => [
'title' => 'Beispielbilder',
'callback' => function ($record, $column, $grid) {
return UploadField::create($column);
}
]
]);
However, I always get errors when I use UploadField:
[Emergency] Uncaught LogicException: Field must be associated with a form to call Link(). Please use $field->setForm($form);
I also tried it with ['field' => UploadField::class], same problem. The extension works, because if I change the field for the DataObject to type Text and use a TextField instead, it works fine. How can I use an UploadField within GridFieldEditableColumns?
I have currently added metadata to a product variation woocommerce_product_after_variable_attributes and woocommerce_save_product_variation Guide here.
function custom_woocommerce_product_after_variable_attributes($loop, $variation_data, $variation)
{
woocommerce_wp_select([
'id' => 'field_1['.absint($variation->ID).']',
'label' => 'Field 1 ',
'value' => get_post_meta(absint($variation->ID), 'field_1', true),
'options' => [
'1' => '1',
'2' => '2',
'3' => '3',
],
]);
}
add_action('woocommerce_product_after_variable_attributes', 'custom_woocommerce_product_after_variable_attributes', 10, 3);
function custom_woocommerce_save_product_variation($post_id)
{
$field1 = $_POST['field_1'][$post_id];
if (! empty($field1)) {
update_post_meta(absint($post_id), 'field_1', esc_html($field1));
}
}
add_action('woocommerce_save_product_variation', 'custom_woocommerce_save_product_variation', 10, 2);
Then in the js hooked into single_variation_wrap when the variation was changed. This was working fine in 3.0.5 but since updating to 3.1.1 in the js i am no longer getting the custom meta_data for variations.
$('.single_variation_wrap').on('show_variation', function(event, variation) {
console.log(variation.meta_data);
});
The meta_data information no longer exists.
How can this be fixed?
I was able to fix this by adding a filter.
function custom_woocommerce_available_variation($variations, $product, $variation)
{
$metadata = $variation->get_meta_data();
if (!empty($metadata)) {
$variations = array_merge($variations, [
'meta_data' => $metadata,
]);
}
return $variations;
}
add_filter('woocommerce_available_variation', 'custom_woocommerce_available_variation', 10, 3);
I'm trying to save my ManyToMany relations between users and categories. Actually I'm trying to save my category with given users, but this doesn't work.
Form
$builder->add('name')
->add('users', EntityType::class, array(
'label' => 'Benutzer',
'class' => 'AppBundle\Entity\User',
'multiple' => true,
'expanded' => true,
'required' => false,
'choice_label' => function (User $user) {
return $user->getUsername();
}
))
->add('submit', SubmitType::class, array(
'label' => 'Speichern'
));
Form Handler
public function onSuccess(Request $request)
{
// Get category from form
$category = $this->getForm()->getData();
// Redirect to parent category when setted
if ($this->parent) {
$category->setParent($this->parent);
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $this->parent->getId()
]));
} else {
// Build new redirect response
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $category->getId()
]));
}
try {
// Save category in database
$this->em->merge($category);
$this->em->flush();
} catch (ORMException $ex) {
throw $ex;
}
return $response;
}
Maybe you have to unserialize the Entity $category first?
$detachedCategory = unserialize($category);
$this->em->merge($detachedCategory);
$this->em->flush();
I found this link regarding that:
How to manage deserialized entities with entity manager?
Not sure if that's the answer, but you might want to do more research.
I need to send from Symfony form ChoiceType::class
But I don't need choices keys, I need to send choices values.
Is that is possible?
$form->add('section', ChoiceType::class, array(
'mapped' => false,
'choices' => array(
1 => 'value1',
2 => 'value2'
),
));
I just want to send value1 if I chose value1,
not key 1 as default.
You can use
array_flip ($array)
refer to php docs
[Since Symfony 2.7] In any case you can play with choice value through choice_value option and a Closure function (Reference):
$form->add('section', ChoiceType::class, array(
'choice_value' => function ($value, $key, $index) {
return $value;
}
));
Useful for dynamic choices.
You just need to reverse it. Also, I don't think you need 'mapped'.
Try this:
$form->add(
'section',
ChoiceType::class,
[
'choices' => [
'value1' => 1,
'value2' => 2,
],
]
);
It should work.
Mayby a bit late but i've made this and it works perfect. Without array_flip. Mayby for someone it 'll be usefull.
$dataUsers = [];
$users = [
['id' => 1, 'firstname' => 'joe', 'lastname' => 'doe'],
['id' => 2, 'firstname' => 'will', 'lastname' => 'fog'],
];
foreach ($users as $u) {
$dataUsers[] = (object)['id' => $u['id'], 'label' => $u['firstname']];
}
$builder
->add('users', ChoiceType::class, [
'choices' => $dataUsers,
'choice_label' => function ($value) {
if (is_object($value)) {
return $value->label;
} else {
return 0;
}
},
'choice_value' => function ($value) {
if (is_object($value)) {
return $value->id;
} else {
return 0;
}
},
'data' => (object)[ 'id' => 2]
]);
I have a table that contains people's names in 3 fields: "lastname", "firstname", "middlename".
I need to get all 3 fields concatenated by the createQueryBuilder() method or somehow else.
My code looks like this:
$formMapper->add('collaborator', 'entity', array
(
'label' => 'acme.admin.person',
'empty_value' => '',
'class' => 'AcmeCoreBundle:Person',
'query_builder' => function ($repository) {
return $repository
->createQueryBuilder('p')
->where('p.status = 1')
->orderBy('p.lastname', 'ASC');
},
'property' => 'lastname'
)
);
Surely, now it only returns the "lastname".
How to modify it to get the result that i need?
One way is to define an unmapped property in your Person entity lets say $titleConcat now create a getter for the property and concat all 3 properties you want to show
protected $titleConcat;
public function getTitleConcat() {
return $this->firstname.' '.$this->middlename. ' ' . $this->lastname;
}
Now in your $formMapper object define 'property' => 'titleConcat'
$formMapper->add('collaborator', 'entity', array
(
'label' => 'acme.admin.person',
'empty_value' => '',
'class' => 'AcmeCoreBundle:Person',
'query_builder' => function ($repository) {
return $repository
->createQueryBuilder('p')
->where('p.status = 1')
->orderBy('p.lastname', 'ASC');
},
'property' => 'titleConcat'
)
);