Merge branch 'develop' into 'master'

all features to master

See merge request group_rocho02/fitness-web!1
This commit is contained in:
rocho 2023-09-14 07:18:46 +00:00
commit 4ca91056b1
616 changed files with 84462 additions and 1649 deletions

6
.gitignore vendored
View File

@ -52,7 +52,13 @@ phpunit.phar
/customerapi/web/assets/**
!/customerapi/web/assets/.gitkeep
/mobileapi/web/assets/**
!/mobileapi/web/assets/.gitkeep
/customerapi/config/*-local.php
/customerapi/runtime/logs/**
!/customerapi/runtime/.gitkeep
environments/cutlergyor/apache2/data

View File

@ -1,6 +1,32 @@
## Start the app
```bash
fitness_web/environments/cutlergyor/apache2
docker-compose up -d
```
Frontend
http://localhost:42001/cutler/frontend/web/index.php?r=site%2Flogin
Backend
http://localhost:42001/cutler/backend/web/index.php?r=site%2Flogin
Rest
[rest.http](rest.http)
## Craete a cutlergyor deployment
See [environments/cutlergyor/apache2/readme.md](environments/cutlergyor/apache2/readme.md)
Yii 2 Advanced Project Template
===============================
Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
developing complex Web applications with multiple tiers.

View File

@ -2,6 +2,7 @@
namespace backend\controllers;
use Mpdf\Mpdf;
use Yii;
use common\models\AccountState;
use backend\models\AccountStateSearch;
@ -11,6 +12,7 @@ use yii\filters\VerbFilter;
use common\models\Account;
use common\models\User;
use common\components\DailyListing;
use common\components\MpdfUtil;
/**
* AccountStateController implements the CRUD actions for AccountState model.
@ -93,7 +95,7 @@ class AccountStateController extends \backend\controllers\BackendController
if ($output == 'pdf') {
$user = User::findOne(\Yii::$app->user->id);
$mpdf=new \mPDF('utf-8', 'A4-L');
$mpdf= MpdfUtil::createMpdfWith6XConstructor('utf-8', 'A4-L');
$mpdf->useSubstitutions=false;
$mpdf->simpleTables = true;
$mpdf->SetHeader( \Yii::$app->params[ "company_name" ] . " - Létrehozva: " .$user->username . ", ".\Yii::$app->formatter->asDatetime(time()) );

View File

@ -8,7 +8,6 @@ use backend\models\CitySearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Object;
use yii\db\Query;
use yii\helpers\Json;

View File

@ -8,7 +8,6 @@ use backend\models\CitySearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Object;
use yii\db\Query;
use yii\helpers\Json;

View File

@ -12,7 +12,6 @@ use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Object;
use backend\models\CustomerUpdate;
use backend\models\CustomerNewsLetterModel;
use yii\db\Query;

View File

@ -4,6 +4,7 @@ namespace backend\controllers;
use common\models\Log;
use common\models\Transfer;
use Mpdf\Mpdf;
use Yii;
use common\models\Ticket;
use backend\models\TicketSearch;
@ -27,6 +28,7 @@ use yii\helpers\VarDumper;
use backend\models\TicketUpdate;
use yii\helpers\Url;
use common\components\Helper;
use common\components\MpdfUtil;
/**
* TicketController implements the CRUD actions for Ticket model.
@ -292,7 +294,7 @@ class TicketController extends \backend\controllers\BackendController {
$fileName = "berletek";
$fileName .= "_" . date ( "Ymd_His" );
$fileName .= ".pdf";
$mpdf = new \mPDF ( 'utf-8', 'A4' );
$mpdf = MpdfUtil::createMpdfWith6XConstructor( 'utf-8', 'A4' );
$mpdf->useSubstitutions = false;
$mpdf->simpleTables = true;
@ -333,7 +335,7 @@ class TicketController extends \backend\controllers\BackendController {
if ($searchModel->output == 'pdf') {
$user = User::findOne ( \Yii::$app->user->id );
$mpdf = new \mPDF ( 'utf-8', 'A4-L' );
$mpdf = MpdfUtil::createMpdfWith6XConstructor ( 'utf-8', 'A4-L' );
$fn = "";
$ov = '_total_content_pdf';
$dt = "_letrehozva_" . date ( "Ymd_His" ) . "_" . $user->username;

View File

@ -47,7 +47,6 @@ class TicketInstallmentRequestController extends Controller
]
]
// everything else is denied
]
];
}
@ -73,6 +72,7 @@ class TicketInstallmentRequestController extends Controller
*/
public function actionPending()
{
\Yii::info("Showing pending");
$model = new TicketInstallmentMarkForSendForm();
if ($model->load(Yii::$app->request->post()) ) {
$model->markForSend();

View File

@ -21,6 +21,7 @@ use backend\models\TransferListUserGroupedSearch;
use backend\models\TransferLaterSearch;
use yii\helpers\Url;
use common\components\Helper;
use common\components\MpdfUtil;
/**
* TransferController implements the CRUD actions for Transfer model.
@ -249,7 +250,7 @@ class TransferController extends \backend\controllers\BackendController
protected function downloadPaymentLaterPDF($dataProvider) {
// $mpdf = new \mPDF ( 'utf-8', 'A4' );
$mpdf = new \mPDF ( 'utf-8', 'A4-L' );
$mpdf = MpdfUtil::createMpdfWith6XConstructor ( 'utf-8', 'A4-L' );
$fn = "utolagos_fizetesek.pdf";
$mpdf->useSubstitutions = false;
@ -452,7 +453,7 @@ class TransferController extends \backend\controllers\BackendController
if ( $searchModel->output === 'pdf'){
$user = User::findOne(\Yii::$app->user->id);
$mpdf=new \mPDF('utf-8', 'A4-L');
$mpdf= MpdfUtil::createMpdfWith6XConstructor('utf-8', 'A4-L');
$fn = "";
$ov = '_total_content_pdf';
$dt= "_letrehozva_".date("Ymd_His"). "_" . $user->username;
@ -561,7 +562,7 @@ class TransferController extends \backend\controllers\BackendController
$searchModel->search(Yii::$app->request->queryParams);
$mpdf=new \mPDF('utf-8', 'A4-L');
$mpdf= MpdfUtil::createMpdfWith6XConstructor('utf-8', 'A4-L');
$stylesheet = file_get_contents( \Yii::getAlias('@vendor'.'/bower/bootstrap/dist/css/bootstrap.css')); // external css
$mpdf->WriteHTML($stylesheet,1);
$mpdf->WriteHTML($this->renderPartial('_result_sale', [

View File

@ -10,6 +10,7 @@ use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use common\components\DetStatProcessor;
use common\components\MpdfUtil;
use backend\models\DestaUploadForm;
use yii\web\UploadedFile;
use yii\data\ArrayDataProvider;
@ -282,7 +283,7 @@ class UgiroController extends Controller {
}
protected function downloadUgiroPdf($model) {
$mpdf = new \mPDF ( 'utf-8', 'A4-L' );
$mpdf = MpdfUtil::createMpdfWith6XConstructor ( 'utf-8', 'A4-L' );
$fn = "köteg.". $model->id_ugiro . ".pdf";
$mpdf->useSubstitutions = false;

View File

@ -12,7 +12,6 @@ use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Object;
use backend\models\UserUpdate;
use common\models\Account;
use common\models\UserAccountAssignment;
@ -109,6 +108,8 @@ class UserController extends \backend\controllers\BackendController
public function updateAccountAssignments($model){
echo "saving accounts";
UserAccountAssignment::deleteAll(['id_user' => $model->id]);
foreach ( $model->selected_accounts as $id_account ){
$uaa = new UserAccountAssignment();

View File

@ -8,7 +8,7 @@ use backend\models\WarehouseSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Object;
use yii\base\BaseObject;
/**
* WarehouseController implements the CRUD actions for Warehouse model.

View File

@ -2,6 +2,7 @@
namespace backend\models;
use common\models\HuBankAccountValidator;
use Yii;
use yii\base\Model;
use common\models\Card;
@ -22,18 +23,41 @@ class TicketInstallmentMarkForSendForm extends Model{
public function rules(){
return [
['items', 'each', 'rule' => ['integer']],
['items', 'validateBankAccount'],
];
}
public function validateBankAccount($attribute, $params){
$items = TicketInstallmentRequest::find()->andWhere([
'in', 'id_ticket_installment_request' , $this->items
])->all();
\Yii::info("validateBankAccount:". count($items));
$validator = new HuBankAccountValidator();
foreach($items as $item){
\Yii::info("validateBankAccount2:". $item->id_ticket_installment_request);
/** @var Customer $customer */
$customer = $item->customer;
\Yii::info("validateBankAccount3:". $customer->username);
$isBankAccountValid = $validator->validate($customer->bank_account);
if (!$isBankAccountValid){
$errorMessage = "";
$errorMessage .= "Vendég=".$customer->name;
$errorMessage .= "; Kártya=".$customer->card->number;
$errorMessage .= "; Megbízás=".$item->id_ticket_installment_request;
$this->addError('items', "Hibás bankszámlaszám:" .$errorMessage );
}
}
}
public function markForSend(){
\Yii::info("mark for send");
if ( $this->validate() && isset($this->items ) && is_array($this->items ) ){
$updated = 0;
$updated = TicketInstallmentRequest::updateAll(['status' => TicketInstallmentRequest::$STATUS_MARKED_TO_SEND ],['in', 'id_ticket_installment_request' , $this->items]);
\Yii::$app->session->setFlash('success', $updated . " megbízás küldésre jelölve " );
}else{
\Yii::$app->session->setFlash('success', " Nem történt küldésre jelölés! " );
\Yii::$app->session->setFlash('error', " Nem történt küldésre jelölés! " . $this->getFirstError('items') );
}
}

View File

@ -7,7 +7,7 @@ use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Transfer;
use yii\db\Expression;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use common\components\Helper;

View File

@ -6,7 +6,7 @@ use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Transfer;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use yii\db\Expression;
use common\models\Account;

View File

@ -7,7 +7,7 @@ use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Transfer;
use yii\db\Expression;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use common\models\Account;

View File

@ -49,31 +49,31 @@ class UserUpdate extends User {
];
}
public function validateEmail($attribute, $params){
/** @var User $user */
$user = User::find()
->andWhere(['email' => $this->email])->one();
if (isset($user)){
if ( $user->id != $this->id ){
$this->addError($attribute,'Az email cím már használatban van!');
}
}
}
public function validateUsername($attribute, $params){
/** @var User $user */
$user = User::find()
->andWhere(['username' => $this->username])->one();
if (isset($user)){
if ( $user->id != $this->id ){
$this->addError($attribute,'A felhasználónév már használatban van!');
}
}
}
// public function validateEmail($attribute, $params){
// /** @var User $user */
// $user = User::find()
// ->andWhere(['email' => $this->email])->one();
//
// if (isset($user)){
// if ( $user->id != $this->id ){
// $this->addError($attribute,'Az email cím már használatban van!');
// }
// }
//
// }
//
// public function validateUsername($attribute, $params){
// /** @var User $user */
// $user = User::find()
// ->andWhere(['username' => $this->username])->one();
//
// if (isset($user)){
// if ( $user->id != $this->id ){
// $this->addError($attribute,'A felhasználónév már használatban van!');
// }
// }
//
// }
/**
* @formatter:on
@ -87,6 +87,28 @@ class UserUpdate extends User {
}
}
}
public function validateEmail($attribute, $params) {
if (! $this->hasErrors ()) {
if ( !empty($this->email) ){
$user = User::findOne(['email' => $this->email]);
if ( isset($user) && $user->id != $this->id){
$this->addError ( $attribute, "Az email már használatban van (".$user->username.")");
}
}
}
}
public function validateUsername($attribute, $params) {
if (! $this->hasErrors ()) {
if ( !empty($this->email) ){
$user = User::findOne(['username' => $this->username]);
if ( isset($user) && $user->id != $this->id){
$this->addError ( $attribute, "A felhasználónév már használatban van (".$user->username.")");
}
}
}
}
public function attributeLabels() {
return [

View File

@ -31,6 +31,9 @@ use yii\helpers\ArrayHelper;
<?= $form->field($model, 'type')->dropDownList(TicketType::ticketTypes() ) ?>
<?= mkTitle("Megjegyzés")?>
<?= $form->field($model, 'comment')->textInput()->label("Megjegyzés") ?>
<?= mkTitle("Alkalmak")?>
<?= $form->field($model, 'max_usage_count')->textInput() ?>
<?= $form->field($model, 'max_reservation_count')->textInput() ?>

View File

@ -31,6 +31,10 @@ $this->params['breadcrumbs'][] = $this->title;
'value' => $model->typeHuman
],
'max_usage_count',
[
'attribute' => 'comment',
'label' => "Megjegyzés"
],
'max_reservation_count',
[
'attribute' => 'time_unit_count',

View File

@ -4,7 +4,7 @@ use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\DetailView;
use yii\base\Widget;
use yii\base\Object;
use yii\base\BaseObject;
use yii\data\ArrayDataProvider;
use common\components\AccountStatisticWidget;
use common\components\DataProviderTotal;

View File

@ -4,7 +4,7 @@ use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\DetailView;
use yii\base\Widget;
use yii\base\Object;
use yii\base\BaseObject;
use yii\data\ArrayDataProvider;
use common\components\AccountStatisticWidget;
use common\components\DataProviderTotal;

View File

@ -18,6 +18,12 @@ use yii\i18n\Formatter;
class DateUtil
{
public static function fromUnixTimeStamp($timestamp){
$dt = DateUtil::utcDate();
$dt->setTimestamp($timestamp);
return $dt;
}
/**
* Get UTC today @00:00:00 .
* Helper method to generate date for mysql
@ -25,13 +31,49 @@ class DateUtil
* @return DateTime
* @throws Exception
*/
public static function todayStart( ){
$d2 = new DateTime();
public static function todayStart(){
$d2 = new DateTime();
return DateUtil::utcDate($d2);
}
/**
* @param $date \DateTime optional. The date to set as utc date. If not set, new DateTime() will be used
* @return DateTime the datetime object with time reset and utc timezone
*/
public static function utcDate($date = null){
$d2 = isset($date ) ? $date : new DateTime();
$d2 = DateUtil::withTimeZoneUTC($d2);
return DateUtil::resetTime($d2);
}
/**
* @param $date \DateTime optional. If not set,defaults to : new DateTime() .
* @return DateTime
*/
public static function utcDateTime($date = null){
$d2 = isset($date ) ? $date : new DateTime();
return DateUtil::withTimeZoneUTC($d2);
}
/**
* @param $date \DateTime
* @return DateTime
*/
public static function withTimeZoneUTC( $date = null){
$d2 = isset($date ) ? $date : new DateTime();
$d2->setTimezone( new DateTimeZone('UTC') );
$d2->setTime(0, 0);
return $d2;
}
/**
* @param $dateTime \DateTime
* @return \DateTime
*/
public static function resetTime($dateTime){
$dateTime->setTime(0, 0);
return $dateTime;
}
/**
* Get UTC t @00:00:00 .
* Helper method to generate date for mysql
@ -39,16 +81,12 @@ class DateUtil
* @return DateTime
* @throws Exception
*/
public static function tomorrowStart( ){
$d2 = new DateTime();
public static function tomorrowStart( $date = null){
$d2 = isset($date) ? $date : new DateTime();
$d2->add(new DateInterval('P1D'));
$d2->setTimezone( new DateTimeZone('UTC') );
$d2->setTime(0, 0);
return $d2;
return DateUtil::utcDate($d2);
}
public static function addMonth($timestamp, $monthCount = 1)
{
@ -99,7 +137,7 @@ class DateUtil
* @return string
* @throws InvalidConfigException
*/
public static function formatUtc($dateTimeObject)
public static function formatDateTimeUtc($dateTimeObject)
{
$formatter = new Formatter;
$formatter->datetimeFormat = 'php:Y-m-d H:i:s';
@ -121,12 +159,15 @@ class DateUtil
}
public static function parseDate($dateString){
$date = DateTime::createFromFormat('Y.m.d', $dateString, new DateTimeZone( 'UTC'));
$date->setTime(0, 0);
return $date;
}
public static function parseDateTime($dateTimeString){
return DateTime::createFromFormat('Y-m-d H:i:s', $dateTimeString, new DateTimeZone( 'UTC'));
}
/**
* @param integer $weekDay Numeric representation of the day of the week. @See https://www.php.net/manual/en/function.date.php
* @return string
@ -145,4 +186,26 @@ class DateUtil
return $translations[$weekDay];
}
/**
* @param $dateTime \DateTime
* @return void
*/
public static function resetSeconds($dateTime){
return $dateTime->setTime($dateTime->format("H"), $dateTime->format("i"),0);
}
/**
* @param $dateTime \DateTime
* @param $minutes integer
* @return mixed
* @throws Exception
*/
public static function addMinutes($dateTime, $minutes){
return $dateTime->add(new \DateInterval('PT' . $minutes . 'M'));
}
public static function minusMinutes($dateTime, $minutes){
return $dateTime->sub(new \DateInterval('PT' . $minutes . 'M'));
}
}

View File

@ -4,7 +4,7 @@ namespace common\components;
use common\models\Transfer;
use yii\base\Object;
use yii\base\BaseObject;
use common\models\MessageDetstaLab;
use common\models\MessageDetstaTetel;
use common\models\MessageDetsta;
@ -16,7 +16,7 @@ use common\models\TicketInstallmentRequest;
* @property common\models\Ugiro $koteg
* @property common\models\giro\GiroDETSTA $giroDETSTA
*/
class DetStaDBSave extends Object
class DetStaDBSave extends BaseObject
{
/**

View File

@ -2,7 +2,7 @@
namespace common\components;
use yii\base\Object;
use yii\base\BaseObject;
use common\models\Ugiro;
use common\components\giro\GiroDETSTA;
@ -14,7 +14,7 @@ use common\components\giro\GiroDETSTA;
* @property \common\models\UGiro $koteg
*
* */
class DetStatProcessor extends Object{
class DetStatProcessor extends BaseObject{
/**aktuális koteg, config paraméterként kapju*/

View File

@ -3,7 +3,7 @@
namespace common\components;
use common\models\Transfer;
use yii\base\Object;
use yii\base\BaseObject;
use common\models\TicketInstallmentRequest;
use common\components\giro\GiroDETSTATetel;
use common\models\Account;
@ -19,7 +19,7 @@ use common\models\Contract;
*
*
*/
class DetStatTetelProcessor extends Object {
class DetStatTetelProcessor extends BaseObject {
/**
* A válasz tétel . Ha nincs megadva, automatikus visszautasítjuk a megbízást
* */

View File

@ -0,0 +1,34 @@
<?php
namespace common\components;
use yii\base\BaseObject;
class DoorMoveContext extends BaseObject {
public $requestId;
public $identifier;
public $device;
public $direction;
public $originalDirection;
public $verifyOnly;
public $createdAt;
public $date;
public $card;
// todo: duplicate of card
public $cardNumber;
public $virtualKey;
public $key;
public $customer;
public $ticket;
public $increasedTicketUsageCount;
public $kind;
public $error;
public $errorCode;
public $exception;
public $actions = [];
}

View File

@ -0,0 +1,23 @@
<?php
namespace common\components;
class FitnessException extends \Exception {
const TYPE_BAD_REQUEST = "BAD_REQUEST";
const UNKNOWN_ERROR = "UNKNOWN_ERROR";
public $errorCode;
public $type;
public $payload;
public $originalException;
public function __construct( $message, $type = FitnessException::TYPE_BAD_REQUEST, $errorCode = null, $payload = null, $originalException= null) {
parent::__construct();
$this->message = $message;
$this->type = $type;
$this->errorCode = $errorCode;
$this->payload = $payload;
$this->originalException = $originalException;
}
}

View File

@ -4,7 +4,7 @@ namespace common\components;
use common\models\Card;
class FreeUniqueCardNumberGenerator extends \yii\base\Object {
class FreeUniqueCardNumberGenerator extends \yii\base\BaseObject {
public $count;
public $keyset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
public $length = 6;

View File

@ -147,6 +147,7 @@ class GD
public function save($file, $quality = 90)
{
try{
switch($this->_mime) {
case 'image/jpeg':
return imagejpeg($this->_image, $file, $quality);
@ -159,6 +160,9 @@ class GD
return imagegif($this->_image, $file);
break;
}
}catch (\Exception $e){
\Yii::error("Failed to save image image:", $e->getMessage());
}
return false;
}
}

View File

@ -538,4 +538,24 @@ class Helper {
return $result;
}
public static function isRestAllowVerifyOnly() {
return \Yii::$app->params ['rest_allow_verify_only'] && \Yii::$app->params ['rest_allow_verify_only'] == true;
}
public static function getDoorEntryStrategy(){
return Helper::getArrayValue(\Yii::$app->params ,'door_entry_strategy','strategy_key');
}
public static function getDoorPassValidityIntervalMinutes(){
return Helper::getArrayValue(\Yii::$app->params ,'door_pass_validity_interval_minutes','10');
}
public static function isWordTypedListenerAllowedOnlyForEmptyCustomer(){
$key = "word_typed_listener_allowed_only_for_empty_customer";
return Helper::getArrayValue(\Yii::$app->params ,$key,'0') === '1';
}
}

View File

@ -1,4 +1,5 @@
<?php
namespace common\components;
use Yii;
@ -10,13 +11,14 @@ use common\components\GD;
class Image
{
/**
* @param UploadedFile $fileInstance
* @param string $dir relative dir from upload dir
* @param unknown $resizeWidth
* @param unknown $resizeHeight
* @param bool $resizeCrop
* @throws HttpException*/
/**
* @param UploadedFile $fileInstance
* @param string $dir relative dir from upload dir
* @param unknown $resizeWidth
* @param unknown $resizeHeight
* @param bool $resizeCrop
* @throws HttpException
*/
public static function upload(UploadedFile $fileInstance, $dir = '', $resizeWidth = null, $resizeHeight = null, $resizeCrop = false)
{
$fileName = Upload::getUploadPath($dir) . DIRECTORY_SEPARATOR . Upload::getFileName($fileInstance);
@ -25,27 +27,27 @@ class Image
? self::copyResizedImage($fileInstance->tempName, $fileName, $resizeWidth, $resizeHeight, $resizeCrop)
: $fileInstance->saveAs($fileName);
if(!$uploaded){
throw new HttpException(500, 'Cannot upload file "'.$fileName.'". Please check write permissions.');
if (!$uploaded) {
throw new HttpException(500, 'Cannot upload file "' . $fileName . '". Please check write permissions.');
}
return Upload::getLink($fileName);
}
public static function saveBinary($binary_data, $dir = '')
{
$fileName = Upload::getUploadPath($dir) . DIRECTORY_SEPARATOR . Upload::genFileName("jpg");
$uploaded = file_put_contents( $fileName, $binary_data );
$uploaded = file_put_contents($fileName, $binary_data);
if(!$uploaded){
throw new HttpException(500, 'Cannot upload file "'.$fileName.'". Please check write permissions.');
if (!$uploaded) {
throw new HttpException(500, 'Cannot upload file "' . $fileName . '". Please check write permissions.');
}
return Upload::getLink($fileName);
}
/**
*
* @param unknown $filename
@ -56,16 +58,14 @@ class Image
*/
static function thumb($filename, $width = null, $height = null, $crop = true)
{
if($filename && file_exists(($filename = Yii::getAlias('@frontend/web') . $filename)))
{
if ($filename && file_exists(($filename = Yii::getAlias('@frontend/web') . $filename))) {
$info = pathinfo($filename);
$thumbName = $info['filename'] . '-' . md5( filemtime($filename) . (int)$width . (int)$height . (int)$crop ) . '.' . $info['extension'];
$thumbName = $info['filename'] . '-' . md5(filemtime($filename) . (int)$width . (int)$height . (int)$crop) . '.' . $info['extension'];
$thumbFile = Yii::getAlias('@frontend/web') . DIRECTORY_SEPARATOR . Upload::$UPLOADS_DIR . DIRECTORY_SEPARATOR . 'thumbs' . DIRECTORY_SEPARATOR . $thumbName;
$thumbWebFile = '/' . Upload::$UPLOADS_DIR . '/thumbs/' . $thumbName;
if(file_exists($thumbFile)){
if (file_exists($thumbFile)) {
return $thumbWebFile;
}
elseif(FileHelper::createDirectory(dirname($thumbFile), 0777) && self::copyResizedImage($filename, $thumbFile, $width, $height, $crop)){
} elseif (FileHelper::createDirectory(dirname($thumbFile), 0777) && self::copyResizedImage($filename, $thumbFile, $width, $height, $crop)) {
return $thumbWebFile;
}
}
@ -74,39 +74,38 @@ class Image
static function copyResizedImage($inputFile, $outputFile, $width, $height = null, $crop = true)
{
if (extension_loaded('gd'))
{
$image = new GD($inputFile);
if (extension_loaded('gd')) {
try {
$image = new GD($inputFile);
if($height) {
if($width && $crop){
$image->cropThumbnail($width, $height);
if ($height) {
if ($width && $crop) {
$image->cropThumbnail($width, $height);
} else {
$image->resize($width, $height);
}
} else {
$image->resize($width, $height);
$image->resize($width);
}
} else {
$image->resize($width);
return $image->save($outputFile);
} catch (\Exception $e) {
\Yii::error("Failed to create thumbnail: ". $e->getMessage());
}
return $image->save($outputFile);
}
elseif(extension_loaded('imagick'))
{
} elseif (extension_loaded('imagick')) {
$image = new \Imagick($inputFile);
if($height && !$crop) {
if ($height && !$crop) {
$image->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);
}
else{
} else {
$image->resizeImage($width, null, \Imagick::FILTER_LANCZOS, 1);
}
if($height && $crop){
if ($height && $crop) {
$image->cropThumbnailImage($width, $height);
}
return $image->writeImage($outputFile);
}
else {
} else {
throw new HttpException(500, 'Please install GD or Imagick extension');
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace common\components;
use Mpdf\Mpdf;
use yii\base\BaseObject;
class MpdfUtil extends BaseObject
{
// mpdf version 6 constructor
//function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
public static function createMpdfWith6XConstructor($mode = '', $format = 'A4', $default_font_size = 0, $default_font = '', $mgl = 15, $mgr = 15, $mgt = 16, $mgb = 16, $mgh = 9, $mgf = 9, $orientation = 'P')
{
return self::createMpdf([
'mode' => $mode,
'format' => $format,
'default_font_size' => $default_font_size,
'default_font' => $default_font,
'margin_left' => $mgl,
'margin_right' => $mgr,
'margin_top' => $mgt,
'margin_bottom' => $mgb,
'margin_header' => $mgh,
'margin_footer' => $mgf,
'orientation' => $orientation
]);
}
public static function createMpdf($options = [])
{
$mpdf = new Mpdf(
array_merge([
'mode' => 'utf-8',
'format' => 'A4'
], $options)
);
return $mpdf;
}
}

View File

@ -2,7 +2,7 @@
namespace common\components;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use common\models\Product;
use yii\data\ActiveDataProvider;
@ -14,7 +14,7 @@ use common\models\Transfer;
* @property common\models\Account $account a kassza
* @property common\models\Product[] $products a termékek
* */
class ProductInventory extends Object{
class ProductInventory extends BaseObject{

View File

@ -0,0 +1,72 @@
<?php
namespace common\components;
class StopWatch
{
public $start;
public $splits = [];
public $stop;
// public function _(){
// $this->start();
// }
public function __construct()
{
$this->start();
}
public function start()
{
$this->start = $this->time();
}
public function split()
{
$this->splits[] = $this->time();
return $this->getSplit();
}
public function stop()
{
$this->stop = $this->time();
}
function time()
{
return time();
}
function diff($start, $end)
{
if (!isset($start) || !isset($end)) {
return -1;
}
return $end - $start;
}
function getSplit()
{
$lastSplit = null;
if (isset($this->stop)) {
$lastSplit = $this->stop;
} else {
$count = count($this->splits);
if ($count > 0) {
$lastSplit = $this->splits[$count - 1];
}
}
return $this->diff($this->start, $lastSplit);
}
function getTotal(){
return $this->diff($this->start, $this->stop);
}
}

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,7 @@ use common\models\Ticket;
class TransferPayout extends \yii\base\Object{
class TransferPayout extends \yii\base\BaseObject{
/**Current user*/
public $idUser = null;

View File

@ -2,16 +2,17 @@
namespace common\components\accountstate;
use yii\base\Object;
use common\models\User;
use common\models\Account;
use common\models\AccountState;
use common\components\DailyListing;
use common\components\MpdfUtil;
use yii\base\BaseObject;
/**
* @property common\models\AccountState $model
* */
class AccountStateMail extends Object {
class AccountStateMail extends BaseObject {
public $controller;
@ -76,7 +77,7 @@ class AccountStateMail extends Object {
protected function attachPdf(){
$mpdf=new \mPDF('utf-8', 'A4-L');
$mpdf= MpdfUtil::createMpdfWith6XConstructor('utf-8', 'A4-L');
$mpdf->useSubstitutions=false;
$mpdf->simpleTables = true;
$mpdf->SetHeader( \Yii::$app->params[ "company_name" ] . " - Létrehozva: " .$user->username . ", ".\Yii::$app->formatter->asDatetime(time()) );

View File

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

View File

@ -0,0 +1,662 @@
<?php
namespace common\manager;
use common\components\DateUtil;
use common\components\DoorMoveContext;
use common\components\FitnessException;
use common\components\Helper;
use common\components\StopWatch;
use common\models\Card;
use common\models\CardKeyAssignment;
use common\models\DoorLog;
use common\models\DoorLogForTest;
use common\models\DoorManagerLog;
use common\models\Key;
use common\models\Log;
use common\models\Ticket;
use common\models\VirtualKey;
use frontend\models\KeyToggleForm;
use yii\base\BaseObject;
use yii\base\InvalidConfigException;
use yii\db\Exception;
use yii\web\BadRequestHttpException;
use yii\web\ServerErrorHttpException;
/**
* Created by IntelliJ IDEA.
* User: rocho
* Date: 2018.12.17.
* Time: 6:12
*/
class CutlerMovarDoorManager extends BaseObject
{
/**
* @param $identifier 00000000: nyomogombos nyitás
* @param $device string B(gomb)|Q(qrcode)|C(nfc),E(emergency)
* @param $direction string IN|OUT
* @param $verifyOnly boolean true: akkor csak lekerdezés, false: megtörtént a mozgás (ilyenkor vonunk le egy alkalmat)
* @param $createdAt number unix timestamp , override createdAt for doorLogs
* @param $date number unix timestamp, override date for validation check 'now'
* @return void
*/
public function move($identifier, $device, $direction, $verifyOnly, $createdAt = null, $date = null)
{
$requestId = uniqid("", false);
$context = new DoorMoveContext([
'requestId' => $requestId,
'identifier' => $identifier,
'device' => $device,
'direction' => $direction,
'originalDirection' => $direction,
'verifyOnly' => $verifyOnly
]);
try {
$stopWatch = new StopWatch();
\Yii::info("$requestId: move with next parameers:" . ";identifier" . $identifier . ";device" . $device . ";direction" . $direction . ";verifyOnly" . $verifyOnly . ";createdAt" . print_r($createdAt, true) . ";date" . print_r($date, true));
\Yii::info("$requestId: move get request: " . print_r($_GET, true));
\Yii::info("$requestId: move post request: " . print_r($_GET, true));
if (isset($createdAt)) {
$createdAt = DateUtil::parseDateTime($createdAt);
} else {
$createdAt = DateUtil::utcDateTime();
}
$context->createdAt = $createdAt;
if (isset($date)) {
$date = DateUtil::parseDateTime($date);
} else {
$date = DateUtil::utcDate();
}
$context->date = $date;
if ($device === 'E') {
$this->moveEmergency($context/*;$requestId,$identifier, $device, $direction, $verifyOnly, $createdAt, $date*/);
return;
}
$cardNumber = $identifier;
switch ($direction) {
case 'IN':
$direction = DoorLog::$DIRECTION_IN;
break;
case 'OUT':
$direction = DoorLog::$DIRECTION_OUT;
break;
default:
throw new FitnessException(
"Direction $direction not supported",
FitnessException::TYPE_BAD_REQUEST,
"INVALID_DIRECTION",
$context
);
}
$context->direction = $direction;
// if device is qr code
if ($device == 'Q') {
// allow only virtual key
$virtualKey = VirtualKey::findOne(['number' => $identifier]);
if (!isset($virtualKey)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_NOT_FOUND",
$context
);
}
$card = Card::findOne($virtualKey->id_card);
if ($card == null) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"CARD_FOR_VIRTUAL_KEY_NOT_FOUND",
$context
);
}
$cardNumber = $card->number;
\Yii::info("$requestId: virtual key and card loaded in sec " . $stopWatch->split());
} else {
// load by rfid or card number
$card = Card::readCard(Helper::fixAsciiChars($identifier));
\Yii::info("$requestId: Card loaded in sec " . $stopWatch->split());
if (!isset($card)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"CARD_NOT_FOUND",
$context
);
}
\Yii::info("$requestId: card loaded in sec " . $stopWatch->split());
$virtualKey = VirtualKey::find()
->andWhere(['id_card' => $card->id_card])
->orderBy(['id' => SORT_DESC])->one();
\Yii::info("$requestId: virtual key for card loaded in sec " . $stopWatch->split());
}
$context->virtualKey = $virtualKey;
$context->card = $card;
$context->cardNumber = $cardNumber;
if ( $card->status != Card::STATUS_ACTIVE){
throw new FitnessException(
"Card is not active",
FitnessException::TYPE_BAD_REQUEST,
"CARD_NOT_ACTIVE",
$context
);
}
\Yii::info("$requestId: Card number " . $card->number);
if ($card->type == Card::TYPE_EMPLOYEE) {
$this->moveEmployee($context /*$identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/);
return;
}
$this->moveCustomer($context /* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/);
} catch (FitnessException $e) {
$context->error = true;
$context->exception = $e->originalException;
$context->errorCode = $e->errorCode;
if ($e->type == FitnessException::TYPE_BAD_REQUEST) {
throw new BadRequestHttpException($e->getMessage());
} else {
throw new ServerErrorHttpException($e->getMessage());
}
} catch (\Exception $e) {
$context->error = true;
$context->exception = $e;
$context->errorCode = "UNKNOWN";
throw $e;
} finally {
// do logging
$this->logContext($context);
}
}
/**
* @param $ctx DoorMoveContext
* @return void
*/
function logContext($ctx)
{
try {
$result = [
//datetime $updated_at --
//datetime $created_at --
//string $ticket_usage
//string $request_id
'request_id' => $ctx->requestId,
//string $identifier
'identifier' => $ctx->identifier,
//bool $verify_only
'verify_only' => $ctx->verifyOnly,
//string $device
'device' => $ctx->device,
//string $direction
'direction' => $ctx->direction,
//string $original_direction
'original_direction' => $ctx->originalDirection,
//integer $card_id_card
'card_id_card' => isset($ctx->card) ? $ctx->card->id_card : null,
//string $card_number
'card_number' => isset($ctx->card) ? $ctx->card->number : null,
//string $ticket_id_ticket
'ticket_id_ticket' => isset($ctx->ticket) ? $ctx->ticket->id_ticket : null,
//string $ticket_type_name
'ticket_type_name' => isset($ctx->ticket) ? $ctx->ticket->ticketType->name : null,
//string $ticket_usage_count
'ticket_usage_count' => isset($ctx->ticket) ? $ctx->ticket->usage_count : null,
//string $customer_id_customer
'customer_id_customer' => isset($ctx->customer) ? $ctx->customer->id_customer : null,
//string $customer_name
'customer_name' => isset($ctx->customer) ? $ctx->customer->name : null,
//string $customer_email
'customer_email' => isset($ctx->customer) ? $ctx->customer->email : null,
//integer $key_id_key
'key_id_key' => isset($ctx->key) ? $ctx->key->id_key : null,
//string $key_number
'key_number' => isset($ctx->key) ? $ctx->key->number : null,
//integer $virtual_key_id
'virtual_key_id' => isset($ctx->virtualKey) ? $ctx->virtualKey->id : null,
//string $validation_kind
'validation_kind' => $ctx->kind,
//bool $error
'error' => $ctx->error,
//string $error_code
'error_code' => $ctx->errorCode,
'ticket_usage' => $ctx->increasedTicketUsageCount,
// 'actions' => implode(",",$ctx->actions),
];
if ($ctx->error === true) {
if (isset($ctx->exception)) {
// string $error_message
$result['error_message'] = substr($ctx->exception->getMessage(), 0, 100);
}
}
\Yii::info("door log: " . implode(";", $result));
\Yii::$app->db->beginTransaction();
$log = new DoorManagerLog($result);
$log->save(false);
\Yii::$app->db->transaction->commit();
} catch (\Exception $e) {
\Yii::error("Failed to log door context:" . $e->getMessage());
}
}
function moveEmergency($ctx)
{
$ctx->kind = "EMERGENCY";
\Yii::info("$ctx->requestId: emergency move");
try {
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
\Yii::$app->db->beginTransaction();
$doorLog = new DoorLog();
$doorLog->version = 2;
$doorLog->direction = DoorLog::$DIRECTION_ALL_EMERGENCY;
$doorLog->source_app = $ctx->device;
$doorLog->created_at = $createdAtStr;
$doorLog->save(false);
Log::log(
[
'type' => Log::$TYPE_INFO,
'message' => 'Ajtó nyitás: vészhelyzet',
'id_door_log' => $doorLog->id_door_log
]
);
$ctx->actions[] = "EMERGENCY_MOVE";
\Yii::$app->db->transaction->commit();
} catch (\Exception $e) {
\Yii::$app->db->transaction->rollBack();
throw new FitnessException(
"unknowon error",
FitnessException::UNKNOWN_ERROR,
"EMERGENCY_OPEN_FAILED",
$ctx,
$e
);
}
}
function moveEmployee($ctx /*$identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/)
{
$ctx->kind = "EMPLOYEE";
/**
* if the card type is employee, neither customer nor ticket is needed.
* Free to enter/leave
*/
\Yii::info("employee move");
try {
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
\Yii::$app->db->beginTransaction();
$doorLog = new DoorLog();
$doorLog->version = 2;
$doorLog->direction = $ctx->direction;
$doorLog->source_app = $ctx->device;
$doorLog->created_at = $createdAtStr;
$doorLog->id_card = $ctx->card->id_card;
$doorLog->card_flag = $ctx->card->flag;
if (!$ctx->verifyOnly) {
$doorLog->save(false);
Log::log(
[
'type' => Log::$TYPE_INFO,
'message' => 'Ajtó nyitás: munkatárs',
'id_door_log' => $doorLog->id_door_log
]
);
}
$ctx->actions[] = "EMPLOYEE_" . $ctx->originalDirection;
\Yii::$app->db->transaction->commit();
} catch (\Exception $e) {
\Yii::$app->db->transaction->rollBack();
throw new FitnessException(
"unknowon error",
FitnessException::UNKNOWN_ERROR,
"EMPLOYEE_FAILED",
$ctx,
$e
);
}
}
/**
* @param $ctx
*
* @return void
* @throws BadRequestHttpException
* @throws ServerErrorHttpException
* @throws InvalidConfigException
* @throws Exception
*/
function moveCustomer($ctx/* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/)
{
$ctx->kind = "CUSTOMER";
\Yii::info("$ctx->requestId: move customer");
$stopWatch = new StopWatch();
try {
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
\Yii::info("$ctx->requestId: crated at str: " . $createdAtStr);
\Yii::$app->db->beginTransaction();
$doorLog = new DoorLog();
$doorLog->version = 2;
$doorLog->direction = $ctx->direction;
$doorLog->source_app = $ctx->device;
$doorLog->created_at = $createdAtStr;
$doorLog->id_card = $ctx->card->id_card;
$doorLog->card_flag = $ctx->card->flag;
$activeTickets = Ticket::readActive($ctx->card, clone $ctx->date);
\Yii::info("$ctx->requestId: active ticket count:" . count($activeTickets));
/** @var Ticket $ticket */
$ticket = null;
if (isset($activeTickets) && count($activeTickets) > 0) {
$ticket = $activeTickets[0];
}
// active ticket is required
if (!isset($ticket)) {
throw new FitnessException(
"$ctx->requestId: No active ticket found for:" . $ctx->card->number,
FitnessException::TYPE_BAD_REQUEST,
"NOT_FOUND_ACTIVE_TICKET",
$ctx
);
}
$ctx->ticket = $ticket;
\Yii::info("$ctx->requestId: ticket {$ticket->id_ticket} loaded in sec " . $stopWatch->split());
$doorLog->id_ticket_current = $ticket->id_ticket;
// customer is required
$customer = $ctx->card->customer;
if (!isset($customer)) {
throw new FitnessException(
"$ctx->requestId: Customer not found for:" . $ctx->card->number,
FitnessException::TYPE_BAD_REQUEST,
"NOT_FOUND_CUSTOMER",
$ctx
);
}
$ctx->customer = $customer;
$doorLog->id_customer = $customer->id_customer;
\Yii::info("$ctx->requestId: customer {$customer->id_customer} loaded in sec " . $stopWatch->split());
if (!$ctx->verifyOnly) {
// save the door log
$doorLog->save(false);
}
\Yii::info("$ctx->requestId: door log {$doorLog->id_door_log} saved in sec " . $stopWatch->split());
// if direction is in, check if usage count must be increased
if ($ctx->direction == DoorLog::$DIRECTION_IN) {
/**
* Virtual key must exist
*/
if (!isset($ctx->virtualKey)) {
throw new FitnessException(
"$ctx->requestId: Customer not found for:" . $ctx->card->number,
FitnessException::TYPE_BAD_REQUEST,
"NOT_FOUND_CUSTOMER",
$ctx
);
}
// todo: virtual key created_at validation
if (isset($ctx->virtualKey->direction_in_at)) {
throw new FitnessException(
"$ctx->requestId: Virtual key - already moved in: " . $ctx->identifier . '/' . $ctx->virtualKey->id_card,
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_ALREADY_IN",
$ctx
);
}
$ctx->actions[] = "VIRTUAL_KEY_MOVE_IN";
// detect if need to increase usage count for ticket
if (!$ctx->verifyOnly) {
$ctx->virtualKey->direction_in_at = Helper::getDateTimeString();
\Yii::info("$ctx->requestId: Setting virtual key direction_in_at");
\Yii::info("$ctx->requestId: Updating virtual key");
$ctx->virtualKey->save(false);
// if the current event is the first door log today
// increase the ticket usage count with 1
$usageCount = $ticket->usage_count;
$ctx->increasedTicketUsageCount = true;
$ticket->usage_count += 1;
$ticket->save(false);
\Yii::info("$ctx->requestId: First ticket usage today, increasing usage count for card: " . $ctx->card->id_card);
\Yii::info("$ctx->requestId: Ticket usage count increased after first doorlog of day in sec " . $stopWatch->split());
}
$ctx->actions[] = "MOVE_IN";
}
if ($ctx->direction == DoorLog::$DIRECTION_OUT || $ctx->direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE) {
// virtual key must exist
if (!isset($ctx->virtualKey)) {
throw new FitnessException(
"$ctx->requestId: Virtual key: move out without virtual key",
FitnessException::TYPE_BAD_REQUEST,
"MOVE_OUT_WITHOUT_VIRTUAL_KEY",
$ctx
);
}
// virtual must already be in
if (!isset($ctx->virtualKey->direction_in_at)) {
throw new FitnessException(
"$ctx->requestId: Virtual key: move out without move in",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_MOVE_OUT_WITHOUT_MOVE_IN",
$ctx
);
}
// virtual key must not be already out
if (isset($ctx->virtualKey->direction_out_at)) {
throw new FitnessException(
"$ctx->requestId: Virtual key: already move out",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_ALREADY_OUT",
$ctx
);
}
if (!$ctx->verifyOnly) {
// set out date
$ctx->virtualKey->direction_out_at = Helper::getDateTimeString();
$ctx->virtualKey->save(false);
}
if (!$ctx->verifyOnly) {
$ticket->count_move_out = $ticket->usage_count;
$ticket->save(false);
}
$ctx->actions[] = "MOVE_OUT";
\Yii::info("$ctx->requestId: direction_out: ticket count_move_out set after direction_out in sec " . $stopWatch->split());
}
$stopWatch->stop();
\Yii::info("$ctx->requestId: finished in sec " . $stopWatch->getTotal());
\Yii::$app->db->transaction->commit();
\Yii::info("$ctx->requestId: Commited");
} catch (FitnessException $fe) {
$this->doRollback();
\Yii::info("$ctx->requestId: rollbacked");
throw $fe;
} catch (\Exception $e) {
$this->doRollback();
\Yii::info("$ctx->requestId: rollbacked");
throw new FitnessException(
"UNKNOWN_ERROR",
FitnessException::UNKNOWN_ERROR,
"CUSTOMER_UNKNOWN_ERROR",
$ctx,
$e
);
}
}
function doRollback()
{
if (isset(\Yii::$app->db->transaction) && \Yii::$app->db->transaction->isActive) {
\Yii::$app->db->transaction->rollBack();
}
}
function getActiveInterval($intervals, $date)
{
foreach ($intervals as $interval) {
$start = $interval['start'];
$end = $interval['end'];
if ($start <= $date && $date < $end) {
return $interval;
}
}
return null;
}
function createTicketUsageInterval($start, $end, $allLogs, $actualDoorLog)
{
$result = ['start' => $start, 'end' => $end, 'logs' => []];
foreach ($allLogs as $log) {
$createdAt = DateUtil::parseDateTime($log->created_at);
if ($createdAt >= $start && $createdAt < $end) {
$result['logs'][] = $log;
}
}
return $result;
}
public function readActive($cardNumber)
{
$card = Card::readCard($cardNumber);
return Ticket::readActive($card);
}
public function resetLogs($cardNumber)
{
$card = Card::readCard($cardNumber);
$card->flag = 0;
$card->flag_out = 0;
$card->save(false);
Card::updateCardFlagTicket($card->id_card);
DoorLog::deleteAll(
['id_card' => $card->id_card]
);
// todo: revoke all assigned key
$this->revokeKey($cardNumber, "f100");
}
public function getLogs($cardNumber)
{
return DoorLog::findAll(
['id_card' => $cardNumber]
);
}
public function getInfo($cardNumber)
{
$card = Card::readCard($cardNumber);
return [
'card' => $card,
'customer' => $card->customer,
'tickets' => Ticket::readActive($card),
'doorLogs' => DoorLog::findAll(
['id_card' => $card->id_card]
),
'lastDoorLog' => DoorLog::find()->orderBy(['id_door_log' => SORT_DESC])->limit(1)->one(),
'doorLogCount' => DoorLog::find()->count()
];
}
public function createLog()
{
\Yii::info("Post create log:" . \Yii::$app->request->method);
if (\Yii::$app->request->isPost) {
$log = new DoorLogForTest();
if ($log->load(\Yii::$app->request->post(), "")) {
if ($log->validate()) {
\Yii::info("Door log saving:" . $log->created_at);
$log->save(false);
return $log;
} else {
throw new BadRequestHttpException(print_r($log->getErrors(), true));
}
} else {
\Yii::info("validated" . print_r($log->errors, true));
throw new BadRequestHttpException();
}
}
throw new BadRequestHttpException('Not a Post');
}
function checkoutKey($cardNumber, $keyNumber)
{
$model = new KeyToggleForm();
$model->card = Card::readCard($cardNumber);
$model->customer = $model->card->customer;
$model->keyCard = $model->card;
$model->keyModel = $model->readKey($keyNumber);
$model->assign();
}
function revokeKey($cardNumber, $keyNumber)
{
$model = new KeyToggleForm();
$model->card = Card::readCard($cardNumber);
$model->customer = $model->card->customer;
$model->keyCard = $model->card;
$model->keyModel = $model->readKey($keyNumber);
$model->revoke();
}
}

View File

@ -0,0 +1,143 @@
<?php
namespace common\manager;
use common\components\DateUtil;
use common\components\Helper;
use common\models\Card;
use common\models\DoorCardPass;
use DateInterval;
use yii\base\BaseObject;
use yii\web\NotFoundHttpException;
/**
* Created by IntelliJ IDEA.
* User: rocho
* Date: 2018.12.17.
* Time: 6:12
*/
class
DoorCardPassManager extends BaseObject
{
public function createNewDoorCardPass($idCard)
{
$model = new DoorCardPass();
$model->id_card = $idCard;
$validUntilTime = DateUtil::utcDateTime();
$validUntilTime->add(new DateInterval('PT' . Helper::getDoorPassValidityIntervalMinutes() . 'M'));
$validUntilTime->setTime($validUntilTime->format("H"), $validUntilTime->format("i"), 0);
$model->valid_until_at = DateUtil::formatDateTimeUtc($validUntilTime);
$model->save(false);
return $model;
}
public function hardReset(){
$now = DateUtil::utcDateTime();
DoorCardPass::updateAll(
[
'invalidated_at' => DateUtil::formatDateTimeUtc($now)
],
[
'invalidated_at' => null
]
);
\Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS())->execute();
}
/**
* @throws NotFoundHttpException
*/
public function updateDoorCardPassStateForCard($idCard)
{
$now = DateUtil::utcDateTime();
$card = Card::findOne($idCard);
if (!isset($card)) {
throw new NotFoundHttpException();
}
$passes = $this->readAllNovInvalidatedAtCardPassForCard($idCard,$now);
$this->setCardFlagAndInvalidateDoorCardPasses($card, $passes,$now);
}
public function updateDoorCardPassStateForAllCard(){
$passes = $this->readAllNonInvalidated();
$map = array();
foreach ($passes as $pass){
$idCard = $pass->id_card;
if ( !array_key_exists($idCard,$map)){
$map[$idCard] = array();
}
$map[$idCard][] = $pass;
}
$now = DateUtil::utcDateTime();
foreach ($map as $idCard => $passes){
$card = Card::findOne($idCard);
if (isset($card)) {
$this->setCardFlagAndInvalidateDoorCardPasses($card, $passes,$now);
}
}
}
private function readAllNovInvalidatedAtCardPassForCard($idCard)
{
return DoorCardPass::find()
->andWhere(
[
'id_card' => $idCard,
'invalidated_at' => null,
]
)->all();
}
private function readAllNonInvalidated()
{
return DoorCardPass::find()
->andWhere(
['invalidated_at' => null]
)->all() ;
}
private function setCardFlagAndInvalidateDoorCardPasses($card, $doorCardPasses, $now)
{
$allowed = $this->hasActiveDoorCardPass($doorCardPasses, $now);
$origFlag = $card->flag;
$card->flag = Helper::setBit($card->flag, Card::$FLAG_DOOR_PASS_ALLOWED, !$allowed);
if ($card->flag !== $origFlag) {
$card->save(false);
}
$this->invalidateNonActiveDoorCardPasses($doorCardPasses, $now);
}
private function invalidateNonActiveDoorCardPasses($doorCardPasses, $now)
{
foreach ($doorCardPasses as $pass) {
if (isset($pass->valid_until_at) && !empty($pass->valid_until_at)) {
\Yii::error( "mydate". print_r($pass->valid_until_at ,true));
$validUntilAt = DateUtil::parseDateTime($pass->valid_until_at);
$active = ($validUntilAt >= $now);
if (!$active) {
$pass->invalidated_at = DateUtil::formatDateTimeUtc($now);
$pass->save(false);
}
}
}
}
private function hasActiveDoorCardPass($doorCardPasses, $now)
{
$active = false;
foreach ($doorCardPasses as $pass) {
if (isset($pass->valid_until_at)) {
$validUntilAt = DateUtil::parseDateTime($pass->valid_until_at);
$active |= ($validUntilAt >= $now);
}
}
return $active;
}
}

View File

@ -0,0 +1,707 @@
<?php
namespace common\manager;
use common\components\DateUtil;
use common\components\DoorMoveContext;
use common\components\FitnessException;
use common\components\Helper;
use common\components\StopWatch;
use common\models\Card;
use common\models\CardKeyAssignment;
use common\models\DoorLog;
use common\models\DoorLogForTest;
use common\models\DoorManagerLog;
use common\models\Key;
use common\models\Log;
use common\models\Ticket;
use common\models\VirtualKey;
use frontend\models\KeyToggleForm;
use Yii;
use yii\base\BaseObject;
use yii\base\InvalidConfigException;
use yii\db\Exception;
use yii\web\BadRequestHttpException;
use yii\web\ServerErrorHttpException;
/**
* Created by IntelliJ IDEA.
* User: rocho
* Date: 2018.12.17.
* Time: 6:12
*/
class KeyDoorManager extends BaseObject
{
/**
* @param $identifier 00000000: nyomogombos nyitás
* @param $device string B(gomb)|Q(qrcode)|C(nfc),E(emergency)
* @param $direction string IN|OUT
* @param $verifyOnly boolean true: akkor csak lekerdezés, false: megtörtént a mozgás (ilyenkor vonunk le egy alkalmat)
* @param $createdAt number unix timestamp , override createdAt for doorLogs
* @param $date number unix timestamp, override date for validation check 'now'
* @return void
* @throws BadRequestHttpException
* @throws Exception
* @throws FitnessException
* @throws InvalidConfigException
* @throws ServerErrorHttpException
*/
public function move($identifier, $device, $direction, $verifyOnly, $createdAt = null, $date = null)
{
$requestId = uniqid("", false);
$context = new DoorMoveContext([
'requestId' => $requestId,
'identifier' => $identifier,
'device' => $device,
'direction' => $direction,
'originalDirection' => $direction,
'verifyOnly' => $verifyOnly
]);
try {
$stopWatch = new StopWatch();
// for testing purposes
if (Helper::isRestAllowVerifyOnly() === false) {
Yii::info("$requestId: verifyonly not allowed");
$verifyOnly = false;
}
Yii::info("$requestId: move with next parameers:" . ";identifier" . $identifier . ";device" . $device . ";direction" . $direction . ";verifyOnly" . $verifyOnly . ";createdAt" . print_r($createdAt, true) . ";date" . print_r($date, true));
Yii::info("$requestId: move get request: " . print_r($_GET, true));
Yii::info("$requestId: move post request: " . print_r($_GET, true));
if (isset($createdAt)) {
$createdAt = DateUtil::parseDateTime($createdAt);
} else {
$createdAt = DateUtil::utcDateTime();
}
$context->createdAt = $createdAt;
if (isset($date)) {
$date = DateUtil::parseDateTime($date);
} else {
$date = DateUtil::utcDate();
}
$context->date = $date;
if ($device === 'E') {
$this->moveEmergency($context/*;$requestId,$identifier, $device, $direction, $verifyOnly, $createdAt, $date*/);
return;
}
$cardNumber = $identifier;
switch ($direction) {
case 'IN':
$direction = DoorLog::$DIRECTION_IN;
break;
case 'OUT':
$direction = DoorLog::$DIRECTION_OUT;
break;
default:
throw new FitnessException(
"Direction $direction not supported",
FitnessException::TYPE_BAD_REQUEST,
"INVALID_DIRECTION",
$context
);
}
$context->direction = $direction;
// if device is qr code
if ($device == 'Q') {
// load virtual key by virtual_key.number
$virtualKey = VirtualKey::findOne(['number' => $identifier]);
if (!isset($virtualKey)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_NOT_FOUND",
$context
);
}
// load card by virutal key
$card = Card::findOne($virtualKey->id_card);
if (!isset($card)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"CARD_FOR_VIRTUAL_KEY_NOT_FOUND",
$context
);
}
$cardNumber = $card->number;
Yii::info("$requestId: virtual key and card loaded in sec " . $stopWatch->split());
} else {
// load card by rfid
$card = Card::readCard(Helper::fixAsciiChars($identifier));
Yii::info("$requestId: Card loaded in sec " . $stopWatch->split());
if (!isset($card)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"CARD_NOT_FOUND",
$context
);
}
Yii::info("$requestId: card loaded in sec " . $stopWatch->split());
// load virtual key by card
$virtualKey = VirtualKey::findOne(['id_card' => $card->id_card]);
Yii::info("$requestId: virtual key for card loaded in sec " . $stopWatch->split());
}
$context->virtualKey = $virtualKey;
$context->card = $card;
$context->cardNumber = $cardNumber;
Yii::info("$requestId: Card number " . $card->number);
// check card status
if ($card->status !== Card::STATUS_ACTIVE) {
throw new FitnessException(
"Card Status is inactive",
FitnessException::TYPE_BAD_REQUEST,
"CARD_STATUS_INACTIVE",
$context
);
}
// load assigned key
$keyAssignment = CardKeyAssignment::findOne(['id_card' => $card->id_card]);
if (isset($keyAssignment)) {
$context->key = Key::findOne($keyAssignment->id_key);
}
if ($card->type == Card::TYPE_EMPLOYEE) {
$this->moveEmployee($context);
return;
}
if (!isset($virtualKey)) {
throw new FitnessException(
"Virtual Key Not Found",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_NOT_FOUND",
$context
);
}
$this->moveCustomer($context);
} catch (FitnessException $e) {
$context->error = true;
$context->exception = $e->originalException;
$context->errorCode = $e->errorCode;
if ($e->type == FitnessException::TYPE_BAD_REQUEST) {
throw new BadRequestHttpException($e->getMessage());
} else {
throw new ServerErrorHttpException($e->getMessage());
}
// throw $e->originalException;
// throw new BadRequestHttpException();
} catch (\Exception $e) {
$context->error = true;
$context->exception = $e;
$context->errorCode = "UNKNOWN";
throw $e;
} finally {
// do logging
$this->logContext($context);
}
}
/**
* @param $ctx DoorMoveContext
* @return void
*/
function logContext($ctx)
{
try {
$result = [
//datetime $updated_at --
//datetime $created_at --
//string $ticket_usage
//string $request_id
'request_id' => $ctx->requestId,
//string $identifier
'identifier' => $ctx->identifier,
//bool $verify_only
'verify_only' => $ctx->verifyOnly,
//string $device
'device' => $ctx->device,
//string $direction
'direction' => $ctx->direction,
//string $original_direction
'original_direction' => $ctx->originalDirection,
//integer $card_id_card
'card_id_card' => isset($ctx->card) ? $ctx->card->id_card : null,
//string $card_number
'card_number' => isset($ctx->card) ? $ctx->card->number : null,
//string $ticket_id_ticket
'ticket_id_ticket' => isset($ctx->ticket) ? $ctx->ticket->id_ticket : null,
//string $ticket_type_name
'ticket_type_name' => isset($ctx->ticket) ? $ctx->ticket->ticketType->name : null,
//string $ticket_usage_count
'ticket_usage_count' => isset($ctx->ticket) ? $ctx->ticket->usage_count : null,
//string $customer_id_customer
'customer_id_customer' => isset($ctx->customer) ? $ctx->customer->id_customer : null,
//string $customer_name
'customer_name' => isset($ctx->customer) ? $ctx->customer->name : null,
//string $customer_email
'customer_email' => isset($ctx->customer) ? $ctx->customer->email : null,
//integer $key_id_key
'key_id_key' => isset($ctx->key) ? $ctx->key->id_key : null,
//string $key_number
'key_number' => isset($ctx->key) ? $ctx->key->number : null,
//integer $virtual_key_id
'virtual_key_id' => isset($ctx->virtualKey) ? $ctx->virtualKey->id : null,
//string $validation_kind
'validation_kind' => $ctx->kind,
//bool $error
'error' => $ctx->error,
//string $error_code
'error_code' => $ctx->errorCode,
'ticket_usage' => $ctx->increasedTicketUsageCount,
// 'actions' => implode(",",$ctx->actions),
];
if ($ctx->error === true) {
if (isset($ctx->exception)) {
// string $error_message
$result['error_message'] = substr($ctx->exception->getMessage(), 0, 100);
}
}
Yii::info("door log: " . implode(";", $result));
Yii::$app->db->beginTransaction();
$log = new DoorManagerLog($result);
$log->save(false);
Yii::$app->db->transaction->commit();
} catch (\Exception $e) {
Yii::error("Failed to log door context:" . $e->getMessage());
}
}
function moveEmergency($ctx)
{
$ctx->kind = "EMERGENCY";
Yii::info("$ctx->requestId: emergency move");
try {
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
Yii::$app->db->beginTransaction();
$doorLog = new DoorLog();
$doorLog->version = 2;
$doorLog->direction = DoorLog::$DIRECTION_ALL_EMERGENCY;
$doorLog->source_app = $ctx->device;
$doorLog->created_at = $createdAtStr;
$doorLog->save(false);
Log::log(
[
'type' => Log::$TYPE_INFO,
'message' => 'Ajtó nyitás: vészhelyzet',
'id_door_log' => $doorLog->id_door_log
]
);
$ctx->actions[] = "EMERGENCY_MOVE";
Yii::$app->db->transaction->commit();
} catch (\Exception $e) {
Yii::$app->db->transaction->rollBack();
throw new FitnessException(
"unknowon error",
FitnessException::UNKNOWN_ERROR,
"EMERGENCY_OPEN_FAILED",
$ctx,
$e
);
}
}
function moveEmployee($ctx /*$identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/)
{
$ctx->kind = "EMPLOYEE";
/**
* if the card type is employee, neither customer nor ticket is needed.
* Free to enter/leave
*/
Yii::info("employee move");
}
/**
* @param $ctx
*
* @return void
* @throws FitnessException
*/
function moveCustomer($ctx/* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/)
{
$ctx->kind = "CUSTOMER";
Yii::info("$ctx->requestId: move customer");
$stopWatch = new StopWatch();
try {
Yii::$app->db->beginTransaction();
// load active ticket
$activeTickets = Ticket::readActive($ctx->card, clone $ctx->date);
Yii::info("$ctx->requestId: active ticket count:" . count($activeTickets));
/** @var Ticket $ticket */
$ticket = null;
// load customer
$customer = $ctx->card->customer;
if (!isset($customer)) {
throw new FitnessException(
"$ctx->requestId: Customer not found for:" . $ctx->card->number,
FitnessException::TYPE_BAD_REQUEST,
"NOT_FOUND_CUSTOMER",
$ctx
);
}
$ctx->customer = $customer;
Yii::info("$ctx->requestId: customer {$customer->id_customer} loaded in sec " . $stopWatch->split());
// if direction is in, check if usage count must be increased
if ($ctx->direction == DoorLog::$DIRECTION_IN) {
if (isset($activeTickets) && count($activeTickets) > 0) {
for ( $i = 0; ($i < count($activeTickets)) && !isset($ticket); $i++){
/**@var $currentTicket Ticket **/
$currentTicket = $activeTickets[$i];
if ( $currentTicket->usage_count < $currentTicket->max_usage_count){
$ticket = $currentTicket;
}
}
}
if (!isset($ticket)) {
throw new FitnessException(
"$ctx->requestId: No active ticket found for:" . $ctx->card->number,
FitnessException::TYPE_BAD_REQUEST,
"NOT_FOUND_ACTIVE_TICKET",
$ctx
);
}
$ctx->ticket = $ticket;
Yii::info("$ctx->requestId: ticket {$ticket->id_ticket} loaded in sec " . $stopWatch->split());
// Key required
if (!isset($ctx->key)) {
throw new FitnessException(
"$ctx->requestId: Key required: " . $ctx->card->id_card,
FitnessException::TYPE_BAD_REQUEST,
"REQUIRED_KEY",
$ctx
);
}
// virtual_key without entry required
if (isset($ctx->virtualKey->direction_in_at)) {
throw new FitnessException(
"$ctx->requestId: Virtual key - already moved in: " . $ctx->identifier . '/' . $ctx->virtualKey->id_card,
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_ALREADY_IN",
$ctx
);
}
$ctx->virtualKey->direction_in_at = Helper::getDateTimeString();
Yii::info("$ctx->requestId: Setting virtual key direction_in_at");
$ctx->actions[] = "VIRTUAL_KEY_MOVE_IN";
if (!$ctx->verifyOnly) {
Yii::info("$ctx->requestId: Updating virtual key");
$ctx->virtualKey->save(false);
}
// if not verifyonly, check, if ticket usage count must be increased
$allDoorLogToday = DoorManagerLog::findAllEntryForTicketFromTime($ctx->ticket->id_ticket);
$countDoorLogsForTicketSince = count($allDoorLogToday);
$ctx->increasedTicketUsageCount = false;
// if the current event is the first door log today
if ($countDoorLogsForTicketSince == 0) {
$ctx->increasedTicketUsageCount = true;
// $usageCount = $ticket->usage_count;
// $ticket->usage_count += 1;
// $ticket->save(false);
// \Yii::info("$ctx->requestId: First ticket usage today, increasing usage count for card: " . $ctx->card->id_card);
// \Yii::info("$ctx->requestId: Ticket usage count increased after first doorlog of day in sec " . $stopWatch->split());
$ctx->actions[] = "TICKET_FIRST_USAGE_TODAY";
} else {
Yii::info("$ctx->requestId: more then one door log today for card: " . $ctx->card->id_card);
// we have already a door log for today, other than this
// Now we split the day into 3hour intervalls, starting with the createdAt value of the first event.
// If the actual event happens in an interval, in which still now doorlog event happend, we increase
// the usage count with 1
// 3 óránként 1-et levonunk
$firstInToday = $allDoorLogToday[0];
Yii::info("$ctx->requestId: first in today for card: " . $ctx->card->id_card . " was at " . $firstInToday->created_at);
$firstEntryDateTimeToday = DateUtil::parseDateTime($firstInToday->created_at);
$interval = \DateInterval::createFromDateString('3 hours');
$startOfTomorrow = DateUtil::tomorrowStart(clone $ctx->date);
$daterange = new \DatePeriod($firstEntryDateTimeToday, $interval, $startOfTomorrow);
$intervals = [];
$intervalStart = null;
foreach ($daterange as $intervalEnd) {
if (isset($intervalStart)) {
$intervals[] = $this->createTicketUsageInterval($intervalStart, $intervalEnd, $allDoorLogToday);
}
$intervalStart = clone $intervalEnd;
}
if ($intervalStart < $startOfTomorrow) {
$intervals[] = $this->createTicketUsageInterval($intervalStart, $startOfTomorrow, $allDoorLogToday);
}
$activeInterval = $this->getActiveInterval($intervals, $ctx->createdAt);
if (!isset($activeInterval)) {
throw new ServerErrorHttpException("$ctx->requestId: Active Interval not found");
}
$logCountInActiveInterval = count($activeInterval['logs']);
if ($logCountInActiveInterval == 0) {
$ctx->increasedTicketUsageCount = true;
$ctx->actions[] = "TICKET_INCREASE_USAGE";
}
}
if ($ctx->increasedTicketUsageCount === true) {
$ticket->usage_count = $ticket->usage_count + 1;
if ($ticket->usage_count > $ticket->max_usage_count) {
throw new FitnessException(
"$ctx->requestId: Ticket usage count exceeded",
FitnessException::TYPE_BAD_REQUEST,
"TICKET_MAX_USAGE_COUNT_EXCEEDED",
$ctx
);
}
if (!$ctx->verifyOnly) {
$ticket->save(false);
}
Yii::info("$ctx->requestId: Ticket usage count increased after first IN after first door_log in interval in sec " . $stopWatch->split());
}
$ctx->actions[] = "MOVE_IN";
}
if ($ctx->direction == DoorLog::$DIRECTION_OUT || $ctx->direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE) {
// virtual key with entry required
if (!isset($ctx->virtualKey->direction_in_at)) {
throw new FitnessException(
"$ctx->requestId: Can't exit without move ind",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_MOVE_OUT_WITHOUT_MOVE_IN",
$ctx
);
}
// virtual_key: only one move out is allowed
if (isset($ctx->virtualKey->direction_out_at)) {
throw new FitnessException(
"$ctx->requestId: virtual key already out. Only one move out allowed.",
FitnessException::TYPE_BAD_REQUEST,
"VIRTUAL_KEY_ALREADY_OUT",
$ctx
);
}
// key must not be unassigned
if (isset($ctx->key)) {
throw new FitnessException(
"$ctx->requestId: Can't exit with card has a key assigned",
FitnessException::TYPE_BAD_REQUEST,
"CARD_LOCKER_KEY_ASSIGNED_FLAG",
$ctx
);
}
// set move_out datetime
$ctx->virtualKey->direction_out_at = Helper::getDateTimeString();
// save virtual key
if (!$ctx->verifyOnly) {
$ctx->virtualKey->save(false);
}
if (isset($activeTickets) && count($activeTickets) > 0) {
for ( $i = 0; ($i < count($activeTickets)) && !isset($ticket); $i++){
/**@var $currentTicket Ticket **/
$currentTicket = $activeTickets[$i];
if ( $currentTicket->count_move_out < $currentTicket->max_usage_count && $currentTicket->count_move_out != $currentTicket->usage_count){
$ticket = $currentTicket;
}
}
}
// if (!isset($ticket)) {
// throw new FitnessException(
// "$ctx->requestId: No active ticket found for:" . $ctx->card->number,
// FitnessException::TYPE_BAD_REQUEST,
// "NOT_FOUND_ACTIVE_TICKET",
// $ctx
// );
// }
// if ( isset($ticket)){
// $ctx->ticket = $ticket;
// $ticket->count_move_out = $ticket->usage_count;
// if (!$ctx->verifyOnly) {
// $ticket->save(false);
// }
// }
$ctx->actions[] = "MOVE_OUT";
Yii::info("$ctx->requestId: direction_out: ticket count_move_out set after direction_out in sec " . $stopWatch->split());
}
$stopWatch->stop();
Yii::info("$ctx->requestId: finished in sec " . $stopWatch->getTotal());
Yii::$app->db->transaction->commit();
Yii::info("$ctx->requestId: Commited");
} catch (FitnessException $fe) {
$this->doRollback();
Yii::info("$ctx->requestId: rollbacked");
throw $fe;
} catch
(\Exception $e) {
$this->doRollback();
Yii::info("$ctx->requestId: rollbacked");
Yii::error($e->getMessage());
throw new FitnessException(
"UNKNOWN_ERROR",
FitnessException::UNKNOWN_ERROR,
"CUSTOMER_UNKNOWN_ERROR",
$ctx,
$e
);
}
}
function doRollback()
{
if (isset(Yii::$app->db->transaction) && Yii::$app->db->transaction->isActive) {
Yii::$app->db->transaction->rollBack();
}
}
function getActiveInterval($intervals, $date)
{
foreach ($intervals as $interval) {
$start = $interval['start'];
$end = $interval['end'];
if ($start <= $date && $date < $end) {
return $interval;
}
}
return null;
}
function createTicketUsageInterval($start, $end, $allLogs)
{
$result = ['start' => $start, 'end' => $end, 'logs' => []];
foreach ($allLogs as $log) {
$createdAt = DateUtil::parseDateTime($log->created_at);
if ($createdAt >= $start && $createdAt < $end) {
$result['logs'][] = $log;
}
}
return $result;
}
public function resetLogs($cardNumber)
{
$card = Card::readCard($cardNumber);
$card->flag = 0;
$card->flag_out = 0;
$card->save(false);
Card::updateCardFlagTicket($card->id_card);
DoorLog::deleteAll(
['id_card' => $card->id_card]
);
// todo: revoke all assigned key
$this->revokeKey($cardNumber, "f100");
}
public function getInfo($cardNumber)
{
$card = Card::readCard($cardNumber);
return [
'card' => $card,
'customer' => $card->customer,
'tickets' => Ticket::readActive($card),
'doorLogs' => DoorLog::findAll(
['id_card' => $card->id_card]
),
'lastDoorLog' => DoorLog::find()->orderBy(['id_door_log' => SORT_DESC])->limit(1)->one(),
'doorLogCount' => DoorLog::find()->count()
];
}
public function createLog()
{
Yii::info("Post create log:" . Yii::$app->request->method);
if (Yii::$app->request->isPost) {
$log = new DoorLogForTest();
if ($log->load(Yii::$app->request->post(), "")) {
if ($log->validate()) {
Yii::info("Door log saving:" . $log->created_at);
$log->save(false);
return $log;
} else {
throw new BadRequestHttpException(print_r($log->getErrors(), true));
}
} else {
Yii::info("validated" . print_r($log->errors, true));
throw new BadRequestHttpException();
}
}
throw new BadRequestHttpException('Not a Post');
}
function checkoutKey($cardNumber, $keyNumber)
{
$model = new KeyToggleForm();
$model->card = Card::readCard($cardNumber);
$model->customer = $model->card->customer;
$model->keyCard = $model->card;
$model->keyModel = $model->readKey($keyNumber);
$model->assign();
}
function revokeKey($cardNumber, $keyNumber)
{
$model = new KeyToggleForm();
$model->card = Card::readCard($cardNumber);
$model->customer = $model->card->customer;
$model->keyCard = $model->card;
$model->keyModel = $model->readKey($keyNumber);
$model->revoke();
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace common\manager;
use common\models\Card;
use common\models\CardEventRegistrationForm;
use common\models\Customer;
use common\models\Event;
use common\models\EventRegistration;
use common\models\MobileDevice;
use common\models\Ticket;
use customerapi\models\available\EventInterval;
use customerapi\models\registrations\EventRegistrationAvailable;
use customerapi\models\details\EventRegistrationView;
use Exception;
use Yii;
use yii\base\BaseObject;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* Created by IntelliJ IDEA.
* User: rocho
* Date: 2018.12.17.
* Time: 6:12
*/
class MobileDeviceManager extends BaseObject
{
public function login($cardNumber, $deviceIdentifier)
{
$card = Card::find()->andWhere(
['number' => $cardNumber]
)->one();
if ( $card == null ){
throw new NotFoundHttpException();
}
$device = MobileDevice::find()
->andWhere(
[
'id_card' => $card->id_card,
'device_identifier' => $deviceIdentifier
]
)->one();
if ( $device === null ){
throw new NotFoundHttpException();
}
// if (
// in_array($device->status, [MobileDevice::STATUS_ACTIVE, MobileDevice::STATUS_INACTIVE], true) === false ){
// throw new NotFoundHttpException();
// }
return $device;
}
public function create($cardNumber, $deviceIdentifier, $deviceName)
{
$card = Card::find()->andWhere(
['number' => $cardNumber]
)->one();
if ( $card == null ){
throw new NotFoundHttpException();
}
// do not allow registering cards without customer
$customer = Customer::find()->andWhere(['id_customer_card' => $card->id_card])->one();
if ( $customer == null ){
throw new NotFoundHttpException();
}
$device = MobileDevice::find()
->andWhere(
[
'id_card' => $card->id_card,
'device_identifier' => $deviceIdentifier
]
)->one();
if ( $device ){
throw new BadRequestHttpException("Device already exists, can't create");
}
$device = new MobileDevice();
$device->device_identifier = $deviceIdentifier;
$device->id_card = $card->id_card;
$device->status = MobileDevice::STATUS_INACTIVE;
$device->device_name = $deviceName;
$device->save(false);
return $device;
}
/**
* @param $cardNumber
* @param $deviceIdentifier
* @return array|MobileDevice|ActiveRecord
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
public function loginOrCreate($cardNumber, $deviceIdentifier, $deviceName)
{
try {
return $this->login($cardNumber, $deviceIdentifier);
} catch (\Exception $e) {
return $this->create($cardNumber, $deviceIdentifier, $deviceName);
}
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace common\manager;
use common\components\DateUtil;
use common\components\Helper;
use common\models\VirtualKey;
use yii\base\BaseObject;
class VirtualKeyManager extends BaseObject
{
public function createNewVirtualKey($idCard)
{
$model = new VirtualKey();
$model->id_card = $idCard;
$model->save(false);
return $model;
}
public function getValidUntilTime($createdAtStr){
$createdAt = DateUtil::parseDateTime($createdAtStr);
$validUntil = DateUtil::addMinutes($createdAt,Helper::getDoorPassValidityIntervalMinutes());
return $validUntil;
}
}

View File

@ -34,6 +34,7 @@ class Card extends \common\models\BaseFitnessActiveRecord
const TYPE_BARCODE = 30;
const TYPE_OLD = 40;
const TYPE_EMPLOYEE = 50;
const TYPE_REVIEW = 60;
public static $FLAG_TICKET = 0; //has valid ticket
@ -41,6 +42,7 @@ class Card extends \common\models\BaseFitnessActiveRecord
public static $FLAG_KEY = 2; //key status
public static $FLAG_STATUS = 3; //allowed/disabled
public static $FLAG_DOOR_ALLOWED = 4; //ticket type allows door
public static $FLAG_DOOR_PASS_ALLOWED = 5; // door pass
/**
* This script is used in daily scripts, to clear the flag door log status
@ -76,6 +78,22 @@ class Card extends \common\models\BaseFitnessActiveRecord
return Card::SQL_CLEAR_STATUS_DOOR_ALLOWED_FLAG() . " and card.id_card = :id ";
}
public static function SQL_DENY_DOOR_CARD_PASS() {
return "update card set flag = flag | (1 << " . Card::$FLAG_DOOR_PASS_ALLOWED . ") ";
}
public static function SQL_ALLOW_DOOR_CARD_PASS() {
return "update card set flag = flag | (1 << " . Card::$FLAG_DOOR_PASS_ALLOWED . ") ";
}
public static function SQL_DENY_DOOR_CARD_PASS_EXPIRED( ){
return "update card ca "
. "inner join door_card_pass dcp on ca.id_card = dcp.id_card "
. "set ca.flag = ca.flag | (1 << " . Card::$FLAG_DOOR_PASS_ALLOWED . ") , dcp.updated_at = now()"
. " WHERE "
. " dcp.updated_at <> dcp.created_at and dcp.created_at <= :datetime ";
}
public static $SQL_UPDATE_FLAG_STATUS_ACTIVE = '
update card set flag = CASE WHEN status = 20 then (flag | 1 << 3) else ( flag & ~(1 << 3 ) ) end
@ -164,6 +182,7 @@ class Card extends \common\models\BaseFitnessActiveRecord
self::TYPE_BARCODE => Yii::t('common/card', 'BARCODE'),
self::TYPE_OLD => Yii::t('common/card', 'OLD'),
self::TYPE_EMPLOYEE => Yii::t('common/card', 'Munkatárs'),
self::TYPE_REVIEW => Yii::t('common/card', 'Review'),
];
}

View File

@ -12,6 +12,7 @@ use yii\behaviors\TimestampBehavior;
* @property integer $id_card
* @property integer $id_key
* @property integer $id_user
* @property string $virtual_key
* @property string $created_at
* @property string $updated_at
*/

View File

@ -6,6 +6,7 @@ use Yii;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\base\NotSupportedException;
use yii\filters\RateLimitInterface;
use yii\web\IdentityInterface;
/**
@ -33,16 +34,17 @@ use yii\web\IdentityInterface;
* @property string $address
* @property string $created_at
* @property string $updated_at
* @property \common\models\Card card
* @property integer status
* @property integer towel_count
* @property \common\models\User user
* @property mixed bank_account
* @property string password_plain
* @property string password_hash
* @property string auth_key
* @property \common\models\Card $card
* @property integer $status
* @property integer $towel_count
* @property \common\models\User $user
* @property mixed $bank_account
* @property string $password_plain
* @property string $password_hash
* @property string $auth_key
* @property string $comment
*/
class Customer extends BaseFitnessActiveRecord implements IdentityInterface
class Customer extends BaseFitnessActiveRecord implements IdentityInterface, RateLimitInterface
{
const STATUS_DELETED = 0;
@ -339,4 +341,23 @@ class Customer extends BaseFitnessActiveRecord implements IdentityInterface
}
}
public function getRateLimit($request, $action)
{
return [1000,3600];
// TODO: Implement getRateLimit() method.
}
public function loadAllowance($request, $action)
{
// TODO: Implement loadAllowance() method.
return [1000,3600];
}
public function saveAllowance($request, $action, $allowance, $timestamp)
{
// TODO: Implement saveAllowance() method.
return [1000,3600];
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "door_card_pass".
*
*
* 'id_door_card_pass'=> $this->primaryKey(),
'id_card' => $this->integer(11),
'id_user' => $this->integer(11),
'created_at' => $this->dateTime()->notNull(),
'updated_at' => $
* @property integer $id_door_card_pass
* @property integer $id_card
* @property integer $id_user
* @property integer $created_at
* @property integer $updated_at
* @property integer $valid_until_at
* @property integer $invalidated_at
*
*/
class DoorCardPass extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'door_card_pass';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
];
}
}

View File

@ -22,12 +22,29 @@ use yii\helpers\ArrayHelper;
* @property integer id_ticket_current
* @property integer card_flag
* @property integer flag_out
* @property integer version
*/
class DoorLog extends \yii\db\ActiveRecord
{
public static $SOURCE_APP_FORGO_VILLA = "forgo_villa";
public static $SOURCE_APP_FITNESS_ADMIN = "fitness_admin";
public static $SOURCE_APP_FORGO_VILLA = "forgo_villa";
public static $SOURCE_APP_FITNESS_ADMIN = "fitness_admin";
public static $DIRECTION_OUT_MANUAL_READ_KEY_ASSIGNED = -2; // "Kézi olvasás/Kulcs ki",
public static $DIRECTION_IN_MANUAL_READ_KEY_UNASSIGNED = -1; // "Kézi olvasás/Kulcs vissza",
public static $DIRECTION_ALL_MANUAL_READ = 0; // "Kézi olvasás",
public static $DIRECTION_OUT_WITHOUT_MOVE = 1; // "KI olvastatás mozgás nélkül",
public static $DIRECTION_IN_WITHOUT_MOVE = 3; // "BE olvastatás mozgás nélkül",
public static $DIRECTION_OUT = 5; // "KI mozgás",
public static $DIRECTION_IN = 7; // "BE mozgás",
public static $DIRECTION_OUT_ERROR_KEY_ASSIGNED = 9; // "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
public static $DIRECTION_IN_ERROR_KEY_MISSING = 11; // "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
public static $DIRECTION_OUT_NO_TICKET = 17; // "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
public static $DIRECTION_IN_NO_TICKET = 19; // "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
public static $DIRECTION_ALL_EMERGENCY = 128; // "Vésznyitás",
public static $DIRECTION_ALL_CARD_BLOCKED = 256; // "Kártya tiltva -> információ mező",
/**
* @inheritdoc
*/
@ -38,13 +55,18 @@ class DoorLog extends \yii\db\ActiveRecord
public function behaviors()
{
return ArrayHelper::merge( [
[
'class' => TimestampBehavior::className(),
'value' => function(){ return date('Y-m-d H:i:s' ); },
'updatedAtAttribute' => false,
]
], parent::behaviors());
return ArrayHelper::merge([
[
'class' => TimestampBehavior::className(),
'value' => function ($event) {
if ( isset($event->sender->created_at) ){
return $event->sender->created_at;
}
return date('Y-m-d H:i:s');
},
'updatedAtAttribute' => false,
]
], parent::behaviors());
}
/**
@ -76,132 +98,146 @@ class DoorLog extends \yii\db\ActiveRecord
];
}
public function getCustomer(){
return $this->hasOne( Customer::className(), ["id_customer" =>"id_customer" ] );
public function getCustomer()
{
return $this->hasOne(Customer::className(), ["id_customer" => "id_customer"]);
}
public function getCustomerName(){
$result = "";
if (isset($this->customer)){
$result = $this->customer->name;
}
return $result;
}
public function getCard(){
return $this->hasOne( Card::className(), ["id_card" =>"id_card" ] );
public function getCustomerName()
{
$result = "";
if (isset($this->customer)) {
$result = $this->customer->name;
}
return $result;
}
public function getCardNumber(){
$result = "";
if (isset($this->card)){
$result = $this->card->number;
}
return $result;
}
public function getKey(){
return $this->hasOne( Key::className(), ["id_key" =>"id_key" ] );
public function getCard()
{
return $this->hasOne(Card::className(), ["id_card" => "id_card"]);
}
public function getKeyNumber(){
$result = "";
if (isset($this->key)){
$result = $this->key->number;
}
return $result;
public function getCardNumber()
{
$result = "";
if (isset($this->card)) {
$result = $this->card->number;
}
return $result;
}
public function getDirectionName(){
$result = "";
if ( $this->source_app == 'forgo_villa'){
if (isset($this->direction)){
$result = Helper::getArrayValue(self::getDirectionTypes() , $this->direction, "-");
}
}else{
$result = "Kézi olvasás";
}
return $result;
public function getKey()
{
return $this->hasOne(Key::className(), ["id_key" => "id_key"]);
}
public function getKeyNumber()
{
$result = "";
if (isset($this->key)) {
$result = $this->key->number;
}
return $result;
}
public function getDirectionName()
{
$result = "";
if ($this->source_app == 'forgo_villa') {
if (isset($this->direction)) {
$result = Helper::getArrayValue(self::getDirectionTypes(), $this->direction, "-");
}
} else {
$result = "Kézi olvasás";
}
return $result;
}
public static function getSourceAppName($source_app){
$result = "";
switch ($source_app){
case self::$SOURCE_APP_FITNESS_ADMIN :
$result = "Recepciós alkalmazás";
break;
case self::$SOURCE_APP_FORGO_VILLA:
$result = "Forgó villa";
break;
}
return $result;
public static function getSourceAppName($source_app)
{
$result = "";
switch ($source_app) {
case self::$SOURCE_APP_FITNESS_ADMIN :
$result = "Recepciós alkalmazás";
break;
case self::$SOURCE_APP_FORGO_VILLA:
$result = "Forgó villa";
break;
}
return $result;
}
public static function getDirectionTypes( ){
return [
-2 => "Kézi olvasás/Kulcs ki",
-1 => "Kézi olvasás/Kulcs vissza",
0 => "Kézi olvasás",
public static function getDirectionTypes()
{
return [
-2 => "Kézi olvasás/Kulcs ki",
-1 => "Kézi olvasás/Kulcs vissza",
0 => "Kézi olvasás",
1 => "KI olvastatás mozgás nélkül",
1 => "KI olvastatás mozgás nélkül",
3 => "BE olvastatás mozgás nélkül",
3 => "BE olvastatás mozgás nélkül",
5 => "KI mozgás",
5 => "KI mozgás",
7 => "BE mozgás",
7 => "BE mozgás",
9 => "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
9 => "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
11 => "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
11 => "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
17 => "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
17 => "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
19 => "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
19 => "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
128 => "Vésznyitás",
256 => "Kártya tiltva -> információ mező",
];
}
128 => "Vésznyitás",
256 => "Kártya tiltva -> információ mező",
];
}
public static function getCardFlagTexts( ){
return [
0 => "Kártya érvényes bérlettel",
1 => "Nincs érvényes bérlet",
2 => "Kártya inaktív/Érvényes bérlet",
3 => "Kártya inaktív/Nincs érvényes bérlet"
public static function getCardFlagTexts()
{
return [
0 => "Kártya érvényes bérlettel",
1 => "Nincs érvényes bérlet",
2 => "Kártya inaktív/Érvényes bérlet",
3 => "Kártya inaktív/Nincs érvényes bérlet"
];
}
];
}
public static function mkDoorLog($direction,$card,$customer = null,$key = null){
public static function mkDoorLog($direction, $card, $customer = null, $key = null)
{
if ( !Helper::isKeyToggleDoorLogEnabled() ){
return;
if (!Helper::isKeyToggleDoorLogEnabled()) {
return;
}
$dlog = new DoorLog();
$dlog->id_card = $card->id_card;
$dlog = new DoorLog();
$dlog->id_card = $card->id_card;
if ( isset($customer)){
$dlog->id_customer = $customer->id_customer;
}
if (isset($customer)) {
$dlog->id_customer = $customer->id_customer;
}
if ( isset($key)){
$dlog->id_key = $key->id_key;
}
$dlog->direction = $direction;
$dlog->type = $card->type;
$dlog->source_app = DoorLog::$SOURCE_APP_FITNESS_ADMIN;
if (isset($key)) {
$dlog->id_key = $key->id_key;
}
$dlog->direction = $direction;
$dlog->type = $card->type;
$dlog->source_app = DoorLog::$SOURCE_APP_FITNESS_ADMIN;
$dlog->id_account = Account::readDefault();
$dlog->id_account = Account::readDefault();
if ( $dlog->direction == 0){
$dlog->card_flag = $card->validity;
}else{
$dlog->card_flag = -1;
}
if ($dlog->direction == 0) {
$dlog->card_flag = $card->validity;
} else {
$dlog->card_flag = -1;
}
$dlog->created_at = date('Y-m-d H:i:s');
$dlog->save(false);
}
$dlog->created_at = date('Y-m-d H:i:s');
$dlog->save(false);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace common\models;
use Yii;
use common\components\Helper;
use yii\behaviors\TimestampBehavior;
use yii\helpers\ArrayHelper;
/**
* This is the model class for table "door_log".
*
* @property integer $id_door_log
* @property integer $id_card
* @property integer $id_customer
* @property integer $id_key
* @property integer $direction
* @property integer $type
* @property integer $id_account
* @property string $created_at
* @property string $source_app
* @property integer id_ticket_current
* @property integer card_flag
* @property integer flag_out
*/
class DoorLogForTest extends DoorLog
{
public function behaviors()
{
return [];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[
['id_card', 'id_customer', 'id_key', 'direction', 'type', 'id_ticket_current'], 'integer'
],
[['created_at'], 'string'],
[['created_at'], 'required'],
];
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace common\models;
use Yii;
use common\components\Helper;
use yii\behaviors\TimestampBehavior;
use yii\helpers\ArrayHelper;
/**
* This is the model class for table "door_manager_log".
*
* @property string $request_id
* @property string $identifier
* @property string $device
* @property string $direction
* @property string $original_direction
* @property bool $verify_only
* @property datetime $created_at
* @property integer $card_id_card
* @property string $card_number
* @property integer $virtual_key_id
* @property integer $key_id_key
* @property string $key_number
* @property string $customer_id_customer
* @property string $customer_name
* @property string $customer_email
* @property string $ticket_id_ticket
* @property string $ticket_usage_count
* @property string $ticket_usage
* @property string $ticket_type_name
* @property string $validation_kind
* @property bool $error
* @property string $error_code
* @property string $error_message
*
*/
class DoorManagerLog extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'door_manager_log';
}
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => TimestampBehavior::className(),
'value' => function ($event) {
if ( isset($event->sender->created_at) ){
return $event->sender->created_at;
}
return date('Y-m-d H:i:s');
},
'updatedAtAttribute' => false,
]
], parent::behaviors());
}
static function findFirstForCardFromTime($idCard,$datetime){
return DoorManagerLog::find()
->andWhere(['id_card' =>$idCard])
->andWhere(['verify_only' => false])
->andWhere(['>=' ,'created_at', $datetime])
->one();
}
static function findAllEntryForTicketFromTime($idTicket, $datetime = null){
return DoorManagerLog::find()
->andWhere(['ticket_id_ticket' =>$idTicket])
->andWhere(['verify_only' => false])
->andWhere(['direction' => 'IN'])
->andWhere(['>=' ,'created_at', isset( $datetime ) ? $datetime : date('Y-m-d H:i:s')])
->all();
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace common\models;
class HuBankAccountValidator
{
public function validate($bankAccount){
if ( !isset($bankAccount)){
// \Yii::error("HuBankAccountValidator: bank account is null");
return false;
}
$stripedBankAccount = preg_replace('/\s+/', '', $bankAccount);
if ( !(strlen($stripedBankAccount) == 24 || strlen($stripedBankAccount) == 16)){
// \Yii::error("HuBankAccountValidator: bank account length is invalid");
return false;
}
$arrayOfNumbers = str_split($stripedBankAccount);
$multipliers = [9,7,3,1];
$groups = [0,0,0];
for ( $i = 0; $i < count($arrayOfNumbers); $i++ ) {
$number = $arrayOfNumbers[$i];
$multiplier = $multipliers[$i % 4];
$total = $multiplier * $number;
$groups[intval($i / 8)] += $total ;
}
$sumOfGroups = 0;
foreach ($groups as $group){
$sumOfGroups += $group;
}
$mod = $sumOfGroups % 10;
if ( $mod > 0 ){
// \Yii::error("HuBankAccountValidator: bank account groups are invalid: " . $groups[0] .",". $groups[1] . "," . $groups[2],true);
return false;
}
return true;
}
}

View File

@ -34,66 +34,70 @@ use yii\helpers\Console;
class Log extends BaseFitnessActiveRecord
{
public static $TYPE_INFO = 10;
public static $TYPE_ERR = 20;
public static $TYPE_TICKET_USAGE_FIRST = 30;
public static $TYPE_TICKET_USAGE_MULTIPLE = 40;
public static $TYPE_LOGIN = 50;
public static $TYPE_DEFAULT_ACCOUNT= 60;
public static $TYPE_CREATE_CUSTOMER= 70;
public static $TYPE_PROCUREMENT_UPDATE = 80;
public static $TYPE_TICKET_COUNT_MOVE_OUT = 90;
public static $TYPE_WASTE = 100;
public static $TYPE_NEWSLETTER_SUBSCRIBE = 110;
public static $TYPE_NEWSLETTER_UNSUBSCRIBE = 120;
public static $TYPE_NEWSLETTER_SENT = 130;
public static $TYPE_TICKET_EXPIRE_SENT = 140;
public static $TYPE_NEWSLETTER_SEND_START = 150;
public static $TYPE_NEWSLETTER_SEND_END = 160;
public static $TYPE_KEY_ASSIGN = 170;
public static $TYPE_KEY_UNASSIGN = 180;
public static $TYPE_TOWEL_IN = 190;
public static $TYPE_TOWEL_OUT = 200;
public static $TYPE_CRUD = 210;
public static $TYPE_TICKET_UPDATED_BY_ADMIN = 220;
public static $TYPE_INFO = 10;
public static $TYPE_ERR = 20;
public static $TYPE_TICKET_USAGE_FIRST = 30;
public static $TYPE_TICKET_USAGE_MULTIPLE = 40;
public static $TYPE_LOGIN = 50;
public static $TYPE_DEFAULT_ACCOUNT = 60;
public static $TYPE_CREATE_CUSTOMER = 70;
public static $TYPE_PROCUREMENT_UPDATE = 80;
public static $TYPE_TICKET_COUNT_MOVE_OUT = 90;
public static $TYPE_WASTE = 100;
public static $TYPE_NEWSLETTER_SUBSCRIBE = 110;
public static $TYPE_NEWSLETTER_UNSUBSCRIBE = 120;
public static $TYPE_NEWSLETTER_SENT = 130;
public static $TYPE_TICKET_EXPIRE_SENT = 140;
public static $TYPE_NEWSLETTER_SEND_START = 150;
public static $TYPE_NEWSLETTER_SEND_END = 160;
public static $TYPE_KEY_ASSIGN = 170;
public static $TYPE_KEY_UNASSIGN = 180;
public static $TYPE_TOWEL_IN = 190;
public static $TYPE_TOWEL_OUT = 200;
public static $TYPE_CRUD = 210;
public static $TYPE_TICKET_UPDATED_BY_ADMIN = 220;
public static $TYPE_MOBILE_DEVICE_STATUS = 230;
public static function getTypes(){
return [
public static function getTypes()
{
return [
Log::$TYPE_INFO => "Info",
Log::$TYPE_ERR => "Hiba",
Log::$TYPE_TICKET_USAGE_FIRST => "Bérlet használat",
Log::$TYPE_TICKET_USAGE_MULTIPLE => "Többszöri bérlet használat",
Log::$TYPE_LOGIN => "Bejelentkezés",
Log::$TYPE_DEFAULT_ACCOUNT=> "Alapértelmezett kassza",
Log::$TYPE_CREATE_CUSTOMER=> "Új vendég",
Log::$TYPE_PROCUREMENT_UPDATE => "Beszerzés módosítás",
Log::$TYPE_TICKET_COUNT_MOVE_OUT => "Ki mozgás",
Log::$TYPE_WASTE => "Selejt",
Log::$TYPE_NEWSLETTER_SUBSCRIBE => "Feliratkozás hirlevélre",
Log::$TYPE_NEWSLETTER_UNSUBSCRIBE => "Leiratkozás hírlevélről",
Log::$TYPE_NEWSLETTER_SENT => "Hirlevél elküldve",
Log::$TYPE_TICKET_EXPIRE_SENT => "Bérlet lejáart figyelmeztetés elküldve",
Log::$TYPE_NEWSLETTER_SEND_START => "Hirlevél küldés start",
Log::$TYPE_NEWSLETTER_SEND_END => "Hirlevél küldés vége",
Log::$TYPE_KEY_ASSIGN => "Kulcs kiadás",
Log::$TYPE_KEY_UNASSIGN => "Kulcs visszaadás",
Log::$TYPE_TOWEL_IN => "Törölköző ki",
Log::$TYPE_TOWEL_OUT => "Törölköző vissza",
Log::$TYPE_CRUD => "CRUD",
Log::$TYPE_TICKET_UPDATED_BY_ADMIN => "Bérlet módosítás"
Log::$TYPE_INFO => "Info",
Log::$TYPE_ERR => "Hiba",
Log::$TYPE_TICKET_USAGE_FIRST => "Bérlet használat",
Log::$TYPE_TICKET_USAGE_MULTIPLE => "Többszöri bérlet használat",
Log::$TYPE_LOGIN => "Bejelentkezés",
Log::$TYPE_DEFAULT_ACCOUNT => "Alapértelmezett kassza",
Log::$TYPE_CREATE_CUSTOMER => "Új vendég",
Log::$TYPE_PROCUREMENT_UPDATE => "Beszerzés módosítás",
Log::$TYPE_TICKET_COUNT_MOVE_OUT => "Ki mozgás",
Log::$TYPE_WASTE => "Selejt",
Log::$TYPE_NEWSLETTER_SUBSCRIBE => "Feliratkozás hirlevélre",
Log::$TYPE_NEWSLETTER_UNSUBSCRIBE => "Leiratkozás hírlevélről",
Log::$TYPE_NEWSLETTER_SENT => "Hirlevél elküldve",
Log::$TYPE_TICKET_EXPIRE_SENT => "Bérlet lejáart figyelmeztetés elküldve",
Log::$TYPE_NEWSLETTER_SEND_START => "Hirlevél küldés start",
Log::$TYPE_NEWSLETTER_SEND_END => "Hirlevél küldés vége",
Log::$TYPE_KEY_ASSIGN => "Kulcs kiadás",
Log::$TYPE_KEY_UNASSIGN => "Kulcs visszaadás",
Log::$TYPE_TOWEL_IN => "Törölköző ki",
Log::$TYPE_TOWEL_OUT => "Törölköző vissza",
Log::$TYPE_CRUD => "CRUD",
Log::$TYPE_TICKET_UPDATED_BY_ADMIN => "Bérlet módosítás",
Log::$TYPE_MOBILE_DEVICE_STATUS => "Mobil eszköz státusz"
];
}
public function getTypeName(){
$types = Log::getTypes();
return Helper::getArrayValue($types,$this->type,null);
}
/**
public function getTypeName()
{
$types = Log::getTypes();
return Helper::getArrayValue($types, $this->type, null);
}
/**
* @inheritdoc
*/
public static function tableName()
@ -134,79 +138,89 @@ class Log extends BaseFitnessActiveRecord
'id_door_log' => Yii::t('common/log', 'Kapu log'),
'created_at' => Yii::t('common/log', 'Dátum idő'),
'updated_at' => Yii::t('common/log', 'Módosítás'),
'start' => 'Időszak kezdete',
'end' => 'Időszak vége'
'start' => 'Időszak kezdete',
'end' => 'Időszak vége'
];
}
public static function info($message ){
self::log(['type' =>self::$TYPE_INFO, 'message' => $message]);
public static function info($message)
{
self::log(['type' => self::$TYPE_INFO, 'message' => $message]);
}
/**
* example
* Log::log([
'type' =>Log::$TYPE_LOGIN,
'message' => $message
]);
* 'type' =>Log::$TYPE_LOGIN,
* 'message' => $message
* ]);
* @param array $config
*/
public static function log( $config ){
$model = new Log($config);
$model->app = \Yii::$app->name;
$model->url = Url::canonical();
$model->id_user = \Yii::$app->user->id;
$model->save(false);
public static function log($config)
{
$model = new Log($config);
$model->app = \Yii::$app->name;
$model->url = Url::canonical();
$model->id_user = \Yii::$app->user->id;
$model->save(false);
}
/**
* create a log from the console app
* */
public static function logC( $config ){
$model = new Log($config);
$model->app = "Fitness rendszer";
$model->url = "console";
$model->id_user = 1;
$model->save(false);
public static function logC($config)
{
$model = new Log($config);
$model->app = "Fitness rendszer";
$model->url = "console";
$model->id_user = 1;
$model->save(false);
}
public function getUser(){
return $this->hasOne( User::className(), ["id" =>"id_user" ] );
public function getUser()
{
return $this->hasOne(User::className(), ["id" => "id_user"]);
}
public function getTicket(){
return $this->hasOne( Ticket::className(), ["id_ticket" =>"id_ticket" ] );
public function getTicket()
{
return $this->hasOne(Ticket::className(), ["id_ticket" => "id_ticket"]);
}
public function getCustomer(){
return $this->hasOne( Customer::className(), ["id_customer" =>"id_customer" ] );
public function getCustomer()
{
return $this->hasOne(Customer::className(), ["id_customer" => "id_customer"]);
}
public function getMoneyMovement(){
return $this->hasOne( MoneyMovement::className(), ["id_money_movement" =>"id_money_movement" ] );
public function getMoneyMovement()
{
return $this->hasOne(MoneyMovement::className(), ["id_money_movement" => "id_money_movement"]);
}
public function getUserName(){
public function getUserName()
{
$user = $this->user;
if ( isset($user)){
if (isset($user)) {
return $user->username;
}
return null;
}
public function getCustomerName(){
public function getCustomerName()
{
$customer = $this->customer;
if ( isset($customer)){
if (isset($customer)) {
return $customer->name;
}
return null;
}
public function getTicketName(){
public function getTicketName()
{
$ticket = $this->ticket;
if ( isset($ticket)){
if (isset($ticket)) {
return $ticket->ticketTypeName;
}
return null;

View File

@ -0,0 +1,134 @@
<?php
namespace common\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\helpers\ArrayHelper;
use yii\web\IdentityInterface;
/**
* This is the model class for table "mobile_device".
*
* @property integer $id
* @property integer $id_card
* @property string $status
* @property string $device_identifier
* @property string $device_name
* @property string $activated_at
* @property string $created_at
* @property string $updated_at
*/
class MobileDevice extends \yii\db\ActiveRecord implements IdentityInterface
{
const STATUS_ACTIVE = 'active';
const STATUS_INACTIVE = 'inactive';
const STATUS_DELETED_MANUAL = 'deleted_manual';
const STATUS_DELETED_SYSTEM = 'deleted_system';
/**
* @inheritdoc
*/
public static function tableName()
{
return 'mobile_device';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
// [['id_card'], 'integer'],
// [['activated_at', 'created_at', 'updated_at'], 'safe'],
// [['created_at', 'updated_at'], 'required'],
// [['status'], 'string', 'max' => 20],
// [['device_identifier'], 'string', 'max' => 255]
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('common/mobiledevice', 'ID'),
'id_card' => Yii::t('common/mobiledevice', 'Id Card'),
'status' => Yii::t('common/mobiledevice', 'Status'),
'device_identifier' => Yii::t('common/mobiledevice', 'Device Identifier'),
'device_name' => Yii::t('common/mobiledevice', 'Device Name'),
'activated_at' => Yii::t('common/mobiledevice', 'Activated At'),
'created_at' => Yii::t('common/mobiledevice', 'Created At'),
'updated_at' => Yii::t('common/mobiledevice', 'Updated At'),
];
}
public function behaviors()
{
return ArrayHelper::merge( [
[
'class' => TimestampBehavior::className(),
'value' => function(){ return date('Y-m-d H:i:s' ); }
]
],
parent::behaviors());
}
public static function toStatusHumanReadable($status){
$result = "";
switch ($status){
case self::STATUS_ACTIVE:
$result ='Aktív';
break;
case self::STATUS_DELETED_MANUAL:
$result ='Törölve (m)';
break;
case self::STATUS_DELETED_SYSTEM:
$result ='Törölve (r)';
break;
case self::STATUS_INACTIVE:
$result ='Inaktív';
break;
}
return $result;
}
public static function findIdentity($id)
{
self::findOne(['id' => $id]);
}
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public function validateAuthKey($authKey)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public function getCard()
{
return $this->hasOne(Card::class, [
'id_card' => 'id_card'
]);
}
}

View File

@ -7,7 +7,7 @@ use yii\helpers\ArrayHelper;
use yii\behaviors\TimestampBehavior;
use common\components\AccountAwareBehavior;
use common\components\UserAwareBehavior;
use yii\base\Object;
use yii\base\BaseObject;
use common\models\Transfer;
/**

View File

@ -24,6 +24,7 @@ use yii\web\HttpException;
* @property string $end
* @property integer $max_usage_count
* @property integer $usage_count
* @property integer $count_move_out
* @property integer $status
* @property integer $price_brutto
* @property integer $part eddig a részletig kell kifizetve lenni

View File

@ -29,6 +29,7 @@ use yii\helpers\ArrayHelper;
* @property string $typeHuman
* @property string $timeUnitHuman
* @property string $accountName
* @property string $comment
*/
class TicketType extends BaseFitnessActiveRecord
{
@ -127,7 +128,7 @@ class TicketType extends BaseFitnessActiveRecord
////////////////
[['door_allowed',], 'integer'],
[['door_allowed',], 'in', 'range' => [ self::FLAG_DOOR_ALLOWED_OFF, self::FLAG_DOOR_ALLOWED_ON ]],
[['comment'], 'string' ],
];
}

View File

@ -6,7 +6,7 @@ use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Transfer;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use yii\db\Expression;
use common\models\Account;

View File

@ -6,7 +6,7 @@ use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\Transfer;
use yii\base\Object;
use yii\base\BaseObject;
use yii\db\Query;
use yii\db\Expression;
use common\models\Account;

View File

@ -20,6 +20,7 @@ use common\components\RoleDefinition;
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property integer $key_listener_enabled
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface

View File

@ -0,0 +1,91 @@
<?php
namespace common\models;
use common\components\DateUtil;
use common\components\Helper;
use common\helpers\AppDateTimeHelper;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\helpers\ArrayHelper;
/**
* This is the model class for table "virtual_key".
*
* @property integer $id
* @property integer $id_card
* @property integer $id_key
* @property integer $number
* @property string $direction_in_at
* @property string $direction_out_at
* @property string $created_at
* @property string $updated_at
*/
class VirtualKey extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'virtual_key';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_card', 'id_key'], 'integer'],
[[ 'created_at', 'updated_at'], 'required'],
[[ 'direction_in_at', 'created_at', 'updated_at'], 'safe']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('common/virtualkey', 'ID'),
'id_card' => Yii::t('common/virtualkey', 'Id Card'),
'id_key' => Yii::t('common/virtualkey', 'Id Key'),
'direction_in_at' => Yii::t('common/virtualkey', 'Direction In At'),
'direction_out_at' => Yii::t('common/virtualkey', 'Direction Out At'),
'created_at' => Yii::t('common/virtualkey', 'Created At'),
'updated_at' => Yii::t('common/virtualkey', 'Updated At'),
];
}
public function behaviors()
{
return ArrayHelper::merge([
[
'class' => TimestampBehavior::className(),
'value' => function () {
return DateUtil::formatDateTimeUtc(DateUtil::utcDateTime() );
}
]
],
parent::behaviors());
}
public static function readNotInCreatedInTheLastXMinutesByIdCard($idCard,$minutes){
$date = DateUtil::utcDateTime();
$date = DateUtil::minusMinutes($date,$minutes );
$dateStr = DateUtil::formatDateTimeUtc($date);
$virtualKeysNotInCreatedInTheLastXMinuteForCard = VirtualKey::find()
->andWhere(['id_card' => $idCard])
->andWhere([">=" ,'created_at',$dateStr])
->andWhere(['direction_in_at' => null])
->orderBy(['created_at' => SORT_DESC])
->all();
return $virtualKeysNotInCreatedInTheLastXMinuteForCard;
}
}

View File

@ -27,7 +27,7 @@
"dmstr/yii2-adminlte-asset": "2.*",
"bassjobsen/bootstrap-3-typeahead": "^4.0",
"bower-asset/webcamjs": "^1.0",
"mpdf/mpdf": "^6.0",
"mpdf/mpdf": "^8.1",
"os/php-excel": "^2.1",
"phpoffice/phpexcel": "^1.8",
"2amigos/yii2-tinymce-widget": "~1.1",
@ -35,7 +35,7 @@
"yiisoft/yii2-composer": "2.0.4",
"sizeg/yii2-jwt": "^2.0",
"fxp/composer-asset-plugin": "dev-master",
"ext-http": "*"
"endroid/qr-code": "^2.5"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",

744
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "62617dd27b81a8c6428c875f01cf0dd8",
"content-hash": "138d862466e8a155a65957524deabe0f",
"packages": [
{
"name": "2amigos/yii2-tinymce-widget",
@ -106,6 +106,52 @@
],
"time": "2015-10-23T14:50:49+00:00"
},
{
"name": "bacon/bacon-qr-code",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/Bacon/BaconQrCode.git",
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/5a91b62b9d37cee635bbf8d553f4546057250bee",
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee",
"shasum": ""
},
"require": {
"ext-iconv": "*",
"php": "^5.4|^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8"
},
"suggest": {
"ext-gd": "to generate QR code images"
},
"type": "library",
"autoload": {
"psr-0": {
"BaconQrCode": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Ben Scholzen 'DASPRiD'",
"email": "mail@dasprids.de",
"homepage": "http://www.dasprids.de",
"role": "Developer"
}
],
"description": "BaconQrCode is a QR code generator for PHP.",
"homepage": "https://github.com/Bacon/BaconQrCode",
"time": "2017-10-17T09:59:25+00:00"
},
{
"name": "bassjobsen/bootstrap-3-typeahead",
"version": "v4.0.0",
@ -703,6 +749,75 @@
],
"time": "2015-11-06T10:35:36+00:00"
},
{
"name": "endroid/qr-code",
"version": "2.5.1",
"source": {
"type": "git",
"url": "https://github.com/endroid/qr-code.git",
"reference": "6062677d3404e0ded40647b8f62ec55ff9722eb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/endroid/qr-code/zipball/6062677d3404e0ded40647b8f62ec55ff9722eb7",
"reference": "6062677d3404e0ded40647b8f62ec55ff9722eb7",
"shasum": ""
},
"require": {
"bacon/bacon-qr-code": "^1.0.3",
"ext-gd": "*",
"khanamiryan/qrcode-detector-decoder": "1",
"myclabs/php-enum": "^1.5",
"php": ">=5.6",
"symfony/options-resolver": "^2.7",
"symfony/property-access": "^2.7"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"symfony/asset": "^2.7",
"symfony/browser-kit": "^2.7",
"symfony/finder": "^2.7",
"symfony/framework-bundle": "^2.7",
"symfony/http-kernel": "^2.7",
"symfony/templating": "^2.7",
"symfony/twig-bundle": "^2.7",
"symfony/yaml": "^2.7"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"Endroid\\QrCode\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jeroen van den Enden",
"email": "info@endroid.nl",
"homepage": "http://endroid.nl/"
}
],
"description": "Endroid QR Code",
"homepage": "https://github.com/endroid/QrCode",
"keywords": [
"bundle",
"code",
"endroid",
"flex",
"qr",
"qrcode",
"symfony"
],
"time": "2018-05-09T20:26:30+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.11.0",
@ -1978,6 +2093,56 @@
],
"time": "2014-11-09T19:54:17+00:00"
},
{
"name": "khanamiryan/qrcode-detector-decoder",
"version": "1",
"source": {
"type": "git",
"url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git",
"reference": "96d5f80680b04803c4f1b69d6e01735e876b80c7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/96d5f80680b04803c4f1b69d6e01735e876b80c7",
"reference": "96d5f80680b04803c4f1b69d6e01735e876b80c7",
"shasum": ""
},
"require": {
"php": "^5.6|^7.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"type": "library",
"autoload": {
"classmap": [
"lib/"
],
"files": [
"lib/common/customFunctions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ashot Khanamiryan",
"email": "a.khanamiryan@gmail.com",
"homepage": "https://github.com/khanamiryan",
"role": "Developer"
}
],
"description": "QR code decoder / reader",
"homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder",
"keywords": [
"barcode",
"qr",
"zxing"
],
"time": "2017-01-13T09:11:46+00:00"
},
{
"name": "lcobucci/jwt",
"version": "3.3.1",
@ -2035,46 +2200,69 @@
},
{
"name": "mpdf/mpdf",
"version": "v6.0.0",
"version": "v8.1.4",
"source": {
"type": "git",
"url": "https://github.com/mpdf/mpdf.git",
"reference": "a15743d030ce3b5b7be36c6e83f76589b27c3f2c"
"reference": "add590e93b7502efafd9839a68cff99f3497b318"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/a15743d030ce3b5b7be36c6e83f76589b27c3f2c",
"reference": "a15743d030ce3b5b7be36c6e83f76589b27c3f2c",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/add590e93b7502efafd9839a68cff99f3497b318",
"reference": "add590e93b7502efafd9839a68cff99f3497b318",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-mbstring": "*",
"php": ">=4.3.10"
"myclabs/deep-copy": "^1.7",
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
"php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0",
"php-http/message-factory": "^1.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0 || ^2.0",
"setasign/fpdi": "^2.1"
},
"require-dev": {
"mockery/mockery": "^1.3.0",
"mpdf/qrcode": "^1.1.0",
"squizlabs/php_codesniffer": "^3.5.0",
"tracy/tracy": "~2.5",
"yoast/phpunit-polyfills": "^1.0"
},
"suggest": {
"ext-bcmath": "Needed for generation of some types of barcodes",
"ext-xml": "Needed mainly for SVG manipulation",
"ext-zlib": "Needed for compression of embedded resources, such as fonts"
},
"type": "library",
"autoload": {
"classmap": [
"mpdf.php",
"classes"
]
"psr-4": {
"Mpdf\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-1.0+"
"GPL-2.0-only"
],
"authors": [
{
"name": "Ian Back"
"name": "Matěj Humpál",
"role": "Developer, maintainer"
},
{
"name": "Ian Back",
"role": "Developer (retired)"
}
],
"description": "A PHP class to generate PDF files from HTML with Unicode/UTF-8 and CJK support",
"homepage": "http://www.mpdf1.com/mpdf/index.php",
"description": "PHP library generating PDF files from UTF-8 encoded HTML",
"homepage": "https://mpdf.github.io",
"keywords": [
"pdf",
"php",
"utf-8"
],
"time": "2015-03-01T10:27:49+00:00"
"time": "2022-12-15T11:24:39+00:00"
},
{
"name": "mrclay/minify",
@ -2121,6 +2309,100 @@
"homepage": "http://code.google.com/p/minify/",
"time": "2016-03-08T11:49:57+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
"files": [
"src/DeepCopy/deep_copy.php"
],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"time": "2022-03-03T13:19:32+00:00"
},
{
"name": "myclabs/php-enum",
"version": "1.6.6",
"source": {
"type": "git",
"url": "https://github.com/myclabs/php-enum.git",
"reference": "32c4202886c51fbe5cc3a7c34ec5c9a4a790345e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/32c4202886c51fbe5cc3a7c34ec5c9a4a790345e",
"reference": "32c4202886c51fbe5cc3a7c34ec5c9a4a790345e",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=5.4"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35|^5.7|^6.0",
"squizlabs/php_codesniffer": "1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"MyCLabs\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP Enum contributors",
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
}
],
"description": "PHP Enum implementation",
"homepage": "http://github.com/myclabs/php-enum",
"keywords": [
"enum"
],
"time": "2019-02-04T21:18:49+00:00"
},
{
"name": "natxet/CssMin",
"version": "v3.0.4",
@ -2205,6 +2487,101 @@
],
"time": "2012-05-02T20:42:37+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
"php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"polyfill",
"pseudorandom",
"random"
],
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "php-http/message-factory",
"version": "v1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-http/message-factory.git",
"reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1",
"reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1",
"shasum": ""
},
"require": {
"php": ">=5.4",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com"
}
],
"description": "Factory interfaces for PSR-7 HTTP Message",
"homepage": "http://php-http.org",
"keywords": [
"factory",
"http",
"message",
"stream",
"uri"
],
"time": "2015-12-19T14:08:53+00:00"
},
{
"name": "phpoffice/phpexcel",
"version": "1.8.1",
@ -2263,6 +2640,103 @@
"abandoned": "phpoffice/phpspreadsheet",
"time": "2015-05-01T07:00:55+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2021-05-03T11:20:27+00:00"
},
{
"name": "rmrevin/yii2-fontawesome",
"version": "2.12.2",
@ -2315,6 +2789,68 @@
],
"time": "2015-11-20T09:17:45+00:00"
},
{
"name": "setasign/fpdi",
"version": "v2.3.6",
"source": {
"type": "git",
"url": "https://github.com/Setasign/FPDI.git",
"reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Setasign/FPDI/zipball/6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
"reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
"shasum": ""
},
"require": {
"ext-zlib": "*",
"php": "^5.6 || ^7.0 || ^8.0"
},
"conflict": {
"setasign/tfpdf": "<1.31"
},
"require-dev": {
"phpunit/phpunit": "~5.7",
"setasign/fpdf": "~1.8",
"setasign/tfpdf": "1.31",
"squizlabs/php_codesniffer": "^3.5",
"tecnickcom/tcpdf": "~6.2"
},
"suggest": {
"setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured."
},
"type": "library",
"autoload": {
"psr-4": {
"setasign\\Fpdi\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Slabon",
"email": "jan.slabon@setasign.com",
"homepage": "https://www.setasign.com"
},
{
"name": "Maximilian Kresse",
"email": "maximilian.kresse@setasign.com",
"homepage": "https://www.setasign.com"
}
],
"description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
"homepage": "https://www.setasign.com/fpdi",
"keywords": [
"fpdf",
"fpdi",
"pdf"
],
"time": "2021-02-11T11:37:01+00:00"
},
{
"name": "sizeg/yii2-jwt",
"version": "v2.0.0",
@ -2410,8 +2946,186 @@
"mail",
"mailer"
],
"abandoned": "symfony/mailer",
"time": "2015-06-06T14:19:39+00:00"
},
{
"name": "symfony/options-resolver",
"version": "v2.8.52",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "7aaab725bb58f0e18aa12c61bdadd4793ab4c32b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/7aaab725bb58f0e18aa12c61bdadd4793ab4c32b",
"reference": "7aaab725bb58f0e18aa12c61bdadd4793ab4c32b",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\OptionsResolver\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony OptionsResolver Component",
"homepage": "https://symfony.com",
"keywords": [
"config",
"configuration",
"options"
],
"time": "2018-11-11T11:18:13+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b",
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/property-access",
"version": "v2.8.52",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-access.git",
"reference": "c8f10191183be9bb0d5a1b8364d3891f1bde07b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/property-access/zipball/c8f10191183be9bb0d5a1b8364d3891f1bde07b6",
"reference": "c8f10191183be9bb0d5a1b8364d3891f1bde07b6",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-ctype": "~1.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\PropertyAccess\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony PropertyAccess Component",
"homepage": "https://symfony.com",
"keywords": [
"access",
"array",
"extraction",
"index",
"injection",
"object",
"property",
"property path",
"reflection"
],
"time": "2018-11-11T11:18:13+00:00"
},
{
"name": "tedivm/jshrink",
"version": "v1.1.0",

View File

@ -1,162 +0,0 @@
sanya@sanyigep ~/public_html/fitness-web $ php composer.phar install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
- Installing yiisoft/yii2-composer (2.0.3)
Loading from cache
- Installing bower-asset/accounting (v0.3.2)
Loading from cache
- Installing bower-asset/jquery (2.1.4)
Loading from cache
- Installing bower-asset/jquery.inputmask (3.1.63)
Loading from cache
- Installing bower-asset/moment (2.10.6)
Loading from cache
- Installing bower-asset/punycode (v1.3.2)
Loading from cache
- Installing bower-asset/bootstrap (v3.3.5)
Loading from cache
- Installing bower-asset/remarkable-bootstrap-notify (3.1.3)
Loading from cache
- Installing bower-asset/yii2-pjax (v2.0.4)
Loading from cache
- Installing cebe/markdown (1.1.0)
Loading from cache
- Installing ezyang/htmlpurifier (v4.6.0)
Loading from cache
- Installing yiisoft/yii2 (2.0.6)
Loading from cache
- Installing yiisoft/yii2-bootstrap (2.0.5)
Loading from cache
- Installing bower-asset/fontawesome (v4.4.0)
Loading from cache
- Installing rmrevin/yii2-fontawesome (2.12.2)
Loading from cache
- Installing cebe/yii2-gravatar (1.1)
Loading from cache
- Installing almasaeed2010/adminlte (v2.3.2)
Loading from cache
- Installing dmstr/yii2-adminlte-asset (2.2.4)
Loading from cache
- Installing kartik-v/bootstrap-fileinput (v4.2.7)
Loading from cache
- Installing kartik-v/bootstrap-star-rating (v3.5.4)
Loading from cache
- Installing kartik-v/dependent-dropdown (v1.4.3)
Loading from cache
- Installing kartik-v/yii2-krajee-base (v1.7.7)
Loading from cache
- Installing kartik-v/yii2-widget-typeahead (v1.0.1)
Loading from cache
- Installing kartik-v/yii2-widget-touchspin (v1.2.0)
Loading from cache
- Installing kartik-v/yii2-widget-timepicker (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-switchinput (v1.3.0)
Loading from cache
- Installing kartik-v/yii2-widget-spinner (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-sidenav (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-select2 (v2.0.3)
Loading from cache
- Installing kartik-v/yii2-widget-rating (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-rangeinput (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-growl (v1.1.1)
Loading from cache
- Installing kartik-v/yii2-widget-fileinput (v1.0.3)
Loading from cache
- Installing kartik-v/yii2-widget-depdrop (v1.0.2)
Loading from cache
- Installing kartik-v/yii2-widget-datetimepicker (v1.4.0)
Loading from cache
- Installing kartik-v/yii2-widget-datepicker (v1.3.3)
Loading from cache
- Installing kartik-v/yii2-widget-colorinput (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-alert (v1.1.0)
Loading from cache
- Installing kartik-v/yii2-widget-affix (v1.0.0)
Loading from cache
- Installing kartik-v/yii2-widget-activeform (v1.4.5)
Loading from cache
- Installing kartik-v/yii2-widgets (v3.4.0)
Loading from cache
- Installing bower-asset/jquery-ui (1.11.4)
Loading from cache
- Installing yiisoft/yii2-jui (2.0.4)
Loading from cache
- Installing swiftmailer/swiftmailer (v5.4.1)
Loading from cache
- Installing yiisoft/yii2-swiftmailer (2.0.4)
Loading from cache
- Installing yiisoft/yii2-codeception (2.0.4)
Loading from cache
- Installing yiisoft/yii2-debug (2.0.5)
Loading from cache
- Installing fzaninotto/faker (v1.5.0)
Loading from cache
- Installing yiisoft/yii2-faker (2.0.3)
Loading from cache
- Installing phpspec/php-diff (v1.0.2)
Loading from cache
- Installing bower-asset/typeahead.js (v0.10.5)
Loading from cache
- Installing yiisoft/yii2-gii (2.0.4)
Loading from cache
fzaninotto/faker suggests installing ext-intl (*)
Generating autoload files

View File

@ -0,0 +1,30 @@
<?php
namespace console\controllers;
use common\manager\DoorCardPassManager;
use common\models\Card;
use /** @noinspection PhpUnusedAliasInspection */
Yii;
use yii\console\Controller;
class DoorCardPassController extends Controller{
public function actionHardReset( )
{
// \Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS())->execute();
$manager = new DoorCardPassManager();
$manager->hardReset();
}
public function actionAllowAllCard( )
{
\Yii::$app->db->createCommand(Card::SQL_ALLOW_DOOR_CARD_PASS())->execute();
}
public function actionInvalidate( )
{
$manager = new DoorCardPassManager();
$manager->updateDoorCardPassStateForAllCard();
}
}

View File

@ -0,0 +1,68 @@
<?php
use yii\db\Migration;
/**
* Class m220213_134539_add_table_mobile_device
*/
class m220213_134539_add_table_mobile_device extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('{{%mobile_device}}', [
'id' => $this->primaryKey(),
'id_card' => $this->integer(11),
'status' => $this->string(20),
'device_identifier' => $this->string(255),
'activated_at' => $this->dateTime(),
'created_at' => $this->dateTime()->notNull(),
'updated_at' => $this->dateTime()->notNull(),
], $tableOptions);
$this->createTable('{{%virtual_key}}', [
'id' => $this->primaryKey(),
'id_card' => $this->integer(11),
'id_key' => $this->integer(11),
'valid_until' => $this->dateTime()->notNull(),
'direction_in_at' => $this->dateTime(),
'direction_out_at' => $this->dateTime(),
'created_at' => $this->dateTime()->notNull(),
'updated_at' => $this->dateTime()->notNull(),
], $tableOptions);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m220213_134539_add_table_mobile_device cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m220213_134539_add_table_mobile_device cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,43 @@
<?php
use yii\db\Migration;
/**
* Class m220218_192423_alter_table_mobile_device_add_column_device_name
*/
class m220218_192423_alter_table_mobile_device_add_column_device_name extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('mobile_device', 'device_name', $this->string() );
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m220218_192423_alter_table_mobile_device_add_column_device_name cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m220218_192423_alter_table_mobile_device_add_column_device_name cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,44 @@
<?php
use yii\db\Migration;
/**
* Class m220220_190302_add_virtual_key_field_for_card_key_assignment_table
*/
class m220220_190302_add_virtual_key_field_for_card_key_assignment_table extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('card_key_assignment','virtual_key', $this->string());
$this->addColumn('card_key_assignment','direction_in_at', 'datetime');
$this->addColumn('card_key_assignment','direction_out_at', 'datetime');
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m220220_190302_add_virtual_key_field_for_card_key_assignment_table cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m220220_190302_add_virtual_key_field_for_card_key_assignment_table cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,42 @@
<?php
use yii\db\Migration;
/**
* Class m220803_190701_alter_table_door_log_add_version
*/
class m220803_190701_alter_table_door_log_add_version extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('door_log', 'version', $this->integer( )->notNull()->defaultValue(1) );
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m220803_190701_alter_table_door_log_add_version cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m220803_190701_alter_table_door_log_add_version cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,217 @@
<?php
use yii\db\Migration;
/**
* Class m220928_165551_update_trigger
*/
class m220928_165551_update_trigger extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$sql = "
drop trigger if exists trigger_inc_ticket_usage_count;
CREATE TRIGGER trigger_inc_ticket_usage_count
AFTER INSERT
ON `door_log`
FOR EACH ROW
begin
DECLARE p_count_all Integer;
DECLARE p_count_all_2 Integer;
DECLARE p_from DATETIME;
DECLARE p_usage_count Integer;
DECLARE p_max_usage_count Integer;
DECLARE p_mo_ticket_id Integer;
DECLARE p_mo_ticket_max_usage_count Integer;
DECLARE p_allow_multiple_enter boolean;
DECLARE p_allow_enter boolean;
delete from devlog;
IF NEW.version = 1
THEN
IF NEW.id_customer is not null and NEW.id_card is not null
THEN
IF (NEW.direction = 7 or New.direction = 3) and NEW.id_ticket_current is not null
then
INSERT INTO devlog (msg) values ('belepes feldoglozas indit');
select count(*)
into @p_count_all
from door_log
where created_at >= CURDATE()
and id_ticket_current = New.id_ticket_current
and (direction = 7 or direction = 3);
INSERT INTO devlog (msg) values (concat('count all', @p_count_all));
IF @p_count_all = 1
THEN
select usage_count, max_usage_count
into @p_usage_count ,@p_max_usage_count
from ticket
where id_ticket = NEW.id_ticket_current;
update ticket set usage_count = usage_count + 1 where id_ticket = NEW.id_ticket_current;
INSERT INTO log (type, message, app, id_ticket, id_door_log, created_at, updated_at)
values (30, concat('Bérlet használat (elotte: ', @p_usage_count, ' > utana: ', @p_usage_count + 1,
' max: ', @p_max_usage_count, ')'), ' trigger_inc_ticket', New.id_ticket_current,
New.id_door_log, now(), now());
else
select min(created_at) +
INTERVAL (3 * FLOOR(((HOUR(TIMEDIFF(min(created_at), now())) / 3)))) hour as last_date
into @p_from
from door_log
where created_at > CURDATE()
and id_customer is not null
and id_ticket_current = NEW.id_ticket_current
and (direction = 7 or direction = 3);
select count(*)
into @p_count_all_2
from door_log
where created_at >= @p_from
and id_ticket_current = New.id_ticket_current
and (direction = 7 or direction = 3);
INSERT INTO devlog (msg)
values (CONCAT('Belépések száma az aktuális 3 órás intervalumban: ', @p_count_all_2));
IF @p_count_all_2 = 1
THEN
INSERT INTO devlog (msg)
values ('Az aktuális intervallumban ez az első belépés, usage_count növelése');
select usage_count, max_usage_count
into @p_usage_count ,@p_max_usage_count
from ticket
where id_ticket = NEW.id_ticket_current;
update ticket set usage_count = usage_count + 1 where id_ticket = New.id_ticket_current;
INSERT INTO log (type, message, app, id_ticket, id_door_log, created_at, updated_at)
values (40, concat('Bérlet használat/egy nap tobbszori (elotte: ', @p_usage_count, ' > utana: ',
@p_usage_count + 1, ' max: ', @p_max_usage_count, ')'),
' trigger_inc_ticket', New.id_ticket_current, New.id_door_log, now(), now());
END IF;
END IF;
End IF;
IF NEW.direction = 5 or New.direction = 1
then
INSERT INTO devlog (msg) values ('Kilépés van folyamatban, kilépések számának beállítása');
update ticket set count_move_out = usage_count where id_ticket = NEW.id_ticket_current;
END IF;
INSERT INTO devlog (msg) values ('Kártya validáció módosítása');
UPDATE card as c1
left JOIN (select ticket.id_card as id_card, max(ticket.id_ticket) as id_ticket
from ticket
where ticket.start <= CURDATE()
and ticket.end >= curdate()
and ticket.status = 10
and ticket.count_move_out < ticket.max_usage_count
and ticket.id_card = New.id_card
group by id_card
order by id_card desc) as t
on t.id_card = c1.id_card
SET c1.validity = case
when t.id_card is null then (c1.validity | 1 << 0)
else (c1.validity & ~(1 << 0)) end
, c1.flag = case
when t.id_card is null then (c1.flag | 1 << 0)
else (c1.flag & ~(1 << 0)) end
, c1.id_ticket_current = case when t.id_ticket is null then null else t.id_ticket end
WHERE c1.type <> 50
and c1.id_card = New.id_card;
IF NEW.direction = 5 or New.direction = 1
then
select max(ticket.id_ticket)
into @p_mo_ticket_id
from ticket
where ticket.start <= CURDATE()
and ticket.end >= curdate()
and ticket.status = 10
and ticket.count_move_out < ticket.max_usage_count
and ticket.id_card = New.id_card
group by id_card
order by id_card desc;
set @p_allow_enter = true;
update card
set flag_out = (flag_out | 1 << 1),
flag = case when @p_allow_enter then (flag & ~(1 << 1)) else (flag | 1 << 1) end
WHERE type <> 50
and id_card = New.id_card;
END IF;
IF (NEW.direction = 7 or New.direction = 3) and NEW.id_ticket_current is not null
THEN
update card
set flag_out = (flag_out & ~(1 << 1)),
flag = (flag | 1 << 1)
WHERE type <> 50
and id_card = New.id_card;
END IF;
END IF;
END IF;
END
";
$this->execute($sql);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m220928_165551_update_trigger cannot be reverted.\n";
return true;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m220928_165551_update_trigger cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,43 @@
<?php
use yii\db\Migration;
/**
* Class m221023_173829_add_table_virtual_key
*/
class m221023_173829_add_table_virtual_key extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->dropColumn("virtual_key",'valid_until');
$this->dropColumn("virtual_key",'direction_out_at');
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m221023_173829_add_table_virtual_key cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m221023_173829_add_table_virtual_key cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,42 @@
<?php
use yii\db\Migration;
/**
* Class m221024_203742_alter_table_virtual_key_add_column_number
*/
class m221024_203742_alter_table_virtual_key_add_column_number extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn("virtual_key","number", $this->string(23));
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m221024_203742_alter_table_virtual_key_add_column_number cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m221024_203742_alter_table_virtual_key_add_column_number cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,27 @@
<?php
use yii\db\Migration;
/**
* Class m221026_111439_alter_table_virtual_key_add_column_direction_out_at
*/
class m221026_111439_alter_table_virtual_key_add_column_direction_out_at extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn("virtual_key", "direction_out_at", $this->dateTime() );
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m221026_111439_alter_table_virtual_key_add_column_direction_out_at cannot be reverted.\n";
return false;
}
}

View File

@ -0,0 +1,58 @@
<?php
use yii\db\Migration;
/**
* Class m230126_202055_create_table_door_card_pass
*/
class m230126_202055_create_table_door_card_pass extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('door_card_pass',[
'id_door_card_pass'=> $this->primaryKey(),
'id_card' => $this->integer(11),
'id_user' => $this->integer(11),
'created_at' => $this->dateTime()->notNull(),
'updated_at' => $this->dateTime()->notNull(),
],
$tableOptions
);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,44 @@
<?php
use yii\db\Migration;
/**
* Class m230126_202055_create_table_door_card_pass
*/
class m230209_200000_alter_table_door_card_pass_add_column_valid_until extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn("door_card_pass","valid_until_at",$this->dateTime());
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,44 @@
<?php
use yii\db\Migration;
/**
* Class m230126_202055_create_table_door_card_pass
*/
class m230209_200010_alter_table_door_card_pass_add_column_invalidated_at extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn("door_card_pass","invalidated_at",$this->dateTime());
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,102 @@
<?php
use yii\db\Migration;
/**
* Class m230126_202055_create_table_door_card_pass
*/
class m230209_200020_create_table_door_manager_log extends Migration
{
/**
* {@inheritdoc}
*
* string $request_id
* string $identifier
* string $device
* string $direction
* string $original_direction
* bool $verify_only
* datetime $created_at
* integer $card_id_card
* string $card_number
* integer $virtual_key_id
* integer $key_id_key
* string $key_number
* string $customer_id_customer
* string $customer_name
* string $customer_email
* string $ticket_id_ticket
* string $ticket_usage_count
* string $ticket_usage
* string $ticket_type_name
* string $validation_kind
* bool $error
* string $error_code
* string $error_message
*/
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('door_manager_log', [
'id_door_manager_log' => $this->primaryKey(),
'created_at' => $this->datetime(),
'updated_at' => $this->dateTime()->notNull(),
'request_id' => $this->string(50),
'identifier' => $this->string(100),
'device' => $this->string(10),
'direction' => $this->string(10),
'original_direction' => $this->string(10),
'verify_only' => $this->boolean(),
'card_id_card' => $this->integer(),
'card_number' => $this->string(50),
'virtual_key_id' => $this->integer(),
'key_id_key' => $this->integer(),
'key_number' => $this->string(),
'customer_id_customer' => $this->integer(),
'customer_name' => $this->string(),
'customer_email' => $this->string(),
'ticket_id_ticket' => $this->string(),
'ticket_usage_count' => $this->string(),
'ticket_usage' => $this->integer(),
'ticket_type_name' => $this->string(),
'validation_kind' => $this->string(50),
'error' => $this->boolean()->defaultValue(false),
'error_code' => $this->string(50),
'error_message' => $this->string(),
],
$tableOptions
);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,43 @@
<?php
use yii\db\Migration;
/**
* Class m230308_060353_add_customer_comment_and_ticket_type_comment
*/
class m230308_060353_add_customer_comment_and_ticket_type_comment extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn("customer", "comment", $this->string());
$this->addColumn("ticket_type", "comment", $this->string());
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230308_060353_add_customer_comment_and_ticket_type_comment cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230308_060353_add_customer_comment_and_ticket_type_comment cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,46 @@
<?php
use yii\db\Migration;
/**
* Class m230626_205132_alter_table_user_add_column_key_listener_enabled
*/
class m230626_205132_alter_table_user_add_column_key_listener_enabled extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn(
"user",
"key_listener_enabled",
$this->integer()->null()->defaultValue(1)
);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230626_205132_alter_table_user_add_column_key_listener_enabled cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230626_205132_alter_table_user_add_column_key_listener_enabled cannot be reverted.\n";
return false;
}
*/
}

View File

@ -0,0 +1,42 @@
<?php
use yii\db\Migration;
/**
* Class m230914_062843_alter_table_door_log_manager_make_updated_at_nullable_and_default
*/
class m230914_062843_alter_table_door_log_manager_make_updated_at_nullable_and_default extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->alterColumn('door_manager_log','updated_at',$this->datetime()->null());
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230914_062843_alter_table_door_log_manager_make_updated_at_nullable_and_default cannot be reverted.\n";
return false;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m230914_062843_alter_table_door_log_manager_make_updated_at_nullable_and_default cannot be reverted.\n";
return false;
}
*/
}

View File

@ -35,6 +35,7 @@ class LoginController extends CustomerApiController
public function actionLogin()
{
$form = new LoginForm();
$form->scenario = "default";
$form->load(\Yii::$app->request->post(), '');

33
doc/composer.md Normal file
View File

@ -0,0 +1,33 @@
# Composer Knowledge base
## upgrade packages
[upgrade.txt](./upgrade.txt)
## use newer github tokens
Edit the composer authentication configuration file ~/.composer/auth.json.
```bash
nano ~/.composer/auth.json
```
Then replace the following.
```json
{
"github-oauth": {
"github.com": "ghp_[YOUR-PERSONAL-TOKEN]"
}
}
```
With this (basic auth):
```json
{
"http-basic": {
"github.com": {
"username": "[YOUR-GITHUB-USERNAME]",
"password": "ghp_[YOUR-PERSONAL-TOKEN]"
}
}
}
```

BIN
doc/image-036276f377.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

174
doc/trigger.sql Normal file
View File

@ -0,0 +1,174 @@
CREATE TRIGGER trigger_inc_ticket_usage_count
AFTER INSERT
ON `door_log`
FOR EACH ROW
begin
DECLARE p_count_all Integer;
DECLARE p_count_all_2 Integer;
DECLARE p_from DATETIME;
DECLARE p_usage_count Integer;
DECLARE p_max_usage_count Integer;
DECLARE p_mo_ticket_id Integer;
DECLARE p_mo_ticket_max_usage_count Integer;
DECLARE p_allow_multiple_enter boolean;
DECLARE p_allow_enter boolean;
delete from devlog;
if NEW.version = 1
then
IF NEW.id_customer is not null and NEW.id_card is not null
THEN
IF (NEW.direction = 7 or New.direction = 3) and NEW.id_ticket_current is not null
then
INSERT INTO devlog (msg) values ('belepes feldoglozas indit');
select count(*)
into @p_count_all
from door_log
where created_at >= CURDATE()
and id_ticket_current = New.id_ticket_current
and (direction = 7 or direction = 3);
INSERT INTO devlog (msg) values (concat('count all', @p_count_all));
IF @p_count_all = 1
THEN
select usage_count, max_usage_count
into @p_usage_count ,@p_max_usage_count
from ticket
where id_ticket = NEW.id_ticket_current;
update ticket set usage_count = usage_count + 1 where id_ticket = NEW.id_ticket_current;
INSERT INTO log (type, message, app, id_ticket, id_door_log, created_at, updated_at)
values (30, concat('Bérlet használat (elotte: ', @p_usage_count, ' > utana: ', @p_usage_count + 1,
' max: ', @p_max_usage_count, ')'), ' trigger_inc_ticket', New.id_ticket_current,
New.id_door_log, now(), now());
else
-- deltaElsoBelépés a napi első door log és 'most' között eltelt órák
-- HOUR( TIMEDIFF( min(created_at) , now() ) )
-- hány darab 3 órás intervallum telt el
-- floor : 2.75 -> 2
-- FLOOR( ( ( HOUR( TIMEDIFF( min(created_at) , now() ) ) /3 ) ) )
-- a napi első belépés után kiszámoljuk az aktuális n-edik 3órás intervallum kezdetét
select min(created_at) +
INTERVAL (3 * FLOOR(((HOUR(TIMEDIFF(min(created_at), now())) / 3)))) hour as last_date
into @p_from
from door_log
where created_at > CURDATE()
and id_customer is not null
and id_ticket_current = NEW.id_ticket_current
and (direction = 7 or direction = 3);
select count(*)
into @p_count_all_2
from door_log
where created_at >= @p_from
and id_ticket_current = New.id_ticket_current
and (direction = 7 or direction = 3);
INSERT INTO devlog (msg)
values (CONCAT('Belépések száma az aktuális 3 órás intervalumban: ', @p_count_all_2));
IF @p_count_all_2 = 1
THEN
INSERT INTO devlog (msg)
values ('Az aktuális intervallumban ez az első belépés, usage_count növelése');
select usage_count, max_usage_count
into @p_usage_count ,@p_max_usage_count
from ticket
where id_ticket = NEW.id_ticket_current;
update ticket set usage_count = usage_count + 1 where id_ticket = New.id_ticket_current;
INSERT INTO log (type, message, app, id_ticket, id_door_log, created_at, updated_at)
values (40, concat('Bérlet használat/egy nap tobbszori (elotte: ', @p_usage_count, ' > utana: ',
@p_usage_count + 1, ' max: ', @p_max_usage_count, ')'), ' trigger_inc_ticket',
New.id_ticket_current, New.id_door_log, now(), now());
END IF;
END IF;
End IF;
IF NEW.direction = 5 or New.direction = 1
then
INSERT INTO devlog (msg) values ('Kilépés van folyamatban, kilépések számának beállítása');
update ticket set count_move_out = usage_count where id_ticket = NEW.id_ticket_current;
END IF;
INSERT INTO devlog (msg) values ('Kártya validáció módosítása');
UPDATE card as c1
left JOIN (select ticket.id_card as id_card, max(ticket.id_ticket) as id_ticket
from ticket
where ticket.start <= CURDATE()
and ticket.end >= curdate()
and ticket.status = 10
and ticket.count_move_out < ticket.max_usage_count
and ticket.id_card = New.id_card
group by id_card
order by id_card desc) as t
on t.id_card = c1.id_card
SET c1.validity = case
when t.id_card is null then (c1.validity | 1 << 0)
else (c1.validity & ~(1 << 0)) end
, c1.flag = case when t.id_card is null then (c1.flag | 1 << 0) else (c1.flag & ~(1 << 0)) end
, c1.id_ticket_current = case when t.id_ticket is null then null else t.id_ticket end
WHERE c1.type <> 50
and c1.id_card = New.id_card;
IF NEW.direction = 5 or New.direction = 1
then
select max(ticket.id_ticket)
into @p_mo_ticket_id
from ticket
where ticket.start <= CURDATE()
and ticket.end >= curdate()
and ticket.status = 10
and ticket.count_move_out < ticket.max_usage_count
and ticket.id_card = New.id_card
group by id_card
order by id_card desc;
set @p_allow_enter = true;
update card
set flag_out = (flag_out | 1 << 1),
flag = case when @p_allow_enter then (flag & ~(1 << 1)) else (flag | 1 << 1) end
WHERE type <> 50
and id_card = New.id_card;
END IF;
IF (NEW.direction = 7 or New.direction = 3) and NEW.id_ticket_current is not null
THEN
update card
set flag_out = (flag_out & ~(1 << 1)),
flag = (flag | 1 << 1)
WHERE type <> 50
and id_card = New.id_card;
END IF;
END IF;
END IF;
END

View File

@ -1,4 +0,0 @@
version: '2'
services:
fitness-ub-php-7:
build: ./service/ub-php

3
docker/fitness/.env Normal file
View File

@ -0,0 +1,3 @@
FITNESS_REST_ALLOW_VERIFY_ONLY=true
#DOOR_ENTRY_STRATEGY=door_pass
FITNESS_WORD_TYPED_LISTENER_ALLOWED_ONLY_FOR_EMPTY_CUSTOMER=1

View File

@ -0,0 +1,56 @@
version: '3'
services:
cutlerweb:
build: ./service/apache2
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
cutler_network:
ports:
- "42001:80"
- "42002:443"
volumes:
- ../../:/var/www/html/cutler
environment:
FITNESS_DB_HOST: cutlerdb
FITNESS_DB_NAME: cutler_prod2
FITNESS_DB_PORT:
FITNESS_DB_USERNAME: cutler_prod
FITNESS_DB_PASSWORD: cutler_prod
FITNESS_MAIL_HOST: cutlermail
FITNESS_MAIL_PORT: 1025
FITNESS_MAIL_USERNAME: test
FITNESS_MAIL_PASSWORD: test
FITNESS_REST_ALLOW_VERIFY_ONLY: "$FITNESS_REST_ALLOW_VERIFY_ONLY"
DOOR_ENTRY_STRATEGY: "$DOOR_ENTRY_STRATEGY"
FITNESS_WORD_TYPED_LISTENER_ALLOWED_ONLY_FOR_EMPTY_CUSTOMER: "$FITNESS_WORD_TYPED_LISTENER_ALLOWED_ONLY_FOR_EMPTY_CUSTOMER"
cutlerdb:
image: mariadb:10.1
networks:
cutler_network:
volumes:
- cutler_mariadb:/var/lib/mysql
- ./service/mariadb/init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
MYSQL_ROOT_PASSWORD: cutler
MYSQL_DATABASE: cutler_prod2
MYSQL_USER: cutler_prod
MYSQL_PASSWORD: cutler_prod
ports:
- "42003:3306"
cutlermail:
image: reachfive/fake-smtp-server
networks:
cutler_network:
volumes:
cutler_photos: {}
cutler_mariadb: {}
networks:
cutler_network:

View File

@ -0,0 +1,42 @@
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# Always set these headers.
#Header always set Access-Control-Allow-Origin "*"
#Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
#Header always set Access-Control-Max-Age "1000"
#Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
# Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
# RewriteEngine On
# RewriteCond %{REQUEST_METHOD} OPTIONS
# RewriteRule ^(.*)$ $1 [R=200,L]
</VirtualHost>

View File

@ -0,0 +1,56 @@
FROM ubuntu:20.04
MAINTAINER rocho02@gmail.com
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Budapest
# apt-get
RUN apt-get update \
&& apt-get -y install bzip2 git nano wget zip unzip curl vim \
&& apt-get -y install libmcrypt-dev libzzip-dev zziplib-bin zlib1g-dev \
&& apt-get -y install apache2 build-essential
# && ufw allow in "Apache Full" \o
RUN apt-get install -y php php-pear php-dev libmcrypt-dev
RUN apt-get -y install php \
libapache2-mod-php \
php-mysql \
php-xml \
php-gd \
php-mbstring \
php-zip \
php-soap \
php-curl \
php-pear \
php-dev \
libmcrypt-dev
RUN pecl channel-update pecl.php.net
RUN pecl update-channels
RUN pecl install mcrypt
RUN apt-get -y install \
# Required by composr
git \
zlib1g-dev \
--no-install-recommends
RUN a2enmod headers
RUN a2enmod rewrite
COPY 000-default.conf /etc/apache2/sites-available/
COPY index.html /var/www/html/
COPY apache2.conf /etc/apache2/
RUN #apt-get install -y certbot python3-certbot-apache
# Ports
EXPOSE 80
# Default command
CMD ["apachectl", "-D", "FOREGROUND"]

Binary file not shown.

View File

@ -0,0 +1,221 @@
# This is the main Apache server configuration file. It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.4/ for detailed information about
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
# hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.
# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
# together by including all remaining configuration files when starting up the
# web server.
#
# * ports.conf is always included from the main configuration file. It is
# supposed to determine listening ports for incoming connections which can be
# customized anytime.
#
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
# directories contain particular configuration snippets which manage modules,
# global configuration fragments, or virtual host configurations,
# respectively.
#
# They are activated by symlinking available configuration files from their
# respective *-available/ counterparts. These should be managed by using our
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
# their respective man pages for detailed information.
#
# * The binary is called apache2. Due to the use of environment variables, in
# the default configuration, apache2 needs to be started/stopped with
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
# work with the default configuration.
# Global configuration
#
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the Mutex documentation (available
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"
#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
Mutex file:${APACHE_LOCK_DIR} default
#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}
#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5
# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log
#
# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
#
LogLevel warn
# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Include list of ports to listen on
Include ports.conf
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
#
# The following directives define some format nicknames for use with
# a CustomLog directive.
#
# These deviate from the Common Log Format definitions in that they use %O
# (the actual bytes sent including headers) instead of %b (the size of the
# requested file), because the latter makes it impossible to detect partial
# requests.
#
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.
# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1 @@
docker build -t cutler:v2 ../../../

View File

@ -0,0 +1,2 @@
docker build --tag apache .

Binary file not shown.

View File

@ -0,0 +1,221 @@
# This is the main Apache server configuration file. It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.4/ for detailed information about
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
# hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.
# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
# together by including all remaining configuration files when starting up the
# web server.
#
# * ports.conf is always included from the main configuration file. It is
# supposed to determine listening ports for incoming connections which can be
# customized anytime.
#
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
# directories contain particular configuration snippets which manage modules,
# global configuration fragments, or virtual host configurations,
# respectively.
#
# They are activated by symlinking available configuration files from their
# respective *-available/ counterparts. These should be managed by using our
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
# their respective man pages for detailed information.
#
# * The binary is called apache2. Due to the use of environment variables, in
# the default configuration, apache2 needs to be started/stopped with
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
# work with the default configuration.
# Global configuration
#
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the Mutex documentation (available
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"
#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
Mutex file:${APACHE_LOCK_DIR} default
#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}
#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5
# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log
#
# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
#
LogLevel warn
# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Include list of ports to listen on
Include ports.conf
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
#
# The following directives define some format nicknames for use with
# a CustomLog directive.
#
# These deviate from the Common Log Format definitions in that they use %O
# (the actual bytes sent including headers) instead of %b (the size of the
# requested file), because the latter makes it impossible to detect partial
# requests.
#
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.
# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,8 @@
# Read the documentation before enabling AddDefaultCharset.
# In general, it is only a good idea if you know that all your files
# have this encoding. It will override any encoding given in the files
# in meta http-equiv or xml encoding tags.
#AddDefaultCharset UTF-8
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,81 @@
# Customizable error responses come in three flavors:
# 1) plain text
# 2) local redirects
# 3) external redirects
#
# Some examples:
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#
#
# Putting this all together, we can internationalize error responses.
#
# We use Alias to redirect any /error/HTTP_<error>.html.var response to
# our collection of by-error message multi-language collections. We use
# includes to substitute the appropriate text.
#
# You can modify the messages' appearance without changing any of the
# default HTTP_<error>.html.var files by adding the line:
#
#Alias /error/include/ "/your/include/path/"
#
# which allows you to create your own set of files by starting with the
# /usr/share/apache2/error/include/ files and copying them to /your/include/path/,
# even on a per-VirtualHost basis. If you include the Alias in the global server
# context, is has to come _before_ the 'Alias /error/ ...' line.
#
# The default include files will display your Apache version number and your
# ServerAdmin email address regardless of the setting of ServerSignature.
#
# WARNING: The configuration below will NOT work out of the box if you have a
# SetHandler directive in a <Location /> context somewhere. Adding
# the following three lines AFTER the <Location /> context should
# make it work in most cases:
# <Location /error/>
# SetHandler none
# </Location>
#
# The internationalized error documents require mod_alias, mod_include
# and mod_negotiation. To activate them, uncomment the following 37 lines.
#<IfModule mod_negotiation.c>
# <IfModule mod_include.c>
# <IfModule mod_alias.c>
#
# Alias /error/ "/usr/share/apache2/error/"
#
# <Directory "/usr/share/apache2/error">
# Options IncludesNoExec
# AddOutputFilter Includes html
# AddHandler type-map var
# Order allow,deny
# Allow from all
# LanguagePriority en cs de es fr it nl sv pt-br ro
# ForceLanguagePriority Prefer Fallback
# </Directory>
#
# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
# ErrorDocument 410 /error/HTTP_GONE.html.var
# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
# </IfModule>
# </IfModule>
#</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,4 @@
# Define an access log for VirtualHosts that don't define their own logfile
CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,73 @@
#
# Disable access to the entire file system except for the directories that
# are explicitly allowed later.
#
# This currently breaks the configurations that come with some web application
# Debian packages.
#
#<Directory />
# AllowOverride None
# Require all denied
#</Directory>
# Changing the following options will not really affect the security of the
# server, but might make attacks slightly more difficult in some cases.
#
# ServerTokens
# This directive configures what you return as the Server HTTP response
# Header. The default is 'Full' which sends information about the OS-Type
# and compiled in modules.
# Set to one of: Full | OS | Minimal | Minor | Major | Prod
# where Full conveys the most information, and Prod the least.
#ServerTokens Minimal
ServerTokens OS
#ServerTokens Full
#
# Optionally add a line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc., but not CGI generated
# documents or custom error documents).
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
# Set to one of: On | Off | EMail
#ServerSignature Off
ServerSignature On
#
# Allow TRACE method
#
# Set to "extended" to also reflect the request body (only for testing and
# diagnostic purposes).
#
# Set to one of: On | Off | extended
TraceEnable Off
#TraceEnable On
#
# Forbid access to version control directories
#
# If you use version control systems in your document root, you should
# probably deny access to their directories. For example, for subversion:
#
#<DirectoryMatch "/\.svn">
# Require all denied
#</DirectoryMatch>
#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
#
#Header set X-Content-Type-Options: "nosniff"
#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
#Header set X-Frame-Options: "sameorigin"
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,20 @@
<IfModule mod_alias.c>
<IfModule mod_cgi.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfModule mod_cgid.c>
Define ENABLE_USR_LIB_CGI_BIN
</IfModule>
<IfDefine ENABLE_USR_LIB_CGI_BIN>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
</IfDefine>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@ -0,0 +1,47 @@
# envvars - default environment variables for apache2ctl
# this won't be correct after changing uid
unset HOME
# for supporting multiple apache2 instances
if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}"
else
SUFFIX=
fi
# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
# temporary state file location. This might be changed to /run in Wheezy+1
export APACHE_PID_FILE=/var/run/apache2/apache2$SUFFIX.pid
export APACHE_RUN_DIR=/var/run/apache2$SUFFIX
export APACHE_LOCK_DIR=/var/lock/apache2$SUFFIX
# Only /var/log/apache2 is handled by /etc/logrotate.d/apache2.
export APACHE_LOG_DIR=/var/log/apache2$SUFFIX
## The locale used by some modules like mod_dav
export LANG=C
## Uncomment the following line to use the system default locale instead:
#. /etc/default/locale
export LANG
## The command to get the status for 'apache2ctl status'.
## Some packages providing 'www-browser' need '--dump' instead of '-dump'.
#export APACHE_LYNX='www-browser -dump'
## If you need a higher file descriptor limit, uncomment and adjust the
## following line (default is 8192):
#APACHE_ULIMIT_MAX_FILES='ulimit -n 65536'
## If you would like to pass arguments to the web server, add them below
## to the APACHE_ARGUMENTS environment.
#export APACHE_ARGUMENTS=''
## Enable the debug mode for maintainer scripts.
## This will produce a verbose output on package installations of web server modules and web application
## installations which interact with Apache
#export APACHE2_MAINTSCRIPT_DEBUG=1

Some files were not shown because too many files have changed in this diff Show More