I need implement RESTful API for my site on symfony 2, so i use FOSRestBundle + JMSSerializerBundle
I have such serializer yml for my entity:
Acme\DemoBundle\Entity\Product:
exclusion_policy: ALL
accessor_order: custom
custom_accessor_order: [id, title]
properties:
id:
expose: true
title:
expose: true
virtual_properties:
getMainPhoto:
serialized_name: photo
The problem is that getMainPhoto return me url to full sized image. I want preprocess this url before sending response to api client where i can generate new url to resized version of such image. I already have service in sf2 which can do this job:
$resized_url = $someService->generateResizedUrl($item->getMainPhoto(), 640, 480);
But i don't know how can i use this service with JMSSerializer. Maybe there is some callbacks for FOSRestBundle\JMSSerializerBundle just before it send response?
Have a look at the documentation. There are is a number of events and/or annotations you can use to hook into the serialization process.
You can exclude the original url, and then add the resized url using http://jmsyst.com/libs/serializer/master/event_system#serializer-post-serialize event.
You have to write a listener that listen when "Product" instances are serialized.
Related
Do you have an example configuration to send logs by email with the Mailer component of Symfony 5.1.
In the Symfony blog we announce this feature, but I can't put the right config in monolog.yaml
https://symfony.com/blog/new-in-symfony-5-1-misc-improvements-part-3 :
That's why in Symfony 5.1 we added a new Monolog log handler which uses the Mailer component to send the logs via email.
Unfortunately this addition only covers the actuall MailerHandler class in the monolog-bridge. This does not cover the possibility to configure it in the monolog-bundle (that's the drawback if those components are distributed over multiple packages).
The PR for the change in the monolog-bundle is still open, and can be found here: Add Symfony Mailer support #354.
If you don't want to wait for the change in the monolog-bundle you could already use it by defining the handler as a service and then using it with the service type in the monolog configuration.
So define your service:
services:
# this configures the "mail" as a prototype, so you can
# define the sender and recipient mail addresses here
symfony_mailer_service_template:
class: Symfony\Component\Mime\Email
calls:
- ['from', ['webapp#example.com']]
- ['to', ['ops#example.com']]
- ['subject', ['Logs']]
symfony_mailer_service:
class: Symfony\Bridge\Monolog\Handler\MailerHandler
arguments:
- '#mailer.mailer'
- '#symfony_mailer_service_template'
- !php/const Monolog\Logger::DEBUG # log level
- true # bubble
And then in your mailer configuration you could use it like this:
monolog:
handlers:
main:
type: fingers_crossed
handler: deduplicated
deduplicated:
type: deduplication
handler: symfony_mailer
symfony_mailer:
type: service
id: symfony_mailer_service
I am trying to set up an API. I would like to use the default implementation of CRUD operations for GET requests and override the operations for POST, PUT and DELETE. That works actually very well already.
But my problem now is, that I would like to change the URL of the default implementation, so it fits to the URLs of my custom operations.
My Code looks something like that:
#ApiResource(
itemOperations={
"get",
"put"={
"path"="/my/very/important/URL/{id}",
"schemes"={"https"},
}
}
)
And I would now like to make the GET operation available through /my/very/important/URL too, without implementing the GET operation.
I found a workaround for what I actually wanted to do: adding a route prefix at the entity.
* #ApiResource(
* routePrefix="/my/very/important/URL"
* )
But unfortunately I can still not prevent API Platform from using the plural of my entity name as URL.
If I have an entity Publication, than API Platform exposes my API with the URL /my/very/important/URL/publications. I still don't know how to fix that.
According to the API Platform documentation:
"The URL, the method and the default status code (among other options) can be configured per operation. In the next example, both GET and POST operations are registered with custom URLs. Those will override the URLs generated by default. In addition to that, we require the id parameter in the URL of the GET operation to be an integer, and we configure the status code generated after successful POST request to be 301:"
https://api-platform.com/docs/core/operations/#configuring-operations
Here we have the example:
# api/config/api_platform/resources.yaml
App\Entity\Book:
collectionOperations:
post:
path: '/grimoire'
status: 301
itemOperations:
get:
method: 'GET'
path: '/grimoire/{id}'
requirements:
id: '\d+'
defaults:
color: 'brown'
host: '{subdomain}.api-platform.com'
schemes: ['https']
options:
my_option: 'my_option_value'
I hope it helps.
I have an entire API deployed and accessible with Swagger UI. It uses Basic Auth over HTTPS, and one can easily hit the Authorize button and enter credentials and things work great with the nice Try it out! feature.
However, I would like to make a public sandboxed version of the API with a shared username and password, that is always authenticated; that is, no one should ever have to bring up the authorization dialog to enter credentials.
I tried to enter an authorization based on the answer from another Stack Overflow question by putting the following code inside a script element on the HTML page:
window.swaggerUi.load();
swaggerUi.api.clientAuthorizations.add("key",
new SwaggerClient.ApiKeyAuthorization(
"Authorization", "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", "header"));
However, when I hit the Try it out! button the authorization is not used.
What would be the proper way to go about globally setting the auth header on all endpoints, so that no user has to enter the credentials manually?
(I know that might sound like a weird question, but like I mention, it is a public username/password.)
If you use Swagger UI v.3.13.0 or later, you can use the following methods to authorize the endpoints automatically:
preauthorizeBasic – for Basic auth
preauthorizeApiKey – for API keys and OpenAPI 3.x Bearer auth
To use these methods, the corresponding security schemes must be defined in your API definition. For example:
openapi: 3.0.0
...
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
api_key:
type: apiKey
in: header
name: X-Api-Key
bearerAuth:
type: http
scheme: bearer
security:
- basicAuth: []
- api_key: []
- bearerAuth: []
Call preauthorizeNNN from the onComplete handler, like so:
// index.html
const ui = SwaggerUIBundle({
url: "https://my.api.com/swagger.yaml",
...
onComplete: function() {
// Default basic auth
ui.preauthorizeBasic("basicAuth", "username", "password");
// Default API key
ui.preauthorizeApiKey("api_key", "abcde12345");
// Default Bearer token
ui.preauthorizeApiKey("bearerAuth", "your_bearer_token");
}
})
In this example, "basicAuth", "api_key", and "bearerAuth" are the keys name of the security schemes as specified in the API definition.
I found a solution, using PasswordAuthorization instead of ApiKeyAuthorization.
The correct thing to do is to add the following line into the onComplete handler:
swaggerUi.api.clientAuthorizations.add("basicAuth",
new SwaggerClient.PasswordAuthorization(
"8939927d-4b8a-4a69-81e4-8290a83fd2e7",
"fbb7a689-2bb7-4f26-8697-d15c27ec9d86"));
swaggerUi is passed to the callback so this is the value to use. Also, make sure the name of your auth object matches the name in the YAML file.
I am trying to implement paypal-rest payment with the payum bundle in symfony (3.1.4).
I need to get PayPal Plus running in my Symfony App.
Therefore I read this article
https://github.com/Payum/Payum/blob/master/docs/paypal/rest/get-it-started.md
Now - I can't figure out what the 'config_path' parameter is ment to be set to and what exactly has to be provides at this config_path.
Symfony states
'The config_path fields are required.'
My payum config looks like this atm
payum:
security:
token_storage:
AppBundle\Entity\PaymentToken: { doctrine: orm }
storages:
AppBundle\Entity\Payment: { doctrine: orm }
gateways:
paypal_express_payment:
factory: paypal_express_checkout
username: "%ppe_uname%"
password: "%ppe_pw%"
signature: "%ppe_signature%"
sandbox: false
paypal_rest_payment:
factory: paypal_rest
client_id: "%ppr_cid%"
client_secret: "%ppr_sec%"
sandbox: true
The paypal_express_payment part works fine.
If I add just a random config-path like 'my_config.txt' Symfony states
Request GetHumanStatus{model: ArrayObject} is not supported. Make sure the gateway supports the requests and there is an action which supports this request (The method returns true). There may be a bug, so look for a related issue on the issue tracker.
So - where and what is the config_path ment to be?
Any help or hints for more documentation that can lead into the right direction is very welcome.
It's meant to be sdk_config.ini from PayPal-PHP-SDK
gateways:
paypal_rest:
factory: paypal_rest
client_id: '%paypal_rest.client_id%'
client_secret: '%paypal_rest.client_secret%'
config_path: '%kernel.root_dir%/config/sdk_config.ini'
UPDATE: I don't think that Doctrine ORM storage is supported by Payum PaypalRest plugin.
PaypalRest\Action\CaptureAction requires the model (Payment) to be inherited from PayPal\Api\Payment and then it uses its create and execute methods for payment capture. I don't think it's a good idea to extend from PayPal\Api\Payment in the Doctrine entity.
I was able to eliminate this error by using Payum\Paypal\Rest\Model\PaymentDetails as a payment and filesystem as a storage:
payum:
storages:
Payum\Paypal\Rest\Model\PaymentDetails:
filesystem:
storage_dir: %kernel.root_dir%/Resources/payments
id_property: idStorage
Try to set it to default value like this:
paypal_rest_payment:
factory: paypal_rest
client_id: "%ppr_cid%"
client_secret: "%ppr_sec%"
sandbox: true
config_path: ~
I am applying this tutorial into symfony 2.4, I've finished the setup in the config.yml and everything, I managed to visit the admin/google/analytics page, but the problem is when I tried to authenticate with the parameters I've created in the config.yml file, it is searching for the scope, here is the parameters.
happy_r_google_analytics:
host: www.example.com
profile_id: MyProfileId
tracker_id: UA-TRACKER-ID
token_file_path: %kernel.root_dir%/var/storage
happy_r_google_api:
application_name: Project Default Service Account
oauth2_client_id: OAuthClientID
oauth2_client_secret: OAuthClientSecret
oauth2_redirect_uri: http://www.example.com/app_local.php/admin/google/analytics/oauth2callback
developer_key: DevelopperKey
site_name: http://www.example.com
I think there's no problem here, I've got no idea where I can set the scope so the google Api client can set it to https://www.googleapis.com/auth/analytics.readonly
You need to define a scope. If you use Google Auth, check Authorization scopes for it.
You must do something like:
$googleClient = new \Google_Client();
$googleClient->setScopes(array(
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
));