Developer

魁!小野の塾 小さな管理機能を作ってみようの巻 第23話
2021.09.23
Lv2

魁!小野の塾 小さな管理機能を作ってみようの巻 第23話

小さな管理機能を作ってみよう 第23話

初心者向け、PHPプログラム構築講座です。
初心者といっても、PHPの勉強を少し行い、LAMP環境が自分で構築でき、少しアプリケーションを作成しているレベルを対象とします。
まったくの初心者の場合は、わからない部分が出てくると思います。
できるだけ細かく説明は入れていきますが、説明がわからない場合は、PHPやMySQLの初心者講座をご覧ください。

対象のスキルレベル

  • LAMP環境の構築
  • PHP言語が読める
  • HTML, CSS, Javascriptが少しわかる
  • Bootstrapのドキュメントをみて、HTMLが書ける
  • Ajax(非同期通信)を利用したことがある
  • SESSIONを利用したことがある

構築環境

  • Windows10
  • XAMPP(PHP7.3.2, MariaDB 10.1.38)

Dashboardの実装

ログイン機能が実装されましたので、続いてDashboardの開発に着手します。
前回共通処理にて、ログインチェックを実装しましたが、その際にローディングマスクが未実装と書いてありました。
ログインチェックに時間がかかる場合に、画面を操作させたくないので、画面全体を覆い、クリック操作できないようにします。

ということで、まずはローディングマスクの実装用cssと、DashboardのHTMLの修正を行っていきたいと思います。

Loadingマスク用CSS作成

Loadingマスクは各画面共通なので、style.cssへ追加していきたいと思います。

/assets/css/style.css(抜粋)
/* loadingの背景 */
.loading{
	width: 100%;
	height: 100%;
	position: fixed;
	top: 0;
	z-index: 1050;
}
/* loadingの真ん中に出すグルグル */
.spinner{
	width: 220px;
	height: 130px;
	background-color: #fff;
}

.loading は、画面全体を覆う白い壁のようなもので、画面の上に配置しています。上に配置するプロパティーは、z-index で指定します。bootstrapのnavbarを考慮して、1050を指定してあります。
.spinner は、白い画面に横220px、高さ130pxの枠をつけたボックスにスピナー(グルグル)を表示させるための枠です。外枠の枠線は、HTMLのクラスで指定していきます。

index.html(抜粋)
<body>
	<section class="loading d-flex justify-content-center align-items-center bg-light">
		<div class="spinner shadow rounded d-flex justify-content-center align-items-center">
			<p class="h4 text-secondary"><i class="fas fa-spinner fa-spin"></i> Loading...</p>
		</div>
	</section>

	<header>
		<nav class="navbar navbar-expand-lg navbar-light shadow bg-white fixed-top">
			<div class="container-fluid">

SECTION要素のクラスにloadingが指定されている部分が外枠(壁)になっています。中身は.spinnerが入っていて、その中に、回転するアイコンと、Loading…の文字が入ります。
アイコンをグルグル回すのは、.fa-spin をつけるだけです。Font Awesomeのどんなアイコンも回ってくれます。なんて簡単!
Font Awesomeのアイコンはそれ以外にも色々クラスを付けるだけで変更できるので、しっかりドキュメントを読んだ方が良いですよ!

※参考 Animating Icons
※参考 Sizing Icons
※参考 Fixed Width Icons
※参考 Icons in a List

実際の画面はこのような感じになります。
共通のJavascript内で定義していた関数(isSignin())を呼び出すと、自動的に上にスライドしていく感じになります。

続いて、login.html, usersEdit.html共通で追加している、process, method のメタタグの追加を行います。

index.html(抜粋)
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<meta name="process">
	<meta name="method">
	<title>DASHBOARD | tech.pjin.jp</title>

	<!-- Bootstrap CSS -->
	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
	<!-- Font Awesome CSS -->
	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
	<!-- Animate.css CSS -->
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
	<!-- Sawarabi Gothic -->
	<link href="https://fonts.googleapis.com/css?family=Sawarabi+Gothic" rel="stylesheet">

	<link rel="stylesheet" href="assets/css/style.css" />

Dashboard.php

HTMLの実装が終了しましたので、Javascriptを実装する前に、PHPの実装を行います。
Controllerは api フォルダー内に実装します。index.phpがリクエストを受け、Controllerにprocessを渡すと、指定ファイルを読込、methodで実行する関数を決定します。
Dashboard機能を実装しますので、Dashboard.php を実装していきます。実装したい機能は大きく4つで、ユーザの登録数、部署の登録数、ユーザの月別登録数推移、部署の月別登録数推移です。

まず、apiフォルダーに、Dashboard.php を作成してください。

/api/Dashboard.php
<?php
class Dashboard {
	/* traitを使う宣言 */
	use Result;

	/* ユーザマスタの登録件数を返します */
	function getUsersEntry($con, $request){
		$sql	= "select count(*) from users";
		if($stmt = $con->prepare($sql)){
			$stmt->execute();
			$stmt->bind_result(
				$count
			);
			if($stmt->fetch()){
				/* 連想配列で、countに件数を入れます */
				$rs	= [
					'count'	=> $count
				];
			}
			$stmt->close();
			/* setList, success は trait(Result)の関数です */
			$this->setList('rs', $rs);
			$this->success();
		}
		return $this->result();
	}

	/* 部署マスタの登録件数を返します */
	function getDeptsEntry($con, $request){
		$sql	= "select count(*) from depts";
		if($stmt = $con->prepare($sql)){
			$stmt->execute();
			$stmt->bind_result(
				$count
			);
			if($stmt->fetch()){
				$rs	= [
					'count'	=> $count
				];
			}
			$stmt->close();
			$this->setList('rs', $rs);
			$this->success();
		}
		return $this->result();
	}

	/* 月別のユーザ登録数を返します。 */
	function getUsersTransition($con, $request){
		$rs	= [];
		/* date_formatで月(%m)を指定してgroup byしているので、月別に登録件数を取得できます(年は関係なし) */
		$sql	 = "select date_format(created, '%m'), count(*) from users ";
		$sql	.= "group by date_format(created, '%m') ";
		$sql	.= "order by date_format(created, '%m') ";

		if($stmt = $con->prepare($sql)){
			$stmt->execute();
			$stmt->bind_result(
				$month,
				$count
			);
			while($stmt->fetch()){
				/* 連想配列で、月をキーに登録件数を保持します。 */
				$rs[$month]	= $count;
			}
			$stmt->close();
			$this->setList('rs', $this->getFullMonthData($rs));
			$this->success();
		}
		return $this->result();
	}

	/* 月別の部署登録件数を返します */
	function getDeptsTransition($con, $request){
		$rs	= [];
		/* date_formatで月(%m)を指定してgroup byしているので、月別に登録件数を取得できます(年は関係なし) */
		$sql	 = "select date_format(created, '%m'), count(*) from depts ";
		$sql	.= "group by date_format(created, '%m') ";
		$sql	.= "order by date_format(created, '%m') ";

		if($stmt = $con->prepare($sql)){
			$stmt->execute();
			$stmt->bind_result(
				$month,
				$count
			);
			while($stmt->fetch()){
				/* 連想配列で、月をキーに登録件数を保持します。 */
				$rs[$month]	= $count;
			}
			$stmt->close();
			$this->setList('rs', $this->getFullMonthData($rs));
			$this->success();
		}
		return $this->result();
	}

	/* 月別の登録件数で、集計月に1~12がない場合に補正します */
	/* 返却されるデータは、通常配列で、12個の要素に値が入ります。 */
	function getFullMonthData($arr){
		$months	= ['01','02','03','04','05','06','07','08','09','10','11','12'];
		$result	= [];
		foreach($months as $month){
			if(array_key_exists($month, $arr)){
				$result[]	= $arr[$month];
			}else{
				$result[]	= 0;
			}
		}
		return $result;
	}
}
?>

getUsersEntry($con, $request) ユーザの登録数(全体)を返します。
getDeptsEntry($con, $request) 部署の登録数(全体)を返します。
getUsersTransition($con, $request) ユーザの月別登録数推移を返します。年の指定がないので、例えば2020年1月に3人、2021年1月に3人の場合は、1月6人と返します。
getDeptsTransition($con, $request) 部署の月別登録数推移を返します。年の指定がないので、ユーザと同様な件数が返ります。
getUsersEntry($con, $request) 月別登録推移をグラフで出力する際に、12カ月分のデータが必用になります。無い場合は、0を入れる必要があり、その補正をしています。例えばシステムの稼働が4月だとすると、4月以外のデータが存在しません。その場合は、1~3月、5~12月のデータを0埋めして返します。

Dashborad.phpの実装はこんなところで、次の回でJavascriptを実装していきたいと思います。

魁!小野の塾