Symfony routing - locale as subdomain with fallback to default - php

I'm trying to set up routing system with subdomain representing current locale. Routing is set via #Routing annotation and looks like this:
/**
* #Route(
* "/",
* name="homepage",
* host="{locale}.{domain}",
* defaults={"locale" = "en", "domain" = "%domain%"},
* requirements={"locale" = "en|de|fr", "domain" = "%domain%"}
* )
*/
Works well for URL's like en.somedomain.com or de.somedomain.com, but fails to find correct route for somedomain.com, without locale.
I understand that because of the host parameter, that is set to represent exact locale.domain pattern, but I can't find way to tell Symfony routing system that there could be additional, default host.
Searched all around for this, but found nothing particular. Would appreciate any help!
UPDATE
There is actually a way to do it, by adding another #Route in annotation, without host parameter:
/**
* #Route(
* "/",
* name="homepage_default",
* defaults={"locale" = "en"}
* )
*/
but thats looks a bit dirty, and I'm not using %domain% parameter there, which is important for me - say, if I would need another subdomain for mobile version.

Well, looks like triple annotation routing to handle locale + subdomain is the only choice for now.
Studying documentation (for example, this article) shows that Symfony developers encourage us to do it that way, which, to me, is not that nice. However, here's the solution...
/**
* #Method({"GET"})
* #Route(
* "/",
* name="homepage",
* host="{mobile}.{_locale}.{domain}",
* defaults={"mobile" = "moblie", "locale" = "%locale%", "domain" = "%domain%"},
* requirements={"mobile" = "mobile|m", "_locale" = "%locale%|de|fr", "domain" = "%domain%"}
* )
* #Route(
* "/",
* name="homepage",
* host="{_locale}.{domain}",
* defaults={"_locale" = "%locale%", "domain" = "%domain%"},
* requirements={"_locale" = "%locale%|de|fr", "domain" = "%domain%"}
* )
* #Route(
* "/",
* name="homepage_default",
* defaults={"_locale" = "%locale%"}
* )
*/
Notice that order is important, starting from subdomains, going down to default. As this looks ugly with #Route annotation, I've decided to re-write this in YAML as well:
homepage_locale_mobile:
path: /
host: "{mobile}.{_locale}.{domain}"
defaults: { mobile: "mobile", _locale: "%locale%", domain: "%domain%" }
requirements:
mobile: "mobile|m"
_locale: "%locale%|de|fr",
domain: "%domain%"
homepage_locale:
path: /
host: "{_locale}.{domain}"
defaults: { _locale: "%locale%", domain: "%domain%" }
requirements:
_locale: "%locale%|de|fr",
domain: "%domain%"
homepage:
path: /
defaults: { _locale: "%locale%" }
Ordered as well. Maybe someone will come across and use it.

I've just had a similar problem with defaults, though it was a route parameter and not locale.
The solution was there to replace the = signs with : as it should be that and the compiler somehow doesn't complains about it.
So try this one out:
/**
* #Route(
* "/",
* name="homepage",
* host="{locale}.{domain}",
* defaults={"locale" : "en", "domain" : "%domain%"},
* requirements={"locale" : "en|de|fr", "domain" : "%domain%"}
* )
*/

Related

How to set #SWG\Info annotation for only area in Symfony using NelmioApiDocBundle

/**
* #SWG\Swagger(
* #SWG\Info(
* title="My first swagger documented API",
* version="1.0.0"
* )
* )
*/
I tried to write this block in:
my base controller - src/MyProject/ApiBundle/Controller/SiteApi/SiteApiBaseController.php
my bundle file - src/MyProject/ApiBundle/MyProjectApiBundle.php
Generated JSON contains empty "info": {"title": ""}
Symfony 3.4, NelmioApiDocBundle 3.9.1(including zircote/swagger-php 2.0.9)
• For controller try:
/**
use FOS\RestBundle\Controller\Annotations as Rest;
use Swagger\Annotations as SWG;
...
* Add Tva.
* #Rest\Post("/tva/add")
* #SWG\Tag(name="TVA Management")
...
...
* #SWG\Response(response=201, description="Tva created successfully.")
...
...
*/
=> You will get something like this:
• For api/doc page Title, Description & Version, try to edit this file:
~Your_Project_Path\config\packages\nelmio_api_doc.yaml

Drupal 8.7.8 Custome Module Created Rest Resource (API) not found

Directory structure:
module_name -> config -> install -> rest.resource.location_api.yml
id: location_api
plugin_id: location_api
granularity: resource
configuration:
methods:
- GET
- POST
- PATCH
- DELETE
formats:
- json
authentication:
- cookie
module_name/src/plugin/rest/resource/LocationApi.php
<?php
namespace Drupal\locations\Plugin\rest\resource;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Controller\ControllerBase;
//use Drupal\node\Entity\Node;
//use Drupal\taxonomy\Entity\Term;
use Drupal\user\Entity\User;
//use Drupal\Core\Database\Connection;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Provides a KDR's Rest Custom Resource For Locations
*
* #RestResource(
* id = "location_api",
* label = #Translation("KDR's Rest Custom Resource For Location"),
* uri_paths = {
* "canonical" = "/kdr-apis/v1.0/location/{sl_id}",
* "https://www.drupal.org/link-relations/create" = "/kdr-apis/v1.0/location"
* }
* )
*/
class LocationApi extends ResourceBase {
}
but when I install the module, then it returns an error,
Message
Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity_bundle:node" plugin does not exist. Valid plugin IDs for Drupal\Core\Condition\ConditionManager are: node_type, request_path, current_theme, user_role in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 of /home/linuxdem/kdr.linuxdemos.me/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).
This was the Drupal 8 cache issue, I have resolved by clearing cache and re-installing module.

Internal error due to serialization with paramconverter

I have an API which takes multiple input values. One of them is a date.
When the date is sent, all is fine.
But, when the user isn't sending a date, I have an error 500 with this error message:
Invalid datetime "Some invalid data", expected format Y-m-d\TH:i:sP.
So I wanted to check if the data sent had the format required.
But I don't understand how things are working, hope you can help.
This is what I have
/**
*
* #Rest\Post(
* path = "/signup",
* name = "api_users_add"
* )
* #Rest\View(StatusCode=201, serializerGroups={"user_detail"})
* #ParamConverter(
* "user",
* converter="fos_rest.request_body",
* options={"deserializationContent"={"groups"={"Deserialize"}}},
* )
* #ParamConverter(
* "profile",
* converter="fos_rest.request_body",
* options={"deserializationContent"={"groups"={"Deserialize"}}},
* )
*/
public function postUserAction(Request $request, User $user, Profile $profile)
{
if (!preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$profile->getBirth())){
return new JsonResponse([
'success' => false,
'message' => "Date d'anniversaire au mauvais format"
]);
}
}
But in fact, I never go into this condition, the error 500 is triggered before.
I guess this has something to do with the #ParamConverter from Profile who can't "deserialize" when birth is not a DateTime.
Thing is, I would like to check what is sent (as I did into my condition) in order to avoid this internal error. But I can't find where this is handled on my code.
Thanks for the help.
Considering this : symfony doc for Param converter fos rest bundle
What I am looking for is to find where the validationErrors are specified.

Custom validaton messages not working on Symfony 3

I have the following declaration in my user class (Symfony 3, it's an entity class):
/**
* #ORM\Column(type="string", length=128, unique=true)
* #Assert\NotBlank (
* groups={"registration"},
* message = "test"
* )
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* groups={"registration"}
* )
*/
private $email;
Everything works fine, except that I can't set a message, instead of my message ('test' for example) a default "This value should not be blank" is displayed.
Yes, I do have
framework:
validation: { enable_annotations: true }
In my config.yml
Edit: and yes I cleared cache by executing:
sudo php bin/console cache:clear
Edit2: Please note that it actually DOES go through validation, Symfony sees that the email is required, it displays a message if I leave the field empty, it's just that it is not my message, Symfony somehow doesn't see the "message" part.
Edit3: Now, after removing the groups={"registration"} part, as well as changing (in controller)
$errors = $validator->validate($user, null, array('registration'));
to
$errors = $validator->validate($user, null);
(removed array('registration'))
the correct message is displayed. However this is not a solution. I need to use groups.
Edit 4:
I'll get crazy...
If I enter no email, and then:
$validator = $this->get('validator');
$errors = $validator->validate($user, null, array('registration'));
dump($errors);
(Notice the "dump" function call) then I see an incorect message displayed on a page (This value should not be blank) but... when I enter the profiler->debug page (the dev tools at the bottom) then I can see that a correct (my) message is there...
Furthermore in profiler->form errors is this incorect message on the list (as only one item) but... it says it refers to a field named "plainPassword" which is not in the form, and does NOT belong to the "registration" group, so it should not be validated in the first place.
What's going on there?
Can You try this?
/**
* #ORM\Column(type="string", length=128, unique=true)
*
*
* #Assert\NotBlank(
* message = "The box cant be left blank")
*
*
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email."
*
* )
*/
private $email;

PHP Swagger and Yii

I have searched and found i have been lost all day now, and I feel I am going round in circles.
I have written, (with help of a few guides), a simple API for my Yii based application.
I have now come to document this API for other to use it.
I read everywhere that Swagger seems to be the way to go to implement, API documentation.
However I can seem to get anywhere on how to use this application
I have followed the instructions on Swagger PHP
Now I am lost has anyone got any examples of what to do next.
I have tried doing some self annotations of my ApiController.php and this doesnt work. I have been trying using the swagger.phar command line, but I still get no where.
I know you will need a lot more information but i dont know what bits of info you need so rather than pasting lots of useless information please ask and i will send anything you need.
To be honest all i would like is some simple API documentation but it just seems impossible.
Cheers
I have implemented swagger-php in my project. Please follow the below suggested instructions :
1) Download swagger-php(github.com/zircote/swagger-php) and swagger-ui(github.com/wordnik/swagger-ui). Extract them to your workspace.
2) Create a folder called swagger-api and blank php file called index.php in you workspace and paste the following code.
<?php
use Swagger\Annotations as SWG;
/**
* #SWG\Resource(
* apiVersion="0.2",
* swaggerVersion="1.2",
* resourcePath="/api.php",
* basePath="http://localhost/swagger-api/"
* )
*/
// Run this in url
// localhost/index.php?action=get_app_list
// This is the API,show the list in array
/**
*
* #SWG\Api(
* path="/api.php?action=get_app_list",
* description="Operations about get app list",
* produces="['application/json']",
* #SWG\Operations(
* #SWG\Operation(
* method="GET",
* summary="Find facet by ID",
* notes="Returns a facet based on ID",
* type="ListResult",
* nickname="getAllResults",
* #SWG\ResponseMessages(
* #SWG\ResponseMessage(
* code=400,
* message="Invalid ID supplied"
* ),
* #SWG\ResponseMessage(
* code=404,
* message="facet not found"
* )
* )
* )
* )
* )
*/
function get_app_list()
{
//normally this info would be pulled from a database.
//build JSON array
$app_list = array(array("id" => 1, "name" => "Web Demo"),
array("id" => 2, "name" => "Audio Countdown"),
array("id" => 3, "name" => "The Tab Key"), array("id" => 4,
"name" => "Music Sleep Timer"));
return $app_list;
}
$possible_url = array("get_app_list");
$value = "An error has occurred";
if (isset($_GET["action"]) && in_array($_GET["action"], $possible_url))
{
switch ($_GET["action"])
{
case "get_app_list":
$value = get_app_list();
break;
$value = "Missing argument";
break;
}
}
//return JSON array
echo(json_encode($value));
?>
3) Create a folder named swagger-docs in workspace.
4) Open you terminal and go the location of swagger-php in you workspace(i.e cd workpace/swagger-php).
5) Execute the following in your terminal
php swagger.phar /workspace/swagger-api -o /workspace/swagger-docs (This can be executed where we contain swagger.phar file).
6) You will see some files created on your swagger docs folder.
7) Open index.html in swagger-ui/dist/
8) Replace -: url: "http://petstore.swagger.wordnik.com/api/api-docs" to url: "http:localhost/swagger-docs"
9) Run localhost/swagger-ui/dist in your browser.

Categories