Magento redirected to other URL after order editting - magento

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

Related

Direct user on certain page after purchased plan use velo code

How to direct user on certain page after successful payment on membership plan using velo code ? cause on wix the users was direct into thank you page
When you use pricing-plans you have one editable page but in fact you have three page.
First one is where you list your plans. /pricing-plans/ Second one is
where the payment made. /pricing-plans/payment/ Last one is where the
thank you page is. /pricing-plans/status/
What you need to do is use wix-location and when URL changes to /pricing-plans/status/ send user to another URL.
Here is an example code inside pricing-plans page in editor.
import wixLocation from 'wix-location';
$w.onReady(() => {
wixLocation.onChange((location) => {
if (wixLocation.url.includes("/pricing-plans/status/")) {
wixLocation.to("redirectedUrl");
}
});
})
pricing-plans can be different for your site it's the URL that you choose and you can change so check that before.

Magento store view redirects not working in 1.8.0.0

I have a store I'm developing that has two store views, one for each language I'm supporting. The products and categories have localized url keys.
In 1.7.0.2 my language switcher would redirect correctly (for ones that had "Create Permanent Redirect" as well as ones with out) but after upgrading to 1.8.0.0, it did not work any more.
Problem
There is a regression in 1.8.0.0, they updated Mage_Core_Controller_Varien_Front to use ::_getRequestRewriteController() in ::dispatch() previously it used Mage_Core_Model_Url_Rewrite and now it uses Mage_Core_Model_Url_Rewrite_Request
On line 143 of app/code/core/Mage/Core/Model/Url/Rewrite/Request.php it has $stores = $this->_app->getStores(); which returns an array of store_id index stores, but it goes on to check if the store it goes on to check with $fromStore, which is a variable from the GET params, ___from_store, which contains the store views key (e.g. default, french, etc), obviously this has problems looking up using a alpha key in a numericly index array.
Solution
The offending line is again, #143 in app/code/core/Mage/Core/Model/Url/Rewrite/Request.php, by simpling changing it to $stores = $this->_app->getStores(false, true) it will work, as the 2nd parameter being true (defaults to false) returns the array with store view codes as the array key.
Hope this helps someone, and if anyone knows the best way to pass this on to the Magento developers, I would appreciate it, as I said, the issue reporting just posted to the home page, which doesn't seem to work.
Edit: I would also like to point out as 1.8.1.0 this is still an issue.

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

MVC Putting an action in the most appropriate correct controller

I was just wondering what the best practice approach is for deciding where to create an action/view in certain situations.
If User hasMany Video
where is the best place to create the action/view to show user videos?
So within the Users account page 'My Videos' link do you
just create a users/my_videos action and view.
create videos/my_videos action and view.
or as is most likely you would already have a Controller/Action of videos/index which would have search functionality. Simply use this passing in a user id.
Any thoughts/advice greatly appreciated
Thanks
Leo
One potential option is to do the following:
Since the videos likely have much more code around them than a simple which user has which videos lookup the video list action should be in the VideosController.
In past projects I have (in CakePHP 1.3) used prefix routing to address some of this.
In config/core.php make sure you enable routing.prefixes to include a 'user' prefix.
<?php
... in routes.php ...
Routing.prefixes = array( 'user' );
?>
In the videos controller make an action with the following signature:
<?php
...
public function user_index( $userID = null ){
...
}
?>
and in the views where you link to the list of users videos the html::link call should look similar to the following:
<?php
...
echo $this->Html->link( 'User\'s Videos', array(
'controller' => 'videos',
'action' => 'index',
'prefix' => 'user',
$this->Session->read( 'Auth.User.id' )
));
?>
Of course this assumes you are using the Auth component here to track the logged in user. The Session helper code to read the authenticated user id might need tweaking.
This lets you a) Not worry too much about routing aside from enabling prefix routing and b) will quickly let you have pretty links like so -- site.com/user/videos/index/419
Couple this with some Slug love ( this is the best link for this I have seen - no slug field required on the db layer - http://42pixels.com/blog/slugs-ugly-bugs-pretty-urls )
You could even end up with urls like so quite easily: site.com/user/videos/index/eben-roux
and with just a tiny bit of editing to app/config/routes.php you could eliminate the /index/ portion and the results would be SEO friendly and user friendly in the format:
site.com/user/videos/eben-roux
http://book.cakephp.org/view/945/Routes-Configuration
As always with code you have the two extremes of:
1) Putting everything in a single controller
2) Having every action in a separate controller
The ideal approach will nearly always be somewhere between the two so how to decide what is grouped together and what is separated?
In MVC I tend to look at the Views and see what the commonalities are: as you point out Users have a ref to a collection of Videos in the Model, but would you want both sets of Data in any single View? i.e. In this example is it likely that you would be on a page that both managed user details, and displayed the list of vids? If not then I'd suggest separate controllers.
If either controller would then be extremely simple - e.g. one method, then may be worth considering merging the two.
I like to keeps things separate.
What I'd do is an index action in videos controller, passing user's id as argument and then displaying only current users video.
public function index($id = null){
$this->paginate = array( 'conditions'=> array('Video.user_id' => $id));
$this->set('videos', $this->paginate());
}
My take is that it depends on the responsibility you assign to the controllers.
I would say that something like a User or a Video controller should be concerned with only those entities.
You may want to consider something like a UserDashboard (or something similar but appropriately named) as alluded to by Dunhamzzz in the comments. This can aggegate all the functionality from an "entry" point-of-view. The same way a banner / shortcut / action menu would work.
Your UserDashboard would use whatever data layer / repository is required to get the relevant data (such as the IVideoRepository or IVideoQuery implementation).
Usually when something doesn't feel right it isn't. Try splitting it out and see how it works. You can alsways re-arrange / refactor again later.
Just a thought.
I don't think there's a 'one-rule-fits-all' solution to this question, but I would try to take an approach in which you would determine what the main object is that you're dealing with, and adding the action/view to that object's controller.
In your example I'd say that your main object is a video and that the action you're requiring is a list of video's filtered by a specific property (in this case the user's id, but this could very well be a category, a location, etc.).
One thing I would not do is let your desired URL determine in which controller you put your functionality. URLs are trivially changed with routes.

CakePHP, organize site structure around groups

So, I'm not quite sure how I should structure this in CakePHP to work correctly in the proper MVC form.
Let's, for argument sake, say I have the following data structure which are related in various ways:
Team
Task
Equipment
This is generally how sites are and is quite easy to structure and make in Cake. For example, I would have the a model, controller and view for each item set.
My problem (and I'm sure countless others have had it and already solved it) is that I have a level above the item sets. So, for example:
Department
Team
Task
Equipment
Department
Team
Task
Equipment
Department
Team
Task
Equipment
In my site, I need the ability for someone to view the site at an individual group level as well as move to view it all together (ie, ignore the groups).
So, I have models, views and controls for Depart, Team, Task and Equipment.
How do I structure my site so that from the Department view, someone can select a Department then move around the site to the different views for Team/Task/Equipment showing only those that belong to that particular Department.
In this same format, is there a way to also move around ignoring the department associations?
Hopefully the following example URLs clarifies anything that was unclear:
// View items while disregarding which group-set record they belong to
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
http://www.example.com/Departments
// View items as if only those associated with the selected group-set record exist
http://www.example.com/Department/HR/Team/action/id
http://www.example.com/Department/HR/Task/action/id
http://www.example.com/Department/HR/Equipment/action/id
Can I get the controllers to function in this manner? Is there someone to read so I can figure this out?
Thanks to those that read all this :)
I think I know what you're trying to do. Correct me if I'm wrong:
I built a project manager for myself in which I wanted the URLs to be more logical, so instead of using something like
http://domain.com/project/milestones/add/MyProjectName I could use
http://domain.com/project/MyProjectName/milestones/add
I added a custom route to the end (!important) of my routes so that it catches anything that's not already a route and treats it as a "variable route".
Router::connect('/project/:project/:controller/:action/*', array(), array('project' => '[a-zA-Z0-9\-]+'));
Whatever route you put means that you can't already (or ever) have a controller by that name, for that reason I consider it a good practice to use a singular word instead of a plural. (I have a Projects Controller, so I use "project" to avoid conflicting with it.)
Now, to access the :project parameter anywhere in my app, I use this function in my AppController:
function __currentProject(){
// Finding the current Project's Info
if(isset($this->params['project'])){
App::import('Model', 'Project');
$projectNames = new Project;
$projectNames->contain();
$projectInfo = $projectNames->find('first', array('conditions' => array('Project.slug' => $this->params['project'])));
$project_id = $projectInfo['Project']['id'];
$this->set('project_name_for_layout', $projectInfo['Project']['name']);
return $project_id;
}
}
And I utilize it in my other controllers:
function overview(){
$this->layout = 'project';
// Getting currentProject id from App Controller
$project_id = parent::__currentProject();
// Finding out what time it is and performing queries based on time.
$nowStamp = time();
$nowDate = date('Y-m-d H:i:s' , $nowStamp);
$twoWeeksFromNow = $nowDate + 1209600;
$lateMilestones = $this->Project->Milestone->find('all', array('conditions'=>array('Milestone.project_id' => $project_id, 'Milestone.complete'=> 0, 'Milestone.duedate <'=> $nowDate)));
$this->set(compact('lateMilestones'));
$currentProject = $this->Project->find('all', array('conditions'=>array('Project.slug' => $this->params['project'])));
$this->set(compact('currentProject'));
}
For your project you can try using a route like this at the end of your routes.php file:
Router::connect('/:groupname/:controller/:action/*', array(), array('groupname' => '[a-zA-Z0-9\-]+'));
// Notice I removed "/project" from the beginning. If you put the :groupname first, as I've done in the last example, then you only have one option for these custom url routes.
Then modify the other code to your needs.
If this is a public site, you may want to consider using named variables. This will allow you to define the group on the URL still, but without additional functionality requirements.
http://example.com/team/group:hr
http://example.com/team/action/group:hr/other:var
It may require custom routes too... but it should do the job.
http://book.cakephp.org/view/541/Named-parameters
http://book.cakephp.org/view/542/Defining-Routes
SESSIONS
Since web is stateless, you will need to use sessions (or cookies). The question you will need to ask yourself is how to reflect the selection (or not) of a specific department. It could be as simple as putting a drop down selection in the upper right that reflects ALL, HR, Sales, etc. When the drop down changes, it will set (or clear) the Group session variable.
As for the functionality in the controllers, you just check for the Session. If it is there, you limit the data by the select group. So you would use the same URLs, but the controller or model would manage how the data gets displayed.
// for all functionality use:
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
You don't change the URL to accommodate for the functionality. That would be like using a different URL for every USER wanting to see their ADDRESS, PHONE NUMBER, or BILLING INFO. Where USER would be the group and ADDRESS, PHONE NUMBER< and BILLING INFO would be the item sets.
WITHOUT SESSIONS
The other option would be to put the Group filter on each page. So for example on Team/index view you would have a group drop down to filter the data. It would accomplish the same thing without having to set and clear session variables.
The conclusion is and the key thing to remember is that the functionality does not change nor does the URLs. The only thing that changes is that you will be working with filtered data sets.
Does that make sense?

Resources