CakePHP - saving one session variable deletes another

I use the session variables in CakePHP to store my Twitter and Facebook user data, when the user logs in, if he linked his Twitter and FB accounts, this information is stored in the session variable next to my own user data.

I have a screen on which a user can connect and disconnect specified data of a social network, the problem is as follows:

Say I have both networks, I decided to disconnect from Facebook, the session variable for Facebook was deleted. Now I want to connect to Facebook, I click the Connect button, the Facebook data is saved, but for some reason it removes the Twitter variable.

How my process works:

1) The user presses the connect button. 2) The user is redirected to the social network system. 3) The user accesses a function that takes the required data, saves it in a session variable called NetworkData, and goes back to the page where he clicked the button. 4) NetworkData is retrieved, installed as the corresponding social network (Facebook or Twitter) in the session and removed from the session.

The code is as follows:

This is the function that the user redirects after entering Twitter or FB:

function retrieve_network($page) { $networkData = null; $this->autoRender = false; $this->layout = 'ajax'; if(isset($_GET['oauth_token'])) { $token = $this->TwitterHelper->setOAuthToken($_GET['oauth_token']); $userinfo = $this->TwitterHelper->getTwitterUserInfo(); $networkData = array( 'TwitterData' => array( 'username' => $userinfo['username'], 'name' => $userinfo['name'], 'token' => $token->oauth_token, 'token_secret' => $token->oauth_token_secret ) ); } else if (isset($_GET['code'])) { $token = $this->FacebookHelper->facebook->getAccessToken(); $userinfo = $this->FacebookHelper->getUserInfo(); $networkData = array( 'FacebookData' => array( 'username' => $userinfo['username'], 'name' => $userinfo['name'], 'email' => $userinfo['email'], 'token' => $token, 'link' => $userinfo['link'], ) ); } $this->Session->write('NetworkData', $networkData); if($page == 'settings') { $this->redirect(array('controller' => 'fonykers', 'action' => 'settings/networks')); } } 

This is a function that retrieves data in network data and sets it into a session:

 function settings($tab) { $this->layout = 'frontend'; $this->Fonyker->recursive = -1; $this->TwitterData->recursive = -1; $this->FacebookData->recursive = -1; if(!$this->checkSessionCookie()) { $this->redirect(array('controller' => 'pages', 'action' => 'home')); } $fields = array( 'Fonyker.id', 'Fonyker.username', 'Fonyker.name', 'Fonyker.email', 'Fonyker.gender', 'Fonyker.birthdate', 'Fonyker.image_url' ); $fonyker = $this->Fonyker->find('first', array( 'conditions' => array( 'Fonyker.fonykid' => $this->Session->read('Fonyker.Fonyker.fonykid') ), 'fields' => $fields )); $this->Fonyker->set($fonyker); $this->data = $fonyker; if($this->Session->read('NetworkData')) { $networkData = $this->Session->read('NetworkData'); $this->Session->delete('NetworkData'); if($networkData['TwitterData']) { $networkData['TwitterData']['fonyker_id'] = $fonyker['Fonyker']['id']; if($this->TwitterData->save($networkData)) { $this->Session->write('TwitterData', $networkData['TwitterData']); } } else if($networkData['FacebookData']) { $networkData['FacebookData']['fonyker_id'] = $fonyker['Fonyker']['id']; if($this->FacebookData->save($networkData)) { $this->Session->write('FacebookData', $networkData['FacebookData']); } } } pr($this->Session->read()); if(!$this->Session->read('TwitterData')) { $this->TwitterHelper->setTwitterObj(); $this->set('twitterUrl', $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings'))); } else { $this->set('twitterUrl', '#'); } if(!$this->Session->read('FacebookData')) { $this->set('facebookUrl', $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access'))); } else { $this->set('facebookUrl', '#'); } $this->set('tab', $tab); } 

This is a function that deletes the network if the user wishes:

 function remove_network($network) { $this->autoRender = false; $this->Fonyker->recursive = -1; $this->TwitterData->recursive = -1; $this->FacebookData->recursive = -1; $response = null; if($network == 'twitter') { $twitterData = $this->TwitterData->find('first', array( 'conditions' => array( 'TwitterData.fonyker_id' => $this->Session->read('TwitterData.fonyker_id') ) )); if($this->TwitterData->delete($twitterData['TwitterData']['id'], false)) { $this->TwitterHelper->setTwitterObj(); $twitterUrl = $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings')); $this->Session->delete('TwitterData'); $response = json_encode(array('ok' => true, 'url' => $twitterUrl)); } else { $response = json_encode(array('ok' => false)); } } if($network == 'facebook') { $facebookData = $this->FacebookData->find('first', array( 'conditions' => array( 'FacebookData.fonyker_id' => $this->Session->read('FacebookData.fonyker_id') ) )); if($this->FacebookData->delete($facebookData['FacebookData']['id'], false)) { $facebookUrl = $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access')); $this->Session->delete('FacebookData'); $response = json_encode(array('ok' => true, 'url' => $facebookUrl)); } else { $response = json_encode(array('ok' => false)); } } echo $response; } 

View code:

 <script type="text/javascript"> $(document).ready(function() { var splitUrl = window.location.href.split('/'); $('#' + splitUrl[splitUrl.length - 1] + '-tab').addClass('active-tab'); $('#' + splitUrl[splitUrl.length - 1] + '-tab').children().addClass('active-tab'); }); </script> <div class="prepend-1 prepend-top span-23"> <div class="tabs span-22"> <ul> <li id="account-tab"> <a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/account"> Account </a> </li> <li id="password-tab"> <a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/password"> Password </a> </li> <li id="notifications-tab"> <a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/notifications"> Notifications </a> </li> <li id="networks-tab"> <a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/networks"> Social Networks </a> </li> </ul> </div> <div class="tab-content prepend-top prepend-1"> <?php if($tab == 'account') { echo $this->element('settings/account'); } else if ($tab == 'password') { echo $this->element('settings/password'); } else if ($tab == 'notifications') { echo $this->element('settings/notifications'); } else { echo $this->element('settings/networks'); } ?> </div> </div> 

Item Code:

 <script type="text/javascript"> $(document).ready(function(){ var deleteNetwork = function(network, button) { $.ajax({ url: '<?php echo $html->url('/fonykers/remove_network/', true); ?>' + network, dataType: 'json', type: 'POST', success: function(response) { if(response.ok) { button.replaceWith('<a id="'+network+'-connect" class="connect-button connect" href="'+response.url+'" class="span-3">Connect</a>'); } } }); } if($('#twitter-connect').attr('href') == '#'){ $('#twitter-connect').addClass('connected'); $('#twitter-connect').html('Connected'); } else { $('#twitter-connect').addClass('connect'); $('#twitter-connect').html('Connect'); } if($('#facebook-connect').attr('href') == '#'){ $('#facebook-connect').addClass('connected'); $('#facebook-connect').html('Connected'); } else { $('#facebook-connect').addClass('connect'); $('#facebook-connect').html('Connect'); } $('.connected').hover( function() { $(this).removeClass('connected'); $(this).addClass('disconnect'); $(this).html('Disconnect') }, function() { $(this).removeClass('disconnect'); $(this).addClass('connected'); $(this).html('Connected') } ); $('#twitter-connect').click(function(event) { if($(this).attr('href') == '#') { event.preventDefault(); deleteNetwork('twitter', $(this)); } }); $('#facebook-connect').click(function(event) { if($(this).attr('href') == '#') { event.preventDefault(); deleteNetwork('facebook', $(this)); } }); }); </script> <div class="span-4 prepend-top"> <div class="span-4"> <div class="span-1"> <?php echo $html->image('twitter-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?> </div> <div class="span-3 last"> <a id="twitter-connect" class="connect-button" href="<?php echo $twitterUrl; ?>" class="span-3"></a> </div> </div> <div class="span-4 prepend-top"> <div class="span-1"> <?php echo $html->image('facebook-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?> </div> <div class="span-3 last"> <a id="facebook-connect" class="connect-button" href="<?php echo $facebookUrl; ?>"></a> </div> </div> </div> 

Sorry for the long post.

+4
source share
2 answers

In your retrieve_network action, which I assume you call when the user reconnects to a specific service, you overwrite the NetworkData session variable if you find that 1 specific service has been connected to:

 if(isset($_GET['oauth_token'])) {...} 

OR

 if(isset($_GET['code'])) {...} 

You set $ networkData for the returned services object and then overwrite the entire session with:

 $this->Session->write('NetworkData', $networkData); 

Following your code, I always checked to see if the existing service will be in the session at the moment, and if this will not overwrite the entire session, just add specific data to the existing NetworkData session array:

 if($this->Session->read('NetworkData.TwitterData')){ $facebookData = array( 'username' => $userinfo['username'], 'name' => $userinfo['name'], 'email' => $userinfo['email'], 'token' => $token, 'link' => $userinfo['link'], ); $this->Session->write('NetworkData.FacebookData', $facebookData); } 

Note. This is just an example showing how you can achieve this. I would reorganize this method with better logic for this particular situation, possibly storing TwitterTata and FacebookData in my own arrays, as opposed to the more complex NetworkData array. Alternatively, you can access the $ _GET parameters through $ this-> params ['url'] ['paramname'] to support the cakePHP convention.

+4
source

I think the problem is that you are replacing network data, and not by combining it.

This means that when you log in using FB, you replace any twitter data with FB, rather than saving both of them.

I hope instead

 $this->Session->write('NetworkData', $networkData); 

what

 $this->Session->write('NetworkData', array_merge($networkData, $this->Session->read('NetworkData')); 

can work.

Otherwise, it seems to me that the session deleting the code should not interact in order to delete the other. However, I might have missed something in this matter. I would do echo () ing / debugging to follow the code execution paths.

0
source

Source: https://habr.com/ru/post/1369204/


All Articles