How to write Controller in GRAV CMS - php

I created a form and want to save submitted data in back-end
//front-end
{% extends 'partials/base.html.twig' %}
{% block content %}
<form method="post" action="savedata">
<input type=text name="data">
<input type="submit">
</form>
{% endblock %}
//back-end
function savedata()
{
echo 'saved data:'.$_POST['data'];
exit;
}
I expect the code like this
$grav->post('/savedata', DataController->savedata);
But I cannot found any tutorial about custom Controller in documentation
How can I achieve this purpose?

Related

Html form returns null?

I try to learn php/twig from a tutorial video and I tried to recreate the exercise but can't get back data from a simple form. The name variable in the action is always null. Everything else works. I looked through it multiple times but did everything like in the video. Some help would be really appreciated, thank you!
The action:
public function AddAction(Request $request) : Response{
$name = $request->request->get("name"); //always null
if ($name){
file_put_contents($this->fname, $name,FILE_APPEND);
$this->addFlash("notice","ITEM ADDED");
}
else{
$this->addFlash("notice","DATA ERROR");
}
return $this->redirectToRoute("list");
}
The form:
{% block body %}
<form action="{{ path('add') }}" mehod="POST">
<table>
<tr><td>Name of new item:</td>
<td><input type="text" name="name"/></td></tr>
<tr><td></td>
<td colspan="2"><input type="submit" value="SEND"/></td></tr>
</table>
</form>
{% endblock %}

Passing select multiple on a form

I'm using codeiniter ,with Twig as template engine,and I have this select multiple on the template
<form action="{{ base_url }}mydirection/encuestas/perfil_interna" method="post" >
<select multiple="multiple" name="profile_questions">
{% for question in questions %}
<option id="qid_{{question.id}}">{{ question.text}}</option>
{% endfor %}
</select>
<input type="submit" value="Enviar">
</form>
this is the function on the controller
public function set_profile_internal_question(){
var_dump($_REQUEST);
}
But I get and empty array
and the route only work without the method
$route['mydirection/encuestas/perfil_interna']= 'Backend/Questions/set_profile_internal_question';
this way doesn't work
$route['mydirection/encuestas/perfil_interna']['POST']= 'Backend/Questions/set_profile_internal_question';
But its a form,post should work.

How to access $_POST in Twig form?

I'm trying to print the value of the input field 'gameTitle' in Twig.
This is my code:
<h1>New game</h1>
<form method="post" action="">
<label>Game Title</label>
<input type="text" value="Monopoly" name="gameTitle"><br>
<input class="btn btn-success" name="submit" type="submit" value="Add game">
</form>
{% if app.request.post('submit') %}
{{ app.request('gameTitle')}}
{% endif %}
I've also tried:
{{ app.request.parameter.post('gameTitle}
As a result I want to print this result: "gameTitle is Monopoly".
My question, how do I do the following PHP code in Twig?
<?php
echo "gameTitle is ".$_POST['gameTitle'];
?>
Update:
- I'm not using Symfony, just Twig: http://twig.sensiolabs.org/
This does not work for me:
{{app.request.post('gameTitle')}}
{{app.request.request.get('gameTitle')}}
{{ app.request.request.get("gameTitle") }}
gameTitle is {{ app.request.request.post('gameTitle') }}
As far as I can see, the vanilla Twig doesn't provide access to the request variables by default. You should pass them to the template explicitly, e.g.:
require __DIR__ . '/vendor/autoload.php';
$loader = new Twig_Loader_Filesystem(__DIR__ . '/templates');
$twig = new Twig_Environment($loader, array(
'cache' => __DIR__ . '/tpl_cache',
));
echo $twig->render('template.twig', ['post' => $_POST]);
Then use it as follows:
{% if post.gameTitle is defined %}
Game title: {{ post.gameTitle }}
{% endif%}
You should use
{{ app.request.request.get("gameTitle") }}
It has been changed.

Symfony3 trying to save into db with forms and twig

It is my first attempt to store product's information into mysql. I apologize in advance if the code is not in the best form, Im still learning. This is my registration.html.twig
{% extends 'base.html.twig' %}
{% block stylesheets %}
<link href="{{ asset('bundles/framework/css/myStyle.css') }}" rel="stylesheet" />
{% endblock %}
{% block title %}Create your product {% endblock %}
{% block body %}
<div id="container">
<h1 id="header">Create your product and store it in the database!</h1>
</div>
<form method="POST" id="registrationForm">
<input type="text" id="pName" placeholder="Product name">
<input type="text" id="pPrice" placeholder="Product price"> <br>
<textarea id="pDescription" placeholder="Product description"></textarea>
</form>
<input type="submit" value="Submit" >
{% endblock %}
I also have Product entity class with setters&getters, not going to include it here because of amount of code.
This is my ProductForm :
class ProductForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('pName')
->add('pPrice')
->add('pDescription')
;
}
}
and here is part of my controller for the /insert page:
public function createAction()
{
$product = 'AppBundle\Entity\Product';
$form = $this->createForm(ProductForm::class, $product);
if($form->isValid())
{
$em= $this->getDoctrine()->getManager();
//Save into database code should go here...
}
}
For starters, it complains that it Expected argument of type "object, array or empty", "string" given which I guess comes from the controller where I try to pass $product variable with specified path to the entity class. In the documentation this part is very confusing. It says $product = ... leaving me without anything, I managed to understand that this is a path to entity class which should be passed to createForm method, but as mentioned before it complains that it is string, not array. Could someone review my code and give a feedback on what is wrong? Im really lost at the moment and not sure what to do next or how to solve this. Thank you in advance.
Your form fields don't have name attributes set, which means that no data will be posted from it.
In the controller, $product should be an instance of AppBundle\Entity\Product, not just a class name:
$product = new \AppBundle\Entity\Product();
The form will not automatically retrieve the data from HTTP request (which are not there because of point 1), you must handle the request manually:
// inject the request here
public function createAction(\Symfony\Component\HttpFoundation\Request $request) {
// ...
$form->handleRequest($request);
if ($form->isValid()) {
// ...
}
}

Wrap Symfony form fields in a div in Twig

Given the simple form build:
$form = add('a')
->add('b')
->add('c')
->add('d')
->add('e')
->add('f');
I'd like to wrap a div tag around ABC and DEF, like so:
<div class="section1">
<input type="text" name="a" />
<input type="text" name="b" />
<input type="text" name="c" />
</div>
<div class="section2">
<input type="text" name="d" />
<input type="text" name="e" />
<input type="text" name="f" />
</div>
Problem is, I am just able to use the Symfony Form Component for this project. Is there a way with twig to render the form fields in groups like above? I will need to specify logic that says something simliar to "start section 1 with 'a' and section 2 with 'd'", so this way if any fields change inbetween (say we remove the field with the name 'b') the form will still work.
My twig file looks like this, which is obviously not correct:
<form action="#" method="POST" {{ form_enctype(form) }}>
{% for child in form.children %}
<div class="form_row">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endfor %}
</form>
The best way to do it I think is building the form outside the controller (as a class, extending AbstracType)
So, you will need these files:
Your controller (as DefaultController.php)
Your twig template (as index.html.twig)
Your main form (MyFormType.php in this example)
One form for each section (in your example Section1Type.php and Section2Type.php)
So, the idea is building one single form (MyFormType) made by many individual section forms (Section1Type and Section2Type). Then calling this main form in your controller and rendering it in your template (with a "for" loop for each section).
So here you have the code:
Your controller:
<?php
# /src/Acme/DefaultBundle/Controller/DefaultController.php
namespace Acme\DefaultBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\DefaultBundle\Form\MyFormType;
class DefaultController extends Controller
{
public function indexAction()
{
$form = $this->createForm(new MyFormType());
return $this->render('AcmeDefaultBundle:Default:index.html.twig', array(
'form' => $form->createView()
));
}
}
Your template:
{# /src/Acme/DefaultBundle/Resources/views/Default/index.html.twig #}
{{ form_start(form) }}
<div class="section1">
{% for input in form.section1 %}
{{ form_label(input) }}
{{ form_widget(input) }}
<br>
{% endfor %}
</div>
<div class="section2">
{% for input in form.section2 %}
{{ form_label(input) }}
{{ form_widget(input) }}
<br>
{% endfor %}
</div>
{{ form_end(form) }}
The main form:
<?php
# /src/Acme/DefaultBundle/Form/MyFormType.php
namespace Acme\DefaultBundle\Form;
use Acme\DefaultBundle\Form\Section1Type;
use Acme\DefaultBundle\Form\Section2Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// This calls your section forms as many as you need
$builder->add('section1', new Section1Type());
$builder->add('section2', new Section2Type());
$builder->add('Send', 'submit');
}
public function getName()
{
return 'myform';
}
}
The Section1 form:
<?php
# /src/Acme/DefaultBundle/Form/Section1Type.php
namespace Acme\DefaultBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class Section1Type extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('a', 'text');
$builder->add('b', 'text');
$builder->add('c', 'text');
}
public function getName()
{
return 'section1';
}
}
And Section2 form:
<?php
# /src/Acme/DefaultBundle/Form/Section2Type.php
namespace Acme\DefaultBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class Section2Type extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('d', 'text');
$builder->add('e', 'text');
$builder->add('f', 'text');
}
public function getName()
{
return 'section2';
}
}
And that's it, you can edit each individual section (adding and removing inputs) and you will get all of them in your template without modifying it.

Categories