You have requested a non-existent service "knp_snappy.pdf" - symfony

I followed the tutorial on https://github.com/KnpLabs/KnpSnappyBundle and https://ourcodeworld.com/articles/read/250/how-to-create-a-pdf-from-html-using-knpsnappybundle-wkhtmltopdf-in-symfony-3.
app/config/config.yml
knp_snappy:`enter code here`
pdf:
enabled: true
binary: /usr/local/bin/wkhtmltopdf
options: []
image:
enabled: true
binary: /usr/local/bin/wkhtmltoimage
options: []
app/AppKernel
new Knp\Bundle\SnappyBundle\KnpSnappyBundle(),
MyController
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
public function pdfAction(string $offerId)
{
$html = $this->renderView('#App/Offer/offer_pdf.html.twig', array(
'offerId' => $offerId
));
return new PdfResponse(
$this->get('knp_snappy.pdf')->getOutputFromHtml($html),
'file.pdf'
);
}
I try and this:
public function offerToPDFAction(string $offerId)
{
$snappy = $this->container->get('knp_snappy.pdf');
$html = '<h1>Hello</h1>';
$filename = 'myFirstSnappyPDF';
return new Response(
$snappy->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="'.$filename.'.pdf"'
)
);
The same problem:
You have requested a non-existent service "knp_snappy.pdf".

/**
* #Route("/{id}/pdf", name="sandbox_pdf", methods={"GET"})
*/
public function pdfAction(\Knp\Snappy\Pdf $snappy, Product $product): Response
{
$html = $this->renderView('pdf/index.html.twig', [
'product' => $product,
]);
$filename = 'product';
return new Response(
$snappy->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'.pdf"'
)
);
}

use Knp\Snappy\Pdf;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
/**
* #Route("/show/pdf/{token}", name="admin_invoice_show_pdf", methods={"GET"})
*/
public function showPdf(Command $command, Pdf $pdf)
{
$html = $this->renderView('admin/invoice/showPdf.html.twig',array('command' $command));
return new PdfResponse($pdf->getOutputFromHtml($html), 'invoice.pdf');
}

Related

How can I pass my UploadedFile data via http guzzle request?

I have two different website : my application and my backoffice (in Laravel)
I create an API route to store a document on my application. I made a request with Guzzle on my backoffice to store a document.
My guzzle http request on backoffice website :
public static function storeDocument($token, $request)
{
$client = new \GuzzleHttp\Client([
'Content-Type' => 'multipart/form-data'
]);
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$datas = [
'document' => $request->file('document'),
'doc_name' => $request->doc_name ?? '',
];
$request = $client->post(env('API_URL') . '/api/document/store/', ['headers' => $headers, 'form_params' => $datas]);
$result = json_decode($request->getBody()->getContents());
return $result;
}
And there is my API route method on application website :
public function store(Request $request) {
$validator = Validator::make($request->all(), [
'document' => 'bail|required|mimes:pdf,doc,docs,csv,txt|max:2048',
'doc_name' => 'bail|string|max:80|nullable',
]);
if($validator->fails()){
return response()->json($validator->errors());
};
$document = $request->document;
$fileName = '';
if(isset($request->doc_name)) {
$fileName = $request->doc_name . '.' . $document->extension();
} else {
$fileName = $document->getClientOriginalName();
}
$result = Storage::putFileAs(
'documentations',
$document,
$fileName,
'public'
);
if($result) {
return response()->json(['success' => 'Le fichier a bien été enregistré'], 201);
} else {
return response()->json(['error' => $errors], 400);
};
}
It seems that my datas aren't sent correctly because storeDocument() gives me an error : 'This field is required'. So it looks like it can't find $request->document which is required...
And with Insomnia I have no error, my file is correctly save.
I want to specify that I pass correct datas to storeDocument.
That is the result of $request->file('document') :
Illuminate\Http\UploadedFile {#1354 ▼
-test: false
-originalName: "test.pdf"
-mimeType: "application/pdf"
-error: 0
#hashName: null
path: "/tmp"
filename: "phpPOxtfN"
basename: "phpPOxtfN"
pathname: "/tmp/phpPOxtfN"
extension: ""
realPath: "/tmp/phpPOxtfN"
aTime: 2022-08-25 14:30:14
mTime: 2022-08-25 14:30:13
cTime: 2022-08-25 14:30:13
inode: 4856076
size: 48632
perms: 0100600
owner: 33
group: 33
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
}
I'm stuck since several hours on this, does anyone has any idea to help me?
Thanks ;)
EDIT: I finally found that I have to pass 'multipart' instead of 'form_params' on my http request.
Moreover I found that I have to use fopen or file_get_contents to send raw datas...
So my storeDocument function looks like this now :
public static function storeDocument($token, $request)
{
$client = new \GuzzleHttp\Client([
'Content-Type' => 'multipart/form-data'
]);
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$datas = [
[
'name' => 'document',
'contents' => file_get_contents($request->file('document')),
],
[
'name' => 'doc_name',
'contents' => $request->doc_name ?? '',
]
];
$request = $client->post(env('API_URL') . '/api/document/store/', ['headers' => $headers, 'multipart' => $datas]);
$result = json_decode($request->getBody()->getContents());
return $result;
}
But it still doesn't work...
Continue searching...

Add links on Wordpress custom endpoint

I created a custom endpoint for specific data from a custom table in my Wordpress plugin. It get's all the data from the table with the getHelpers() function. After that it will be merged by some user data. I would like to add the profile_image as a link to the response so we can get it with the embed parameter.
What is the best way to add the link to the response? I know the $response->add_link() function but this would add it to the response and not to each contributor.
I tried to add the link as an array but this won't react on the _embed parameter.
This is my code for the custom endpoint:
class VEMS_Rest_Contributors extends WP_REST_Controller {
protected $namespace = 'vems/v2';
protected $rest_base = 'contributors';
/**
* Register the routes for coupons.
*/
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'args' => $this->get_collection_params(),
) );
}
public function get_items( WP_REST_Request $request ) {
$project_id = $request->get_param( 'project_id' );
$contributors = array();
if( !empty($project_id) ) {
$project = new VEMS_Project( $request['project_id'] );
$helpers = $project->getHelpers();
foreach($helpers as $helper) {
$contributor = array();
if( !empty($helper->contributor_id) ) {
$user = get_user_by( 'ID', $helper->contributor_id );
$user_meta = get_user_meta( $helper->contributor_id );
$contributor['ID'] = $helper->contributor_id;
$contributor['user_nicename'] = $user->data->display_name;
$contributor['user_profile_image'] = $user_meta['contributor_profile_image'][0];
} else {
$contributor['user_nicename'] = $helper->name;
$contributor['user_profile_image'] = $helper->image_id;
}
$contributor['item_total'] = $helper->item_total;
$contributor['checked'] = $helper->checked;
$contributor['helper_date'] = $helper->helper_date;
/*
$contributor['_links']['profile_image'] = array(
'href' => rest_url( '/wp/v2/media/' . $contributor['user_profile_image'] ),
'embeddable' => true
);
*/
$contributors[] = $contributor;
}
}
$response = rest_ensure_response( $contributors );
return $response;
}
public function get_collection_params() {
$params['project_id'] = array(
'description' => __( 'Limit result set to contributors assigned a specific project.', 'vems' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
return $params;
}
}
to handle links on route vems/v2/contributors?_embed, the element profile_image must be an array of links and then you can do that
$contributor['_links']['profile_image'] = [
[
'href' => rest_url( '/wp/v2/media/' . $contributor['ID'] ),
'embeddable' => true,
],
];

Drupal 7: How to send HTML Email

Could someone tell me what i am missing to send an HTML email using Drupal's function? Here is my call:
try{
drupal_mail('my_module', 'forgot', $node->field_email_address['und'][0]['value'], language_default(), array('reset_key' => $key),'do-not-reply#myemailaddress.com');
}catch(Exception $e){
print_r($e->getMessage());die();
}
And here is the function:
function my_module_mail($key, &$message, $params) {
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
// $headers = array(
// 'MIME-Version' => '1.0',
// 'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
// 'Content-Transfer-Encoding' => '8Bit',
// 'X-Mailer' => 'Drupal'
// );
// $message['headers'] = $headers;
$message['subject'] = 'Why wont this send html??';
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['body'][] = $body;
$message['from'] = 'do-not-reply#myemailaddress.com';
}
I tired just the html header and the full set that is commented out. What am I missing? The email sends fine but it's plain text. Thanks and let me know!
You can use this function
function my_module_custom_drupal_mail($target = NULL, $from = null, $subject, $message, $attachment = NULL){
$my_module = 'my_module';
$my_mail_token = microtime();
$message = array(
'id' => $my_module . '_' . $my_mail_token,
'to' => $target,
'subject' => $subject,
'body' => array($message),
'module' => $my_module,
'key' => $my_mail_token,
'from' => "$from <email#email.com>",
'headers' => array(
'From' => "$from <email#email.com>",
'Sender' => "$from <email#email.com>",
'Return-Path' => "$from <email#email.com>",
'Content-Type' => 'text/html; charset=utf-8'
),
);
if ($attachment) {
$file_content = file_get_contents($attachment[0]);
$message['params']['attachments'][] = array(
'filecontent' => $file_content,
'filename' => $attachment[1],
'filemime' => $attachment[2],
);
}
$system = drupal_mail_system($my_module, $my_mail_token);
$message = $system->format($message);
if ($system->mail($message)) {
return TRUE;
}
else {
return FALSE;
}
}
AND call it like :
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
$subject ='Why wont this send html??';
$from = 'myemail#email.com';
$sent = my_module_custom_drupal_mail($node->field_email_address['und'][0]['value'], $from, $subject, $body);
Customize it like you want ! :)
A few things need to be done:
/**
* Class SomeCustomModuleMailSystem Implements MailSystemInterface.
*
* Used to enable HTML email to be sent.
*/
class SomeCustomModuleMailSystem extends DefaultMailSystem {
public function format(array $message) {
$message['body'] = implode("\n\n", $message['body']);
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
}
This to be done one time, so probably in a hook_enable or hook_update:
$current = variable_get('mail_system', ['default-system' => 'DefaultMailSystem']);
$addition = ['some_custom_module' => 'SomeCustomModuleMailSystem'];
variable_set('mail_system', array_merge($current, $addition));
Invoke hook_mail as normal, e.g.
/**
* Implements hook_mail().
*/
function some_custom_module_mail($key, &$message, $params) {
switch ($key) {
case 'some_mail_key':
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
Finally call it with something like this:
// Set variables required for the email.
$module = 'some_custom_module';
$key = 'some_mail_key';
$to = $email = 'thetoaddress#something.com';
$language = language_default();
$params['subject'] = 'Email subject';
$params['body'] = '<html><body>The HTML!</body></html>';
$from = 'thefromaddress#something.com';
$send = TRUE;
// Send the mail and log the result.
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
if ($result['result'] === TRUE) {
watchdog('some_custom_module', 'HTML email successfully sent.', [], WATCHDOG_INFO);
}
else {
watchdog('some_custom_module', 'HTML email failed to send', [], WATCHDOG_ERROR);
}

JMSPaymentPaypalBundle blank order summary

hi i was wondering on how to show order summary in paypal with JMSPaymentPaypalBundle ?!
ay tips will be greatly appreciated ..
here is my paypalController code in case needed
<?php
namespace Splurgin\EventsBundle\Controller;
use JMS\DiExtraBundle\Annotation as DI;
use JMS\Payment\CoreBundle\Entity\Payment;
use JMS\Payment\CoreBundle\PluginController\Result;
use JMS\Payment\CoreBundle\Plugin\Exception\ActionRequiredException;
use JMS\Payment\CoreBundle\Plugin\Exception\Action\VisitUrl;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
class PaymentController
{
/** #DI\Inject */
private $request;
/** #DI\Inject */
private $router;
/** #DI\Inject("doctrine.orm.entity_manager") */
private $em;
/** #DI\Inject("payment.plugin_controller") */
private $ppc;
/**
* #DI\Inject("service_container")
*
*/
private $container;
/**
* #Template
*/
public function detailsAction($package)
{
// note this ticket at this point in inactive ...
$order = $this->container->get('ticket')->generateTicket($package);
$order = $this->em->getRepository('SplurginEventsBundle:SplurginEventTickets')->find($order);
$packageId = $order->getPackageId();
$package = $this->em->getRepository('SplurginEventsBundle:SplurginEventPackages')->find($package);
$price = $package->getPrice();
var_dump($price);
if($price == null){
throw new \RuntimeException('Package was not found: '.$result->getReasonCode());
}
$form = $this->getFormFactory()->create('jms_choose_payment_method', null, array(
'amount' => $price,
'currency' => 'USD',
'default_method' => 'payment_paypal', // Optional
'predefined_data' => array(
'paypal_express_checkout' => array(
'return_url' => $this->router->generate('payment_complete', array(
'order' => $order->getId(),
), true),
'cancel_url' => $this->router->generate('payment_cancel', array(
'order' => $order->getId(),
), true)
),
),
));
if ('POST' === $this->request->getMethod()) {
$form->bindRequest($this->request);
if ($form->isValid()) {
$this->ppc->createPaymentInstruction($instruction = $form->getData());
$order->setPaymentInstruction($instruction);
$this->em->persist($order);
$this->em->flush($order);
return new RedirectResponse($this->router->generate('payment_complete', array(
'order' => $order->getId(),
)));
}
}
return array(
'form' => $form->createView(),
'order'=>$order->getId(),
);
}
/** #DI\LookupMethod("form.factory") */
protected function getFormFactory() { }
/**
*/
public function completeAction($order)
{
$order = $this->em->getRepository('SplurginEventsBundle:SplurginEventTickets')->find($order);
$instruction = $order->getPaymentInstruction();
if (null === $pendingTransaction = $instruction->getPendingTransaction()) {
$payment = $this->ppc->createPayment($instruction->getId(), $instruction->getAmount() - $instruction->getDepositedAmount());
} else {
$payment = $pendingTransaction->getPayment();
}
$result = $this->ppc->approveAndDeposit($payment->getId(), $payment->getTargetAmount());
if (Result::STATUS_PENDING === $result->getStatus()) {
$ex = $result->getPluginException();
if ($ex instanceof ActionRequiredException) {
$action = $ex->getAction();
if ($action instanceof VisitUrl) {
return new RedirectResponse($action->getUrl());
}
throw $ex;
}
} else if (Result::STATUS_SUCCESS !== $result->getStatus()) {
throw new \RuntimeException('Transaction was not successful: '.$result->getReasonCode());
}
}
public function cancelAction($order)
{
die('cancel the payment');
}
}
i really dont know why this is not a part of the docs , but the bundle is capable of setting checkout parameters out of the box ...
here is how i have done it
$form = $this->getFormFactory()->create('jms_choose_payment_method', null, array(
'amount' => $price,
'currency' => 'USD',
'default_method' => 'payment_paypal', // Optional
'predefined_data' => array(
'paypal_express_checkout' => array(
'return_url' => $this->router->generate('payment_complete', array(
'order' => $order->getId(),
), true),
'cancel_url' => $this->router->generate('payment_cancel', array(
'order' => $order->getId(),
), true),
'checkout_params' => array(
'L_PAYMENTREQUEST_0_NAME0' => 'event',
'L_PAYMENTREQUEST_0_DESC0' => 'some event that the user is trying to buy',
'L_PAYMENTREQUEST_0_AMT0'=> 6.00, // if you get 10413 , then visit the api errors documentation , this number should be the total amount (usually the same as the price )
// 'L_PAYMENTREQUEST_0_ITEMCATEGORY0'=> 'Digital',
),
),
),
));
error code can be found here
SetExpressCheckout Request Fields here
i will provide a pull request to the documentation as soon as i can .. :)

Upgrading to Symfony 2.1 broke WebTestCase functional test sessions

in 2.0 the code below worked correctly, since upgrading to 2.1 the session var is going MIA.
public function __construct()
{
$this->client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'unittest#test.com',
'PHP_AUTH_PW' => 'test',
));
//set the session
$this->container = $this->client->getContainer();
$this->client->getCookieJar()->set(new \Symfony\Component\BrowserKit\Cookie(session_name(), true));
$this->session = $this->container->get('session');
$this->session->set('company_id', '9999');
$this->session->save();
}
public function testGetClientsAction()
{
$this->client->request(
'GET',
'/clients',
array(),
array(),
array('HTTP_X-Requested-With' => 'XMLHttpRequest', 'HTTP_accept' => 'application/json')
);
$content = $this->client->getResponse()->getContent();
$status = $this->client->getResponse()->getStatusCode();
$this->assertNotEmpty($content);
$this->assertEquals(200, $status);
}

Resources