Magento 2 session unsetting itself - magento

I need to be able to store some custom session variables that exist for the custom, regardless of whether they're signed in or not, but for some reason my sessions keep deleting themselves.
I have used this example to help me add my session code in.
Here's my code
Block file
<?php
namespace MyVendor\MyModel\Block;
use Magento\Framework\View\Element\Template;
class ProductSearch extends Template {
protected $_customSession;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Customer\Model\Session $customSession,
array $data = []
){
parent::__construct($context, $data);
$this->_customSession = $customSession;
}
//Get the car model from the session
public function getSessionCarModel(){
return $this->_customSession->getCarModel();
}
//Unset the car model from the session
public function unsetSessionCarModel(){
return $this->_customSession->unsCarModel();
}
}
and heres the top of my template file that sorts the session when its loaded
productsearchbanner.phtml
<?php
//If the user has selected a new model, unset our session then start a new one
if(isset($_POST['modelSelect'])){
//Unset the other sessions
$block->unsetSessionCarModel();
//Set the model session
$block->setSessionCarModel($_POST['model']);
}
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
?>
The way the code is meant to work is, if the $_POST['modelSelect'] is set, the user has come from the model select page so we need to start the process again and reset their session, but if they haven't, the session should remain the same.
My issue is, when I come from the model select page, my session variable shows in the var dump no problem, as shown below.
But then as soon as I go to any another page on my site (for example, the homepage) and then back to the product search page, the session has cleared?
What am I doing wrong? Why does my session clear every time I load a page? I just need to be able to set the equivalent of $_SESSION['carModel'] and it be persistent for that user, regardless of if they're logged in or not, or where on the site they go.
Can someone please point me in the right direction?

Setting sessions in Blocks or Template files is a problem. This is because of full page cache. Magento's execution cycle changes with FPC turned on.
Controllers or Models are the best places to update session data.
But, if you need to update your session in a template / block, then you can call a custom action via AJAX and have it update the session info.
Generally, one would need to take these steps in Magento 2:
create a new controller / action pair in an existing or a new module, that would update session info. This controller should ideally accept AJAX requests only.
have a template rendered in container before_body_end and toss some jQuery code in there, that will query the controller / action pair to have the session info updated.
This way, whenever the page will load, it will trigger a session update ( or you can have it trigger on any other event, say when a user clicks something etc. ) by requesting your controller / action, say, /my-module/my-controller/my-session-updater-action.

Related

Deleting customer addresses in magento

I need to delete customer addresses programmatically, but I didn't find a function to do that.
$recordedAddresses = array();
foreach ($customer->getAddresses() as $address)
{
$recordedAddresses = $address->toArray();
}
I already took the addresses' collection as showed above, I just wanna delete them by id.
Curiously I didn't find examples but using API.
Could someone gimme a hand with that?
Somehow Magento keeps empty entities after using $address->delete() in my case. There were empty addresses on account preventing admin from saving the customer form when using this method.
Only way I've found to actually remove the address from user account is by changing the protected $_isDeleted flag to true:
$address = Mage::getModel('customer/address')->load($addressId);
$address->isDeleted(true);
Hope it saves some time for anyone who will stumble uppon same Magento behaviour.
Have a look at the Mage_Customer_AddressController controller class and deleteAction() method. Essentially all you need to is load the address by it's id:
$address = Mage::getModel('customer/address')->load($addressId);
and then delete it:
$address->delete();
delete() is a standard method you can run against all models (see Mage_Core_Model_Abstract), you can also set the _isDeleted flag and call save() which will have the same result.

Extending Joomla 2.5 Banner Component

I really hope someone can help me.
I need to be able to serve banners in categories which are dependant on a session variable - and can't find a component which does that. So I'd like to extend the Joomla Banner component in order to select banners based on a session variable which contains the category path.
The correct session variable is being stored correctly.
In order to do this I added an option in the banners module .xml to allow for a session variable and the name of the session variable. This is being stored correctly in the module table within the params field along with the other module parameters.
Then I started on the
components > banners > com_banners > models > banners.php
by adding two lines of code in getListQuery where the SQL is assembled. They are:
$sess_vars = $this->getState('filter.sess_vars');
$sess_vars_name = $this->getState('filter.sess_vars_name');
But both variables contain nothing even though the ones the component already has can be retrieved fine. Without a doubt I need to change something somewhere else as well - but just can't figure out what to do.
Any help would be greatly appreciated.
The first thing to do is not hack the core files, hacking the core prevents you from using the built-in update feature to apply the regular bug fixes and security patches released by Joomla! (e.g. the recently released 2.5.9 version).
Rather make a copy of them and modify it so it's called something else like com_mybanners. Apart from the folder name and the entry point file (i.e. banners.php becomes mybanners.php) you will also want to update the components banners.xml to mybanners.php.(You will need to duplicate and modify both the front end /components/com_banners/ and /administrator/components/mybanners.php.)
Because of the way Banners work (i.e. banners are displayed in a module) you will also need to duplicate and modify /modules/mod_banners/,/modules/mod_banners/mod_banners.php and /modules/mod_banners/mod_banners.xml. Changing mod_banners to mod_mybanners in each location.
In Joomla! components the state is usually populated when JModel is instantiated, however, in this case the component is really about managing banners and recording clicks the display is handled by mod_banners. So, you will want to add some code to mod_mybanners.php to use the session variables you want to act on. Normally when a models state is queried you will collect the variables via JInput and add them to your object's state e.g.
protected function populateState()
{
$jApp = JFactory::getApplication('site');
// Load state from the request.
$pk = $jApp->input->get('id',0,'INT');
$this->setState('myItem.id', $pk);
$offset = $jApp->input->get('limitstart',0,'INT');
$this->setState('list.offset', $offset);
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
// Get the user permissions
$user = JFactory::getUser();
if ((!$user->authorise('core.edit.state', 'com_mycomponent')) && (!$user->authorise('core.edit', 'com_mycomponent')))
{
$this->setState('filter.published', 1);
$this->setState('filter.archived', 2);
}
}
The populateState() method is called when a state is read by the getState method.
This means you will have to change your copy of /components/com_banners/models/banner.php to capture your variables into the objects state similar to my example above.
From there it's all your own code.
You can find all of this information in the Developing a Model-View-Controller tutorial on the Joomla Doc's site

get joomla registration form variables?

I'm working on getting joomla registration form values that user enters
at the time of registration. After two days of searching I reached to the
file Joomla2.5.7\components\com_users\controllers\registration.php. In the register() method I
tried to echo $data and $requestData variables but didn't see any output, on registering a new entry. I also tried to echo javascript but was unsuccessful. I'm trying to connect joomla database with my own database, so that whenever new user registers , he is also registered to my website. How can I get the registration form variables, any kind of help is really appreciated.
Ty this
On registration controller you can find a function call to model like this
$return = $model->register($data);
after that just
echo "<pre/>";
print_r($data);
Also in the registration model
components\com_users\model\registration.php
register() method is defined you can check that for more info.
In addition if you want to add the users info to the other DB like your website DB.
The best place to write mysql query is :
// Store the data.
if (!$user->save()) {
$this->setError(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError()));
return false;
}else{
//Your custom mysql query to other DB or tables
}
find the above section in the registration model inside register()method.
Hope this may solve your problem..
I hope this tutorial helps you. You will find it explains the process of joomla registration form very well.
http://youtu.be/2AyCzb2vTaU

Prevent direct access to a page in Joomla

I have a payment gateway integrated on my website. When user is done with payment he/she is redirected to a particular page say www.example.com/redirect. I want to prevent users from directly entering this url (www.example.com/redirect) in address bar and access the page. I want it asap.
Actually the page is protected from guest users but if logged in user types that url then it will redirect him to that page and hence the payment option will be skipped. I want the user must pay the amount first and then redirected to this page.
Hard to answer precisely since you only give a non-joomla url as an example, but at the top of every Joomla script is the following line:
defined('_JEXEC') or die( 'Restricted access' );
You obviously can't prevent a user from typing in the url, so this will at least detect if a session is already in place. If the user isn't in an active Joomla session, this will fire and prevent access. You could easily adapt it to do whatever you want to happen for your requirement, depending on whatever you have to check with, i.e. if the referrer is your payment gateway, etc.
I had a similar desire. I wanted the page to only display if the users was logged in and if they had filled out the order entry page.
What I decided to do was check to see if there was data in the POST.
controller/place_order.php (snipet)
public function submitOrder()
{
$post = JRequest::get('post');
$model = $this->getModel();
if($post != null && $post != ''){
if($model->placeOrder()){
}
}
JRequest::setVar('layout', 'submitOrder');
parent::display();
}
This prevents the task from executing my placeOder function anything in the model. Then I just add something similar to the submit order page. In your case "redirect".
view/place_order/tmpl/submitOrder.php (snipet)
defined('_JEXEC') or die('Restricted access');
$user =& JFactory::getUser();
if ($user->guest) {
echo "<p>You must login to access this page.</p>";
}
else if($_POST == "" || $_POST == null){
echo "<p>You can not directly access this page.</p>";
}else {
//Your order was submitted successfully HTML (don't forget to close it at the bottom ;)
There are a lot of ways you could do it... you probably don't even need to check in the controller if you don't want to but I do to save on time. With out seeing your code it's hard to tailor the answer but if you grasp the concept here it should help (I hope...).
You might also want to check out this page from Joomla on authorization and privileges.
this should be done in your component's base controller (controller.php). if you look at this code snippet:
// Check for edit form.
if ($vName == 'form' && !$this->checkEditId('com_weblinks.edit.weblink', $id))
{
// Somehow the person just went to the form - we don't allow that.
return JError::raiseError(403,
JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id));
}
this block of code is present in most of core components intended to do exactly what you want. how ever how this actually dos what it does is explained through the $this->checkEditId() function. I hope you are familiar with the JControllerForm class and if you are not check out the API. because creating an edit id for a page and "authorizing user for access to a specific page based on his last page" is done by JControllerForm.

Magento redirected to other URL after order editting

Currently I'm experiencing a problem after editing orders in the Magento admin. The page is always redirected to another URL, the base of which belongs to the store view that the order belongs to. And this page requires re-login to the admin.
For example, I have two base URLs, each belongs to one store view:
www.example.old.com //old store view (default)
www.example.new.com //new store view
The system uses www.example.old.com as the default base URL. So under www.example.old.com I create an order for the new store and invoice it. Then on submitting the invoice, the page is redirected from
http://www.example.old.com/index.php/admin/sales_order_invoice/new/order_id/1234/
to
http://www.example.new.com/admin/sales_order/view/order_id/1234/
And it requires login for another time.
I traced the redirection code to Mage_Core_Model_Url
public function getRouteUrl($routePath=null, $routeParams=null)
...
$url = $this->getBaseUrl().$this->getRoutePath($routeParams);
public function getBaseUrl($params = array())
....
if (isset($params['_store'])) {
$this->setStore($params['_store']);
}
....
return $this->getStore()->getBaseUrl($this->getType(), $this->getSecure());
Then I don't know what to do. There is no parameter _store but it seems that Magento determines which store view to run based on the order being treated, when it is supposed to stay on the same base URL throughout the admin.
Have you tried to enable customer data sharing between the stores in the backend?
Sorry for newbie answer, still learning magento
For those who may still show interests to this old entry, I share my solution. It is not a good one, indeed it is a hard-coded redirection to avoid going back to an uncertain URL, but it fixed the problem for me.
In the controller action where the redirection happens, modify
$this->_redirect(..., array(... => ...));
to
$this->_redirect(..., array(... => ..., '_store' => Mage::app()->getStore($storeId)));
This ensures that the redirection always goes to the specified store.
Reason is that Magento switchs context to store of order because it requires to translate the email template correctly.
Look at class Mage_Core_Model_Template there are two method _applyDesignConfig and _cancelDesignConfig. First function switches context and remember old context, second function should return all back. But, there is a bug. See more at: http://www.magthemes.com/magento-blog/magento-142-multiwebsite-admin-redirect-problem-quick-workaround/#comment-1084

Resources