Concrete5 5.7: Using file objects in a Single Page Controller - concrete5

I try to attach a file object to a mail object.
I have included the following in the form of my view:
$f = new Concrete\Core\Application\Service\FileManager();
//...
echo $f->file('file', 'test', 'pls choose');
Then I submit my form back to the controller. There (BTW all other form fields arrive in the controller as expected) I do:
$files = $this->post('test');
$file = \File::getByID($files);
which should return a File object. When I do
$file = \File::getRelativePathFromID($files);
it gives me the correct path to the chosen file.
So far so good. BUT when I try to send a mail with exactly that file object attached:
$mail = Loader::helper('mail');
$mail->setTesting(false);
$mail->setSubject('test-subject');
$mail->to($this->post('uEmail'));
//...
$attach = $mail->addAttachment($file);
$attach->filename = 'tttt';
$mail->sendMail();
the following error occurs:
call_user_func_array() expects parameter 1 to be a valid callback,
class 'Concrete\Core\File\Version' does not have a method 'getPath'
which apparently comes from this class method (API):
namespace Concrete\Core\Mail;
//...
class Service {
//...
/**
* Add attachment to send with an email.
*
* Sample Code:
* $attachment = $mailHelper->addAttachment($fileObject);
* $attachment->filename = "CustomFilename";
* $mailHelper->send();
*
* #param File $fob File to attach
* #return StdClass Pointer to the attachment
*/
public function addAttachment(\Concrete\Core\File\File $fob)
{
// #TODO make this work with the File Storage Locations
$fv = $fob->getVersion();
$path = $fob->getPath();
$name = $fv->getFileName();
//...
}
//...
}
which apparently wants a file object as param, which I think I passed, weren't I?
Why my file object becomes a FileVersion object, which, as I see by myself, hasn't got a method getPath().
My other trials so far:
$fv = $f->getApprovedVersion();
$fv->setFile($f);
$fv->getFile();
$fv = $f->getRecentVersion();
$fv->setFile($f);
$fv->getFile();
How do I get the correct file object, which I have to, maybe (??) , take out of the last/approved Version of this file?

This was a bug that has been fixed in the upstream, you'll have to either patch this yourself or wait until version 7.4 lands.

Related

Confusion on the Symfony 4 upload documentation

I'm learning Symfony 4 right now and I came across this documentation about file upload in the controller page that I got confused.
public function new(Request $request)
{
$product = new Product();
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $file stores the uploaded PDF file
/** #var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $product->getBrochure();
On form submission, $file was used to store the content of the uploaded file as specified by the annotation. But what's the point of this $product->getBrochure()? $product should held nothing inside since it was newly created from the Product entity.
In your controller you generate a form with an underlying object to store the data which is the Product Entity. The controller can be accessed on two ways.
first in the GET method without any form data and second in the POST method with data from the form fields. In Symfony the data from the form fields will be placed in your entity automatically and even validated automatically. It all happens with the line
$form->handleRequest($request);
So the uploaded file data is stored in the entity too and if you want to access it you will have to get it out of the entity by a public method like $product->getBrochure();
It seems the documentation in the Symfony 4 File Upload page is incorrect. This might be a little late for you, but the problem still exists.
Instead of using:
$file = $product->getBrochure();
use:
$file = $form['brochure']->getData();
The first will return the file name which is a string while the second will get the actual file.

Transform GET parameters to clean URL

I use Datatables on fronted to send GET parameters to my Silex application.
Datatables send GET parameters of that type:
champs_societes%5B%5D=naf&zone-geographique=ville&effectif%5B%5D=eff_1a9&effectif%5B%5D=eff_10a19&effectif
%5B%5D=eff_20a49&effectif%5B%5D=eff_plus5000&ca%5B%5D=10k-50k&ca%5B%5D=50k-100k&ca%5B%5D=1kk-2kk&ca%5B
%5D=2kk-5kk&champs_societes%5B%5D=capital_int&fondation%5Bmin%5D=&fondation%5Bmax%5D=&champs_societes
%5B%5D=siren&champs_societes%5B%5D=siret&champs_societes%5B%5D=nature&nature%5B%5D=Etablissement&champs_societes
%5B%5D=formejur&champs_societes%5B%5D=emailg&champs_contacts%5B%5D=emailn&ac_formejur=Artisan-Commer
%C3%A7ant%2CBanque+Populaire%2FLoi+Mars+1917%2CCoop.+%C3%80+Responsabilit%C3%A9+Limit%C3%A9e&ac_naf=0113Z
%2C0121Z%2C0126Z%2C0130Z&ac_departements=14%2C50%2C61%2C68%2C03&ac_villes=77330%2C77680%2C77340&ac_fonction
=Assistant%2CCharg%C3%A9+D'Affaires%2CContr%C3%B4leur+De+Gestion%2CDirecteur+%2F+Responsable
I there a way to genereate a clean URL from this chain ? Ideally by using the Symfony/Silex routing.
Thanks for help
EDIT
I get the GET params above with Request:
$app->post('/ajax/formprocess', function (Request $request) use ($app) {
$df = new Filtres( $request->request->get('dataForm') );
$filtroAdd = $df->getRequest();
I would try with Request class first
Request class from HttpFoundation component (default in Symfony, not sure about Silex as I never used it)
/**
* #param \Symfony\Component\HttpFoundation\Request $request
*/
public function someAction(Request $request)
{
$request->getSchemeAndHttpHost();
$request->getBasePath();
$request->getQueryString(); // this will be the most helpful in your case
// access what you need and build normalized url
}
You should be able to build clean normalized url
Edit, solution for parsing query parameter string to array
$queryParameters = 'query parameters as string to be parsed';
$output = [];
parse_str($queryParameters, $queryParameters);
print_r($queryParameters);
http://php.net/manual/en/function.parse-str.php

How to show content of a custom block using PHP code format in Drupal 8

I have added some custom code in a block using PHP code format to show that block on a specific page. I have checked all the things working fine on Devel PHP page but contents are not showing on page. The code below fetches the field value of a destination node.
$refer = $_SERVER[HTTP_REFERER];
$parsed = parse_url($refer);
$alias = array_pop($parsed);
$dst = \Drupal::service('path.alias_manager')->getPathByAlias($alias , $langcode);
$nid = array_pop(explode('/', $dst));
$dest_node = node_load($nid);
$body = $dest_node->get('body')->getValue();
print $body; //have tried other printing methods also but invain
Hope this clarifies the question.
Thanks
Are you sure that it works in Devel? I've just tried to execute your code, and this line:
$body = $dest_node->get('body')->getValue();
returns Array.
Try to use this one instead:
$body = $dest_node->body->value;
First of all, your first block of code (getting current node) can be replaced with just one line:
$node = \Drupal::service('current_route_match')->getParameter('node');
And the whole block can be changed in the following way:
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
print $node->body->value;
}
P.S. And it's definitely a bad idea to use PHP text filter. You may easily write your own custom module providing required block. The simplest block plugin requires several lines of code:
/**
* #file
* Contains \Drupal\my_module\Plugin\Block\MyBlock.
*/
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides my super block.
*
* #Block(
* id = "my_module_block",
* admin_label = #Translation("My Block"),
* category = #Translation("My Module"),
* )
*/
class MyBlock extends BlockBase{
/**
* Builds and returns the renderable array for this block plugin.
*
* #return array
* A renderable array representing the content of the block.
*
* #see \Drupal\block\BlockViewBuilder
*/
public function build() {
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
return [ '#markup' => $node->body->value ];
}
}
}
This file MyBlock.php must be placed in /src/Plugin/Block/ directory inside your custom module named my_module.

Symfony3 get parameters from URL

I discovering symfony3, but im stuck at getting the parameters passed with a link from an action.
In my twig file, im redirecting the user to an action:
<td>go to</td>
And im my action, i'm trying to get the id with:
/**
* #Route("/AfficheDetail", name="esprit_park_affiche")
*/
public function afficheAction()
{
$id = $this->getParameter("id");
return $this->render("#EspritPark/Voiture/affiche.html.twig", array("id" => $id));
}
but each time i get: The parameter "id" must be defined.
like the getParameter isnt returning anything.
I even tried with:
$id = $this->get("request")->get("id");
but i get: You have requested a non-existent service "request". Did you mean one of these: "monolog.logger.request", "request_stack", "router.request_context", "data_collector.request"?
The getParameter() method from the base Controller class is looking up parameters from the service container.
I would make the parameters part of your route. You can then retrieve the values through the action method's parameters:
/**
* #Route("/AfficheDetail/{id}/{serie}/{dateMise}/{marque}", name="esprit_park_affiche")
*/
public function afficheAction($id, $serie, $dateMise, $marque)
{
// ...
}
If you do not add them to the route pattern, they will be accessible through the URL parameters (the current request will be injected automatically if you type hint an argument with the Request class):
public function afficheAction(Request $request)
{
$id = $request->query->get('id');
$serie = $request->query->get('serie');
$dateMise = $request->query->get('dateMise');
$marque = $request->query->get('marque');
// ...
}

Symfony2 render controller from service?

I want to render controller from my custom class. I know that I should use forward function but I don't know with service I have to use?
I have found something like that
$subRequest = $this->container->get('request')->duplicate(
array(),
null,
array('topicId' => $topicId,'_controller' => 'SomeBundle:Topic:close'));
return $this->container->get('http_kernel')
->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
It's a forward function but if I use it I get headers.
How to hide header from forward function?
I need it because I want to render custom logic ( get from DB and other ). It's my idea for modules.
After reading a post about controller utils on whitewashing.de
I created my own utils function I inject in every controller.
The forward function in there works fine up to sf 2.7 and looks like this:
/**
* Forwards the request to another controller.
*
* #param string $controller The controller name (a string like BlogBundle:Post:index)
* #param array $path An array of path parameters
* #param array $query An array of query parameters
*
* #return Response A Response instance
*/
public function forward($controller, array $path = array(), array $query = array())
{
$path['_controller'] = $controller;
$subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path);
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}
Take a look at the documentation for forwarding requests.

Resources