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.
Related
So, I was recently reading through the require system of OpalRb, and came across the interesting require_table variable. Reading through the methods there, it's clear that require_table is used to see whether a file has already been loaded or not, for methods like require or loaded. But, I'm not sure how or where this variable gets stored. Wouldn't the opal/corelib/runtime.js file just get reloaded once the browser reloads the page, thus resetting require_table's value? I guess I'm just trying to better understand how require works with the dynamics of a browser.
The require table is defined here and yes, the runtime is reloaded when the browser is reloaded. That's normal as the whole HTML page starts from scratch reloading all of its assets and thus reloading Opal and its dependencies too.
It's impossible anyway to persist live objects through requests, the best you can do is to persist some data (e.g. with localStorage) but of course that has nothing to do with loaded libs and can at best be used to save requests (don't do that! or you would re-invent HTTP cache).
I built a translation system for fun which reads all trans()/Lang::get() calls in my app and presents them along with their current translations in the localisation files in resources/lang, so that an admin user can enter new translations which updates a single localisation file on the fly.
Everything works as intended, but there's one minor annoyance: every time the form is sent and the localisation file is updated, the page reloads (through a redirect()->route() call, not e.g. redirect()->back()), but most of the time, it still displays the old information even though the file has been updated properly.
If I refresh, the changes show up after 0.5-5 seconds, which makes me assume it's a cache issue. So the question is: can I trigger a language cache ignore while I'm in the translation system, or is there another and/or smarter way? I did try sleeping for a couple of seconds, but it made the user experience kind of crappy.
I've got the same issue.
I added in my controller sleep and info to extra refresh the page from js.
sleep(2);
return back()->with("refresh","yes");
and then in my view:
#if (session('refresh'))
<script>
location.reload(true);
</script>
#endif
I know it's a stupid solution but it works. If somebody know a better way to do it, write me a comment please.
So I have a framework we've built on codeigniter. It uses regular codeigniter sessions by default which allows up to 4kb storage encrypted on a cookie.
Its for general apps that require a registration process, which can vary in size as questions are generated dynamically through an admin panel. Registration process relies on session data as it redirects throughout process.
I have used db_sessions in the past when I knew this would be an issue on the framework, however, I'm now considering the possibility to always have registration process using db_session and the rest of the site use the 4kb cookie session.
Is this possible. It seems like it could be a really bad idea, but I don't really want to rework the dynamic registration process or really use db_session for whole site as it will eventually make the site run very slow if too many users are online at once.
so I'm think I can just set the variable in config to be true only when the registration controller is loaded(by checking the url via $_SERVER or the uri helper if I can load it in the config which I'm guessing I cant).
Does this seem plausible?
It seems like it could be a really bad idea
You answered your own question :) You'll have issues when the user switches from one page to another. What happens if they open multiple windows, press a 'back' button etc. You'll need to switch the cookie over when they start registration, and switch it back at the end. It will be very very messy for basically no gain.
but I don't really want to rework the dynamic registration process or
really use db_session for whole site as it will eventually make the
site run very slow if too many users are online at once.
The reality is; your website has to be huge to have ANY real performance issues by using a DB for your sessions. Any if you are not using the DB, then you are relying on the cookie stored on the users computer. Depending on your site, this means they might have the ability to edit that cookie and change "admin = true" or something.
Just use the DB session - I think you are overcomplicating the situation.
I am having issues with using the session component in cakephp.
They worked fine throughout the site, when on a dev site on a different server.
After uploading the final version on the new server, it seems that the session will not start in certain controllers. Only on two controllers is this happening, but nothing seems to be done differently on these controllers - except possibly the fact that only these two controllers are using a custom file uploader component. Have tried disabling this and nothing changed.
The website is an ecommerce system, with the problems mainly occuring when trying to add an item to the basket, which is stored in a session. this session is remaining blank, whereas on the dev site worked a charm.
I am also using the auth component to login/logout, and although these 2 areas are not required to be logged in to function, they cause it to switch to logged out whenever they are loaded - and this then switches back by itself when any other areas of the site are accessed. The auth and session components are loaded in the appcontroller.
Thanks!
I've had a similar problem before now, and for me I was under the same impression as #starlocke that something needed kick starting. Instead of using Cake's Session component I used the session_start() command, after checking that $_SESSION was not defined. For example:
if(!isset($_SESSION)) session_start();
This was placed inside the beforeFilter() method of the AppController class.
I then also had a problem where it was saying it couldn't start the session because of there already being output to the server, this was solved for me by deleting any closing ?> tags inside controllers, as these aren't required by php and stop any unneeded output being sent to the browser like in this case.
Further reading on php closing tags:
Why I don’t use closing PHP tags
PHP closing tag
My personal experiences have shown that CakePHP's sessions are independent of Apache+PHP sessions. With that in mind, it helps to take some action to always guarantee that a CakePHP Session (instead of the usual Apache+PHP session) is instantiated early in your website's workflow , for example, adding something like $this->Session->read('foo'); inside your site's AppController's beforeFilter(). It shouldn't matter what key you try to read, and 'foo' should be enough to start your CakePHP sessions.
I'm still pretty new to AJAX and javascript, but I'm getting there slowly.
I have a web-based application that relies heavily on mySQL and there are individual user accounts that are accessed and the UI is populated with user specific data.
I'm working on getting rid of a tabbed navigation bar that currently loads new pages because all that changes from page to page is information within one box.
The thing is that box needs to reload info from the database, etc.
I have had great help from users here showing that I need to call the database within the php page that ajax is calling.
OK-so pardon the lengthy intro-what I'm wondering is are there any specific limitations to what ajax can call that I need to know about? IE: someone mentioned that it's best not to call script files and that I should remove scripts from the php page that is being called and keep those in the 'parent' page. Any other things like this I need to keep in mind?
To clarify: I'm not looking to discuss the merits/drawbacks of the technology. I'm wondering about specific coding implementation that I need to be aware of (for example-I didn't until yesterday realize that if even if I had established a mySQL connection on the page, that I would need to re establish that connection in my called page as well...makes perfect sense now).
XMLHttpRequest which powers ajax has a number of limitations. I recommend brushing up on the same origin policy. This is a pivotal rule because it limits where AJAX calls can be made.
First, you can't have Javascript embedded in the HTTP response to an AJAX call. That's a security issue.
No mention of the dynamics of the database, but if the data to be displayed in tabs doesn't have to be real-time, why not cache it server-side?
I find that like any other protocol, Ajax works best in tightly controlled conditions. It wouldn't make much sense for updating nearly the whole page, unless you find that the user experience is improved with an on-page 'loader'. Without going into workarounds, disadvantages will include losing the browser back button / history, issues such as the one your friend mentioned, and also embedded resources and other rich content can suffer as well, and just having an extra layer of complexity to deal with in your app. Don't treat it as magic sauce for your app - make sure every use delivers specific results that benefit your client / audience.
IMHO, it's best to put your client side javascript in a separate page and then import it - neater container. one thing I've faced before is how to call xml back which contains code to run such as more javascript - it's worth checking if this is likely earlier on and avoiding, than having to look at evals.
Mildly interesting.