I observed that there are more than one session class in Magento, for example, Mage::getModel('core/session'), Mage::getModel('customer/session') and so on. When I want to use session as a storage, which session class should I choose? And Why? I'm just confused.
Magento's code is organized into modules. One of the purposes of a module is to provide namespaces. That is, modules allow one group of developers to write code without fear that their variables, objects, etc. will be accidentally stomped on by another group of developers.
Every module in Magento can have it's own session object. By giving each module it's own session object Magento helps developers avoid name conflicts in the PHP global session variable. For example, the following code
Mage::getModel('core/session')->setData('foo',$someValue);
Mage::getModel('customer/session')->setData('foo',$someOtherValue);
will save both values to the session, even though they have the same key.
As to which session class you should choose — if you're writing your own module you should create your own session class/model, thereby avoiding the above mentioned conflicts.
Practically speaking though, saving things on core/session shouldn't be a problem so long as you namespace your variables in some way.
Mage::getModel('core/session')->setData('my_namespace_foo',$someValue);
Related
I'm writing a Joomla plugin, which is basically just a wrapper around an application written in CakePHP (version 3.3; not in a good position to upgrade this at the current moment). I'm running into various issues with session data.
First problem is that Cake's Request object creates a Session object, which does not allow for the possibility that the PHP session might already have been started; it throws an error in this case. (I see no changes in this area of the code in Cake v3.6.)
My original solution to this was to have my plugin code close the Joomla session before starting up Cake, and let Cake do its own thing with its own cookie and session table. But by doing this I lose any changes that Joomla might make to its session after my code runs, which isn't ideal.
Next attempt was to hack the Session class slightly (proof of concept; a proper implementation to be made without any core changes if it works) to allow setting the _started member to true before starting the dispatcher. This works, in that Cake and Joomla data are now saved together in the Joomla session table.
However, Cake's session data includes Auth.User, the record of the user currently logged in. That record includes objects of type Cake\I18n\FrozenDate. On any page load after this has been written into the session, that class is not yet available (Cake's autoloader hasn't run) when Joomla loads the session. So those fields come in as __PHP_Incomplete_Class, which then breaks other things.
My current solution to this is to reload the entire session at this point (session_reset), first copying any uncommitted changes Joomla has made to $_SESSION, then restoring them after the reset.
In limited testing so far, this seems to be working. But I'm wondering whether I've missed some obvious problem, or obvious easier solution. Any comments, suggestions, or thought-provoking questions much appreciated. :-)
For example, is there some way for me to run Cake's autoloader before Joomla initializes the session, without hacking the Joomla core at all? That could be a simpler solution.
If this turns out well, I'll see what I can do to make the code available.
I am really confused about when to use Mage::registry() and Mage session.
Can any one suggest what is diff between both on them and when to use.
The Magento registry is not persisted, as in once you are on a new page you will not see those registry variables still set. I mainly use the registry to communicate between controllers and blocks.
The session will persist, but know that there are multiple namespaces for sessions in Magento, and they will be cleared at certain times, like the checkout/session being cleared after the order is placed. It's best practice to create your own namespace for your session to avoid any conflicts like duplicate variables or clearing it at the wrong time.
As always Alan Storm has some good things to read on this topic:
http://alanstorm.com/magento_registry_singleton_tutorial
How to use Session in Magento
Use Mage::registry() when you want to access variable in the SAME page request (e.g. passing variable from controller to template)
Use session when you want to access variables across DIFFERENT page requests (e.g. navigating from one page to another)
Mage::registry() implies creation of new global variables which can be accessed anywhere within your Magento store.
Being a static function, Magento registry can be called directly without the object being instantiated as in case of dynamic functions.
Magento registry can be called like ClassName::StaticFunctionName().
while Mage::getSingleton() is just like session in PHP.
I hope I could explain my point.
I just started with Joomla 3.x and I'm writing a component for Joomla v3 which is supposed to create new usergroups for creating 'groups'- the design requirements being:
An organisation may set up a group to offer access to some set of services -including communication but also also other types of services - to their members
(the other services is the reason why I believe the community and forum joomla extensions are not suitable- they mostly focus at fora and social media services, not the services I will implement.)
Other persons/members of the organisation may register to this group, which allow him/her to access these services
ps: it is also possible for person to set up a personal account and get access to the set of services. This person may also join one or more groups at a later stage
How to do code the creating of new usergroups? I noticed a possible suggested solution at How to create custom User Group Programmatically in Joomla 3.x, but I struggle to understand how to use the suggested JTableUsergroup class because of the limited documentation at http://docs.joomla.org/API17:JTableUsergroup(?) Does creating an instance of JTableUsergroup results in the creation of a new customer user group?
Another question: how to add users to a customer usergroup? The only hint I found was at http://api.joomla.org/cms-3/classes/JUserHelper.html - using the method addUserToGroup of class JUserHelper.
Many of the Joomla development concepts are well document but I could not find one for managing custom user groups...
Appreciate your help;-)
First, overall, the best consistent documentation of Joomla APIs is in the docblocks for the classes. Then to be honest what I do a lot of times is to search for where in the core the API is used. There are some great pieces of narrative documentation in the wiki, but on the whole I always start with the docblocks which are very complete. However in this case it's pretty simple.
You need to do something along the lines of
$newrow = JTable::getInstance('Usergroup');
//code to add your data
$newtable->save(); // Shortcut for check, bind, store
However, if I were you I would look carefully at UsersModelGroup because there are a lot of other things that should normally happen in this process such as running the user plugins. So I might include and extend that model (which manages the table class) rather than going to the table class directly. In fact your whole component might even be able to extend almost all of the users component or it might also be possible that you could do what you want with plugins rather than reinventing the whole thing.
In terms of assigning users to groups that is trickier because of some legacy things in the code. I think the setter followed by a $user->save() ($user being a JUser instance) is probably the way to go when adding to groups. What I probably would do is to write a custom JFormField that would manage opt-in groups because the core usergroup field includes everything. You could extend that and exclude the groups that you want to have only managed by admin.
As often happens, I have a nice solution to one problem, which unfortunately causes another.
We have an app that provides services to members of various organizations, parts of a larger parent. The organizations require custom URLs. So, members of org A access the URL https://server/vdir/OrgA, and members of org B access the URL https://server/vdir/OrgB.
Both of these would map to the exact same area, controller, and action in the app, although they might look different to the end user due to some custom view content.
Because the list of organizations using this app is dynamic, and because not all organizations will start using it at the same time, I started out setting up the route mapping programmatically. In the target Area, I override the RegisterArea method, pull the active organizations from the database, and execute a custom context.MapRoute call for each.
Doing it this way avoids another problem, which was that the the URLs that have the organization sitepath ("OrgA") in them look exactly like those that have a meaningful area name in them, which actually does map to an area. Treating the organization sitepaths as virtual area names and explicitly mapping them to the target Area avoided certain misdirections.
And this works, nicely. But: it's all executed at Application_Start. If we add an organization, it doesn't become active until we restart the app, which would be highly disruptive to anybody who was using it at that time.
So my questions are two:
Is there a better approach than mine for doing this? I did research the problem, but the relevant keywords are so ubiquitous that it was a bit of a needle-and-haystack situation.
If there isn't one, is there a way to refresh the route mappings without restarting the app?
Phil Haack wrote an article dealing with exactly this problem.
The really, really short version of which is that you place your route registrations in a file other than Global.asax and cache the contents of that file. The cache has the file as a dependency and calls a method when the cache is invalidated (read: file is altered) that re-registers your routes.
I've started a CI project and I'm going to use it with Doctrine, there is benchmarking system for the latter and I'd like to remove the ability to use native CodeIgniter DB class, since it won't be benchmarked. I though about simply removing the corresponding files, but I'm afraid it could cause CI errors in other places. How can I remove the ability to use native CI DB class?
I personally would not do it. I just want to force the future developers with random level of qualification not to load it as well
I also use Doctrine in connection with CodeIgniter and there is no need to do anything with the CI DB class. Just ignore it and use Doctrine as you would do normally. If you don't use the DB classes or don't load it, they won't get benchmarked.
If you haven't already found it, look at the wiki, ot gives a good idea what to do with Doctrine
edit to your 1st comment: If you really want to disable the DB class, I see one way: either delete the core file(s)/folder(s) or rename it so that a loading just fails. Alternatively, change their code so they cannot be loaded. If you do so, it should be really well documented somewhere so that the error will be obvious to someone after you.
Don't load it in your controller.
Theoretically, you could create a hook and disable CI's DB functionality. In the hook, you would extend the CI_DB class and the display an error message if the class gets loaded. I'm sorry I can't give specifics, but you'd probably have to inspect the system's database classes to see what would need to be altered.
At least that way, you wouldn't need to make changes to the CI core.