Giter VIP home page Giter VIP logo

sofpyon / inaka-portal Goto Github PK

View Code? Open in Web Editor NEW
5.0 3.0 0.0 8.77 MB

[DEPRECATED] inaka-portal は PortalDots に改称し、リポジトリも移転します。移行先➡️

Home Page: https://github.com/portal-dots/PortalDots

License: MIT License

PHP 91.18% HTML 5.78% Shell 0.19% Dockerfile 0.02% ActionScript 0.54% Vue 2.28%
inaka-portal events websystem php codeigniter laravel vue forms gui

inaka-portal's Introduction

inaka-portal's People

Contributors

dependabot[bot] avatar hosakou avatar sofpyon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

inaka-portal's Issues

申請、ユーザーを削除できるようにする

現状、申請やユーザーは削除できないようになっているが、削除できるようにする。

  • 申請自体を削除した場合
    • その申請内の設問・回答などを全て削除する
  • 申請の設問を削除した場合
    • その設問に対する回答も削除する
  • ユーザーを削除した場合
    • そのユーザーに関係する全てのデータを削除する

ユーザー情報変更機能

背景

現状、一般ユーザーが自身のユーザー情報を変更する方法がない。

実装内容

  • 一般ユーザーが自身のユーザー情報を変更できるようにする
  • メールアドレス・学籍番号の変更の場合、メール認証を再度求める

@hosakou
実装内容については対面で打ち合わせます!

【申請】申請フォーム回答後、新しい設問が追加された場合、回答者は新しく追加された設問を保存できない

再現手順

S : スタッフユーザー
A : 回答者(一般ユーザー)

  1. S が a, b, c の 3 つが設問であるフォーム f を作成する
  2. A が f に対し、a. b. c の 3 つ全てに回答する
  3. S が f に対し、新しく設問 d を追加する
  4. 設問 d が追加されたことを知った A が設問 d に回答しようとしても、エラーこそ表示されないものの、データベース上には d の回答が保存されない

原因

回答更新時、 form_answer_details に対し update を実行するように設計されているため。

新しく追加された設問については form_answer_details にレコードがないため、設問 d に対して update しても何も起こらない。

Laravel 化するまでの暫定的な対応

  • updatedelete + insert に置き換える
    • form_answer_details には適切なインデックスが設定されていないため、 ON DUPLICATE KEY UPDATE 文は利用できない
    • この方法は、テーブル構造を変更しないと、AUTO INCREMENT の id が増え続けてしまう

Laravel 化した後の対応

(全ての DB テーブルに対し適切なインデックスを設定した上で)

テスト導入(PHP 編)

背景

  • 現状、inaka-portal ではテストが書かれていない。ちゃんとテスト書きたい

実装内容

  • まずは現時点で Laravel に移行したコードについて、テストを書く

今後の展望

  • CodeIgniter から Laravel に移行する際、まずは CodeIgniter の実装が PASS するようなテストを書き、その上で Laravel から移行すると良さそう

phpcs を導入

背景

  • PHP のコーディングスタイルを揃えたい

ドキュメント整備

ドキュメントを執筆している際、説明がわかりにくくなるようであれば、 inaka-portal 自体のコードを変更することも検討する。

【申請】申請ページのURL改修

背景

現在、申請フォームページの URL は以下のような形式になっている。

  • 新規回答 : /home/applications/【団体ID】/forms/【フォームID】/new
  • 回答の編集 : /home/applications/【団体ID】/forms/【フォームID】/【回答ID】

URL の途中に団体IDが挟まっているため、例えば「パンフ申請のURLはこれです!ここからアクセスしてね!」という誘導ができない。

実装内容

そこで、申請フォームページの URL は以下のような形式にしたい。

  • 新規回答 : /forms/【フォームID】/answers/new?circle_id=【団体ID】
  • 回答の編集 : /forms/【フォームID】/answers/【回答ID】/edit

具体的な実装内容として、

  • URL を、(ほぼ) Resourceful にする。
  • 団体IDは GET パラメータで渡す
    • 団体 ID は省略可能。省略した場合、団体を選ぶ画面になるようにする。

メモ

  • まだ Laravel 化はしない
  • とりあえずは、「ブース単位で回答できるようにするモード」には対応しない
    • 現状で対応していないものは、この issue でも対応しない。いずれ対応していく

【申請】フォームデザインの調整

背景

現状の申請フォームのデザイン、あまり優れているとは言えない。

特にセクション見出しが見出しっぽくないのをなんとかしたい。

image

実装内容

これら以外にも、「こここうした方が良い気がする」とかあれば、良い感じにしてもらえると嬉しいです!

フォーム_-_イナカポータル

ESLint の Warning をなんとかする

背景

現状、以下 2 つの ESLint ルールについては、 error ではなく warning になるようにしている。

  • import/no-cycle
  • camelcase

ずっと warning に設定して誤魔化し続けるわけにはいかないので、対処する。

実装内容

  • import/no-cycle
    • import による循環参照が起こっているため、循環参照を解消する
    • 全て解消できたら .eslintrc.js から import/no-cycle に関する行を消す
  • camelcase
    • JS 内の変数名が camelCase ではなく snake_case になってるのが原因で warning が出ている
    • snake_case を camelCase に今から直すのは大変なので、 snake_case を許容するようにする
      • snake_case を強制するか、 snake_case でも camelCase でも問題ないようにするか、要検討。後者は微妙だが…

【ログイン画面】お知らせ・配布資料を表示する

背景

「理大祭ウェブポータ(2nd gen.)」では、ログイン画面にお知らせを表示していたが、inaka-portal(第1世代に相当)でも同様の機能を実装したい

実装内容

  • ログイン画面に、「次の予定」「お知らせ」「配布資料」を表示する

Stylelint 導入

背景

ESLint を導入したが、CSS 部分はまだだった。Stylelint を導入して、Vue ファイルや既存の CSS ファイルにチェックを入れたい。

【申請】1団体で複数回答できるようにする

背景

現状、DB の Form テーブルには、1団体が回答できる最大数を指定できる max_answers というカラムがあるが、このカラムの情報は使われていない。

max_answers を元に、複数の回答を作成できるようにしたい。

実装内容

  • max_answers が 2 以上の場合の条件分岐を追加する
    • 回答の新規作成ページにアクセスした場合、すでに回答ずみのリストを表示し、「以下の回答も編集できます。新規回答の作成もできます。」的な表示をする

インストーラー

inaka-portal 初回起動時、WordPress みたいにインストーラーが起動するようにしたい。

  • DB 設定
  • メールサーバー設定
  • 管理者ユーザー設定

とか

Husky、ESLint、Prettier を導入

背景

  • ESLint、Prettier を導入することで、JavaScript のコーディングスタイルをいい感じに揃えたい
  • Husky を導入することで、Git Commit 時に自動的にコードフォーマット処理が走るようにしたい

【申請】申請ページを Laravel + Vue 化する

#39 が終わったら着手する。

背景

現状、申請ページは CodeIgniter で作成されているが、それを Laravel + Vue にする。

実装内容

  • 設問一つ一つの表示を Vue コンポーネントにする
    • 申請フォームエディターで使用している Vue コンポーネントと共有できるようにする
  • SPA にしない。Axios ではなく普通にフォームを送信するスタイルにする
    • 送信ボタンを押したら HTML 標準の POST 処理
    • POST 先 : /forms/【フォームID】/answers
    • PATCH 先 : /forms/【フォームID】/answers/【回答ID】/edit
  • フォームのデザインは微調整する

「ログイン状態を維持する」が機能していない?

背景

「ログイン状態を維持する」機能は Laravel が標準で持っている機能である。

remember_web_なんちゃら という Cookie をセットすることによって、ログイン状態を維持している

…はずが、この Cookie がどうやら機能していない?


ログイン状態は session_id という Cookie が管理している。この Cookie が存在しない場合、 Laravel は remember_web_なんちゃら という Cookie が存在しているか確認し、存在する場合、この Cookie で自動ログインしてくれるものと僕は認識している。

しかし session_id を消すと、自動ログインせず、普通にログイン画面が表示されてしまう。

この原因の調査をお願いしたいです!

Laravelのバージョンを6.xにする

背景

現在の inaka-portal の Laravel は 5.8 だが、最新のバージョンは 6.x。

6.0 は LTS(長期サポート)版なので、inaka-portal も Laravel 6.x にアップグレードしたい。

メール一斉送信機能

追記

独自にメール一斉送信機能を実装するよりも、 SendGrid のようなサービスを使った方が良い気もする

背景

ポータルに登録しているユーザー全員にメールを送信する機能が欲しい

実装内容

  • スタッフモード上に、メールを一斉送信するための画面を用意する
    • 今ある「お知らせ」機能に、メールを一斉送信する機能を追加する感じが良さそう
  • 「メールを登録ユーザー全員に配信」にチェックを入れてお知らせを保存すると、DB上のメール配信キューテーブルに Enqueue される
    • キューテーブル上に入れる情報は後述
  • CRON で、メール配信プログラム(以下の「メモ」参照)を定期的に実行し、少しずつメールを配信していく
  • 管理画面では、メールの配信状況を確認できる画面を用意する
    • 全体の何%に対し配信が完了しているのか、的な画面

キューテーブルに入れる情報

  • id: メールジョブID
  • subject,body : メールの件名・本文
    • 「お知らせ」を管理するテーブルとは別に本文を持たせる。さもないと、メール配信が途中の段階でお知らせが修正された場合、お知らせ修正前・修正後でメールの配信内容にズレが生じてしまうので。
  • email : 宛先
  • name : 受取人の名前
    • メール送信時の宛先蘭は、 email と name で [name] のような形式にする。そうすることで、相手に届く時、宛先がユーザーフレンドリーな表示になる
  • is_locked : 排他ロック中か
  • is_sent : 送信済みか
  • count_failed : メール送信失敗回数
  • その他,諸々の時間情報(ジョブ作成日時,送信日時,etc)

メモ

昔適当に書いてた、メールを一斉送信できそうなコード。ちゃんと動くかどうかは知らん

<?php

class EmailService
{
    const NUMBERS_PER_EXECUTE = 100; // 1回の処理で取得するメールレコード数
    const SEND_INTERVAL_SEC = 1; // メール送信間隔(秒)
    const SEC_PER_JOB = 60; // プログラム強制終了まで
    const NUM_RETRY_PER_EMAIL_ADDRESS = 3; // 送信失敗した場合,リトライする回数
    const NUM_RETRY_PER_JOB = 10; // 1回のジョブで繰り返す回数

    function enqueue()
    {
        for ($i = 0; $i < 10; ++$i) {
            $email = new App\Email();
            $email->subject = "件名";
            // ...
            $email->save();
        }
    }

    function runJob()
    {
        const START_TIME = now(); // 開始時刻(UNIXエポック) (秒)

        // 今期失敗回数
        // (この関数が呼び出されて以降失敗した回数)
        $count_failed_now = 0;

        $emails = App\Email::orderBy('id', 'ASC')
                            ->where('is_locked', false) // 排他ロックされていない
                            ->where('is_sent', false)   // かつ,未送信
                            ->where('count_failed', '<', NUM_RETRY_PER_EMAIL_ADDRESS) // かつ,リトライ上限に達していないレコード
                            ->take(NUMBERS_PER_EXECUTE)
                            ->get();           // 最新 NUMBERS_PER_EXECUTE 件を取得
        foreach ($emails as $email) {

            // ロック処理
            $email->is_locked = true;
            $email->save();
            
            try {
                // ...何らかの送信処理...

                // 送信済みフラグセット
                $email->is_sent = true;
                $email->save();
            } catch (Exception $e) {
                // 送信失敗したので失敗カウントを1つ追加
                ++$email->count_failed;
                ++$count_failed_now;
                
                // TODO: エラーの内容をログに残せたら良さそう

                // ロック解除
                $email->is_locked = false;
                $email->save();

                // ...今度CRONが起動したらやり直す
            }

            // 現在実行中の runJob で、失敗回数が NUM_RETRY_PER_JOB 回を超えたら
            // サーバー側の設定ミスなどが考えられるので、処理を中止する
            if ($count_failed_now > NUM_RETRY_PER_JOB) {
                // ...管理者にメールするなりログに書き込むなりする...

                // とりあえず強制終了
                break;
            }

            // 強制終了するか否か
            if (now() - START_TIME > SEC_PER_JOB) break;

            // スリープ
            sleep(SEND_INTERVAL_SEC);
        }
    }
}

【セキュリティ】スタッフモードの二段階認証がスキップされる問題を解消

原因

一度 2 段階認証が成功すると $_SESSION['staff_authorized'] が true にセットされるが、ログアウト時、このセッションはリセットされない。

そのため、ログアウトしてから再度スタッフユーザーとしてログインし、スタッフモードにアクセスすると 2 段階認証はスキップされ、スタッフモードにアクセスできてしまう。

【Staff/ユーザー管理】ユーザー登録可能かどうかの判断方法をスタッフが選べるようにする

  • ユーザー登録可能かどうかを判断するかどうか
    • 判断を行い、不可判定の場合は登録を受け付けない
      • 「間違いであると考えられる場合は、お問い合わせください」みたいに表示&スタッフモードでユーザー登録できるようにする
    • 判断を行わない
  • 判断方法
    • 学籍番号@ + 大学発行メールアドレスのドメイン
      • ユーザー登録フォームには 学籍番号 入力欄は表示され、 大学発行メールアドレス 入力欄は表示されない
    • 学籍番号 入力欄とは別に 大学発行メールアドレス の入力欄を表示する
      • その際、 RP_UNIVEMAIL_DOMAIN が、 大学発行メールアドレス末尾 に含まれるかどうかを検証する
      • 部分一致確認不可( hoge@example.com.malicious.example.net のようなものが通ってしまう )
  • 学籍番号入力欄を
    • 必須にする
    • 任意項目にする
    • 表示しない

メモ

  • 大学発行メールアドレスを格納するフィールドを DB に用意する
  • RP_UNIVEMAIL_DOMAIN に先頭のアットマークは含めない
    • DOMAIN なのにアットマークを含めての指定が必要なのは不自然。アットマークを含めるにしても RP_UNIVEMAIL_SUFFIX あたりが適切なのでは?

【申請】申請中・承認・要再提出のステータスを設定できる機能

概要

グループウェアでは「ワークフロー機能」と呼ばれていたりするような機能。

提出された申請に対し、

  • 申請中 (pending? confirming?)
  • 承認 (approved)
  • 要再提出 (rejected? denied の方が適切な気がする)

のステータスを設定できるようにする。

承認・要再提出の場合、共にコメントをフォーム上に表示し、また、承認・要再提出にされたことを申請者にメールで送信する。

また、承認理由・要再提出理由をフォームやメールで表示する。

承認された場合、申請者は申請を変更できないようにする。
(承認後、スタッフなら編集可能にしたい)

実装内容(WIP)

  • answers テーブルに、status カラムを追加する
    • status カラムには pending、approved、rejected のいずれかが取れる
    • Enum にせず、varchar 型で
  • answers テーブルに、status_reason カラムを追加する(text)
    • nullable
    • approved、rejected の場合、status_reason の内容が理由として表示される(省略可)
  • forms テーブルに、is_auto_approve カラムを追加する(boolean)
    • true の場合、回答を提出すると answers テーブルでは status = approved になる
    • false の場合、回答を提出すると answers テーブルでは status = pending になる。rejected された状態で回答を編集した場合も pending に変わる(理由テキストはまだ消さない)
  • forms テーブルの is_auto_approve が false の場合、回答ページ上にはステータスを表示する
    • pending の場合、「申請中 — この申請はまだ承認されていません」
    • approved の場合、「承認 — この申請は承認されました or 理由テキスト」
    • rejected の場合、「要再提出 — この申請は却下されました。内容を編集して再提出してください or 理由テキスト」
  • スタッフモードで、回答の承認・要再提出を設定できるようにする
    • 回答を選ぶ→モーダルが開く→承認・要再提出を選択+理由テキストを入力→団体に(承認|要再提出)メールが送信される

【Laravel】使用フレームワークを Laravel に移行

ロードマップ

  • 申請フォーム機能から「セクション」機能を廃止
    • データベース構造が複雑化しているため
  • modified_at カラムを updated_at カラムに変更するなど、Laravel 標準の規約に揃える
  • 別フォルダで laravel new コマンドを実行して生成されたファイルを配置
    • public ディレクトリには Laravel の public/index.phppublic/index_laravel.php にリネームしたものを配置する
  • CodeIgniter 側の public/index.php では、URL によって CodeIgniter にルーティングするか Laravel にルーティングするかを分ける処理を入れる
  • 簡単に移行できそうな部分から Laravel に処理を移行していく

今後の設計方針

  • 新機能は Laravel で開発する
    • 新機能を導入することで、CodeIgniter 側のコードに変更が必要になる場合は止むを得ない
  • CodeIgniter と Laravel が混在している開発途中の段階であっても、動作に問題ないようにする
    • 利用者側には Codeigniter と Laravel が混在していることを意識させない

【申請フォームエディター】FormRequestクラスによるバリデーション

背景

現状、申請フォームエディター画面上から送信される HTTP リクエストはバリデーションされていない。

Laravel の FormRequest クラスを作成し、全てのリクエストは FormRequest のバリデーションを経由するようにする。

実装内容

  • フォームタイトルが空欄だったらエラーにする
  • 最小文字数が 0 未満だったらエラー
  • 最大文字数が MySQL の integer 型の範囲を超えていたらエラー

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.