簡易グループウェア スケジュールWeb「LiteScl.oda」の導入

# 導入経緯
会社では運用チームに属していて、各県にある30近い工場の運用作業を行っている。
現在、GW期間の稼働スケジュールやサーバー停止や再起動などをExcelファイルのメールでやり取りしている。
そこで、簡易的なグループウェアでスケジュール管理できないかと検索して見つけたのが、島根県大田市(おおだし)のオープンソース「[LiteScl.oda (大田市スケジュールWeb)](http://www.city.ohda.lg.jp/tag/27/11464)」である。※大田市では、[LiteScl](https://osdn.jp/projects/litescl/) Ver0.9から改良している。
ちなみに島根県といえば、Rubyの開発者である「[まつもとゆきひろ](https://ja.wikipedia.org/wiki/%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8%E3%82%86%E3%81%8D%E3%81%B2%E3%82%8D)氏」が在住しているということによりオープンソース活動には積極的である。

もちろん、会社内ではグループウェアを既に使用しているが、あくまで社員が対象となっており、各工場をそのグループウェアに追加するわけには行かないのである。
昨今ではクラウド上でグループウェアを無料で使えるものが出ているが、外部に情報を出すのも問題が出てくるため、あくまでイントラまたはプライベートネットワーク内で使用できるものを探していた。
参照:[４種の無料グループウェア徹底比較！登録前に違いをチェック！](http://www.iqube.net/free_groupware_comparing.html)

# 環境
* Windows Server 2008R2
* Apache Ver 2.4.20
* PHP Ver 5.6.19 → PHP Ver 7.1(2017/03/01)
* MySQL Ver 5.7.12
* LiteScl.oda Ver3.23b
* .NET Framework 4.6 ※MySQLインストーラーが.NET4以上のため

# 導入方法
## Apache2.4の導入
D:\Apache24に64bit版を導入した
参照: [Apacheのダウンロードとインストール - Windows環境](http://webkaru.net/php/windows-apache-install/)
※ 参照記事は「Visual Studio 2012 の Visual C++ 再頒布可能パッケージ」であるが、現在は「Visual Studio 2015 の Visual C++ 再頒布可能パッケージ」を[ダウンロード]((https://www.microsoft.com/ja-jp/download/details.aspx?id=4814))してください。そうしないとエラー「VCRUNTIME140.dllがない」が発生します。

### httpd.conf の編集
Dドライブ直下にApache24フォルダおよびPHP5フォルダとして導入したため、関連部分を編集している。
また、ポート80はIISで使用しているため、1080としている。

```bash:httpd.conf 
ServerRoot "D:/Apache24"

#Listen 12.34.56.78:80
Listen 1080

LoadModule php5_module d:/php5/php5apache2_4.dll

DocumentRoot "D:/Apache24/htdocs"
<Directory "D:/Apache24/htdocs">
   # None -> All　　
    AllowOverride All

    Order allow,deny
    Allow from all

    Require all granted
</Directory>

<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "D:/Apache24/cgi-bin/"

<Directory "D:/Apache24/cgi-bin">

<IfModule mime_module>
    AddType application/x-httpd-php .php
    
PHPIniDir "D:\php5"
```

※httpd.confを編集したら、Apache2.4サービスを再起動しないと設定が反映されない。

もし、Apache2.4のサービスが開始できずにイベントログに「Apache2.4 サービスは、サービス固有エラー ファンクションが間違っています。」のログがある場合

[対応方法](http://t12488mac.blogspot.jp/2011/06/windowsapache.html) 「httpd.exe -t」でエラー箇所が分かります。

```
D:\Apache24\bin>httpd.exe -t
httpd.exe: Syntax error on line 189 of D:/Apache24/conf/httpd.conf: Cannot load
modules/mod_python.so
```

## PHP5.6の導入
D:\PHP5に導入した。
参照:[PHPのダウンロードとインストール - Windows環境](http://webkaru.net/php/windows-php-instal/)

環境変数 Pathに「;D:\php5」を追記
「php.ini-development」をコピーし、「php.ini」に名前変更した。

```bash:php.ini
extension_dir = "D:\php5\ext"

;コメントを外す
extension=php_mbstring.dll
extension=php_mysql.dll
extension=php_mysqli.dll

error_reporting  =  E_ALL & ~E_NOTICE

;コメントを外して変更
date.timezone = Asia/Tokyo

[mbstring]
;コメントを外す
mbstring.language = Japanese

;コメントを外して変更
mbstring.internal_encoding = UTF-8
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.encoding_translation = Off
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
mbstring.substitute_character = none
mbstring.func_overload = 0
```

※Apacheのhttpd.confに「PHPIniDir "D:\php5"」を追加して、D:\php5\php.iniを読まれるように設定している。

## MySQLの導入
C:\Program Files\MySQLに導入した。
参照 [MySQL Server 5.6 を Windows にインストールする手順](http://weblabo.oscasierra.net/installing-mysql56-windows-1/)

環境変数 Pathに「;C:\Program Files\MySQL\MySQL Server 5.7\bin」を追記

C:\Program Files\MySQL\MySQL Server 5.7\libにある「libmysql.dll」を、D:\Apache24\binフォルダ直下にコピーした。

## PHP7.1に変更(2017/03/01)
PHP7はPHP5とくらべて実行処理速度が大幅に改善されたとのことで、バージョンアップしてみました。
残念ながら非推奨の関数が使用されていたため、ソースリストの修正が必要でした。

### 設定変更点
環境変数 Pathを「;D:\php5」から「;D:\php7」に変更

```bash:httpd.conf
LoadModule php7_module d:/php7/php7apache2_4.dll

PHPIniDir "D:\php7" 
```
```bash:php.ini
extension_dir = "D:\php7\ext"
;コメントを付けるか削除する
;extension=php_mysql.dll
```
### ソースリスト変更点

```php:split→explode
//$ar=split("/",$m);
//  ↓ 変更例
//$ar=explode("/",$m);

htmltemplate.inc(107) $ar=split("/",$m);
htmltemplate.inc(125) $ar=split("/",$m);
```

```php:eregi→preg_match
//if (!eregi('[0-9A-Za-z]', $value)){
//  ↓ 変更例
//if (!preg_matcheregi('/[0-9A-Za-z]/', $value)){

scl_m.php(276)  if (!eregi('[0-9A-Za-z]', $value)){
grp_e_m.php(29) if (!eregi('[0-9A-Za-z]',$d['grpid'])){
usr_e_m.php(151) if (!eregi('[0-9A-Za-z]',$d['usrid'])){
usr_e_m.php(189) //if (!eregi('[0-9A-Za-z]',$d['pass'])){
usr_e_m.php(241) if (!eregi('[0-9A-Za-z]',$d['usrid'])){
usr_e_m.php(265) //if (!eregi('[0-9A-Za-z]',$d['pass'])){
__initial.php(25) if (!eregi('[0-9A-Za-z]',$s_initinf['dbname'])){ 
__initial.php(33) if (!eregi('[0-9A-Za-z]',$s_initinf['adminid'])){ 
__initial.php(41) if (!eregi('[0-9A-Za-z]',$s_initinf['adminpass'])){
```

```php:mysql_→mysqli_
//$db = mysql_connect
// ↓ 変更例
//$db = mysqli_connect

getdbmysql.php(16) $db = mysql_connect($s_initinf['dbhost'], $s_initinf['dbuser'], $s_initinf['dbpass']);
getdbmysql.php(18) //mysql_select_db("scdb");//"$s_dbname);
getdbmysql.php(19) mysql_select_db($s_initinf['dbname']);
getdbmysql.php(24) return mysql_query($query);
getdbmysql.php(28) $a = mysql_fetch_array($result);
scl_csv.php(33) while ($r = mysql_fetch_array($result)) {
uty.php(51) return mysql_escape_string($s);
__initial.php(99) if (mysql_connect($s_initinf['dbhost'], $s_initinf['dbuser'], $s_initinf['dbpass'])){
__initial.php(101) mysql_select_db('mysql');
__initial.php(102) mysql_query('CREATE DATABASE ' . $s_initinf['dbname']);
__initial.php(104) mysql_select_db($s_initinf['dbname']);
__initial.php(106) mysql_query($val);
__initial.php(135) if (mysql_connect($s_initinf['dbhost'], $s_initinf['dbuser'], $s_initinf['dbpass'])){
__initial.php(136) mysql_select_db($s_initinf['dbname']);
__initial.php(138) mysql_query($val);
```

```php:引数の修正
mysql_ → mysqli_ 変更後
uty.php(51)
return mysqli_escape_string($s);
↓
return mysqli_escape_string(s_getDb(), $s);

getdbmysql.php(24)
return mysqli_query($query);
↓
return mysqli_query($db, $query);

getdbmysql.php(28)
$a = mysqli_fetch_array($result);
↓
$a = mysqli_fetch_array(s_getDb(), $result);
```
### ブラウザ対応
Chromeではログイン情報がセンターに表示されないので修正

```html:login.tpl
<table summary="ログイン情報" border=1 cellspacing=1 cellpadding=1 align="center">
↓
<table summary="ログイン情報" border=1 cellspacing=1 cellpadding=1 align="center" style="margin-left:auto;margin-right:auto;">
```

## LiteScl.odaの導入
[LiteScl.oda (大田市スケジュールWeb)](http://www.city.ohda.lg.jp/tag/27/11464)から、最新版のLiteScl.oda Ver3.23bをダウンロードし、Webサーバー(D:\Apache24\htdocsフォルダ)内に「litescl」フォルダを置きます。フォルダ名はリネーム可能です。

## .htaccess でファイルの一覧表示を制御する
Webサーバー(D:\Apache24\htdocs\litescl)フォルダ内に、「.htaccess」を作成します。

```bash:.htaccess

# 一覧表示を禁止する場合
Options -Indexes
```

参照:[.htaccess でディレクトリ内のファイル一覧表示を制御する ( -Indexes )](http://hensa40.cutegirl.jp/archives/1366)

## ファイルのアクセス権
必要に応じて、現時点では特にしない。

## ファイアーウォールの設定
Windows Server 2008R2では、ポートを開放しないと外部からWebサーバーに繋がらないため、下記サイトを参考に1080ポートを開放、名前は「HTTP(1080)」とした。
参照:[Windows Server 2008のポート80を開ける](http://server.aulta.net/windows-server-2008-standard-edition-r2-64bit/windows-server-2008-port80)

## 導入環境「WampServer」の紹介
今回は使用していないが、Windowsシステム上にApache, PHP5, MySQLを一括してインストールする環境として「[WampServer](https://osdn.jp/projects/sfnet_wampserver/)」が用意されている。 

## 動作確認
Apacheの動作確認：「localhost:1080/index.html」として「It works!」と表示される。
PHPの動作確認：Webサーバー(D:\Apache24\htdocsフォルダ)内に下記のindex.phpを作成して「localhost:1080/index.php」としてPHP情報が表示がされる。
PHP情報が表示されない場合、httpd.confの設定で「AddType application/x-httpd-php .php」の追記を忘れている可能性がある。

```php:index.php
<?php
phpinfo();
?>
```
# スケジュールWeb「LiteScl.oda」の起動
「localhost:1080/litescl/initial.php」をブラウザで開きます。
MySqlインストール時に設定したユーザー名(root)とPWを入力する。

導入処理(データベースとテーブル生成)
![litescl_initial.png](https://qiita-image-store.s3.amazonaws.com/0/14053/1badccf0-9433-f8c3-8086-986b7f3e3116.png)

※導入処理後はinitial.phpをリネームするか削除してください。

下記のエラーが発生した場合、php.iniの「extension_dir = "D:\php5\ext"」の設定忘れか、「libmysql.dll」のコピー忘れの可能性があります。

```bash
DB情報を書き込みました

Fatal error: Call to undefined function mysql_connect() in D:\Apache24\htdocs\litescl\initial.php on line 99
```

ログイン画面
![litescl_login.png](https://qiita-image-store.s3.amazonaws.com/0/14053/5d6a7b97-7cb5-5d8d-ede0-8e0e2adb17ee.png)

※導入処理後はinitial.phpをリネームするか削除してください。

* ログイン画面の標題→skjweb.gifを変更してください。
* アプリケーション名→conf.php　APPNAMEを変更してください。

# 週間スケジュール表示
<img src="http://www.city.ohda.lg.jp/images/220130118141449.jpg">

# 予定の入力
スケジュール入力画面
<img src="http://www.city.ohda.lg.jp/images/320130118141449.jpg">

複数日の入力やtodo機能、非公開制御、予定対象者の選択などの機能が見られる。
![litescl_task.png](https://qiita-image-store.s3.amazonaws.com/0/14053/fcc36606-f9df-0620-8ac3-e14084078296.png)


# 仕様
## グループとユーザー
文字数の設定は次のとおり
グループid 10文字（半角英数）
グループ名 20文字
ユーザーid 20文字（半角英数）
ユーザー名 20文字
パスワード 10文字（半角英数記号）

adminでログイン後、登録の流れは次のようになります。

①グループの登録
②ユーザーの登録（既定グループの登録）
③グループにユーザーの追加（複数所属の場合）

## グループについて
「グループID」10桁のうち先頭3桁が同一で公開となっているものについては同一グループ内でスケジュールが共有できるようにしています。
また公開・非公開関係なく先頭5桁が同じものは同一グループで共有します。

仕様：共有できるスケジュールの範囲はユーザー情報のグループIDと比較して
* グループID先頭3桁が同じ公開グループ
* グループID先頭5桁が同じグループ
* 自分が所属するグループの構成員

※修正したい場合はgrp_e_m.phpのSQL部分を修正

## 祝日について
祝日の設定が必要です。
2003-2007年,2012-2020年まで設定されています。
設定ファイルは「holinf.php」です。
祝日以外の休日設定も可能です

## その他参考事項
* 画面の配色、文字の大きさ等→style_XX.cssの各値を変更
* 本システムのデータは全てMySQLデータベース内に格納されていますのでバックアップをおこないたい場合はMySQLデータのバックアップをおこなってください。

## ライセンス
BSDライセンス
LiteScl.oda Copyright (C) 2012 32205大田市

# 改良したいところ
* デザイン
* 予定日の複数一括登録 例 4/29～5/5、5/8～5/9 を一括登録
* スケジュールのカレンダーの２週間表示
* 予定内容の入力で対象者を複数選択した場合の分割登録機能
* 予定名のTodo一覧化機能