add rest application and discount-status rest method

This commit is contained in:
Roland Schneider 2018-08-31 07:50:14 +02:00
parent 017bf0f9e4
commit 767211d6c7
33 changed files with 805 additions and 16 deletions

View File

@ -3,3 +3,4 @@ Yii::setAlias('common', dirname(__DIR__));
Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('rest', dirname(dirname(__DIR__)) . '/rest');

View File

@ -3,7 +3,6 @@
namespace common\models;
use Yii;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\db\Expression;
use common\components\Helper;
@ -241,18 +240,23 @@ class Ticket extends \common\models\BaseFitnessActiveRecord
}
/**
* @param \common\models\Card $card the card to which we are looking for
*
* @return array|\yii\db\ActiveRecord[]
*/
public static function readActive($card){
/**
* @param \common\models\Card $card the card to which we are looking for
*
* @param \DateTime $validOnDay on which day must be the ticket valid
* @return array|\yii\db\ActiveRecord[]
*/
public static function readActive($card, $validOnDay = null){
if ( $card == null )
return [];
$query = Ticket::find();
$today = date('Y-m-d');
if (!isset( $validOnDay ) ){
$today = date('Y-m-d');
}else{
$today = $validOnDay->format('Y-m-d');
}
$query->andWhere(['ticket.id_card' => $card->id_card]);
$query->andWhere( 'ticket.start <= :today' ,[ 'today' => $today] );

View File

@ -71,6 +71,8 @@ class User extends ActiveRecord implements IdentityInterface
*/
public static function findIdentityByAccessToken($token, $type = null)
{
$authorization = base64_decode($token);
\Yii::info("findIdentityByAccessToken", $authorization);
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}

View File

@ -0,0 +1,44 @@
<?php
use yii\db\Schema;
use yii\db\Migration;
use common\models\User;
class m180829_155430_add_rest_user extends Migration
{
/**
* @return bool|void
* @throws Exception
*/
public function up()
{
$user = new User();
$user->username = "discount_system";
$user->email = "discount_system@rocho-net.hu";
$user->setPassword("NmqFb\ivjtX1=yT*Aw5Y");
$user->generateAuthKey();
$user->save();
$role = Yii::$app->authManager->createRole('discount_system');
Yii::$app->authManager->add($role);
Yii::$app->authManager->assign($role, $user->id);
}
public function down()
{
echo "m180829_155430_add_rest_user cannot be reverted.\n";
return false;
}
/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}

View File

@ -9,5 +9,6 @@ docker run \
-p 86:80 \
--name fitness-web \
--hostname test.fintess_web.hu \
--link mariadb1:mariadb1 \
-e XDEBUG_CONFIG="idekey=PHPSTORM" \
docker_fitness-ub-php-7:latest

View File

@ -0,0 +1,21 @@
<?php
$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];
if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
return $config;

View File

@ -0,0 +1,3 @@
<?php
return [
];

View File

@ -0,0 +1,18 @@
<?php
// NOTE: Make sure this file is not accessible when deployed to production
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) {
die('You are not allowed to access this file.');
}
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = require(__DIR__ . '/../../tests/codeception/config/frontend/acceptance.php');
(new yii\web\Application($config))->run();

View File

@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();

View File

@ -36,6 +36,8 @@ return [
'backend/web/assets',
'frontend/runtime',
'frontend/web/assets',
'rest/runtime',
'rest/web/assets',
],
'setExecutable' => [
'yii',
@ -44,6 +46,7 @@ return [
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
'rest/config/main-local.php',
],
],
'Production' => [
@ -53,6 +56,8 @@ return [
'backend/web/assets',
'frontend/runtime',
'frontend/web/assets',
'rest/runtime',
'rest/web/assets',
],
'setExecutable' => [
'yii',
@ -60,6 +65,7 @@ return [
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
'rest/config/main-local.php',
],
],
'rochonet' => [
@ -69,6 +75,8 @@ return [
'backend/web/assets',
'frontend/runtime',
'frontend/web/assets',
'rest/runtime',
'rest/web/assets',
],
'setExecutable' => [
'yii',
@ -76,6 +84,7 @@ return [
'setCookieValidationKey' => [
'backend/config/main-local.php',
'frontend/config/main-local.php',
'rest/config/main-local.php',
],
],
];

View File

@ -0,0 +1,9 @@
<?php
return [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '',
],
],
];

View File

@ -0,0 +1,3 @@
<?php
return [
];

View File

@ -0,0 +1,18 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);
$application = new yii\web\Application($config);
$application->run();

View File

@ -13,14 +13,14 @@ return [
'bootstrap' => ['log'],
'controllerNamespace' => 'frontend\controllers',
'components' => [
'assetsAutoCompress' =>
[
'class' => '\iisns\assets\AssetsCompressComponent',
'enabled' => true,
'jsCompress' => true,
'cssFileCompile' => true,
'jsFileCompile' => true,
],
// 'assetsAutoCompress' =>
// [
// 'class' => '\iisns\assets\AssetsCompressComponent',
// 'enabled' => true,
// 'jsCompress' => true,
// 'cssFileCompile' => true,
// 'jsFileCompile' => true,
// ],
'request' => [
'enableCsrfValidation'=>false,
],

30
rest/assets/AppAsset.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace rest\assets;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
'js/app.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}

View File

@ -0,0 +1,37 @@
<?php
/**
* Configuration file for the "yii asset" console command.
* Note that in the console environment, some path aliases like '@webroot' and '@web' may not exist.
* Please define these missing path aliases.
*/
Yii::setAlias('@webroot', realpath(__DIR__ . '/../web'));
Yii::setAlias('@web', '/');
return [
// Adjust command/callback for JavaScript files compressing:
'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to} --warning_level QUIET',
// Adjust command/callback for CSS files compressing:
'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}',
// The list of asset bundles to compress:
'bundles' => [
'rest\assets\AppAsset',
'yii\web\YiiAsset',
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset'
],
// Asset bundle for compression output:
'targets' => [
'allRest' => [
'class' => 'rest\assets\MyAsset' ,
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
],
],
// Asset manager configuration:
'assetManager' => [
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
],
];

2
rest/config/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
main-local.php
params-local.php

View File

@ -0,0 +1 @@
<?php

43
rest/config/main.php Normal file
View File

@ -0,0 +1,43 @@
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-rest',
'name' =>'Fitness recepció',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'rest\controllers',
'components' => [
'request' => [
'enableCsrfValidation'=>false,
'csrfParam' => '_csrf-rest',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'user' => [
'identityClass' => 'common\models\User',
'enableSession' => false,
'enableAutoLogin' => false,
'loginUrl' => null,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
],
'params' => $params,
];

4
rest/config/params.php Normal file
View File

@ -0,0 +1,4 @@
<?php
return [
'adminEmail' => 'admin@example.com',
];

View File

@ -0,0 +1,99 @@
<?php
/**
* Created by IntelliJ IDEA.
* User: rocho
* Date: 2018.08.29.
* Time: 21:58
*/
namespace rest\controllers;
use common\components\Helper;
use common\models\Card;
use common\models\Ticket;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
class CustomerController extends RestController
{
/**
* @param $number
* @param int $lastXDays default 0. Search for valid tickets also in the last x days.
* @return array
* @throws \Exception
*/
public function actionDiscountStatus($number , $lastXDays = 0 ){
$number = Helper::fixAsciiChars( $number );
$query = Card::find();
$query->andWhere(['or',
['and',[ 'in','card.number' , [$number]],"trim(coalesce(card.number, '')) <>'' " ],
['and', ['in','card.rfid_key' ,[ $number] ],"trim(coalesce(card.rfid_key, '')) <>'' "],
]);
$card = $query->one();
if ( !isset($card)){
throw new NotFoundHttpException("Kártya nem található");
}
$customer = $card->customer;
if ( !isset($customer) ){
throw new NotFoundHttpException("Vendég nem található");
}
if ( isset($lastXDays) ){
if (!is_numeric($lastXDays)){
throw new BadRequestHttpException("lastXDays paraméter hibás");
}
if ( $lastXDays > 6 || $lastXDays < 1){
throw new BadRequestHttpException("lastXDays paraméter érték hibás");
}
}
// check if has valid ticket today
/** @var \common\models\Card $card */
$tickets = Ticket::readActive($card );
$hasValidTicket = count($tickets) > 0;
// try to find any valid ticket in the lastXDays
$minusDay = 1;
while ( !$hasValidTicket && $minusDay <= $lastXDays ){
/** @var integer $minusDay */
$day = $this->getDateMinusDays($minusDay);
$tickets = Ticket::readActive($card, $day );
$hasValidTicket = count($tickets) > 0;
$minusDay = $minusDay + 1;
}
$result = [
'discount' => $hasValidTicket
];
if ( isset($customer) ){
$result['card_number'] = $card->number;
$result['name'] = $customer->name;
}
return $result;
}
/**
* @param $minusDays
* @return \DateTime
* @throws \Exception
*/
private function getDateMinusDays($minusDays){
$date = new \DateTime('now');
$date->sub(new \DateInterval('P'.$minusDays.'D'));
$date->setTime(0,0,0);
return $date;
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace rest\controllers;
use common\models\User;
use yii\filters\auth\HttpBasicAuth;
use yii\rest\Controller;
class RestController extends Controller
{
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'auth' => [$this, 'auth']
];
return $behaviors;
}
public function auth($username, $password)
{
try {
$user = User::findOne(['username' => $username]);
if ($user->validatePassword($password)) {
return $user;
}
} catch (\Exception $e) {
\Yii::error("Failed to load user: " . $e->getMessage());
}
return null;
}
}

View File

@ -0,0 +1,124 @@
<?php
namespace rest\controllers;
use Yii;
use common\models\LoginForm;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\User;
use common\components\Helper;
use common\models\Log;
/**
* Site controller
*/
class SiteController extends Controller
{
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout' ],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
/**
* @inheritdoc
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
/**
* Displays homepage.
*
* @return mixed
*/
public function actionIndex()
{
return $this->render('index');
}
/**
* Logs in a user.
*
* @return mixed
*/
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
$geoip = Helper::getGeoIp();
$message = "";
$user = User::findOne(\Yii::$app->user->id);
if ( isset($geoip)){
$ip = isset( $geoip->ip ) ? $geoip->ip : "";
$city = isset( $geoip->city ) ? $geoip->city : "";
$message = "Bejelentkezés: " .$user->username. " Ip cím:". $ip . " Város: " . $city;
}
Log::log([
'type' =>Log::$TYPE_LOGIN,
'message' => $message
]);
return $this->redirect(['account/select']);
} else {
return $this->render('login', ['model' => $model,]);
}
}
/**
* Logs out the current user.
*
* @return mixed
*/
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
}

2
rest/runtime/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,84 @@
<?php
/* @var $this \yii\web\View */
/* @var $content string */
use yii\helpers\Html;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use rest\assets\AppAsset;
use common\widgets\Alert;
use kartik\widgets\AlertBlock;
use yii\helpers\Url;
AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<script>
var reception_card_url = '<?php echo Url::toRoute('customer/reception');?>';
</script>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
<?php
$items = [];
NavBar::begin([
'brandLabel' => 'Web Recepció',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'navbar-inverse navbar-fixed-top',
],
]);
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $items,
]);
NavBar::end();
?>
<div class="container">
<?= Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<?= Alert::widget() ?>
<?= $content ?>
</div>
</div>
<footer class="footer" style="min-height: 60px; height: auto;">
<div class="container">
<div class="row">
<div class="col-md-12">
<p class="pull-left">&copy; <?= Yii::$app->name ?> <?= Yii::$app->params['version'] ?> Fitness - WebAdmin <?= date('Y') ?></p>
</div>
</div>
<div class="row">
<div class="col-md-12">
Ingyenesen használható alkalmazás.
Az oldalon szereplő adatok csak tájékoztató jellegűek.<br>
Az adatok helyességéért és igazságtartalmáért felelősséget nem vállalunk.<br>
Az oldal nem használható hivatalos adatforrásként.<br>
</div>
</div>
</div>
</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

27
rest/views/site/error.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/* @var $this yii\web\View */
/* @var $name string */
/* @var $message string */
/* @var $exception Exception */
use yii\helpers\Html;
$this->title = $name;
?>
<div class="site-error">
<h1><?= Html::encode($this->title) ?></h1>
<div class="alert alert-danger">
<?= nl2br(Html::encode($message)) ?>
</div>
<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>
</div>

14
rest/views/site/index.php Normal file
View File

@ -0,0 +1,14 @@
<?php
/* @var $this yii\web\View */
$this->title = 'My Yii Application';
?>
<div class="site-index">
<div class="jumbotron">
<h1>Web Recepció</h1>
<p class="lead">Üdvözöljük Web Recepció oldalunkon!</p>
</div>
</div>

39
rest/views/site/login.php Normal file
View File

@ -0,0 +1,39 @@
<?php
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \common\models\LoginForm */
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
$this->title = Yii::t('common/site' ,'Login');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-login">
<h1><?= Html::encode($this->title) ?></h1>
<p>Please fill out the following fields to login:</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'rememberMe')->checkbox() ?>
<div style="color:#999;margin:1em 0">
<?= Html::a(Yii::t('common/site' ,'Forgot password'), ['site/request-password-reset']) ?>.
</div>
<div class="form-group">
<?= Html::submitButton(Yii::t('common/site' ,'Login'), ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>

2
rest/web/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/index.php
/index-test.php

91
rest/web/css/site.css Normal file
View File

@ -0,0 +1,91 @@
html,
body {
height: 100%;
}
.wrap {
min-height: 100%;
height: auto;
margin: 0 auto -60px;
padding: 0 0 60px;
}
.wrap > .container {
padding: 70px 15px 20px;
}
.footer {
height: 60px;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
padding-top: 20px;
}
.jumbotron {
text-align: center;
background-color: transparent;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
.not-set {
color: #c55;
font-style: italic;
}
/* add sorting icons to gridview sort links */
a.asc:after, a.desc:after {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
padding-left: 5px;
}
a.asc:after {
content: /*"\e113"*/ "\e151";
}
a.desc:after {
content: /*"\e114"*/ "\e152";
}
.sort-numerical a.asc:after {
content: "\e153";
}
.sort-numerical a.desc:after {
content: "\e154";
}
.sort-ordinal a.asc:after {
content: "\e155";
}
.sort-ordinal a.desc:after {
content: "\e156";
}
.grid-view th {
white-space: nowrap;
}
.hint-block {
display: block;
margin-top: 5px;
color: #999;
}
.error-summary {
color: #a94442;
background: #fdf7f7;
border-left: 3px solid #eed3d7;
padding: 10px 20px;
margin: 0 0 15px 0;
}

BIN
rest/web/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

2
rest/web/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow: