I am building a front module for a website that is using 301 Moved Permanently option in SEO and URLs configuration.
Wesbite uses Prestashop 1.6.1.9.
In module, I am defining the route like this:
public static $ModuleRoutes = array(
'module-aacategories-viewmapping-mapping' => array(
'controller' => 'viewmapping',
'rule' => 'mappings{/:tree}',
'keywords' => array(
'tree' => array('regexp' => '[/_a-zA-Z0-9-\pL]*', 'param' => 'tree'),
),
'params' => array(
'fc' => 'module',
'module' => 'aacategories',
)
)
);
In browser address bar, when I enter:
site.local/en/mappings/test-map/first-test
I get:
Please use the following URL instead:
site.local/en/index.php?controller=viewmapping&tree=test-map%2Ffirst-test&module=aacategories
This latter link gives 404. However, when I append &fc=module to the url, it goes to desired page.
The problems:
1- How to force Prestashop routing to append &fc=module at the end?
2- How to keep the friendly url in address bar and not be redirected?
Note: When I change configuration in SEO and URLs to no redirection, then it works. But it is not the configuration needed in prod.
Your help is much appreciated. Thanks in advance.
The problem is you are setting public property $php_self in your module controller.
You need to remove the property so that core front controller does not do a canonical redirect.
The code that does this is in FrontController.php line 378.
if (!empty($this->page_name)) {
$page_name = $this->page_name;
} elseif (!empty($this->php_self)) {
$page_name = $this->php_self;
} elseif (Tools::getValue('fc') == 'module' && $module_name != '' && (Module::getInstanceByName($module_name) instanceof PaymentModule)) {
$page_name = 'module-payment-submit';
}
// #retrocompatibility Are we in a module ?
elseif (preg_match('#^'.preg_quote($this->context->shop->physical_uri, '#').'modules/([a-zA-Z0-9_-]+?)/(.*)$#', $_SERVER['REQUEST_URI'], $m)) {
$page_name = 'module-'.$m[1].'-'.str_replace(array('.php', '/'), array('', '-'), $m[2]);
} else {
$page_name = Dispatcher::getInstance()->getController();
$page_name = (preg_match('/^[0-9]/', $page_name) ? 'page_'.$page_name : $page_name);
}
And then does a canonical redirect if you set that property on line 401.
if (!empty($this->php_self) && !Tools::getValue('ajax')) {
$this->canonicalRedirection($this->context->link->getPageLink($this->php_self, $this->ssl, $this->context->language->id));
}
Related
I have created my own Request API ( POST : {{baseUrl}}/products/create ). This API is used to create many products and returns only the total number of existing products in Shopware. I want to execute my request in postman, but I can not. There is a way to make work the request in Postman ?
ApiController.php
<?php declare(strict_types=1);
namespace TestApi\Controller\Api;
use Shopware\Core\Framework\Context;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* #RouteScope(scopes={"api"})
*/
class ApiController extends AbstractController
{
protected EntityRepositoryInterface $productRepository;
public function __construct(EntityRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
/**
* #Route("/products/create", name="api.product.create", methods={"POST"})
*/
public function createProducts(Context $context): JsonResponse
{
$this->productRepository->create([
[
'name' => 'Product 1',
'productNumber' => 'SW1231',
'stock' => 10,
'taxId' => 'bc3f1ba6f75749c79b5b4a9d673cf9d4',
'price' => [['currencyId' => Defaults::CURRENCY, 'gross' => 50, 'net' => 25, 'linked' => false]],
],[
'name' => 'Product 2',
'productNumber' => 'SW1232',
'stock' => 10,
'taxId' => 'bc3f1ba6f75749c79b5b4a9d673cf9d4',
'price' => [['currencyId' => Defaults::CURRENCY, 'gross' => 50, 'net' => 25, 'linked' => false]],
]
], $context);
$criteria = new Criteria();
$products = $this->productRepository->search($criteria, $context);
return new JsonResponse($products->count());
}
}
Postman :
For information I have provided the Authorization header in the request.
Actually your issue lies inside your controller, you use the api route scope, which means that the api authentication mechanism should be used. But all routes with the api route scope need to start with the /api prefix in the path.
Routes without a /api or /store-api prefix are assumed to be storefront requests with the storefront authorization. You should also get an error because of the mismatch of route scope and actual api path, but probably the CSRF error is thrown before that is validated.
To fix your code use /api/products/create as the path for your custom controller action and also use the /api prefix in postman to access your route.
You're making a request against the storefront, not an api endpoint. The CSRF protection only comes into play in the storefront. Is your baseUrl missing the /api prefix? The value should be like http://localhost/api.
I am using Silex and apache. I want to disallow access for anonymous users to localhost/admin page. I read docs, docs of SimpleUserProvider and create the following index.php:
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Provider;
use Symfony\Component\HttpFoundation\Request;
$app = new Silex\Application();
$app->register(new Provider\SecurityServiceProvider());
$app->register(new Provider\SessionServiceProvider());
$app->register(new Provider\TwigServiceProvider(), [
"twig.path" => __DIR__.'/../views'
]);
$app['debug'] = true;
$app['security.firewalls'] = array(
'default' => array(
'pattern' => '^/',
),
'secured' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
'daria' => array('ROLE_USER', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
),
),
);
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN', 'https'),
array('^.*$', 'ROLE_USER'),
);
$app -> boot();
$app->get('/', function () {
return 'Hello from Silex container.';
});
$app->get('/admin/', function() {
return "Admin page";
});
$app->get('/login', function(Request $request) use ($app) {
return "Login page";
});
$app->get('/logout/', function() {
return "Logout page";
});
$app->get('/admin/login_check/', function() {
return "Admin login check page";
});
$app->run();
As Symfony 2 docs says, if I request to localhost/admin, I should see input fields for pass and login in alert.
So when I go to 'localhost' all are right, I see correct message. But when I go to 'localhost/admin' I expect that browser will ask with alert my login and password. But it doesn't happens, I get 'ERR_CONNECTION_REFUSED Site localhost disallow connection'. In apache log I have 301 http code. Is it normal behavior that browser doesn't ask login/password with alert? If yes, what should I add to code to change that behavior?
P.S. I know that hardcoded login and password are terrible, but I am just started Silex and it doesn't matter.
I think that you get ERR_CONNECTION_REFUSED error because of redirect to https. Try to remove this redirect by changing array('^/admin', 'ROLE_ADMIN', 'https'), to array('^/admin', 'ROLE_ADMIN'),.
Remove default section from firewalls. This section is first, catches all requests and doesn't require authorization.
If you want standard alert with user/password prompt, specify http entry point instead of form.
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/admin/',
'http' => array(),
'users' => array(
'admin' => array('ROLE_ADMIN', '...'),
'daria' => array('ROLE_USER', '...'),
),
),
);
i am trying to allow accessing the $_GET for both clean url and normal get request in YII (Yii 1.1.14), so for example if i have a controller Cities and action getCities that var_dump($_GET) only
1- http://example.com/cities/getCities/country_id/100
==> the output is array(1) { ["country_id"]=> string(3) "100" }
2- http://example.com/cities/getCities?country_id=100
==> the output is array(0) { }
my urlManager is
'urlManager' => array(
'class' => 'ext.localeurls.LocaleUrlManager',
'languageParam' => 'lang', // Name of the parameter that contains the desired language when constructing a URL
'urlFormat' => 'path',
'showScriptName' => false,
'caseSensitive' => false,
'rules'=>array(
'login'=>'/home/login'
)
),
how could i allow Yii to recognize $_GET in both cases above?
EDIT
i am using nginx 1.6. GET params (?x=y) is working fine on other Yii projects, only this project doesn't. I changed the web-server to apache, and i got it working on this project!!! although this project has the same nginx configurations like others!!
I am including Keen in my product (code snippet below)
require INCLUDE_DIR . '/vendor/autoload.php'; // Autoloader for Composer (https://getcomposer.org/)
use KeenIO\Client\KeenIOClient;
class Statistics extends Model {
private $client;
public function __construct( $id = null ){
parent::__construct();
$this->client = KeenIOClient::factory([
'projectId' => KEEN_PROJECT_ID,
'writeKey' => KEEN_WRITE_KEY,
'readKey' => KEEN_READ_KEY
]);
}
...
but I continue to get an "Class 'KeenIO\Client\KeenIOClient' not found" error when the "KeenIOClient::factory" line runs. I was able to successfully install Keen.io through Composer - I feel it's something simple I'm missing - any ideas?
So I can't leave a comment, but I am wondering if there is maybe an issue with the include path? I was able to get this PHP snippet to work:
require 'vendor/autoload.php';
use KeenIO\Client\KeenIOClient;
$client = KeenIOClient::factory([
'projectId' => "53f3a8687d8cb95095000001",
'readKey' => "99a06e48fd7fb1279bc40995160eb0b61a9e0efaab8b651b029f0d895f77c0a804ba089282eff28bf8ad07f337422441d0542b7feaac9fea1e92fc153ee7efc51afad3276bda8d7754a338b349d540bfb402cba0dfdc82498c217054efd8abd0f47a0c0bc963bbdf0dc938c91b17d9f2"
]);
$count = $client->count('bitcoin-prices', [
'impressions' => [
'interval' => 'daily',
'timeframe' => 'this_30_days',
'group_by' => 'keen.timestamp'
]
]);
print_r($count);
That project id and read key are from the keen io open data sets (good to test with).
I am using magento api ..
in which i have used "catalog_product_attribute_media.create" ..thats giving problem if it doesn't get image on server where this image exist.
problem is that ..it stoping my script to run further
I have checked if URL is none.. but how can i handle this situation that is it getting url ...but image not exist
here is my code...
if($products[$counter]->small_image_url){//check if url exists
$newImage = array(
'file' => array(
'name' => 'file_name',
'content' => base64_encode(file_get_contents($products[$counter]->small_image_url)),
'mime' => 'image/jpeg'),
'label' => $products[$counter]->product_name,
'position' => 2,
'types' => array('thumbnail_image'),
'exclude' => 0
);
$imageFilename = $proxy->call($sessionId, 'product_media.create', array($sku, $newImage));
}
Have you tried checking for an empty string?
if($products[$counter]->small_image_url && $products[$counter]->small_image_url != '')