Convert Twig array to a PHP array - multidimensional-array

Using file_get_contents I'm able to get the contents of a twig file which contains just one multidimensional array:
Twig:
{% set settings = {
theme : '#91141b',
transforms : {
thumb : { mode:'crop', width:300, height:300, quality:80, position:'center-center'},
small : { mode:'fit', width:100, height:100, quality:70, position:'center-center'},
header : { mode:'fit', height:800, quality:80, position:'center-center'},
mobile : { mode:'crop', width:640, height:1136, quality:60, position:'center-center'}
},
globals : {
telephone : '123456678',
address : '42 Wallaby Way, Sydney'
},
social : {
facebook : 'http://www.facebook.com',
twitter : 'http://www.twitter.com',
linkedin : 'http://www.linkedin.com',
youtube : 'http://www.youtube.com'
}
} %}
In PHP, I now have this string to play with:
{% set settings = { theme : '#91141b', transforms : { thumb : { mode:'crop', width:300, height:300, quality:80, position:'center-center'}, small : { mode:'fit', width:100, height:100, quality:70, position:'center-center'}, header : { mode:'fit', height:800, quality:80, position:'center-center'}, mobile : { mode:'crop', width:640, height:1136, quality:60, position:'center-center'} }, globals : { telephone : '123456678', address : '42 Wallaby Way, Sydney' }, social : { facebook : 'http://www.facebook.com', twitter : 'http://www.twitter.com', linkedin : 'http://www.linkedin.com', youtube : 'http://www.youtube.com' } } %}
Is there a way to turn this into a usable PHP multidimensional array? Like this:
PHP:
$settings = array(
'theme' => '#91141b',
'transforms' => [
'thumb' => [ 'mode'=>'crop', 'width'=>300, 'height'=>300, 'quality'=>80, 'position'=>'center-center'],
'small' => [ 'mode'=>'fit', 'width'=>100, 'height'=>100, 'quality'=>70, 'position'=>'center-center'],
'header' => [ 'mode'=>'fit', 'height'=>800,'quality'=>80, 'position'=>'center-center'],
'mobile' => [ 'mode'=>'crop', 'width'=>640, 'height'=>1136,'quality'=>60, 'position'=>'center-center']
],
'globals' => [
'telephone' => '123456678',
'address' => '42 Wallaby Way, Sydney'
],
'social' => [
'facebook' => 'http://www.facebook.com',
'twitter' => 'http://www.twitter.com',
'linkedin' => 'http://www.linkedin.com',
'youtube' => 'http://www.youtube.com'
]
);
I wonder if there is a parser function I'm unaware of.
Thanks,
Mark

Ok, I sort of figured it out.
In the twig file, render out the settings variable with a json_encode filter:
{{ settings|json_encode|raw }}
Then in your PHP plugin you can render in the twig file and use PHP's json_decode.
$file = '_includes/settings';
$settings = json_decode(craft()->templates->render($file), true);

Related

Add class TextEditorField EasyAdmin 4

is there a way to add a custom class to a specific tag with the TextEditorField - EasyAdmin : https://symfony.com/bundles/EasyAdminBundle/current/fields/TextEditorField.html
This field is using trix editor : https://trix-editor.org
I'd like to do something like this :
public function configureFields(string $pageName): iterable {
return [
TextEditorField::new('description', 'Description')->setNumOfRows(30)->setTrixEditorConfig([
'blockAttributes' => [
'default' => ['tagName' => 'p'],
'heading1' => ['tagName' => 'h2', 'class' => 'myClass'],
]
])
];
}
Actually, I want to add the class 'myClass' to all the h2 tags.

Multilevel dynamic forms in Symfony

I need to create a form adding faculty to the database. First, the user selects a region from the list ( / ChoiceType), then the city of this region from the following list, the university, and finally enters the name of the faculty. The default values are the first region from the database, its first city and first university.
Sending the page with default data works, the choice of the region works, but the the choice of the city return to 500 status
Form:
Twig and ajax:
{% extends 'admin/insert/insert.html.twig' %}
{% block title %}Add Faculty{% endblock %}
{% block body %}
<div class="insert">
<h1 class="insert__title">Add Faculty</h1>
{{ form_start(insert_faculty, { 'attr' : {'class' : 'insert__form'} }) }}
{% for message in app.flashes('success') %}
<div class="insert__success">
{{ message }}
</div>
{% endfor %}
<div class="insert__errors">
{{ form_errors(insert_faculty) }}
</div>
{{ form_label(insert_faculty.region, 'Region:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.region, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.city, 'City:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.city, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.university, 'University:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.university, { 'attr' : {'class' : 'insert__input'} }) }}
{{ form_label(insert_faculty.name, 'Name:', { 'label_attr' : {'class' : 'insert__label'} }) }}
{{ form_widget(insert_faculty.name, { 'attr' : {'class' : 'insert__input insert__input_name'} }) }}
<button type="submit" class="insert__button">Save</button>
{{ form_end(insert_faculty) }}
<div class="insert__buttons">
Back
</div>
</div>
{% block javascripts_footer %}
{{ parent() }}
<script>
let $region = $('#insert_faculty_region');
$region.change(function() {
let $form = $(this).closest('form');
let data = {};
data[$region.attr('name')] = $region.val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(get) {
$('#insert_faculty_city').html(
$(get).find('#insert_faculty_city').html()
);
$('#insert_faculty_university').html(
$(get).find('#insert_faculty_university').html()
);
}
});
});
let $city = $('#insert_faculty_city');
$city.change(function() {
let $form = $(this).closest('form');
let data = {};
data[$city.attr('name')] = $city.val();
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(get) {
$('#insert_faculty_university').html(
$(get).find('#insert_faculty_university').html()
);
}
});
});
</script>
{% endblock %}
{% endblock %}
Form class:
class InsertFacultyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('region', ChoiceType::class, [
'choices' => $options['regions_array'],
'mapped' => false,
])
->add('city', ChoiceType::class, [
'choices' => null,
'mapped' => false,
])
->add('university', ChoiceType::class, [
'choices' => null,
])
->add('name')
;
$formModifier = function (FormInterface $form, $entity_parent) {
if (get_class($entity_parent) === 'App\Entity\Region') {
if (!$entity_parent->getCities()->count()) {
$form->add('city', ChoiceType::class, [
'choices' => null,
'mapped' => false,
]);
}
else {
$cities_in_database = $entity_parent->getCities();
foreach ($cities_in_database as $city) {
$cities[$city->getName()] = $city;
}
$form->add('city', ChoiceType::class, [
'choices' => $cities,
'mapped' => false,
]);
}
}
else if (get_class($entity_parent) === 'App\Entity\City') {
if (!$entity_parent->getUniversities()->count()) {
$form->add('university', ChoiceType::class, [
'choices' => null,
]);
}
else {
$university_in_database = $entity_parent->getUniversities();
foreach ($university_in_database as $university) {
$universities[$university->getName()] = $university;
}
$form->add('university', ChoiceType::class, [
'choices' => $universities,
]);
}
}
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options, $formModifier, $builder) {
$region = $options['regions_array'][array_key_first($options['regions_array'])];
$city = $region->getCities()[0];
$formModifier($event->getForm(), $region);
$formModifier($event->getForm(), $city);
}
);
$builder->get('region')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$region = $event->getForm()->getData();
$city = $region->getCities()[0];
$formModifier($event->getForm()->getParent(), $region);
$formModifier($event->getForm()->getParent(), $city);
}
);
$builder->get('city')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$city = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $city);
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Faculty::class,
'regions_array' => null,
]);
$resolver->setAllowedTypes('regions_array', 'array');
}
}
Controller:
/**
* #Route("/admin/insert/faculty", name="faculty")
*/
public function faculty(Request $request)
{
$regions_in_database = $this->getDoctrine()->getRepository(Region::class)->findAll();
$regions = [];
foreach ($regions_in_database as $region) {
$regions[(string)$region->getName()] = $region;
}
$faculty = new Faculty();
$insert_faculty = $this->createForm(InsertFacultyType::class, $faculty, [
'regions_array' => $regions,
]);
if (!$regions_in_database) {
$insert_faculty->addError(new FormError("There are no regions!"));
}
$insert_faculty->handleRequest($request);
if ($insert_faculty->isSubmitted() && $insert_faculty->isValid()) {
$repository = $this->getDoctrine()->getRepository(University::class);
$faculty_in_database = $repository->findOneBy(
[
'name' => $faculty->getName(),
'university' => $faculty->getUniversity(),
]
);
if ($faculty_in_database) {
$insert_faculty->addError(new FormError('Such a faculty is already in the database!'));
}
else {
$faculty->setRating(0);
if(!$faculty->getUniversity()) {
$insert_faculty->addError(new FormError("Select the university!"));
}
else {
$entity_manager = $this->getDoctrine()->getManager();
$entity_manager->persist($faculty);
$entity_manager->flush();
$this->addFlash(
'success',
'Faculty "' . $faculty->getName() . '" successfully saved!'
);
}
}
}
return $this->render('admin/insert/faculty/faculty.html.twig', [
'insert_faculty' => $insert_faculty->createView(),
]);
}
I invite you to use the Symfony debug toolbar. It will allow you to see the different problems associated with your code and give much more information about the problems that appear.
Profiler Symfony
About your problem, I think it is necessary to debug at the level of what your form sends to your application. But if you want more help, you must provide the error message that come with your 500 error.

How can I print php variable in twig?

I want to make a twig template for my custom module that outputs Next and Previous article links.
In my .module file I have
<?php
/**
* #file
* Code for the nextprev module.
*/
function nextprev_theme($existing, $type, $theme, $path) {
return [
'nextprev_template' => [
'variables'=> [
'nextprev' => 'Some_value',
],
],
];
}
In my controller file I use
public function build() {
/**
* {#inheritdoc}
*/
$node = \Drupal::request()->attributes->get('node');
$created_time = $node->getCreatedTime();
$nextprevlinks .= $this->generateNext($created_time);
$nextprevlinks .= $this->generatePrevious($created_time);
$renderable = [
'#theme' => 'nextprev_template',
'#nextprev' => 'nextprevlinks',
];
$rendered = drupal_render($renderable);
}
}
I want to print out my $nextprevlinks in twig as {{ nextprev }}
I've made twig template within my module folder and it works, however I can't print out my {{ nextprev }} variable, it returns Null when I use kint.
I also added nextprev.routing.yml with:
nextprev.block:
path: /node
defaults:
_controller: Drupal\nextprev\Controller\NextPrevLinksBlock::build
requirements:
_permission: 'access content'
This must work:
$renderable = [
'#theme' => 'nextprev_template',
'#nextprev' => $nextprevlinks,
];
But I think, it coild be better, if you return renderable array from controller like this:
return [
'#theme' => 'nextprev_template',
'#nextprev' => $nextprevlinks,
];

How to create a external menu link in drupal 8?

I want to create an external menu link here is my code.
class MyClass extends DeriverBase implements ContainerDeriverInterface {
public function getDerivativeDefinitions($base_plugin_definition) {
$links = [];
$sites = [
'www.google.com' => 'http://gwa-caromaww2.netsol.local/',
'www.drupal.org' => 'http://drupal.org/'
];
foreach ($sites as $key => $site) {
$links['sites'.$key] = [
'title' => $key,
'path' => $site,
] + $base_plugin_definition;
}
return $links;
}
}
When I installed my custom module It genrates an error saying:
Symfony\Component\Routing\Exception\RouteNotFoundException: Route "" does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 190 of D:\workspace\projects\caromaww\core\lib\Drupal\Core\Routing\RouteProvider.php).
Try passing:
'url' => $site
instead of path.
External pointing menu links would use an url value
https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-menu-links

One of Drupal Commerce shipping services abruptly disappears/rule gets deleted

I am not sure whether this a bug or not. I have one shipping method that includes two shipping services. One of the shipping services is available only if the ordered items include Arabic language books; in such a case the user is represented with two shipping options instead of one.
Apparently for no obvious reason, one the shipping services becomes broken and the rules component suddenly disappears.
I didn't create the rule myself, I found out that the rule "Collect rates: IPS" is created. Also, the rules components are created on the fly.
The shipping services I am referring to is called "kkkkkkk". Please find below some screenshots and my code for more info:
function myips_commerce_shipping_method_info() {
$shipping_methods = array();
$shipping_methods['ippppps'] = array(
'title' => t('IPS'),
'description' => t('IPS commerce shipping'),
);
commerce_shipping_services_reset();
//entity_defaults_rebuild();
//rules_clear_cache(TRUE);
return $shipping_methods;
}
function myips_commerce_shipping_service_info() {
$contains_arabic=arabic_books_contained();
$shipping_services = array();
$shipping_services['ppppp'] = array(
'title' => 'Express Mail - DHL',
//'description' => 'Express Mail - DHL',
'display_title' => t('Express Mail - DHL'),
'shipping_method' => 'ippppps',
'price_component' => 'shipping',
'callbacks' => array(
'rate' => 'commerce_ipppppls_service_rate_order',
),
);
if($contains_arabic=='true') {
$shipping_services['kkkkkkk'] = array( //arbitrary name w/ 'service' in there
'title' => 'kkkkkkk', //title for the interface
// 'description' => 'Lebanon Shipment option for books shipped from lebanon',
'display_title' => t('Registered Mail'),
'shipping_method' => 'ippppps',
'price_component' => 'shipping',
'callbacks' => array(
'rate' => 'commerce_ipppppsssss_service_rate_order',
),
);
}
return $shipping_services;
}
my shipping rule:
{ "commerce_shipping_method_ippppps" : {
"LABEL" : "Collect rates: IPS",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "commerce_shipping" ],
"ON" : { "commerce_shipping_collect_rates" : [] },
"DO" : [
{ "commerce_shipping_method_collect_rates" : {
"shipping_method_name" : "ippppps",
"commerce_order" : [ "commerce-order" ]
}
}
]
}
}
my shipping rule component for one of the shipping services, the second appears abruptly:
{ "commerce_shipping_service_ppppp" : {
"LABEL" : "Rate Express Mail - DHL",
"PLUGIN" : "rule",
"OWNER" : "rules",
"REQUIRES" : [ "commerce_shipping" ],
"USES VARIABLES" : { "commerce_order" : { "type" : "commerce_order", "label" : "Order" } },
"DO" : [
{ "commerce_shipping_service_rate_order" : {
"shipping_service_name" : "ppppp",
"commerce_order" : [ "commerce-order" ]
}
}
]
}
}
Am I missing something, should I add something in my code, should any custom rules be created?
Thank you!

Resources