Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not for channels #2

Open
TELLO0815 opened this issue Dec 23, 2022 · 8 comments
Open

Not for channels #2

TELLO0815 opened this issue Dec 23, 2022 · 8 comments

Comments

@TELLO0815
Copy link

TELLO0815 commented Dec 23, 2022

I think its easy to make it for channels available. I put the base linker key to the DB channel themselfe. If you create a channel, I think it must be there. So it runs simple for each channel, if you call the base linker-connector over other channel domain.

`use Spinbits\SyliusBaselinkerPlugin\Handler\HandlerInterface;
use Spinbits\SyliusBaselinkerPlugin\Rest\Exception\ForbiddenException;
use Spinbits\SyliusBaselinkerPlugin\Rest\Exception\InvalidArgumentException;
use Spinbits\SyliusBaselinkerPlugin\Rest\Exception\RestException;
use Spinbits\SyliusBaselinkerPlugin\Rest\Input;
use Spinbits\SyliusBaselinkerPlugin\Rest\Response;
use Spinbits\SyliusBaselinkerPlugin\Rest\ResponseError;
use Spinbits\SyliusBaselinkerPlugin\Rest\ResponseInterface;
use Exception;
use Sylius\Component\Channel\Context\ChannelContextInterface;

class RequestHandler
{
private const HANDLER_NOT_FOUND = 'Handler for action "%s" is not configured. Please use "setHandler" to map it.';

/** @var HandlerInterface[] */
private array $handlers = [];

/** @var ChannelContextInterface */
private $channelContext;

public function __construct(
    ChannelContextInterface $channelContext
)
{
    $this->channelContext = $channelContext;
}

/**
 * @param Input $input
 * @return ResponseInterface
 */
public function handle(Input $input): ResponseInterface
{
    try {
        $this->checkPassword($input);
        $this->checkAction($input);
        $handler = $this->handlers[(string) $input->action()];

        return new Response($handler->handle($input));
    } catch (Exception $e) {
        return new ResponseError($e->getMessage(), $e->getCode());
    }
}

/**
 * @param string $action
 * @param HandlerInterface $handler
 */
public function registerHandler(string $action, HandlerInterface $handler): void
{
    $this->handlers[$action] = $handler;
}

public function supportedActions(): array
{
    return array_keys($this->handlers);
}

/**
 * @param Input $input
 * @throws RestException
 */
private function checkAction(Input $input): void
{
    if (null === $input->action()) {
        throw new InvalidArgumentException("Missing action parameter");
    }
    if (!isset($this->handlers[$input->action()])) {
        throw new InvalidArgumentException(sprintf(self::HANDLER_NOT_FOUND, $input->action()));
    }
}
/**
 * @param Input $input
 *
 * @throws ForbiddenException
 * @throws RestException
 */
private function checkPassword(Input $input): void
{
    if (null === $input->password()) {
        throw new InvalidArgumentException("Missing password parameter");
    }
    if ($input->password() !== $this->channelContext->getChannel()->getBaselinker()) {
        throw new ForbiddenException("Wrong password");
    }
}

}`

<service id="Spinbits\SyliusBaselinkerPlugin\RequestHandler"> <argument key="$channelContext" type="service" id="Sylius\Component\Channel\Context\ChannelContextInterface"/> <call method="registerHandler"> <argument type="string">FileVersion</argument> <argument type="service" id="Spinbits\SyliusBaselinkerPlugin\Handler\FileVersionActionHandler" /> </call> .....

And Sylius admin channel as well.

@mmdevcodeclutch
Copy link

mmdevcodeclutch commented Mar 30, 2023

@TELLO0815 I'm new to Sylius - I'm trying to make it work with baselinker plugin with multiple channels. Right now, at baselinker tester I get this response while trying to perform action ProductsList:

Array
(
    [[error](https://developers.baselinker.com/shops_api/index.php?tester=1&prod_id=error)] => 1
    [[error_code](https://developers.baselinker.com/shops_api/index.php?tester=1&prod_id=error_code)] => 0
    [[error_text](https://developers.baselinker.com/shops_api/index.php?tester=1&prod_id=error_text)] => Channel could not be found! Tip: You can use the Web Debug Toolbar to switch between channels in development.
)

I assumed I must implement RequestResolverInterface, register it and then return correct channel after baselinker hits baselinker-connector endpoint. Should I decide which channel to return based for example on request origin? Could you give any advice on that?

@jakublech
Copy link
Contributor

@TELLO0815 Not sure if I understand what is the issue. It is ok to use one key for all channels. If you want to use separate keys let me know. I can manage it.
@mmdevcodeclutch please check if you have configured your channel hostname. Sylius may not found channel if it is wrong or not configured.

@TELLO0815
Copy link
Author

@jakublech I use the version I posted. Works fine ;-)

@mmdevcodeclutch
Copy link

mmdevcodeclutch commented Mar 30, 2023

@jakublech All my channels in table have hostname value provided, but for some reason channel isn't provided on incoming request. I used database dump from staging server, all hostnamees in my table are set to shop domains. For local development I set hostname to localhost on one of channels on which code column value is default. Is this correct? I'm not sure if this is something specific for this project I'm working on, or this default code comes from sylius.

@mmdevcodeclutch
Copy link

Also channel is already set in DebugToolbar while I'm accessing any other endpoint. So sylius knows which one to use in other cases but baselinker tester for some reason gets this error with channel not found.

@mmdevcodeclutch
Copy link

My bad, I had localhost in hostname column in one of sylius_channels table records, but baselinker tester was making requests to ngrok tunnel URL I provided as link to connector file. After adding channel with ngrok link as hostname everything works as its should.

@jakublech
Copy link
Contributor

@TELLO0815 So I assume you need to define separate baselinker password per channel?

@TELLO0815
Copy link
Author

TELLO0815 commented Mar 31, 2023

@jakublech Yes, to get a connection for multiple domain = channel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants