CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2024-04-10
by Yehor Samoilenko

Original Post

Original - Posted on 2023-06-21
by Jacob



            
Present in both answers; Present only in the new answer; Present only in the old answer;

In this answer, I will explain how to add a custom button component to the default `config.xml` file of the Shopware 6 plugin. The button is used for API test.
The plugin structure looks like this:
```bash └── MyPlugin ├── src │ ├── Controller │ │ └── Api │ │ └── ApiTestController.php │ ├── Resources │ │ ├── app │ │ │ └── administration │ │ │ └── src │ │ │ ├── component │ │ │ │ └── api-test-button │ │ │ │ ├── api-test-button.html.twig │ │ │ │ └── index.js │ │ │ ├── service │ │ │ │ └── api-test.service.js │ │ │ ├── snippet │ │ │ │ ├── de-DE.json │ │ │ │ └── en-GB.json │ │ │ └── main.js │ │ ├── config │ │ │ ├── config.xml │ │ │ ├── routes.xml │ │ │ └── services.xml │ │ └── public │ └── MyPlugin.php └── composer.json ```
1. Add a component named `api-test-button` to the `config.xml` file.
File contents `config.xml`:
```xml <?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/trunk/src/Core/System/SystemConfig/Schema/config.xsd"> <card> <title>Main Settings</title> <title lang="de-DE">Haupteinstellungen</title>
<input-field type="text"> <name>apiKey</name> <label>API Key</label> <label lang="de-DE">API-Schlüssel</label> </input-field>
<component name="api-test-button"> <name>apiTest</name> </component> </card> </config> ```
2. Create a `component/api-test-button` folder in the `administration/src` folder and create the `index.js` and `api-test-button.html.twig` files in that folder.
File contents `api-test-button.html.twig`:
```html <div> <sw-button-process :is-loading="isLoading" :process-success="isSaveSuccessful" @process-finish="saveFinish" @click="check" > {{ $tc('apiTestButton.buttonLabel') }} </sw-button-process> </div> ```
File contents `index.js`:
```javascript import template from './api-test-button.html.twig';
const { Component, Mixin } = Shopware;
Component.register('api-test-button', { template,
props: ['label'], inject: ['apiTest'],
mixins: [ Mixin.getByName('notification') ],
data() { return { isLoading: false, isSaveSuccessful: false, }; },
computed: { pluginConfig() { let $parent = this.$parent;
while ($parent.actualConfigData === undefined) { $parent = $parent.$parent; }
return $parent.actualConfigData.null; } },
methods: { saveFinish() { this.isSaveSuccessful = false; },
check() { this.isLoading = true; this.apiTest.check(this.pluginConfig).then((res) => { if (res.success) { this.isSaveSuccessful = true; this.createNotificationSuccess({ title: this.$tc('apiTestButton.title'), message: this.$tc('apiTestButton.success') }); } else { this.createNotificationError({ title: this.$tc('apiTestButton.title'), message: this.$tc('apiTestButton.error') }); }
this.isLoading = false; }); } } }) ```
3. Create a `service` folder in the `administration/src` folder and create the `api-test.service.js` file in it.
File contents `api-test.service.js`:
```javascript const ApiService = Shopware.Classes.ApiService;
export default class ApiTestService extends ApiService { constructor(httpClient, loginService, apiEndpoint = 'api-test') { super(httpClient, loginService, apiEndpoint); }
check(values) { const headers = this.getBasicHeaders();
return this.httpClient.post( `_action/${this.getApiBasePath()}/verify`, values, { headers } ).then((response) => { return ApiService.handleResponse(response); }); } } ```
4. Create a `snippet` folder within the `administration/src` folder, then create the `en-GB.json` and `de-DE.json` files inside it.
File contents `en-GB.json`:
```json { "apiTestButton": { "buttonLabel": "Check", "title": "API Test", "success": "Connection was successfully tested", "error": "Could not connect. Please check your credentials" } } ```
File contents `de-DE.json`:
```json { "apiTestButton": { "buttonLabel": "Check", "title": "API Test", "success": "Verbindung wurde erfolgreich getestet", "error": "Verbindung konnte nicht hergestellt werden. Bitte prüfen Sie Ihre Zugangsdaten" } } ```
5. Create a `main.js` file inside `administration/src` folder.
File contents `main.js`:
```javascript import './component/api-test-button';
import ApiTestService from './service/api-test.service'; Shopware.Service().register('apiTest', () => { return new ApiTestService( Shopware.Application.getContainer('init').httpClient, Shopware.Service('loginService') ); });
import deDE from './snippet/de-DE.json'; import enGB from './snippet/en-GB.json';
Shopware.Locale.extend('de-DE', deDE); Shopware.Locale.extend('en-GB', enGB); ```
6. Go ahead and create a new file `ApiTestController.php` in the directory `<plugin root>/src/Controller/Api/`.
File contents `ApiTestController.php`:
```php <?php
namespace MyPlugin\Controller\Api;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Annotation\Route;
#[Route(defaults: ['_routeScope' => ['api']])] class ApiTestController { #[Route(path: '/api/_action/api-test/verify', name: 'api.action.api-test.verify', methods: ['POST'])] public function check(RequestDataBag $dataBag): JsonResponse { return new JsonResponse($this->checkCredentials($dataBag)); }
public function checkCredentials(RequestDataBag $dataBag): array { $apiKey = $dataBag->get('MyPlugin.config.apiKey'); $success = ['success' => false];
// Write your code here
return $success; } } ```
7. Next, you need to register the controller in the DI-container and make it public.
File contents `services.xml`:
```xml <?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services> <service id="MyPlugin\Controller\Api\ApiTestController" public="true"> <tag name="controller.service_arguments"/> </service> </services> </container> ```
8. The last thing to do is to tell Shopware how to look for new routes in plugin. This is done with a `routes.xml` file.
File contents `routes.xml`:
```xml <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing https://symfony.com/schema/routing/routing-1.0.xsd">
<import resource="../../Controller/**/*Controller.php" type="annotation"/> </routes> ```
[The result is displayed in the screenshot.][1]

[1]: https://i.stack.imgur.com/2Jt9c.png
Shopware is based on Symfony, so the discussed solution should work, and is sufficient for limited internationalization. E.g. If you only need to support a few languages.
I just tested this myself and it works to some extent in **Shopware 6.4.20.2**.
However, if a certain route was the same for two different localizations, only one of the routes would register properly. E.g. This will **not** work:
``` /** * @Route({"da-DK": "/kundeservice", "nb-NO": "/kundeservice" "en-US": "/support"}, name="frontend.support.page", methods={"GET"}) */ ``` Note the route is the same for both `da-DK` and `nb-NO`, and this will therefore not work properly, because it will "collapse" somehow and give you the wrong locale if you do `$request->getLocale()` later.
An easier way is to define the routes in the `routes.xml` of your plugin:
``` <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing https://symfony.com/schema/routing/routing-1.0.xsd">
<route id="supportPage" controller="nameOfPlugin\Storefront\Controller\supportPageController::supportPage" methods="GET|HEAD"> <path locale="da-DK">/kundeservice</path> <path locale="nb-NO">/kundeservice</path> <path locale="en-US">/support</path> </route> </routes> ``` Note. The `da-DK` and `nb-NO` translations are duplicated, and the route locale will be collapsed/overwritten, so it is not accurate in PHP. That's why you might want to include the **host name** too!
In addition, if your localization is domain name specific, you will for example be able to access the **English** URL on the **Danish** domain; this is a small issue, but it should not be possible, and it can lead to duplicated content in search engines.
To fix both problems, you got to associate the routes with the specific **host name** rather than just the locale.

Create seperate `route´ elements for each domain. E.g:
``` <route id="supportPage" controller="nameOfPlugin\Storefront\Controller\supportPageController::supportPage" methods="GET|HEAD" host="da.example.com"> <path locale="da-DK">/kundeservice</path> </route>
<route id="supportPage" controller="nameOfPlugin\Storefront\Controller\supportPageController::supportPage" methods="GET|HEAD" host="no.example.com"> <path locale="nb-NO">/kundeservice</path> </route> ```

If you need to fetch the locale you defined in `routes.xml` from *PHP* you can do it like this: ``` echo $request->getLocale();exit(); ```


        
Present in both answers; Present only in the new answer; Present only in the old answer;