学習日記48日目

スタートアップ研修記はこちらです。

どうも、enomotoです。
今日から、PHP制作は新しいステージへ。
ということでカレンダーを作り始めました。
前回のは微妙に貼り付けにくいネタでしたが、
今回は問題なさそうなので全部張っていきたいと思います。

今回の仕様

  1. 月ごとのカレンダーが表示できる(1ヶ月単位)
  2. 日ごとの詳細画面がありスケジュールを見ることができる
  3. 上記2のスケジュール詳細画面では、一覧表示とスケジュール登録・削除・編集ができる。
  4. できれば、ログイン画面を付けて複数使い分けたい。

それを踏まえて時間を見積もり制作を開始したのですが…
デザインの時間を入れるのを忘れた。
ということで最低限のデザインになっています。

本日の進んだところ

  • 月ごとのカレンダーが表示できるようになった!
  • 日付毎のリンクもできた!

次回以降への課題

  • スケジュール登録画面を作り、DBにデータを格納する。
  • DBのデータを表示できるようにする
  • DBのデータを編集できるようにする
  • ログイン画面を付けてマルチユーザー化する

今回のファイル構成

/
├ /web/index.php
|   └/css/style.css
├ /modules/calendar/view/month_view.php
|                └/logic/month_view.php
└ /lib/controler.php
  • 今回はPEAR::Calendarを使用。

/web/index.php

<?php

// 定義
define ('WEB_ROOT_DIR',realpath(dirname(__FILE__).'/../'));
define ('__TITLE__','カレンダー');


// 呼び出し
require_once ('Calendar/Validator.php'); //PEAR::Calendar::Validator
require_once ('Calendar/Year.php'); //PEAR::Calendar::Year
require_once ('Calendar/Month.php'); //PEAR::Calendar::Month
require_once ('Calendar/Day.php'); //PEAR::Calendar::Day
require_once (WEB_ROOT_DIR.'/lib/controller.php');

// Controller.php呼び出し
$view = new Controller();
$view->dispatch();

/lib/controller.php

<?php

class Controller
{
  
  //メンバー変数
  private $year;
  private $month;
  private $model;
  
  public function __construct() {

    if (isset($_GET['year']) && isset($_GET['month'])) {
      // $_GET['year']と$_GET['month']が入っていたら場合
      $this->year = $_GET['year'];
      $this->month = $_GET['month'];
      
    } elseif(isset($_GET['year']) && !isset($_GET['month'])) {
      // $_GET['year']は入っていて$_GET['month']は入っていない場合
      $this->year = $_GET['year'];
      $this->getMonth();
    } else {
      // それ以外の処理が来たら表示。
      $this->year = date('Y');
      $this->month = date('n');
    }
  }

  // $_GET['month']が無い場合にファイルを探して$monthに値を入れる。
  public function getMonth() {
    $this->month = date('n');
  }
    
  public function dispatch() {
    if(isset($_GET['day'])) {
      require_once(WEB_ROOT_DIR.'/modules/calendar/logic/day_view.php');
      $model = new DayView();
      $model->execute();
      $model->render(WEB_ROOT_DIR.'/modules/calendar/view/day_view.php');
    } else {
      require_once(WEB_ROOT_DIR.'/modules/calendar/logic/month_view.php');
      $model = new MonthView();
      $model->execute();
      $model->rendar(WEB_ROOT_DIR.'/modules/calendar/view/month_view.php');
    }
  }
}

/modules/calendar/logic/month_view.php

<?php
class MonthView
{

  public $day;
  public $year;
  public $month;
  public $first_day;
  public $first_week;
  public $month_days;
  public $today;
  public $days = 1;
  public $calendar;

  public function rendar($get) {
    // テンプレート読み込み
    require_once($get);
  }
  
  public function execute() {
    if (isset($_GET['year']) && isset($_GET['month'])) {
      // GETにYearとMonthが入力されていたら
      if ($_GET['year'] >= 1970 && $_GET['year'] <= 2100) {
        // Yearが1970から2100までだったらGETの中身を代入
        $this->year = $_GET['year'];
      } else {
        // それ以外は現在のYearを代入
        $this->year = date('Y');
      }
      if ($_GET['month'] >= 1 && $_GET['month'] <= 12) {
        // Monthが1から12までだったらGETの中身を代入
        $this->month = $_GET['month'];
      } else {
        // それ以外は現在のMonthを代入
        $this->month = date('n');
      }
    } elseif(isset($_GET['year']) && !isset($_GET['month'])) {
      // GETにYearとMonthが入力されていたら
      if ($_GET['year'] >= 1970 && $_GET['year'] <= 2100) {
        // Yearが1970から2100までだったらGETの中身を代入
        $this->year = $_GET['year'];
      } else {
        // それ以外は現在のYearを代入
        $this->year = date('Y');
      }
      // Monthは無いのでとりあえず1を代入
      $this->month = 1;
    } else {
      // 何もない場合は現在のYearとMonthを代入
      $this->year = date('Y');
      $this->month = date('n');
    }
    // PEAR::Calendar::Dayの開始
    $this->calendar = new Calendar_Day($this->year,$this->month,$this->days);
    // この月の初日のmktime
    $this->first_day = mktime(0,0,0,$this->calendar->thisMonth(),1,$this->calendar->thisYear()); // month,day,year
    // この月の初日の曜日
    $this->first_week = date('w', $this->first_day); //1日の曜日(0:日〜6:土)
    // この月の日数
    $this->month_days = date('t', $this->first_day); //$y年$m月の日数
    // 本日
    $this->today = date('j'); //本日
    // この日記のタイトル
    $this->cal_title = sprintf('%d年%d月のカレンダー',$this->year,$this->month); //タイトル
  }
  public function getCallinktag($year,$month) {
    // YYYY年MM月というリンクタグを作る
    return sprintf('<a href="?year=%d&amp;month=%d">%d年%d月</a>',$year,$month,$year,$month);
  }
  public function getlinktag($year,$month,$days) {
    // 日付毎のURL生成
    return sprintf('?year=%d&amp;month=%d&amp;day=%d',$year,$month,$days);
  }
  public function checkYear($month) {
    if ($month == 1) {
      // Monthが1なら去年の年を出す
      return $this->calendar->prevYear();
    } elseif ($month > 12) {
      // Monthが12以上なら去年の年を出す
      return $this->calendar->nextYear();
    } else {
      // なんでもなければ今年。
      return $this->calendar->thisYear();
    }
  }
}

/modules/calendar/view/month_view.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link href="./css/style.css" rel="stylesheet" type="text/css" />
<title><?php echo __TITLE__; ?></title>
</head>
<body>
<div id="wrapper">
   <h1><?php echo $this->cal_title; ?></h1>
<div id="navi">
<p class="float_left"><?php echo $this->getCallinktag($this->checkYear($this->calendar->thisMonth()),$this->calendar->prevMonth()); ?></p>
<p class="float_right"><?php echo $this->getCallinktag($this->checkYear(($this->calendar->thisMonth())+1),$this->calendar->nextMonth()); ?></p>
</div>
<p class="center"><a href="?">今月に戻る</a></p>
<table>
   <thead>
   <tr>
   <th><span class="cal_sun"></span></th>
   <th></th>
   <th></th>
   <th></th>
   <th></th>
   <th></th>
   <th><span class="cal_sat"></span></th>
   </tr>
   </thead>
   <tbody>
<?php while(checkdate($this->month,$this->days,$this->year)): ?>
   <tr>
   <!-- ここから一週間 -->
   <?php for($this->i=0;$this->i<7;$this->i++): ?>
   <?php if(!checkdate($this->month,$this->days,$this->year)): ?>
   <!-- 存在しない日付も空白で埋める -->
   <td> </td>
   <?php else: ?>
   <!-- 何曜日かの確認 -->
   <?php $this->week = date('w', mktime(0,0,0,$this->month,$this->days,$this->year)); ?>
   <!-- 日付に曜日が存在するなら -->
   <?php if($this->week==$this->i): ?>
   <td><a href="<?php echo $this->getlinktag($this->year,$this->month,$this->days); ?>">
   <?php if ($this->week==0): ?>
   <!-- 日曜日なら -->
   <span class="cal_sun"><?php echo $this->days; ?></span></a></td>
   <?php elseif ($this->week==6): ?>
   <!-- 土曜日なら -->
   <span class="cal_sat"><?php echo $this->days; ?></span></a></td>
   <!-- それ以外 -->
   <?php else: ?>
   <?php echo $this->days; ?></a></td>
   <?php endif; ?>
   <?php $this->days++; ?>
   <?php else: ?>
   <td> </td>
   <?php endif; ?>
   <?php endif; ?>
   <?php endfor; ?>
<!-- ここまで一週間 -->
   </tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</body>
</html>

/web/css/style.css

body {
    margin: 0;
    padding: 0;
}

a {
    color: #000000;
}

#wrapper {
    margin: 0 auto;
    padding: 0;
    width: 800px;
}

#navi {
    margin: 0 auto;
    width: 500px;
}

#navi p.float_left {
    float: left;
    width: 250px;
}

#navi p.float_right {
    float: right;
    width: 250px;
    text-align: right;
}

p.center {
    text-align: center;
}

h1 {
    text-align: center;
}

table {
    width: 800px;
    text-align: center;
}

th {
    font-size: large;
}

td {
    margin: 0;
    font-size: x-large;
    border: solid 1px;
}

.cal_sat {
    color: blue;
}

.cal_sun {
    color: red;
}