友達の招待・承認系の続きをつくる(CakePHP修行 #43)

SPONSORED LINK

Pocket

さてさてCakePHP修行。ちょっと間が開きましたがさぼっていたわけではありません。細かいところで苦戦していました。

では作業報告。淡々といきます。

■ 友達の招待(メール編)

友達を自分の友達にするには二通りあります。メールで直接招待する方法と、友達の友達をみていて「この人とつながりたいな」と思ったときです。

まずはメールでの招待からいってみましょう。画面の流れは前回の「SNSっぽい友達系の処理をつくりはじめてみる(CakePHP修行 #38)」で紹介しました。

ここからメールを受け取った人がとる処理を考えます。

えーと、いきなりコード。簡単そうに見えていろいろ面倒でした。

function invite() {
  // check login
  $this->_checkLogin();
  // sys message
  $this->set('sys_msg', $this->Session->read('sys_msg'));
  $this->Session->delete('sys_msg');
  // get "my info"
  $me = $this->User->findById_hash($_COOKIE['my_id']);
  $this->set('me', $me);
  $this->pageTitle = 'Invite a new friend';
  // from start
  $this->set('email_error', false);
  if (!empty($this->data)) {
    // error handling
    if (empty($this->data['User']['email'])) { 
      $this->set('email_error', true); 
      return false; 
    }
    // user exists?
    if ($this->User->findCount(aa('User.email',$this->data['User']['email']))) {
      // user exists!
      $pal = $this->User->findByEmail($this->data['User']['email']);
      if ($this->Friend->findCount(array('Friend.user_id'=>$me['User']['id'],'Friend.friend_user_id'=>$pal['User']['id']))) { 
        $this->set('email_error', true); 
        return false;
      }
      $this->data['Friend']['id'] = null;
      $this->data['Friend']['user_id'] = $me['User']['id'];
      $this->data['Friend']['friend_user_id'] = $pal['User']['id'];
      $this->data['Friend']['status'] = 0;
      $this->Friend->save($this->data);
      $inviteLink = WWW_URL.'friends'.DS.'accept'.DS.$this->Friend->getLastInsertID();
      $inviteMail = VIEWS.'mail/friends_accept.php';
    } else {
      // new user, add user and update hash
      $this->User->id = null;
      $this->User->save($this->data['User']);
      $new_id = $this->User->getLastInsertID();
      $new_user['User']['id'] = $new_id;
      $new_user['User']['id_hash'] = sha1(SHA1_KEY.$new_id);
      $this->User->save($new_user['User']);
      // add friend relationship
      $this->Friend->id = null;
      $this->data['Friend']['user_id'] = $me['User']['id'];
      $this->data['Friend']['friend_user_id'] = $new_id;
      $this->data['Friend']['status'] = 0;
      $this->Friend->save($this->data['Friend']);
      $inviteLink = WWW_URL.'users'.DS.'join'.DS.$this->Friend->getLastInsertID();
      $inviteMail = VIEWS.'mail/users_join.php';
    }
    // send invites
    $inviter = $me['User']['name'];
    $msg = implode (file($inviteMail));
    eval ("\$msg = \"$msg\";");
    $toName = $this->data['User']['email'];
    $subject = "[code*code] Invitation from ... ".$me['User']['name'];
    mb_send_mail ($toName, $subject, $msg, "From: ".ADMIN_EMAIL);
    // write msg, jump
    $this->Session->write('sys_msg', 'Invitaion mail has been sent.');
    $this->redirect('/friends/');
  }
}

面倒だったのは、今から招待しようとしている人のメールアドレスがすでに登録されているかどうか、また、すでに招待メールを送ったかどうかなどの判断をして場合分けしていくところ。

最初ぐちゃぐちゃとコードを書いていたのですが、わけがわからなくなったので、コーヒー飲んで気分をすっきりさせたあとにゼロから勢いで書きましたw。

なお、これで次のようなメールが送られます。まずは未登録の場合の招待メール。

Hello,
taguchi wants you!
click a link below to join in!

http://www.codexcode.com/users/join/6

次にすでに登録されている場合の招待メール。

Hello,
akiyan wants to join your network.
click a link below to accept him!

http://www.codexcode.com/friends/accept/8

IDもろだしでよくないのでは、という意見もありますが、それはそれ。面倒なのでこのままにしちゃいました。まぁ、良しとしましょう。

で、これを受け取った人は次のような画面に飛びます(未登録の場合。登録済みの場合は後述)。

join.gif

↑ ここで友達からのメッセージを見て登録します。

join_2.gif

↑ 無事登録できました!

■ 友達の友達を友達として登録する

さて次は友達の友達を見ていて「お、この人と友達になりたい!」と思った場合です。画面で処理の流れを見ていきましょう。

accept_1.gif

↑ まだ自分の友達でないユーザーをみるとこんな感じ。「Addしますか?」ときかれます。

accept_2.gif

↑ Addしたい場合はメッセージを入れられます。

accept_3.gif

↑ それを受け取ったほうはトップページでこのように「承認依頼が来ています!」と出ます。

accept_4.gif

↑ 承認するかどうか選べます。

さらりと書きましたが、なかなか大変でした。友達にAddする部分のコードはこちら。

function add($id) {
  // check login
  $this->_checkLogin();
  // sys message
  $this->set('sys_msg', $this->Session->read('sys_msg'));
  $this->Session->delete('sys_msg');
  // get "my info"
  $me = $this->User->findById_hash($_COOKIE['my_id']);
  $this->set('me', $me);
  $pal = $this->User->findById($id);
  $this->set('pal', $pal);
  $this->pageTitle = 'Add a new friend';
  // process form
  if (!empty($this->data)) {
    $f = $this->Friend->findCount(array('Friend.user_id'=>$me['User']['id'],'Friend.friend_user_id'=>$id)) ?  $this->Friend->find(array('Friend.user_id'=>$me['User']['id'],'Friend.friend_user_id'=>$id),'id') : false;
    $this->data['Friend']['id'] =  $f ?  $f['Friend']['id'] : null;
    $this->data['Friend']['user_id'] = $me['User']['id'];
    $this->data['Friend']['friend_user_id'] = $id;
    $this->data['Friend']['status'] = 0;
    if ($this->Friend->save($this->data)) {
      $this->Session->write('sys_msg', 'Invitaion mail has been sent.');
      $this->redirect('/friends/');
    }
  }
}

次のその友達をAccept(承認)する場合はこちら。

function accept($id) {
  // check login
  $this->_checkLogin();
  // sys message
  $this->set('sys_msg', $this->Session->read('sys_msg'));
  $this->Session->delete('sys_msg');
  // get "my info"
  $me = $this->User->findById_hash($_COOKIE['my_id']);
  $this->set('me', $me);
  $pal = $this->User->findById($this->Friend->field('user_id', "Friend.id=$id"));
  $this->set('pal', $pal);
  $this->pageTitle = 'Accept a new friend';
  // process form
  $this->set('memo', $this->Friend->field('memo', "Friend.id=$id"));
  $this->set('id', $id);
  // var_dump($this->params);
  if (!empty($this->params['form'])) {
    switch($this->params['form']['cmd']) {
      case 'yes':
        // accept
        $this->data['Friend']['id'] = $id;
        $this->data['Friend']['status'] = 1;
        $this->Friend->save($this->data);
        // link from me
        $this->data['Friend']['id'] = null;
        $this->data['Friend']['user_id'] = $me['User']['id'];
        $this->data['Friend']['friend_user_id'] = $pal['User']['id'];
        $this->data['Friend']['status'] = 1;
        $this->Friend->save($this->data);
        $this->Session->write('sys_msg', 'New member to your network!');
        $this->redirect('/friends/');
        break;
      case 'no':
        $this->Friend->del($id);
        $this->Session->write('sys_msg', 'Request declined!');
        $this->redirect('/users/home/');
        break;
      Default:
        break;
    }
  }
}

さすがにここらへんまでやるといろいろ慣れてきましたね。findやfield、findCountなどを使いこなせるようになってきました(かな?)。

さてこのままでもSNSっぽいとは思うのですがやはり日記のコメントぐらいは残したいもの。最後に日記コメント系の処理を作りこんでいきます。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

ツイッターもやっています!

SPONSORED LINK

  1. No comments yet.

  1. No trackbacks yet.