Jao's Blog

プログラミング備忘録

マイページ機能を作成する #13

 さて、ユーザーに関連する項目を確認及び編集ができる機能(通称マイページ機能)を追加していきましょう。

f:id:Kyokuya_jao:20200623213240p:plain
 当初の設計では、この画面で編集したい項目をクリックすれば、そのまま編集モードに切り替わる想定でした。手間を考慮し、編集画面を別ページに用意することとします。

マイページを作成する

 日記をつけた日数などの計算は後で行うものとします。とりあえず、ユーザー名やララからの呼び方などの項目をデータベースから取り出し、表示します。

f:id:Kyokuya_jao:20200623213354p:plain
 右上の編集ボタンを押すと、編集画面に移行します。テキストボックスのvalue要素に、引っ張ってきたデータを取り入れます。日記編集と同じようなシステムです。
 ちなみに「ララの一人称」は思い付きで追加した機能です。文字通り、私でも僕でもオレでも、好きな一人称で喋ってくれます。
 アイコン画像の変更は、ドットインストールのレッスンを踏襲しています。「アップロードした画像は必ず200×200にリサイズされる」「その前に使っていた画像は削除される」という機能を独自に追加しました。あとは画像のファイル名をデータベースに格納し、マイページで他の情報と共に表示させればOKです。

日記の記録を計算する

 「日記をつけた日数」「現在連続記録日数」「最大連続記録日数」の三項目を計算し、データベースに格納する処理を作成しましょう。  処理が発生するタイミングは、日記を更新したタイミングがベストだと思われます。日記更新処理の最後に、これらの処理を割り込ませることにしましょう。

    // 日記の日付のみを全て取り出す
    $tempDiaryDates = $myDiary->getDiaryDates($id);
    // 最大日記記録数を取得
    $highScore = $users->getHighScore($id);

    // 日記を一日もつけてない場合は処理をスキップ
    if($tempDiaryDates){
      // 日記の総日数を格納
      $countDiary = count($tempDiaryDates);
      // 日付の後ろについている曜日を切り取る
      $diaryDates = $this->_validatediaryDates($tempDiaryDates);
      // 日付が連続かどうかを判定する
      $keepDays = $this->_checkContinuity($diaryDates);
      // 連続日記が最大連続日数を超えた場合更新
      if($keepDays > $highScore){
        $highScore = $keepDays;
      }
      // 諸々をデータベースに登録
      $users->updateDiaryData([
        'NoteDays' => $countDiary,
        'KeepNoteDays' => $keepDays,
        'HighScoreNoteDays' => $highScore,
        'id' => $id
      ]);
    }else{
      $keepDays = 0;
    }

    // return $countDiary;
  }
  private function _validatediaryDates($values){
    $res = [];
    foreach($values as $value){
      $res[] = substr($value , 0, 10);
    }
    return $res;
  }
  private function _checkContinuity($values){
    $keepDays = 1;
    // 日数の差が1なら連続カウント
    for($i = 0; $i < count($values) - 1; $i++){
      $time1 = new \DateTime($values[$i]);
      $time2 = new \DateTime($values[$i + 1]);

      $diff = $time1->diff($time2);
      if($diff->format('%d') == 1){
        $keepDays++;
      }else{
        break;
      }
    }
    return $keepDays;
  }

 頑張って自作した処理なので、載せておきます。こういうものを作っている時が一番楽しいですね。

日記をつけた総日数

 これは単純です。データベースから日記を全て取り出し、count関数で計算するだけです。

現在連続記録日数

 まず、データベースから日記の日付を、降順で全て取り出します。この日付を使ってDateTimeオブジェクトを作成したいですが、例の如く後ろについている曜日表記(-Mon等)が邪魔なので、substr関数でこれらを切り取ります。
 foreachを回し、最新の日記と、その一つ前の日記の日数の差を、diff関数で計算します。非常に便利というか、この関数がなければ何も成り立ちませんでした。日付の差が1だった場合は、それらの日記は連続している、ということなので、連続日数を保持する変数に+1します。差が1でなかった場合、そこで処理をストップします。この方法により、最新の日記から連続でどれだけ日記をつけているのか、計算できました。

最大連続記録日数

 データベースから、最大連続記録日数を取り出しておきます。初期値は0です。
 上記の現在連続記録日数の処理が終わった段階で、その日数と、データベースから取り出した最大連続記録日数を比較します。最大記録を上回っているようなら、データを上書きします。

f:id:Kyokuya_jao:20200623213606p:plainf:id:Kyokuya_jao:20200623213602p:plain
 完璧です。目立ったバグが発生することもなく、非常に気持ちよく制作することができました。

 さて、ユーザーが手を加える機能は、ひとまず完成といったところです。残すところは、画竜点睛とも言えるララのセリフ機能を実装するのみです。
 それでは、今回はこのあたりで。