Compare commits

..

No commits in common. "bd719a0219c15a9b85cf5ec8917de1e2ffce86a9" and "1da1b42c14e5aba0d8e7387d0abea3e6290cb484" have entirely different histories.

9 changed files with 8 additions and 567 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
config.php config.php
.htaccess

View File

@ -1,67 +0,0 @@
# Timecard
退勤管理などで使用できるタイムカードアプリです。
## 必要なもの
- MySQL サーバー
- PHPが動くウェブサーバー
## インストール方法
1. ウェブサイトにTimecardをアップロードします。
2. install.php にアクセスします。
3. インストールをクリックしてインストール作業を始めます。
4. 最後にインストーラー削除をクリックして完了です。
## 設定方法
1. config.sample.php をコピーし、そのファイルをconfig.phpに改名します。
2. mysqlの項目を設定します。
3. canonicalにはタイムカードを配置したURLを入力します。
4. heads にはスクリプトのソースなど、HEADタグないに自動追加したいタグなどを入力します。必要なければそのままでOK
5. admin_usersには管理者権限を持つユーザー名を入力します。例えば、作成したユーザー「root」に管理者権限を持たせるには、admin_usersに「root」を追加します。
## デザインの修正
template フォルダ内のファイルを修正します。
### view.php
メインで表示される画面です。
### create.php
ユーザー作成画面で表示される画面です。
### login.php
ユーザーログイン画面で表示される画面です。
### passwd.php
パスワード変更時に表示される画面です。
### error.php
サーバーエラー発生時に表示される画面です。
## システムの修正
provide フォルダ内のファイルを修正します。
### BootLoader.php
ページの追加などはBootLoaderを修正します。
## バグなど
メールとかSNSとか、issuesとかから報告してもらえたら修正すると思います。
## License
Bootstrap
[https://getbootstrap.jp/](https://getbootstrap.jp/)

View File

@ -1,5 +1,6 @@
<?php <?php
ini_set("display_erros", "on");
require_once __DIR__ . '/provide/autoload.php'; require_once __DIR__ . '/provide/autoload.php';
$boot = new BootLoader(__DIR__); $boot = new BootLoader(__DIR__);

View File

@ -1,7 +0,0 @@
<?php
require_once __DIR__ . '/provide/autoload.php';
$boot = new BootLoader(__DIR__);
$boot->install();

View File

@ -32,15 +32,8 @@ class BootLoader
$isAdmin = false; $isAdmin = false;
$loginUser = []; $loginUser = [];
$works = []; $works = [];
$month = 0;
$page = filter_input(INPUT_GET, "p") ?? "home"; $page = filter_input(INPUT_GET, "p") ?? "home";
$tmonth = filter_input(INPUT_GET, "m");
if ($result = filter_var($tmonth, FILTER_VALIDATE_INT))
{
$month = $result;
}
if ($user->hasLogout()) if ($user->hasLogout())
{ {
@ -116,7 +109,7 @@ class BootLoader
} }
$result = $this->cards->hasCard($loginUser["id"], $isAdmin); $result = $this->cards->hasCard($loginUser["id"], $isAdmin);
$works = $this->cards->SelectTimes($loginUser["id"], $month); $works = $this->cards->SelectTimes($loginUser["id"]);
$lastCard = $this->cards->getLastInsert($loginUser["id"]); $lastCard = $this->cards->getLastInsert($loginUser["id"]);
$users = $this->cards->getUsers(); $users = $this->cards->getUsers();
@ -125,7 +118,6 @@ class BootLoader
"users" => $users, "users" => $users,
"user" => $loginUser, "user" => $loginUser,
"works" => $works, "works" => $works,
"queryTime" => $this->cards->queryTime,
"canonical" => $this->config["canonical"], "canonical" => $this->config["canonical"],
"config" => $this->config, "config" => $this->config,
"addCard" => $result, "addCard" => $result,
@ -167,104 +159,4 @@ class BootLoader
$this->pdo = $db->getDB(); $this->pdo = $db->getDB();
$this->config = $config; $this->config = $config;
} }
/**
* Install Timecard
*/
public function install()
{
try {
$step = "welcome";
$configPath = $this->root . '/config.php';
if (!file_exists($configPath))
{
$from = @file_get_contents($this->root . "/config.sample.php");
@file_put_contents($configPath, $from);
}
$install = new Installer($configPath);
$install->open();
$fStep = filter_input(INPUT_POST, "step");
switch ($fStep)
{
case "welcome":
$step = "mysql";
break;
case "mysql":
$hostname = filter_input(INPUT_POST, "hostname");
$dbname = filter_input(INPUT_POST, "dbname");
$username = filter_input(INPUT_POST, "username");
$password = filter_input(INPUT_POST, "password");
$install->readToBuffer();
$install->setKeyBuffer("hostname", $hostname);
$install->setKeyBuffer("dbname", $dbname);
$install->setKeyBuffer("username", $username);
$install->setKeyBuffer("password", $password);
$install->writeBuffer();
$step = "link";
break;
case "link":
$url = filter_input(INPUT_POST, "url");
$install->readToBuffer();
$install->setKeyBuffer("canonical", $url);
$install->writeBuffer();
$step = "account";
break;
case "account":
$this->InitPDO();
$this->cards = new Timecard($this->pdo);
$this->cards->InitTables();
$user = new User($this->pdo);
$username = filter_input(INPUT_POST, "username");
if (!$user->hasCreate())
{
throw new \RuntimeException("ユーザーを作成できませんでした。");
}
$install->readToBuffer();
$install->setKeyBuffer("admin_users", "[" . $username . "]", false);
$install->writeBuffer();
$step = "done";
break;
case "done":
@unlink($this->root . "/install.php");
header("Location: index.php");
exit;
break;
default:
break;
}
$install->close();
$this->model->viewModel("install", [
"step" => $step
]);
} catch (\RuntimeException $e)
{
http_response_code(401);
$result = $this->model->viewModel("error", [
"exception" => $e,
"message" => $e->getMessage(),
"config" => $this->config,
]);
if (!$result)
{
echo $e->getMessage();
exit;
}
}
}
} }

View File

@ -1,150 +0,0 @@
<?php
class Installer
{
public function __construct($file)
{
$this->filePath = $file;
}
protected $filePath;
protected $fp;
public function open()
{
$this->fp = fopen($this->filePath, "r+");
return $this->fp;
}
public function close()
{
fclose($this->fp);
}
public function read()
{
return fgets($this->fp, 4096);
}
public function write($value)
{
fwrite($this->fp, $value);
}
protected $buffer = [];
public function dumpBuffer()
{
return $this->buffer;
}
public function readToBuffer()
{
$line = false;
while (($line = $this->read()) !== false) {
$line = trim($line);
array_push($this->buffer, $line);
}
}
public function writeBuffer()
{
ftruncate($this->fp,0);
fseek($this->fp, 0, SEEK_SET);
for ($i = 0; $i < count($this->buffer); $i++)
{
$this->write($this->buffer[$i] . PHP_EOL);
}
}
public function setKeyBuffer($key, $value, $formal = true)
{
$key = $this->format($key);
if ($formal)
{
$value = $this->format($value);
}
for ($i = 0; $i < count($this->buffer); $i++)
{
$line = $this->buffer[$i];
$line = trim($line);
$args = explode("=>", $line);
if (count($args) != 2)
{
continue;
}
$args[0] = trim($args[0]);
$args[1] = trim($args[1]);
if ($args[0] == $key)
{
$args[1] = $value;
$newLine = $args[0] . " => " . $args[1];
$last = mb_substr($line, -1);
if ($last == ",")
{
$newLine .= ",";
}
$this->buffer[$i] = $newLine;
break;
}
}
}
public function rewrite($key, $value)
{
$line = false;
$key = $this->format($key);
$value = $this->format($value);
$args = [$key, $value];
$buffer = [];
while (($line = $this->read()) !== false) {
$line = trim($line);
$args = explode("=>", $line);
if (count($args) != 2)
{
array_push($buffer, $line);
continue;
}
$args[0] = trim($args[0]);
$args[1] = trim($args[1]);
if ($args[0] == $key)
{
$args[1] = $value;
$newLine = $args[0] . " => " . $args[1];
$last = mb_substr($line, -1);
if ($last == ",")
{
$newLine .= ",";
}
} else {
$newLine = $line;
}
echo $newLine . PHP_EOL;
array_push($buffer, $newLine);
}
ftruncate($this->fp,0);
fseek($this->fp, 0, SEEK_SET);
for ($i = 0; $i < count($buffer); $i++)
{
$this->write($buffer[$i] . "\n");
}
}
public function format($value)
{
return "\"" . $value . "\"";
}
}

View File

@ -12,7 +12,6 @@ class Timecard
} }
protected $pdo; protected $pdo;
public $queryTime = [];
public function InitTables() public function InitTables()
{ {
@ -95,36 +94,16 @@ class Timecard
return true; return true;
} }
public function SelectTimes($uid, $month = 0) public function SelectTimes($uid)
{ {
try { try {
$mm = strtotime(sprintf("%dmonth", $month));
$today = ((int) date("d")) - 1; $today = ((int) date("d")) - 1;
$dayCount = (int) date("t"); $dayCount = (int) date("t");
if ( $month == 0 ) $startTime = date("Y-m-d 00:00:00", strtotime(sprintf("-%ddays", $today)));
{ $endTime = date("Y-m-d 00:00:00", strtotime(sprintf("+%ddays", $dayCount - $today)));
$startTime = date("Y-m-d 00:00:00", strtotime(sprintf("-%ddays", $today)));
$endTime = date("Y-m-d 00:00:00", strtotime(sprintf("+%ddays", $dayCount - $today)));
} else {
$y = date("Y", $mm);
$m = date("m", $mm);
$ly = $y;
$lm = $m + 1;
if ($lm > 12)
{
$ly += 1;
$lm = 1;
}
$startTime = date("Y-m-d 00:00:00", strtotime(sprintf("%d-%d-01", $y, $m))); $smt = $this->pdo->prepare("SELECT * FROM cards WHERE startTime > ? AND endTime < ? AND uid=?;");
$endTime = date("Y-m-d 00:00:00", strtotime(sprintf("%d-%d-01", $ly, $lm)));
}
$this->queryTime = [$startTime, $endTime];
$smt = $this->pdo->prepare("SELECT * FROM cards WHERE startTime > ? AND startTime < ? AND uid=?;");
$smt->execute([ $smt->execute([
$startTime, $startTime,
$endTime, $endTime,

View File

@ -1,183 +0,0 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>インストール | タイムカード</title>
<link rel="canonical" href="<?php echo $args["canonical"]; ?>" />
<link rel="stylesheet" href="<?php echo $args["canonical"]; ?>css/bootstrap.min.css" />
<?php foreach ($args["config"]["heads"] as $key => $val): ?>
<?php echo $val; ?>
<?php endforeach; ?>
</head>
<body>
<div class="container">
<h2>タイムカード</h2>
</div>
<div class="container mt-3">
<?php if($args["step"] == "welcome"): ?>
<h2>Welcome to Installer</h2>
<p>
インストーラーを実行するには、ボタンをクリックしてください。
</p>
<form class="form" method="POST">
<button class="btn btn-success" name="step" value="welcome">インストール</button>
</form>
<?php elseif($args["step"] == "done"): ?>
<h2>インストール完了</h2>
<p>
インストール作業が完了しました。<br />
インストーラーを削除するには、ボタンをクリックしてください。
</p>
<form class="form" method="POST">
<button class="btn btn-danger" name="step" value="done">インストーラー削除</button>
</form>
<?php elseif($args["step"] == "mysql"): ?>
<h2>MYSQL設定</h2>
<form class="form" method="POST">
<div class="form-group row">
<div class="col-md-2">
<label for="hostname" class="form-label">ホスト名</label>
</div>
<div class="col-md-7">
<input class="form-control" type="text" name="hostname" id="hostname" required />
</div>
<div class="col-md-3 form-text">
ホスト名を入力してください。
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="dbname" class="form-label">データベース名</label>
</div>
<div class="col-md-7">
<input class="form-control" type="text" name="dbname" id="dbname" required />
</div>
<div class="col-md-3 form-text">
データベース名を入力してください。
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="username" class="form-label">ユーザー名</label>
</div>
<div class="col-md-7">
<input class="form-control" type="text" name="username" id="username" required />
</div>
<div class="col-md-3 form-text">
ユーザー名を入力してください。
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password" class="form-label">パスワード</label>
</div>
<div class="col-md-7">
<input class="form-control" type="password" name="password" id="password" required />
</div>
<div class="col-md-3 form-text">
パスワードを入力してください。
</div>
</div>
<input type="hidden" name="step" value="mysql" />
<div class="form-group row">
<div class="col-md-2">
</div>
<div class="col-md-7">
<button class="btn btn-primary" type="submit">設定</button>
</div>
<div class="col-md-3 form-text">
</div>
</div>
</form>
<?php elseif($args["step"] == "link"): ?>
<h2>リンク設定</h2>
<form class="form" method="POST">
<div class="form-group row">
<div class="col-md-2">
<label for="url" class="form-label">ウェブサイトURL</label>
</div>
<div class="col-md-7">
<input class="form-control" type="url" name="url" id="url" required />
</div>
<div class="col-md-3 form-text">
ウェブサイトURLを入力してください。
</div>
</div>
<input type="hidden" name="step" value="link" />
<div class="form-group row">
<div class="col-md-2">
</div>
<div class="col-md-7">
<button class="btn btn-primary" type="submit">設定</button>
</div>
<div class="col-md-3 form-text">
</div>
</div>
</form>
<?php elseif($args["step"] == "account"): ?>
<h2>管理者アカウント作成</h2>
<form class="form" method="POST">
<div class="form-group row">
<div class="col-md-2">
<label for="username" class="form-label">ユーザー名</label>
</div>
<div class="col-md-7">
<input type="text" value="" class="form-control" name="username" id="username" />
</div>
<div class="col-md-3 form-text">
ユーザー名を入力してください。
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password" class="form-label">パスワード</label>
</div>
<div class="col-md-7">
<input type="password" value="" class="form-control" name="password" id="password" />
</div>
<div class="col-md-3 form-text">
パスワードを入力してください。
</div>
</div>
<input type="hidden" name="mode" value="create" />
<input type="hidden" name="step" value="account" />
<div class="form-group row">
<div class="col-md-2">
</div>
<div class="col-md-7">
<button class="btn btn-primary" type="submit">作成</button>
</div>
<div class="col-md-3 form-text">
</div>
</div>
</form>
<?php endif; ?>
</div>
<div class="container">
<footer class="footer">
<div class="container text-center">
<p class="text-muted">
Copyright &copy; 2022 <a href="https://devras.net">DevRas</a> All Rights Reserved.
</p>
<p class="text-muted">
TimeCard v1.0.0
<a href="https://github.com/kemasama/Timecard">github</a>
</p>
</div>
</footer>
</div>
</body>
</html>

View File

@ -118,37 +118,12 @@
<hr /> <hr />
<?php if($args["logged"]): ?> <?php if($args["logged"]): ?>
<div class="container-fluid row">
<div class="col-md-4 offset-md-5">
<nav aria-label="Page navigation">
<ul class="pagination">
<li class="page-item"><a class="page-link" href="?m=-2">先々月</a></li>
<li class="page-item"><a class="page-link" href="?m=-1">先月</a></li>
<li class="page-item"><a class="page-link" href="?m=0">今月</a></li>
</ul>
</nav>
</div>
</div>
<div class="container mt-3"> <div class="container mt-3">
<?php if(empty($args["works"]) && !$args["lastCard"]): ?> <?php if(empty($args["works"]) && !$args["lastCard"]): ?>
<p class="text-danger">タイムカードは登録されていません。</p> <p class="text-danger">タイムカードは登録されていません。</p>
<?php else: ?> <?php else: ?>
<?php $hours = 0; $minutes = 0; ?> <?php $hours = 0; $minutes = 0; ?>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover table-bordered">
<tr>
<th>開始日</th>
<th>終了日</th>
</tr>
<tr>
<th><?php echo $args["queryTime"][0]; ?></th>
<th><?php echo $args["queryTime"][1]; ?></th>
</tr>
</table>
</div>
<div class="table-responsive mt-1">
<table class="table table-hover table-bordered"> <table class="table table-hover table-bordered">
<tr> <tr>
<th>始業</th> <th>始業</th>