Jump to content

Hooking before session init


Pete
 Share

Recommended Posts

Hi folks

I need to grab some data from a separate script before PW's session kicks in to avoid sessions wiping each other out in the wrong order.

I see you can hook before session::init, and in the PW wire/core/Session.php class there's a $data array it looks like you can populate around line 267

@session_start();

if(!empty($this->data)) {
   foreach($this->data as $key => $value) $this->set($key, $value);
}

but I can't for the life of me work out how to populate that data array so that something like $data = array('test' => 'this is a test') gets passed to the session as $session->test

Anyone got any ideas?

I think I'm looking along the right lines on this one - hook before session::init, do the dirty bit of getting data from the other script, store it in the $data array and let PW's session wipe out the other one. Otherwise the other script wipes out PW's session instead and whilst PW can still remember lots of stuff like what page it's on, the loss of PW's session causes problems when dealing with currently-logged-in user etc.

Because of these conflicting sessions between two separate scripts that I can't work around any other way, my only other option is to call file_get_contents on a local url which totally works but seems wasteful if I can do something like what I'm trying to above instead.

Any help would be greatly appreciated!

 

Link to comment
Share on other sites

26 minutes ago, Pete said:

but I can't for the life of me work out how to populate that data array

I don't think you can at that point. I'd just hook both before and after init, store the external data in a variable/property somewhere in the before hook, retrieve that data in the after hook and assign it using the regular Session::set method.

Link to comment
Share on other sites

I've got my dunce hat on today - how would I put something in a variable before init that I could then access after init? It's been a long time since I did anything like that but it sounds like a good option ?

Maybe if wire() is available before I could to wire()->test = 'something' and access that later? I just can't envision the code in my head to write it.

Link to comment
Share on other sites

This probably needs to happen inside an autoload module's constructor as module init / init.php is likely too late. Wire() is already available at that time. Here's a little PoC snippet:

	public function __construct() {
		$this->addHookBefore("Session::init", function(HookEvent $event) {
			// fill the data backpack with whatever you extract from the
			// external session:
			$this->wire('dataBackpack', ["some" => "thing"]);
		});

		$this->addHookAfter("Session::init", function(HookEvent $event) {
			foreach($this->wire('dataBackpack') as $k => $v) {
				// set the retrieved data as session properties:
				$event->object->set($k, $v);
			}
		});
	}

 

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

Thanks, this seems to work great!

Now if only I could get FileCompiler to stop compiling the externally-included application files I'd be onto a winner (wasn't expecting it to go crazy and it breaks on a crucial file!). Seems the only way to stop that is to add

// FileCompiler=0

to the top of the relevant external script page, but that isn't upgrade-proof for the external script. It would be great if there was a way to tell file compiler to leave that whole directory alone.

Link to comment
Share on other sites

I actually thought I was onto a winner with this little gem:

$this->wire('files')->compileInclude(wire('config')->paths->root . 'talk/init.php', [false, false, false, true]);

See notes here: https://processwire.com/api/ref/wirefiletools/compile-include/

I thought that would work as the included file DOES have a namespace at the top, though not a PW one, and the last option should have skipped it ?

Just now, kongondo said:

Not sure if this helps?

https://processwire.com/api/ref/wirefiletools/compile/

In $options, see skipIfNamespace

You beat me to it by seconds, but alas it doesn't seem to be doing the job.

Link to comment
Share on other sites

5 minutes ago, kongondo said:

And this?

 

Thanks, changing it to this worked:

$this->wire('files')->compileInclude(wire('config')->paths->root . 'talk/init.php', array('includes'=>true,'namespace'=>true,'modules'=>true,'skipIfNamespace'=>true));

I guess it was a different combination of options else it wanted them to be named (likely the latter now I look at it more closely).

Got there in the end - thanks guys!

P.S. you've just both helped me do a better forum member integration for the new PW website by the way ? Making two very different scripts play nice was NOT easy!

  • Like 5
Link to comment
Share on other sites

Oooh, follow-up question - how would I go about accessing a variable stored in PW's session at this stage:

$this->addHookBefore("Session::init", function(HookEvent $event) {

I'm guessing there's a way to temporarily get the session data at that point maybe?

Just thought of a scenario where I'd need to grab a variable from PW's session and check it before running the external script (so I don't always need to keep running the script if I already have the data in the PW session - seems wasteful to load a bunch of external classes every time).

Link to comment
Share on other sites

26 minutes ago, Pete said:

I'm guessing there's a way to temporarily get the session data at that point maybe?

Not really, unfortunately. At that point you can assemble the session name, but to retrieve the data associated with it, you have to invoke session_start.

  • Like 1
Link to comment
Share on other sites

It might actually be useful to do session_start actually since it doesn't matter that the forum software then wipes it out as it'll get wiped out in turn by PW's session again later on.

I shall have a play.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...