Custom extension is not passing magento 2 validation - php

We have created a simple Magento 2 extension and verified it using their tool: https://github.com/magento/marketplace-eqp
However, when we submit the extension for technical review, it always fails with the following error:
Magento extension review error
I have searched all over and all I found was to make sure that we did not have the attribute cacheable="false" in any block that we were injecting because it would invalidate the entire full page cache. We do not have that attribute at all.
Is there anything else I should test in order to pass Magento 2 technical review?
Thank you!

You should check that pages in report
Assertions:
AssertHitHeader: validates that after sending a request for the test page, the server returns HIT for the expected header.
So
Inspect page headers-
Success criteria:
The first time accessing the page will always be a MISS.
Subsequent times accessing the page will be a HIT.
How to verify - http://devdocs.magento.com/guides/v2.0/config-guide/varnish/config-varnish-final.html

Related

Why are symfony flash messages not removed from session?

I wrote a controller in Shopware 6 (symfony based) that adds a flash messages via $this->addFlash(...).
As expected the message is shown in the storefront (product detail page).
In the function \Symfony\Component\HttpFoundation\Session\Flash\FlashBag::all the message is removed as expected (checked via xdebug).
But when I refresh, the flash message is shown again and is also contained in the session.
I also checked this directly in the PHP session:
$_SESSION['_symfony_flashes']
The message is correctly removed there, but reappears on the next page load.
The only idea I have is, that the session is not persisted after the flash message is removed from it. But I never faced such behavior in the Symfony sessions or PHP sessions.
What could be the reason for this?
My best guess is that the page is cached with the flash message intact. Afaik flash messages are primarily used on routes that are exempt from caching. The product detail page is not one of those by default. You might have to enrich the cache key for the page by a parameter denoting whether the flash message should be shown or not.
Adding to dneustadt's answer: As the product detail page is cached, also your flash message will not show if the detail page is generated and cached without the addFlash() and later your condition for the addFlash() becomes true: Then your controller will just not be hit and the cached page without the flash message will be shown.

Shopware 6 Saving Affiliate/Campaign code to session at anytime I enter the shop

I'm on a Production System 6.4.2.1, but had the same problem on a newer version 6.4.14
If you enter the shop for the first time with a query parameter URL for example https://shop/?affiliateCode=test&campaignCode=test, the codes will not be saved to the session to use it for example in the cart or have this flags on an order (which is standard shopware function).
After you entered the shop you have to navigate to another page than paste in the url with query parameter to get it saved to the session.
If you than delete your site data and enter the shop again with this
query parameter url its not working again.
This issue happens only in production if cache is turned on.
As far as I could investigate this issue I noticed that for the very first time symfony fires the "BeforeSendResponseEvent" which Shopware listens to but this just terminates the first request with our query parameters
So now if you navigate to another page and enter the url with query parameter again, than Symfony will trigger the KernelEvent which Shopware listens to to add the query parameters to the session.
Did anyone else had trouble with this issue before?
Yeah, I think you got it right. Looking at the listener the corresponding event isn't dispatched if the http cache is hit. The affiliate and campaign parameters become part of the cache key and therefore consecutive requests will result in cache hits, avoiding the listener.
I think your best bet might be to create a ticket on the issue tracker. Ultimately this will need to be fixed in the codebase.
For now the only way to be sure the codes are stored in the sessions would be to publicize URLs with the parameters on routes that aren't http cached, like /account/register. For workarounds you could register your own controller that avoids the http cache and redirects to the home page, just for the sake of not missing these parameters. Another option would be to listen to to HttpCacheHitEvent as described here and set the codes to the session yourself, even though you might also have to start the session at that point.

Not able to complete a transaction with Amazon Pay in PHP

I'm struggling to complete a Amazon Pay transaction in PHP.
First of all I followed this guide https://developer.amazon.com/de/docs/amazon-pay-checkout/get-set-up-for-integration.html and implemented version 2 of Amazon Pay. For implementation I used the following PHP Amazon Pay SDK: https://github.com/amzn/amazon-pay-api-sdk-php
Up to point 4 (Set payment info) I got everything working. But here I am stuck. 4.2 says that the response contains an amazonPayRedirectUrl to which the user has to be redirected.
My problem is the following:
I am working with a kind of legacy software where there are a lot of forms in an online shop. When these forms are submitted they are always posting to the same url and depending on the payload data different views are loaded to proceed in the checkout process. When I am now redirecting the user via the generated amazonPayRedirectUrl (using header function of PHP) the user is redirected to the shops landing page (due to htaccess config) instead of the page/view which should logically follow in the checkout process because the redirect does not include the payload data of the submit form.
I already tried to save the needed checkout session id (which is appened as a query parameter to the amazonPayRedirectUrl) into the session to complete the transaction without redirecting the user but this does not work. When calling $client->completeCheckoutSession I get an error message in the response: InvalidCheckoutSessionStatus You tried to call an operation on a Checkout Session that is in a state where that operation is not allowed. The status of the checkout session in the response is "open" instead of "completed". I assume this error occurs because I did not redirect the user (not sure though).
What would be the best way to redirect the user to the correct logically following view/page in the checkout process? Do I somehow have to gather the submit data and do an ajax call including this payload data while calling the amazonPayRedirectUrl or how do I prevent being redirected to the shops landing page respectivly load the correct following view/form?
Thanks in advance!

Sentry PHP - Determining if the exception/event was actually sent successfully

I've implemented the PHP library against a Sentry onpremise installation into a project which is working great, I have no problems with the functionality when its set up to work.
What I'd like to do is determine when for any reason the actual sentry recording fails, however struggling to find where in the application flow Sentry returns something that can be utilised to determine 'recording success'.
I've forced a failure by changing the DSN address being used in the Raven_Client construct to an invalid URL and can confirm events are NOT being recorded - which is expected.
The Sentry Raven_Client exposes a method getLastEventID() which seems to contain an ID at the creation of the event itself, and not upon successful submission to the server (which I expected it to be, and had done a check on to display my error page).
There is also a getLastError() method, which is null at the point my application (CodeIgniter) has entered the My_Exceptions::show_exception() method to display an error page to the client.
The SentryID is populated, and the error is null, and I'm not sure what else there is available to check on to know that the error report actually failed to be recorded.
The reason I want to do this is so that I can show a different view to the user (that doesn't say 'Support have been notified'; as they haven't) and also the functionality to check that $sentryEventId and show a custom feedback form obviously needs to be hidden as the sentryEventId is invalid and the feedback wont go anywhere.
If you are on version 1.10.0 of the Sentry PHP SDK and are not using any async way of sending the events (the default) the getLastEventID() will be null if the send action fails.
See also the PR that introduced this change.

PHP Validation - passing http POST values forwards to a 3rd party checkout

I don't know whether this is possible, I can't seem to find any other help guides so this may not be possible...
I have a checkout page which POSTs a load of variables forwards to a 3rd party payment processor (WorldPay).
I want to know if it is possible to put a PHP script of some sort inbetween the two pages for validation purposes.
EG if an item in the basket has sold out while they were filling out the form, it could catch the customer before money is taken. Or useful if they tamper with form data.
If I do this on my own site I could use sessions to pass the POST data forward but as it's an external website, I don't know how to send the data without making another HTML page with a hidden form & refresh for instance.
Is it possible to do this 'invisibly' - not actually showing a HTML page inbetween?
Yes you can do that by hooking into the onsubmit hook of the form and sending out an Ajax call like this (using jQuery):
$('#myform')[0].onsubmit = function() {
if (form_check_elements(this.elements)) { /* ««« eg JS validator here */
data = $('#myform').serialize();
$.post('/ajax_validator.php', data, function(data, textStatus) {
$('#myform')[0].submit(); /* ««« check the textStatus before here and
eventually do not submit (wrap it in
an if-clause) */
});
return false; /* make the form not post directly */
} else {
return false; /* do not post if JS validation fails */
}
};
We use this snippet to store form data in a session before posting to a 3rd party so we have it available when the 3rd party returns to our page.
Edit: Keep in mind that this will only work with JS enabled, but it is fallback-safe: The form still submits without JS support.
EDIT:
Ashley said:
Okay, i've taken a look at the cURL
manual and written this very simple
script to forward the POST values to
the 3rd party checkout. This just
displays the contents of the checkout
page though. The URL address shows the
script currently running rather than
forwarding to the 3rd party site. Also
all their relatively linked graphics
will not work. Can 'true' forwarding
be achieved using cURL?
The short answer - no.
With the way you described your payment process if you want to step in the middle of the offsite process to do things (customize html/messages, validate data, etc.) then you need to handle the entire process which cURL would allow you to do.
With cURL, you dont "forward" the request - you sort of "proxy" the request. So the fact that the browser URL never changes and that the relative graphics dont work is expected. With the use of cURL or something similar you would never let the user end user know that they are even touching an external page. you would be handling all the requests to that external server on your server and then simply displaying the response from the external server to your user OR parsing that response so that you can use the data from it in a customized way.
Essentially this means if secure.wp3.rbsworldpay.com/wcc/purchase is returning a form that requires futher interaction from the user you have to mimic this form on your server and display that instead. Then when the user submits your form you use cURL again to make a request to the external server - this time to post the next round of data submitted by the user. So for example lets say:
secure.wp3.rbsworldpay.com/wcc/purchase shows the cart
secure.wp3.rbsworldpay.com/wcc/confirm shows a final confirmation of the payment to be made
secure.wp3.rbsworldpay.com/wcc/success and secure.wp3.rbsworldpay.com/wcc/error show whether the transaction succeeded or failed respectively.
Then you are actuall going to need to make 2 requests externally as part of you transaction process which could be summarized like so:
User shops at your site and adds items to cart
User clicks on checkout and you validate the cart/user data
If the data from #2 was valid you package up the data and post to secure.wp3.rbsworldpay.com/wcc/purchase via cURL
If the cURL response from #3 was successful you build your own confirm page using data from the cURL response and display it to the user.
The user submits the confirmation of the purchase to your server.
You package up the data submitted to your server in #5 and post it to secure.wp3.rbsworldpay.com/wcc/confirm via cURL.
If the cURL response from #6 was successful then you parse it for the expected "error" or "success" message returned from external server and display them or your own custom error messages.
Rinse and repeat in case of error ;-)
Generally speaking most payment processors have an option of processing that supports this basic process often returning easy to parse data as XML, JSON, or Plain Text instead of HTML. You might want to look in to this. A lot of times they will often have libraries built for various programming languages to help ease the integration process.
Yep it sure is... i normally use the curl extension to do stuff like this, or an http client class that utilizes curl. You might want to make it a tad easier on yourself and use one of these class libraries - for example Zend_Http_Client. It supports not only curl but also sockets and proxies.
Yes, you can. What you are looking for is the CURL function:
http://php.net/manual/en/book.curl.php
Also see:
http://php.dzone.com/news/execute-http-post-using-php-cu
I rather like the HTTP_Request2 package from PEAR, which basically wraps cURL and/or sockets in some simple objects. POSTing works great. You can use that to bounce the POST request to your validation-checker, then on to the payment processor.
I would suggest you to go like this:
Before directing a user to the form, you check (through SQL queries) whether the item in the basket has sold out. If it has been sold, redirect the user to some other page saying that this item has been sold out otherwise let him go to the form for new purchase.

Categories