I’m using FileCache in my cache component. In my controller, I’m using :
[
'class' => 'yii\filters\HttpCache',
'only' => ['view'],
'etagSeed' => function ($action, $params) {
$model = $this->findModel(Yii::$app->request->get("id"));
return $model->update_time;
},
],
With etagSeed and/or lastModified I got the same behavior issue:
The cache works well with yii\filters\PageCache and yii\filters\HttpCache. But when the cache is invalidated (for example after updating the page), I still see the old cached content.
So when I'm visiting the target page from other page, I'm getting the old content. But when I push F5, the page refreshs with the last content.
I've checked the Etag value on my GET request in the browser, and I've found that I'm getting the old Etag value until I refresh the page using the F5 button.
This can be a standard browser behavior when using HttpCache ? But how can I see the new content without refreshing each time the browser to get the last content ?
Am I missing something ?
You could use PageCache and dependency in your controller. Note, that if your page is public, you should be prepared probably to accept an empty ID.
public function behaviors()
{
return [
'viewCache' => [
'class' => 'backend\components\filters\PageCache',
'only' => ['view'],
'duration' => 86400, // 1 day
'variations' => [
$_GET['id'] ?? null,
],
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT update_time FROM my_table WHERE id = :id',
'params' => [
':id' => $_GET['id'] ?? null,
]
]
'enabled' => [
isset($_GET['id']),
],
],
];
}
Related
I have 2 models: Order and Product, each has belongsToMany with pivot set properly.
In OrderCrudController, I also use FetchOperation and make a fethProducts() function as below:
use \Backpack\CRUD\app\Http\Controllers\Operations\FetchOperation;
public function fetchProducts()
{
return $this->fetch([
'model' => \App\Models\Product::class,
'searchable_attributes' => ['name','sku']
]);
// return $this->fetch(\App\Models\Product::class); <-- I also tried this one
}
protected function setupCreateOperation()
{
CRUD::setValidation(OrderRequest::class);
// other fields
$this->crud->addField([
'name' => 'products',
'type' => 'relationship',
'pivotSelect' => [
'attribute' => 'name',
'ajax' => true,
],
'subfields' => [
[
'name' => 'quantity',
'type' => 'number',
],
],
]);
}
But it comes to unexpected behavior when I search the product, the select2 field remains "searching" though the request successfully retrieved the data.
screenshot - select2 field
screenshot - ajax results
PS: this field works perfectly without subfields, no vendor overrides etc., so I think I've set everything correctly.
Anyone can help?
This was asked two months ago but somehow I missed it, just noticed it today after someone opened an issue on the GitHub repository.
I am happy you guys found a solution for it but unfortunatelly I cannot recommend it as using the select2_from_ajax will miss the functionality to don't allow the selection of the same pivots twice, otherwise you will have undesired consequences when saving the entry.
I've just submitted a PR to fix this issue, I will ping you guys here when it's merged, probably by next Monday.
Cheers
I just came accross this exact problem and after quite some research and trials, i finally found a solution !
The problem seems to be related to the relationship field type inside the pivotSelect. Try to use select2_from_ajax instead and don't forget to set method to POST explicitly, that worked for me like a charm.
Here is what you might try in your case :
$this->crud->addField([
'name' => 'products',
'type' => 'relationship',
'pivotSelect' => [
'attribute' => 'name',
'type' => 'select2_from_ajax',
'method' => 'POST',
'data_source' => backpack_url('order/fetch/products') // Assuming this is the URL of the fetch operation
],
'subfields' => [
[
'name' => 'quantity',
'type' => 'number',
],
],
]);
in my application Symfony 5.4 and PHP 8.0, i'm using Stripe Payment Checkout https://stripe.com/docs/payments/checkout, after payment success or error my user need to be redirect.
'success_url' => $YOUR_DOMAIN.'/domain/projet/{CHECKOUT_SESSION_ID}/domain/succes',
'cancel_url' => $YOUR_DOMAIN.'/domain/projet/{CHECKOUT_SESSION_ID}/error',
But user is disconnect and i don't want user disconnect, sometime if we are lucky user is not disconnect after payment.
#[Route('/espace-client/payer/project/{idBilling}/{idProject}', name: 'final')]
public function stripePayment(int $idBilling, int $idProject)
{
$project = $this->projectRepository->findOneById($idProject);
$billing = $this->billingRepository->findOneById($idBilling);
$YOUR_DOMAIN = 'https://127.0.0.1:8000';
$productStripe[] = [
'price_data' => [
'currency' => 'eur',
'unit_amount' => $billing->getPrice(),
'product_data' => [
'name' => $billing->getName(),
'images' => null,
],
],
'quantity' => 1,
];
Stripe::setApiKey($this->publicKey);
$checkout_session = Session::create(
[
'line_items' => [[
$productStripe,
]],
'payment_method_types' => [
'card',
],
'mode' => 'payment',
'success_url' => $YOUR_DOMAIN.'/espace-client/projet/{CHECKOUT_SESSION_ID}/paiement/succes',
'cancel_url' => $YOUR_DOMAIN.'/espace-client/projet/{CHECKOUT_SESSION_ID}/erreur',
]
);
$billing->setStripeSessionId($checkout_session->id);
$this->entityManager->flush();
return $this->redirect($checkout_session->url);
}
I tryied everyting but user is disconnected always and i don't know why.
Payment, checkout all is ok
If your users get disconnected after the Stripe redirect, it usually means that one or more of the user’s cookies (such as their login or session cookie) are lost during the redirect process. And there are two common causes for this:
A mismatch between HTTPS and HTTP protocols after the redirect. For example if the user is browsing your website on HTTPS, but then gets redirected to a HTTP URL. To fix this, make sure all URLs involved use the same protocol.
The SameSite attribute is set to strict on the cookies used for login or session. If that’s the case, those cookies will not be included when the user is redirected back to your website because that redirect is considered a cross-site request. To fix this, change the SameSite attribute from strict to either lax or none. More info here.
In ZF3, I'm initializing my session as following:
config/autoload/global.php
'session_config' => [
'name' => 'gintra3',
'cookie_lifetime' => 60*60*1,
'gc_maxlifetime' => 60*60*24*30,
],
'session_storage' => [
'type' => Zend\Session\Storage\ArrayStorage::class,
],
'session_manager' => [
'storage' => Zend\Session\Storage\SessionArrayStorage::class,
'validators' => [
Zend\Session\Validator\RemoteAddr::class,
Zend\Session\Validator\HttpUserAgent::class,
],
],
module/Application/Module.php
$sessionManager = $e->getApplication()->getServiceManager()->get(SessionManager::class);
$sessionTableGateway = new TableGateway('session',$e->getApplication()->getServiceManager()->get('Zend\Db\Adapter\Adapter'));
$sessionSaveHandler = new DbTableGateway($sessionTableGateway,new DbTableGatewayOptions());
$sessionManager->setSaveHandler($sessionSaveHandler);
Now, when I'm storing data like this on page 1:
$sessionC = new Container('test');
$sessionC->testVariable = "helloWorld";
And retrieve it on page 2 like this:
$sessionC = new Container('test');
Debug::dump($sessionC->testVariable);
I get an output on page 2 like this:
vendor/zendframework/zend-debug/src/Debug.php:97:null
When I check the database table, the 'data' column of the corresponding session_id contains "helloWorld" after loading page 1. After loading page 2, it does not contain "helloWorld" anymore.
If I comment out all session-related lines in Module.php, a PHPSESSID cookie is created on page load and session data saving and storing works fine now.
It does not matter if I use DbTableGateway as a save_handler or just use standard save_handler. The problem occurs in both cases.
When using my individual session storage, also FlashMessenger and Csrf-Form-Validation stop working due to the same mechanism of loosing all session data on page load.
Where is my problem? What am I overseeing?
Thanks a lot for some ideas.
I am using the Official PHP driver to connect to Elasticsearch(v 2.3), every when I index a new document it takes from 5sec to 60sec to be able to get it into my filter results. How can I cut down the delay time to zero?
Here is my index query
# Document Body
$data = [];
$data['time'] = $time;
$data['unique'] = 1;
$data['lastACtivity'] = $time;
$data['bucket'] = 20,
$data['permission'] = $this->_user->permission; # Extracts User Permission
$data['ipaddress'] = $this->_client->ipaddress(); # Extracts User IP Address
# Construct Index
$indexRequest = [
'index' => 'gorocket',
'type' => 'log',
'refresh' => true,
'body' => $data
];
# Indexing Document
$confirmation = $client->index( $indexRequest );
And here is my search filter query
# Query array
$query =[ 'query' => [
'filtered' => [
'filter' => [
'bool' => [
'must' =>[
[
'match' => [ 'unique' => 1 ]
],
[
'range' => [
'lastACtivity' => [
'gte' => $from,
'lte' => $to
],
'_cache' => false
]
]
],
'must_not' => [
[ 'match' => [ 'type' => 'share' ] ],
]
]
]
]
]
];
# Prepare filter parameters
$filterParams = [
'index' => 'gorocket',
'type' => 'log',
'size' => 20,
'query_cache' => false,
'body' => $query
];
$client->search($filterParams);
Thank you.
When you index a new document you can specify the refresh parameter in order to make the new document available immediately for your next search operation.
$params = [
'index' => 'my-index',
'type' => 'my-type',
'id' => 123,
'refresh' => true <--- add this
];
$response = $client->index($params);
The refresh parameter is also available on the bulk operation if you're using it.
Be aware, though, that refreshing too often can have negative impacts on performance.
There is a refresh option provided, which needs a value (in seconds) to refresh the index. For example, if you update something in index, it gets written in the index but not ready for reading until the index is refreshed.
Refresh can be set to true for refreshing the index as soon as any change happens. This needs to be very carefully thought, because many times, it downgrades your performance as its an overkill to refresh for each small operation, plus many bulk refreshes can make the index busy.
Tip: Use an elasticsearch plugin, such as kopf and see more such options like refresh rate, to configure.
I use yii-jui to add some UI elements in the views such as datePicker. In the frontend\config\main-local.php I set the following to change the theme used by the JqueryUI:
$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'gjhgjhghjg87hjh8878878',
],
'assetManager' => [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/flick/jquery-ui.css'],
],
],
],
],
];
I tried the following to override this configuration item in the controller actions method:
public function actions() {
Yii::$app->components['assetManager'] = [
'bundles' => [
'yii\jui\JuiAsset' => [
'css' =>
['themes/dot-luv/jquery-ui.css'],
],
],
];
return parent::actions();
}
Also I tried to set the value of Yii::$app->components['assetManager'] shown above to the view itself (it is partial view of form _form.php) and to the action that calls this view (updateAction). However, all this trying doesn't be succeeded to change the theme. Is there in Yii2 a method like that found in CakePHP such as Configure::write($key, $value);?
You should modify Yii::$app->assetManager->bundles (Yii::$app->assetManager is an object, not an array), e.g.
Yii::$app->assetManager->bundles = [
'yii\jui\JuiAsset' => [
'css' => ['themes/dot-luv/jquery-ui.css'],
],
];
Or if you want to keep other bundles config :
Yii::$app->assetManager->bundles['yii\jui\JuiAsset'] = [
'css' => ['themes/dot-luv/jquery-ui.css'],
];
You are going about this all wrong, you want to change the JUI theme for 1 controller alone because of a few controls. You are applying 2 css files to different parts of the website that have the potential to change styles in the layouts too. The solution you found works but it is incredibly bad practice.
If you want to change just some controls do it the proper way by using JUI scopes.
Here are some links that will help you:
http://www.filamentgroup.com/lab/using-multiple-jquery-ui-themes-on-a-single-page.html
http://jqueryui.com/download/
In this way you are making the website easier to maintain and you do not create a bigger problem for the future than you what solve.