2011-08-26 78 views
4

我在CakePHP中使用会话变量来存储我的相关用户Twitter和Facebook数据,当用户登录时,如果他已经链接了他的Twitter和FB帐户,这些信息保存在会话中我自己的用户数据旁边的变量。CakePHP - 保存一个会话变量删除另一个

我有一个屏幕,用户可以链接和取消链接所述社交网络数据,问题是:

比方说,我有两个网络连接,我决定从Facebook,为Facebook会话变量断开被删除。现在我想重新连接到Facebook,我点击连接按钮,Facebook数据被保存,但由于某种原因它删除了Twitter变量。

我的过程中的工作方式如下:在连接按钮

1)用户点击。 2)用户被引导到社交网络身份验证。 3)用户被引导到一个函数,该函数获取所需的数据,并将其保存在一个名为NetworkData的会话变量中,并被导回到单击该按钮的页面。 4)NetworkData被提取,设置为会话中相应的社交网络(Facebook或Twitter)并从会话中删除。

代码如下:

这是用户在登录后直接到Twitter或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')); 
     } 
    } 

这是检索什么是网络数据,并将其设置的功能到会话:

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); 
    } 

这是如果用户希望,消除了网络功能:

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; 
} 

查看代码:

<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> 

元素代码:

<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> 

很抱歉的长期职位。

回答

4

在你retrieve_network行动,这我假设当用户重新连接到特定服务称呼你,你要覆盖NetworkData会话变量 如果你发现1个特别服务已连接到:

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

OR

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

您可以设置$ networkData到返回的服务对象,然后通过覆盖整个过程:

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

按照你的代码,我会经常检查,看是否存在服务是目前正在开会,如果是不覆盖整个会话,只是具体的数据添加到现有的NetworkData session数组:

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); 
} 

注意:这只是一个示例,显示如何实现此目的。我会用这个更好的逻辑对这种特殊情况进行重构,也许将TwitterData和FacebookData存储在它们自己的独立数组中,而不是一个更大更复杂的NetworkData数组。此外,您可以通过$ this-> params ['url'] ['paramname']访问$ _GET params来维护cakePHP约定。

+1

这是问题的一部分,如果您检查我的设置方法,在用户从我的检索网络重定向后,它会检查添加的网络,删除NetworkData并添加必要的网络,无论是TwitterData还是FacebookData,因此它不会重要的是如果NetworkData被覆盖,因为它不是从那里开始的,它在提取必要的信息之后被删除。现在,编写任何会话变量会覆盖整个会话?因为我的其他会话变量保持不变 – 8vius

+0

在设置()方法之前,当前存在的NetworkData会话将在retrieve_network()方法中被覆盖。您的retrieve_network动作仅考虑Twitter或Facebook,而不是在当前会话期间,因此如果在NetworkData会话中设置了TwitterData,然后Facebook尝试连接或重新连接,则整个NetworkData会话仅被Facebook数据覆盖。当你通过$ this-> Session-> write('name',$ var)设置会话时,就像做$ _SESSION ['name'] = $ var一样。使用write()不会附加到现有会话。 – Anthony

+0

这就是安东尼应该发生的事情,点击连接到Twitter或Facebook按钮后,我的回调URL指向retrieve_network(),然后在那里提取NetworkData并重定向到设置。 现在,我该如何追加与Cake的会话?奇怪的是,当我写我的其他会话变量不会被删除。同样,当用户登录时,我会提取他的FB和Twitter数据,并将它们分开写入,并在回应会话时并排存在。 – 8vius

0

我认为问题在于您正在替换网络数据,而不是合并它。

这意味着当你用FB登录时,你用FB替换任何twitter数据,而不是同时保留它们。

我希望的也许不是

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

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

可能会奏效。

否则,在我看来,会话删除代码不应该交互删除另一个。尽管我可能漏掉了一些东西。我会做一些echo()ing /调试以遵循代码执行路径。

+0

再次这不是问题,如果你检查我的设置方法,你会看到在设置TwitterData或FacebookData之后NetworkData被删除 – 8vius

+1

@ 8vius你坚持认为你的代码没有问题,但是还是有问题。你能否展示你的相关视图代码?试试我的解决方案,看看有什么不同。 – Ivo

+0

我并不坚持我的代码没有问题@Ivo,我只是说在发布之前人们似乎没有彻底阅读代码,因为我相当清楚我的NetworkData会话变量从会话中被删除在完成其功能后,我会用我的视图代码更新我的问题 – 8vius