Error202
2 years ago
commit
960876a1bf
85 changed files with 3552 additions and 0 deletions
@ -0,0 +1,39 @@
|
||||
# phpstorm project files |
||||
.idea |
||||
|
||||
# netbeans project files |
||||
nbproject |
||||
|
||||
# zend studio for eclipse project files |
||||
.buildpath |
||||
.project |
||||
.settings |
||||
|
||||
# windows thumbnail cache |
||||
Thumbs.db |
||||
|
||||
# composer vendor dir |
||||
/vendor |
||||
|
||||
# composer itself is not needed |
||||
composer.phar |
||||
|
||||
# composer lock |
||||
composer.lock |
||||
|
||||
# Mac DS_Store Files |
||||
.DS_Store |
||||
|
||||
# phpunit itself is not needed |
||||
phpunit.phar |
||||
# local phpunit config |
||||
/phpunit.xml |
||||
|
||||
tests/_output/* |
||||
tests/_support/_generated |
||||
|
||||
#vagrant folder |
||||
/.vagrant |
||||
|
||||
# PostgreSQL database files |
||||
/pgdata |
@ -0,0 +1,29 @@
|
||||
Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com) |
||||
All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions |
||||
are met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
notice, this list of conditions and the following disclaimer in |
||||
the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Yii Software LLC nor the names of its |
||||
contributors may be used to endorse or promote products derived |
||||
from this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,14 @@
|
||||
init: docker-down-clear docker-up |
||||
up: docker-up |
||||
down: docker-down |
||||
restart: down up |
||||
|
||||
docker-up: |
||||
docker-compose up -d
|
||||
|
||||
docker-down: |
||||
docker-compose down --remove-orphans
|
||||
|
||||
docker-down-clear: |
||||
docker-compose down -v --remove-orphans
|
||||
|
@ -0,0 +1,233 @@
|
||||
<p align="center"> |
||||
<a href="https://github.com/yiisoft" target="_blank"> |
||||
<img src="https://avatars0.githubusercontent.com/u/993323" height="100px"> |
||||
</a> |
||||
<h1 align="center">Yii 2 Basic Project Template</h1> |
||||
<br> |
||||
</p> |
||||
|
||||
Yii 2 Basic Project Template is a skeleton [Yii 2](https://www.yiiframework.com/) application best for |
||||
rapidly creating small projects. |
||||
|
||||
The template contains the basic features including user login/logout and a contact page. |
||||
It includes all commonly used configurations that would allow you to focus on adding new |
||||
features to your application. |
||||
|
||||
[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2-app-basic.svg)](https://packagist.org/packages/yiisoft/yii2-app-basic) |
||||
[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-basic.svg)](https://packagist.org/packages/yiisoft/yii2-app-basic) |
||||
[![build](https://github.com/yiisoft/yii2-app-basic/workflows/build/badge.svg)](https://github.com/yiisoft/yii2-app-basic/actions?query=workflow%3Abuild) |
||||
|
||||
DIRECTORY STRUCTURE |
||||
------------------- |
||||
|
||||
assets/ contains assets definition |
||||
commands/ contains console commands (controllers) |
||||
config/ contains application configurations |
||||
controllers/ contains Web controller classes |
||||
mail/ contains view files for e-mails |
||||
models/ contains model classes |
||||
runtime/ contains files generated during runtime |
||||
tests/ contains various tests for the basic application |
||||
vendor/ contains dependent 3rd-party packages |
||||
views/ contains view files for the Web application |
||||
web/ contains the entry script and Web resources |
||||
|
||||
|
||||
|
||||
REQUIREMENTS |
||||
------------ |
||||
|
||||
The minimum requirement by this project template that your Web server supports PHP 7.4. |
||||
|
||||
|
||||
INSTALLATION |
||||
------------ |
||||
|
||||
### Install via Composer |
||||
|
||||
If you do not have [Composer](https://getcomposer.org/), you may install it by following the instructions |
||||
at [getcomposer.org](https://getcomposer.org/doc/00-intro.md#installation-nix). |
||||
|
||||
You can then install this project template using the following command: |
||||
|
||||
~~~ |
||||
composer create-project --prefer-dist yiisoft/yii2-app-basic basic |
||||
~~~ |
||||
|
||||
Now you should be able to access the application through the following URL, assuming `basic` is the directory |
||||
directly under the Web root. |
||||
|
||||
~~~ |
||||
http://localhost/basic/web/ |
||||
~~~ |
||||
|
||||
### Install from an Archive File |
||||
|
||||
Extract the archive file downloaded from [yiiframework.com](https://www.yiiframework.com/download/) to |
||||
a directory named `basic` that is directly under the Web root. |
||||
|
||||
Set cookie validation key in `config/web.php` file to some random secret string: |
||||
|
||||
```php |
||||
'request' => [ |
||||
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation |
||||
'cookieValidationKey' => '<secret random string goes here>', |
||||
], |
||||
``` |
||||
|
||||
You can then access the application through the following URL: |
||||
|
||||
~~~ |
||||
http://localhost/basic/web/ |
||||
~~~ |
||||
|
||||
|
||||
### Install with Docker |
||||
|
||||
Update your vendor packages |
||||
|
||||
docker-compose run --rm php composer update --prefer-dist |
||||
|
||||
Run the installation triggers (creating cookie validation code) |
||||
|
||||
docker-compose run --rm php composer install |
||||
|
||||
Start the container |
||||
|
||||
docker-compose up -d |
||||
|
||||
You can then access the application through the following URL: |
||||
|
||||
http://127.0.0.1:8000 |
||||
|
||||
**NOTES:** |
||||
- Minimum required Docker engine version `17.04` for development (see [Performance tuning for volume mounts](https://docs.docker.com/docker-for-mac/osxfs-caching/)) |
||||
- The default configuration uses a host-volume in your home directory `.docker-composer` for composer caches |
||||
|
||||
|
||||
CONFIGURATION |
||||
------------- |
||||
|
||||
### Database |
||||
|
||||
Edit the file `config/db.php` with real data, for example: |
||||
|
||||
```php |
||||
return [ |
||||
'class' => 'yii\db\Connection', |
||||
'dsn' => 'mysql:host=localhost;dbname=yii2basic', |
||||
'username' => 'root', |
||||
'password' => '1234', |
||||
'charset' => 'utf8', |
||||
]; |
||||
``` |
||||
|
||||
**NOTES:** |
||||
- Yii won't create the database for you, this has to be done manually before you can access it. |
||||
- Check and edit the other files in the `config/` directory to customize your application as required. |
||||
- Refer to the README in the `tests` directory for information specific to basic application tests. |
||||
|
||||
|
||||
TESTING |
||||
------- |
||||
|
||||
Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](https://codeception.com/). |
||||
By default, there are 3 test suites: |
||||
|
||||
- `unit` |
||||
- `functional` |
||||
- `acceptance` |
||||
|
||||
Tests can be executed by running |
||||
|
||||
``` |
||||
vendor/bin/codecept run |
||||
``` |
||||
|
||||
The command above will execute unit and functional tests. Unit tests are testing the system components, while functional |
||||
tests are for testing user interaction. Acceptance tests are disabled by default as they require additional setup since |
||||
they perform testing in real browser. |
||||
|
||||
|
||||
### Running acceptance tests |
||||
|
||||
To execute acceptance tests do the following: |
||||
|
||||
1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration |
||||
|
||||
2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full-featured |
||||
version of Codeception |
||||
|
||||
3. Update dependencies with Composer |
||||
|
||||
``` |
||||
composer update |
||||
``` |
||||
|
||||
4. Download [Selenium Server](https://www.seleniumhq.org/download/) and launch it: |
||||
|
||||
``` |
||||
java -jar ~/selenium-server-standalone-x.xx.x.jar |
||||
``` |
||||
|
||||
In case of using Selenium Server 3.0 with Firefox browser since v48 or Google Chrome since v53 you must download [GeckoDriver](https://github.com/mozilla/geckodriver/releases) or [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) and launch Selenium with it: |
||||
|
||||
``` |
||||
# for Firefox |
||||
java -jar -Dwebdriver.gecko.driver=~/geckodriver ~/selenium-server-standalone-3.xx.x.jar |
||||
|
||||
# for Google Chrome |
||||
java -jar -Dwebdriver.chrome.driver=~/chromedriver ~/selenium-server-standalone-3.xx.x.jar |
||||
``` |
||||
|
||||
As an alternative way you can use already configured Docker container with older versions of Selenium and Firefox: |
||||
|
||||
``` |
||||
docker run --net=host selenium/standalone-firefox:2.53.0 |
||||
``` |
||||
|
||||
5. (Optional) Create `yii2basic_test` database and update it by applying migrations if you have them. |
||||
|
||||
``` |
||||
tests/bin/yii migrate |
||||
``` |
||||
|
||||
The database configuration can be found at `config/test_db.php`. |
||||
|
||||
|
||||
6. Start web server: |
||||
|
||||
``` |
||||
tests/bin/yii serve |
||||
``` |
||||
|
||||
7. Now you can run all available tests |
||||
|
||||
``` |
||||
# run all available tests |
||||
vendor/bin/codecept run |
||||
|
||||
# run acceptance tests |
||||
vendor/bin/codecept run acceptance |
||||
|
||||
# run only unit and functional tests |
||||
vendor/bin/codecept run unit,functional |
||||
``` |
||||
|
||||
### Code coverage support |
||||
|
||||
By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able |
||||
to collect code coverage. You can run your tests and collect coverage with the following command: |
||||
|
||||
``` |
||||
#collect coverage for all tests |
||||
vendor/bin/codecept run --coverage --coverage-html --coverage-xml |
||||
|
||||
#collect coverage only for unit tests |
||||
vendor/bin/codecept run unit --coverage --coverage-html --coverage-xml |
||||
|
||||
#collect coverage for unit and functional tests |
||||
vendor/bin/codecept run functional,unit --coverage --coverage-html --coverage-xml |
||||
``` |
||||
|
||||
You can see code coverage output under the `tests/_output` directory. |
@ -0,0 +1,31 @@
|
||||
<?php |
||||
/** |
||||
* @link https://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license https://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace app\assets; |
||||
|
||||
use yii\web\AssetBundle; |
||||
|
||||
/** |
||||
* Main application asset bundle. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class AppAsset extends AssetBundle |
||||
{ |
||||
public $basePath = '@webroot'; |
||||
public $baseUrl = '@web'; |
||||
public $css = [ |
||||
'css/site.css', |
||||
]; |
||||
public $js = [ |
||||
]; |
||||
public $depends = [ |
||||
'yii\web\YiiAsset', |
||||
'yii\bootstrap5\BootstrapAsset' |
||||
]; |
||||
} |
@ -0,0 +1,27 @@
|
||||
actor: Tester |
||||
bootstrap: _bootstrap.php |
||||
paths: |
||||
tests: tests |
||||
output: tests/_output |
||||
data: tests/_data |
||||
helpers: tests/_support |
||||
settings: |
||||
memory_limit: 1024M |
||||
colors: true |
||||
modules: |
||||
config: |
||||
Yii2: |
||||
configFile: 'config/test.php' |
||||
|
||||
# To enable code coverage: |
||||
#coverage: |
||||
# #c3_url: http://localhost:8080/index-test.php/ |
||||
# enabled: true |
||||
# #remote: true |
||||
# #remote_config: '../codeception.yml' |
||||
# whitelist: |
||||
# include: |
||||
# - models/* |
||||
# - controllers/* |
||||
# - commands/* |
||||
# - mail/* |
@ -0,0 +1,34 @@
|
||||
<?php |
||||
/** |
||||
* @link https://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license https://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace app\commands; |
||||
|
||||
use yii\console\Controller; |
||||
use yii\console\ExitCode; |
||||
|
||||
/** |
||||
* This command echoes the first argument that you have entered. |
||||
* |
||||
* This command is provided as an example for you to learn how to create console commands. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class HelloController extends Controller |
||||
{ |
||||
/** |
||||
* This command echoes what you have entered as the message. |
||||
* @param string $message the message to be echoed. |
||||
* @return int Exit code |
||||
*/ |
||||
public function actionIndex($message = 'hello world') |
||||
{ |
||||
echo $message . "\n"; |
||||
|
||||
return ExitCode::OK; |
||||
} |
||||
} |
@ -0,0 +1,75 @@
|
||||
{ |
||||
"name": "yiisoft/yii2-app-basic", |
||||
"description": "Yii 2 Basic Project Template", |
||||
"keywords": ["yii2", "framework", "basic", "project template"], |
||||
"homepage": "https://www.yiiframework.com/", |
||||
"type": "project", |
||||
"license": "BSD-3-Clause", |
||||
"support": { |
||||
"issues": "https://github.com/yiisoft/yii2/issues?state=open", |
||||
"forum": "https://www.yiiframework.com/forum/", |
||||
"wiki": "https://www.yiiframework.com/wiki/", |
||||
"irc": "irc://irc.freenode.net/yii", |
||||
"source": "https://github.com/yiisoft/yii2" |
||||
}, |
||||
"minimum-stability": "stable", |
||||
"require": { |
||||
"php": ">=7.4.0", |
||||
"yiisoft/yii2": "~2.0.45", |
||||
"yiisoft/yii2-bootstrap5": "~2.0.2", |
||||
"yiisoft/yii2-symfonymailer": "~2.0.3" |
||||
}, |
||||
"require-dev": { |
||||
"yiisoft/yii2-debug": "~2.1.0", |
||||
"yiisoft/yii2-gii": "~2.2.0", |
||||
"yiisoft/yii2-faker": "~2.0.0", |
||||
"phpunit/phpunit": "~9.5.0", |
||||
"codeception/codeception": "^5.0.0 || ^4.0", |
||||
"codeception/lib-innerbrowser": "^4.0 || ^3.0 || ^1.1", |
||||
"codeception/module-asserts": "^3.0 || ^1.1", |
||||
"codeception/module-yii2": "^1.1", |
||||
"codeception/module-filesystem": "^3.0 || ^2.0 || ^1.1", |
||||
"codeception/verify": "^3.0 || ^2.2", |
||||
"symfony/browser-kit": "^6.0 || >=2.7 <=4.2.4" |
||||
}, |
||||
"config": { |
||||
"allow-plugins": { |
||||
"yiisoft/yii2-composer" : true |
||||
}, |
||||
"process-timeout": 1800, |
||||
"fxp-asset": { |
||||
"enabled": false |
||||
} |
||||
}, |
||||
"scripts": { |
||||
"post-install-cmd": [ |
||||
"yii\\composer\\Installer::postInstall" |
||||
], |
||||
"post-create-project-cmd": [ |
||||
"yii\\composer\\Installer::postCreateProject", |
||||
"yii\\composer\\Installer::postInstall" |
||||
] |
||||
}, |
||||
"extra": { |
||||
"yii\\composer\\Installer::postCreateProject": { |
||||
"setPermission": [ |
||||
{ |
||||
"runtime": "0777", |
||||
"web/assets": "0777", |
||||
"yii": "0755" |
||||
} |
||||
] |
||||
}, |
||||
"yii\\composer\\Installer::postInstall": { |
||||
"generateCookieValidationKey": [ |
||||
"config/web.php" |
||||
] |
||||
} |
||||
}, |
||||
"repositories": [ |
||||
{ |
||||
"type": "composer", |
||||
"url": "https://asset-packagist.org" |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,33 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* This class only exists here for IDE (PHPStorm/Netbeans/...) autocompletion. |
||||
* This file is never included anywhere. |
||||
* Adjust this file to match classes configured in your application config, to enable IDE autocompletion for custom components. |
||||
* Example: A property phpdoc can be added in `__Application` class as `@property \vendor\package\Rollbar|__Rollbar $rollbar` and adding a class in this file |
||||
* ```php |
||||
* // @property of \vendor\package\Rollbar goes here |
||||
* class __Rollbar { |
||||
* } |
||||
* ``` |
||||
*/ |
||||
class Yii { |
||||
/** |
||||
* @var \yii\web\Application|\yii\console\Application|__Application |
||||
*/ |
||||
public static $app; |
||||
} |
||||
|
||||
/** |
||||
* @property yii\rbac\DbManager $authManager |
||||
* @property \yii\web\User|__WebUser $user |
||||
* |
||||
*/ |
||||
class __Application { |
||||
} |
||||
|
||||
/** |
||||
* @property app\models\User $identity |
||||
*/ |
||||
class __WebUser { |
||||
} |
@ -0,0 +1,56 @@
|
||||
<?php |
||||
|
||||
$params = require __DIR__ . '/params.php'; |
||||
$db = require __DIR__ . '/db.php'; |
||||
|
||||
$config = [ |
||||
'id' => 'basic-console', |
||||
'basePath' => dirname(__DIR__), |
||||
'bootstrap' => ['log'], |
||||
'controllerNamespace' => 'app\commands', |
||||
'aliases' => [ |
||||
'@bower' => '@vendor/bower-asset', |
||||
'@npm' => '@vendor/npm-asset', |
||||
'@tests' => '@app/tests', |
||||
], |
||||
'components' => [ |
||||
'cache' => [ |
||||
'class' => 'yii\caching\FileCache', |
||||
], |
||||
'log' => [ |
||||
'targets' => [ |
||||
[ |
||||
'class' => 'yii\log\FileTarget', |
||||
'levels' => ['error', 'warning'], |
||||
], |
||||
], |
||||
], |
||||
'db' => $db, |
||||
], |
||||
'params' => $params, |
||||
/* |
||||
'controllerMap' => [ |
||||
'fixture' => [ // Fixture generation command line. |
||||
'class' => 'yii\faker\FixtureController', |
||||
], |
||||
], |
||||
*/ |
||||
]; |
||||
|
||||
if (YII_ENV_DEV) { |
||||
// configuration adjustments for 'dev' environment |
||||
$config['bootstrap'][] = 'gii'; |
||||
$config['modules']['gii'] = [ |
||||
'class' => 'yii\gii\Module', |
||||
]; |
||||
// configuration adjustments for 'dev' environment |
||||
// requires version `2.1.21` of yii2-debug module |
||||
$config['bootstrap'][] = 'debug'; |
||||
$config['modules']['debug'] = [ |
||||
'class' => 'yii\debug\Module', |
||||
// uncomment the following to add your IP if you are not connecting from localhost. |
||||
//'allowedIPs' => ['127.0.0.1', '::1'], |
||||
]; |
||||
} |
||||
|
||||
return $config; |
@ -0,0 +1,14 @@
|
||||
<?php |
||||
|
||||
return [ |
||||
'class' => 'yii\db\Connection', |
||||
'dsn' => 'mysql:host=localhost;dbname=yii2basic', |
||||
'username' => 'root', |
||||
'password' => '', |
||||
'charset' => 'utf8', |
||||
|
||||
// Schema cache options (for production environment) |
||||
//'enableSchemaCache' => true, |
||||
//'schemaCacheDuration' => 60, |
||||
//'schemaCache' => 'cache', |
||||
]; |
@ -0,0 +1,7 @@
|
||||
<?php |
||||
|
||||
return [ |
||||
'adminEmail' => 'admin@example.com', |
||||
'senderEmail' => 'noreply@example.com', |
||||
'senderName' => 'Example.com mailer', |
||||
]; |
@ -0,0 +1,46 @@
|
||||
<?php |
||||
$params = require __DIR__ . '/params.php'; |
||||
$db = require __DIR__ . '/test_db.php'; |
||||
|
||||
/** |
||||
* Application configuration shared by all test types |
||||
*/ |
||||
return [ |
||||
'id' => 'basic-tests', |
||||
'basePath' => dirname(__DIR__), |
||||
'aliases' => [ |
||||
'@bower' => '@vendor/bower-asset', |
||||
'@npm' => '@vendor/npm-asset', |
||||
], |
||||
'language' => 'en-US', |
||||
'components' => [ |
||||
'db' => $db, |
||||
'mailer' => [ |
||||
'class' => \yii\symfonymailer\Mailer::class, |
||||
'viewPath' => '@app/mail', |
||||
// send all mails to a file by default. |
||||
'useFileTransport' => true, |
||||
'messageClass' => 'yii\symfonymailer\Message' |
||||
], |
||||
'assetManager' => [ |
||||
'basePath' => __DIR__ . '/../web/assets', |
||||
], |
||||
'urlManager' => [ |
||||
'showScriptName' => true, |
||||
], |
||||
'user' => [ |
||||
'identityClass' => 'app\models\User', |
||||
], |
||||
'request' => [ |
||||
'cookieValidationKey' => 'test', |
||||
'enableCsrfValidation' => false, |
||||
// but if you absolutely need it set cookie domain to localhost |
||||
/* |
||||
'csrfCookie' => [ |
||||
'domain' => 'localhost', |
||||
], |
||||
*/ |
||||
], |
||||
], |
||||
'params' => $params, |
||||
]; |
@ -0,0 +1,6 @@
|
||||
<?php |
||||
$db = require __DIR__ . '/db.php'; |
||||
// test database! Important not to run tests on production or development databases |
||||
$db['dsn'] = 'mysql:host=localhost;dbname=yii2basic_test'; |
||||
|
||||
return $db; |
@ -0,0 +1,72 @@
|
||||
<?php |
||||
|
||||
$params = require __DIR__ . '/params.php'; |
||||
$db = require __DIR__ . '/db.php'; |
||||
|
||||
$config = [ |
||||
'id' => 'basic', |
||||
'basePath' => dirname(__DIR__), |
||||
'bootstrap' => ['log'], |
||||
'aliases' => [ |
||||
'@bower' => '@vendor/bower-asset', |
||||
'@npm' => '@vendor/npm-asset', |
||||
], |
||||
'components' => [ |
||||
'request' => [ |
||||
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation |
||||
'cookieValidationKey' => 'kxzoL3hScKXhQzb-QNrA75YJw7mrG_Su', |
||||
], |
||||
'cache' => [ |
||||
'class' => 'yii\caching\FileCache', |
||||
], |
||||
'user' => [ |
||||
'identityClass' => 'app\models\User', |
||||
'enableAutoLogin' => true, |
||||
], |
||||
'errorHandler' => [ |
||||
'errorAction' => 'site/error', |
||||
], |
||||
'mailer' => [ |
||||
'class' => \yii\symfonymailer\Mailer::class, |
||||
'viewPath' => '@app/mail', |
||||
// send all mails to a file by default. |
||||
'useFileTransport' => true, |
||||
], |
||||
'log' => [ |
||||
'traceLevel' => YII_DEBUG ? 3 : 0, |
||||
'targets' => [ |
||||
[ |
||||
'class' => 'yii\log\FileTarget', |
||||
'levels' => ['error', 'warning'], |
||||
], |
||||
], |
||||
], |
||||
'db' => $db, |
||||
'urlManager' => [ |
||||
'enablePrettyUrl' => true, |
||||
'showScriptName' => false, |
||||
'rules' => [ |
||||
], |
||||
], |
||||
], |
||||
'params' => $params, |
||||
]; |
||||
|
||||
if (YII_ENV_DEV) { |
||||
// configuration adjustments for 'dev' environment |
||||
$config['bootstrap'][] = 'debug'; |
||||
$config['modules']['debug'] = [ |
||||
'class' => 'yii\debug\Module', |
||||
// uncomment the following to add your IP if you are not connecting from localhost. |
||||
//'allowedIPs' => ['127.0.0.1', '::1'], |
||||
]; |
||||
|
||||
$config['bootstrap'][] = 'gii'; |
||||
$config['modules']['gii'] = [ |
||||
'class' => 'yii\gii\Module', |
||||
// uncomment the following to add your IP if you are not connecting from localhost. |
||||
//'allowedIPs' => ['127.0.0.1', '::1'], |
||||
]; |
||||
} |
||||
|
||||
return $config; |
@ -0,0 +1,128 @@
|
||||
<?php |
||||
|
||||
namespace app\controllers; |
||||
|
||||
use Yii; |
||||
use yii\filters\AccessControl; |
||||
use yii\web\Controller; |
||||
use yii\web\Response; |
||||
use yii\filters\VerbFilter; |
||||
use app\models\LoginForm; |
||||
use app\models\ContactForm; |
||||
|
||||
class SiteController extends Controller |
||||
{ |
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function behaviors() |
||||
{ |
||||
return [ |
||||
'access' => [ |
||||
'class' => AccessControl::class, |
||||
'only' => ['logout'], |
||||
'rules' => [ |
||||
[ |
||||
'actions' => ['logout'], |
||||
'allow' => true, |
||||
'roles' => ['@'], |
||||
], |
||||
], |
||||
], |
||||
'verbs' => [ |
||||
'class' => VerbFilter::class, |
||||
'actions' => [ |
||||
'logout' => ['post'], |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function actions() |
||||
{ |
||||
return [ |
||||
'error' => [ |
||||
'class' => 'yii\web\ErrorAction', |
||||
], |
||||
'captcha' => [ |
||||
'class' => 'yii\captcha\CaptchaAction', |
||||
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, |
||||
], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* Displays homepage. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function actionIndex() |
||||
{ |
||||
return $this->render('index'); |
||||
} |
||||
|
||||
/** |
||||
* Login action. |
||||
* |
||||
* @return Response|string |
||||
*/ |
||||
public function actionLogin() |
||||
{ |
||||
if (!Yii::$app->user->isGuest) { |
||||
return $this->goHome(); |
||||
} |
||||
|
||||
$model = new LoginForm(); |
||||
if ($model->load(Yii::$app->request->post()) && $model->login()) { |
||||
return $this->goBack(); |
||||
} |
||||
|
||||
$model->password = ''; |
||||
return $this->render('login', [ |
||||
'model' => $model, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* Logout action. |
||||
* |
||||
* @return Response |
||||
*/ |
||||
public function actionLogout() |
||||
{ |
||||
Yii::$app->user->logout(); |
||||
|
||||
return $this->goHome(); |
||||
} |
||||
|
||||
/** |
||||
* Displays contact page. |
||||
* |
||||
* @return Response|string |
||||
*/ |
||||
public function actionContact() |
||||
{ |
||||
$model = new ContactForm(); |
||||
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) { |
||||
Yii::$app->session->setFlash('contactFormSubmitted'); |
||||
|
||||
return $this->refresh(); |
||||
} |
||||
return $this->render('contact', [ |
||||
'model' => $model, |
||||
]); |
||||
} |
||||
|
||||
/** |
||||
* Displays about page. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function actionAbout() |
||||
{ |
||||
return $this->render('about'); |
||||
} |
||||
} |
@ -0,0 +1,15 @@
|
||||
<?php |
||||
|
||||
namespace app\controllers\api; |
||||
|
||||
use yii\rest\Controller; |
||||
|
||||
class TestController extends Controller |
||||
{ |
||||
public function actionIndex(): array |
||||
{ |
||||
return [ |
||||
'test152', 'test153' |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
version: '2' |
||||
services: |
||||
php: |
||||
image: yiisoftware/yii2-php:8.1-apache |
||||
volumes: |
||||
- ~/.composer-docker/cache:/root/.composer/cache:delegated |
||||
- ./:/app:delegated |
||||
ports: |
||||
- '8001:80' |
||||
depends_on: |
||||
- api-postgres |
||||
|
||||
api-postgres: |
||||
image: postgres:14.8-alpine |
||||
environment: |
||||
POSTGRES_USER: app |
||||
POSTGRES_PASSWORD: secret |
||||
POSTGRES_DB: app |
||||
PGDATA: "/var/lib/postgresql/data/pgdata" |
||||
volumes: |
||||
- .:/var/lib/postgresql/data |
||||
# - db-postgres:/var/lib/postgresql/data |
||||
# net stop winnat // перезапуск службы, если бд не запускается (Windows) |
||||
# docker-compose run --rm php composer install // обновление композера, установка расширений, работа с консолью |
||||
ports: |
||||
- "54333:5432" |
||||
|
||||
volumes: |
||||
db-postgres: |
@ -0,0 +1,22 @@
|
||||
<?php |
||||
use yii\helpers\Html; |
||||
|
||||
/** @var \yii\web\View $this view component instance */ |
||||
/** @var \yii\mail\MessageInterface $message the message being composed */ |
||||
/** @var string $content main view render result */ |
||||
?> |
||||
<?php $this->beginPage() ?> |
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
||||
<html xmlns="http://www.w3.org/1999/xhtml"> |
||||
<head> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?= Yii::$app->charset ?>" />
|
||||
<title><?= Html::encode($this->title) ?></title>
|
||||
<?php $this->head() ?> |
||||
</head> |
||||
<body> |
||||
<?php $this->beginBody() ?> |
||||
<?= $content ?> |
||||
<?php $this->endBody() ?> |
||||
</body> |
||||
</html> |
||||
<?php $this->endPage() ?> |
@ -0,0 +1,13 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* @var yii\web\View $this view component instance |
||||
* @var yii\mail\BaseMessage $message the message being composed |
||||
* @var string $content main view render result |
||||
*/ |
||||
|
||||
$this->beginPage(); |
||||
$this->beginBody(); |
||||
echo $content; |
||||
$this->endBody(); |
||||
$this->endPage(); |
@ -0,0 +1,65 @@
|
||||
<?php |
||||
|
||||
namespace app\models; |
||||
|
||||
use Yii; |
||||
use yii\base\Model; |
||||
|
||||
/** |
||||
* ContactForm is the model behind the contact form. |
||||
*/ |
||||
class ContactForm extends Model |
||||
{ |
||||
public $name; |
||||
public $email; |
||||
public $subject; |
||||
public $body; |
||||
public $verifyCode; |
||||
|
||||
|
||||
/** |
||||
* @return array the validation rules. |
||||
*/ |
||||
public function rules() |
||||
{ |
||||
return [ |
||||
// name, email, subject and body are required |
||||
[['name', 'email', 'subject', 'body'], 'required'], |
||||
// email has to be a valid email address |
||||
['email', 'email'], |
||||
// verifyCode needs to be entered correctly |
||||
['verifyCode', 'captcha'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* @return array customized attribute labels |
||||
*/ |
||||
public function attributeLabels() |
||||
{ |
||||
return [ |
||||
'verifyCode' => 'Verification Code', |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* Sends an email to the specified email address using the information collected by this model. |
||||
* @param string $email the target email address |
||||
* @return bool whether the model passes validation |
||||
*/ |
||||
public function contact($email) |
||||
{ |
||||
if ($this->validate()) { |
||||
Yii::$app->mailer->compose() |
||||
->setTo($email) |
||||
->setFrom([Yii::$app->params['senderEmail'] => Yii::$app->params['senderName']]) |
||||
->setReplyTo([$this->email => $this->name]) |
||||
->setSubject($this->subject) |
||||
->setTextBody($this->body) |
||||
->send(); |
||||
|
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
@ -0,0 +1,81 @@
|
||||
<?php |
||||
|
||||
namespace app\models; |
||||
|
||||
use Yii; |
||||
use yii\base\Model; |
||||
|
||||
/** |
||||
* LoginForm is the model behind the login form. |
||||
* |
||||
* @property-read User|null $user |
||||
* |
||||
*/ |
||||
class LoginForm extends Model |
||||
{ |
||||
public $username; |
||||
public $password; |
||||
public $rememberMe = true; |
||||
|
||||
private $_user = false; |
||||
|
||||
|
||||
/** |
||||
* @return array the validation rules. |
||||
*/ |
||||
public function rules() |
||||
{ |
||||
return [ |
||||
// username and password are both required |
||||
[['username', 'password'], 'required'], |
||||
// rememberMe must be a boolean value |
||||
['rememberMe', 'boolean'], |
||||
// password is validated by validatePassword() |
||||
['password', 'validatePassword'], |
||||
]; |
||||
} |
||||
|
||||
/** |
||||
* Validates the password. |
||||
* This method serves as the inline validation for password. |
||||
* |
||||
* @param string $attribute the attribute currently being validated |
||||
* @param array $params the additional name-value pairs given in the rule |
||||
*/ |
||||
public function validatePassword($attribute, $params) |
||||
{ |
||||
if (!$this->hasErrors()) { |
||||
$user = $this->getUser(); |
||||
|
||||
if (!$user || !$user->validatePassword($this->password)) { |
||||
$this->addError($attribute, 'Incorrect username or password.'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Logs in a user using the provided username and password. |
||||
* @return bool whether the user is logged in successfully |
||||
*/ |
||||
public function login() |
||||
{ |
||||
if ($this->validate()) { |
||||
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Finds user by [[username]] |
||||
* |
||||
* @return User|null |
||||
*/ |
||||
public function getUser() |
||||
{ |
||||
if ($this->_user === false) { |
||||
$this->_user = User::findByUsername($this->username); |
||||
} |
||||
|
||||
return $this->_user; |
||||
} |
||||
} |
@ -0,0 +1,104 @@
|
||||
<?php |
||||
|
||||
namespace app\models; |
||||
|
||||
class User extends \yii\base\BaseObject implements \yii\web\IdentityInterface |
||||
{ |
||||
public $id; |
||||
public $username; |
||||
public $password; |
||||
public $authKey; |
||||
public $accessToken; |
||||
|
||||
private static $users = [ |
||||
'100' => [ |
||||
'id' => '100', |
||||
'username' => 'admin', |
||||
'password' => 'admin', |
||||
'authKey' => 'test100key', |
||||
'accessToken' => '100-token', |
||||
], |
||||
'101' => [ |
||||
'id' => '101', |
||||
'username' => 'demo', |
||||
'password' => 'demo', |
||||
'authKey' => 'test101key', |
||||
'accessToken' => '101-token', |
||||
], |
||||
]; |
||||
|
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public static function findIdentity($id) |
||||
{ |
||||
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public static function findIdentityByAccessToken($token, $type = null) |
||||
{ |
||||
foreach (self::$users as $user) { |
||||
if ($user['accessToken'] === $token) { |
||||
return new static($user); |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Finds user by username |
||||
* |
||||
* @param string $username |
||||
* @return static|null |
||||
*/ |
||||
public static function findByUsername($username) |
||||
{ |
||||
foreach (self::$users as $user) { |
||||
if (strcasecmp($user['username'], $username) === 0) { |
||||
return new static($user); |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getAuthKey() |
||||
{ |
||||
return $this->authKey; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function validateAuthKey($authKey) |
||||
{ |
||||
return $this->authKey === $authKey; |
||||
} |
||||
|
||||
/** |
||||
* Validates password |
||||
* |
||||
* @param string $password password to validate |
||||
* @return bool if password provided is valid for current user |
||||
*/ |
||||
public function validatePassword($password) |
||||
{ |
||||
return $this->password === $password; |
||||
} |
||||
} |
@ -0,0 +1,162 @@
|
||||
<?php |
||||
/** |
||||
* Application requirement checker script. |
||||
* |
||||
* In order to run this script use the following console command: |
||||
* php requirements.php |
||||
* |
||||
* In order to run this script from the web, you should copy it to the web root. |
||||
* If you are using Linux you can create a hard link instead, using the following command: |
||||
* ln ../requirements.php requirements.php |
||||
*/ |
||||
|
||||
// you may need to adjust this path to the correct Yii framework path |
||||
// uncomment and adjust the following line if Yii is not located at the default path |
||||
//$frameworkPath = dirname(__FILE__) . '/vendor/yiisoft/yii2'; |
||||
|
||||
|
||||
if (!isset($frameworkPath)) { |
||||
$searchPaths = array( |
||||
dirname(__FILE__) . '/vendor/yiisoft/yii2', |
||||
dirname(__FILE__) . '/../vendor/yiisoft/yii2', |
||||
); |
||||
foreach ($searchPaths as $path) { |
||||
if (is_dir($path)) { |
||||
$frameworkPath = $path; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (!isset($frameworkPath) || !is_dir($frameworkPath)) { |
||||
$message = "<h1>Error</h1>\n\n" |
||||
. "<p><strong>The path to yii framework seems to be incorrect.</strong></p>\n" |
||||
. '<p>You need to install Yii framework via composer or adjust the framework path in file <abbr title="' . __FILE__ . '">' . basename(__FILE__) . "</abbr>.</p>\n" |
||||
. '<p>Please refer to the <abbr title="' . dirname(__FILE__) . "/README.md\">README</abbr> on how to install Yii.</p>\n"; |
||||
|
||||
if (!empty($_SERVER['argv'])) { |
||||
// do not print HTML when used in console mode |
||||
echo strip_tags($message); |
||||
} else { |
||||
echo $message; |
||||
} |
||||
exit(1); |
||||
} |
||||
|
||||
require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); |
||||
$requirementsChecker = new YiiRequirementChecker(); |
||||
|
||||
$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; |
||||
$gdOK = $imagickOK = false; |
||||
|
||||
if (extension_loaded('imagick')) { |
||||
$imagick = new Imagick(); |
||||
$imagickFormats = $imagick->queryFormats('PNG'); |
||||
if (in_array('PNG', $imagickFormats)) { |
||||
$imagickOK = true; |
||||
} else { |
||||
$imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; |
||||
} |
||||
} |
||||
|
||||
if (extension_loaded('gd')) { |
||||
$gdInfo = gd_info(); |
||||
if (!empty($gdInfo['FreeType Support'])) { |
||||
$gdOK = true; |
||||
} else { |
||||
$gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Adjust requirements according to your application specifics. |
||||
*/ |
||||
$requirements = array( |
||||
// Database : |
||||
array( |
||||
'name' => 'PDO extension', |
||||
'mandatory' => true, |
||||
'condition' => extension_loaded('pdo'), |
||||
'by' => 'All DB-related classes', |
||||
), |
||||
array( |
||||
'name' => 'PDO SQLite extension', |
||||
'mandatory' => false, |
||||
'condition' => extension_loaded('pdo_sqlite'), |
||||
'by' => 'All DB-related classes', |
||||
'memo' => 'Required for SQLite database.', |
||||
), |
||||
array( |
||||
'name' => 'PDO MySQL extension', |
||||
'mandatory' => false, |
||||
'condition' => extension_loaded('pdo_mysql'), |
||||
'by' => 'All DB-related classes', |
||||
'memo' => 'Required for MySQL database.', |
||||
), |
||||
array( |
||||
'name' => 'PDO PostgreSQL extension', |
||||
'mandatory' => false, |
||||
'condition' => extension_loaded('pdo_pgsql'), |
||||
'by' => 'All DB-related classes', |
||||
'memo' => 'Required for PostgreSQL database.', |
||||
), |
||||
// Cache : |
||||
array( |
||||
'name' => 'Memcache extension', |
||||
'mandatory' => false, |
||||
'condition' => extension_loaded('memcache') || extension_loaded('memcached'), |
||||
'by' => '<a href="https://www.yiiframework.com/doc-2.0/yii-caching-memcache.html">MemCache</a>', |
||||
'memo' => extension_loaded('memcached') ? 'To use memcached set <a href="https://www.yiiframework.com/doc-2.0/yii-caching-memcache.html#$useMemcached-detail">MemCache::useMemcached</a> to <code>true</code>.' : '' |
||||
), |
||||
// CAPTCHA: |
||||
array( |
||||
'name' => 'GD PHP extension with FreeType support', |
||||
'mandatory' => false, |
||||
'condition' => $gdOK, |
||||
'by' => '<a href="https://www.yiiframework.com/doc-2.0/yii-captcha-captcha.html">Captcha</a>', |
||||
'memo' => $gdMemo, |
||||
), |
||||
array( |
||||
'name' => 'ImageMagick PHP extension with PNG support', |
||||
'mandatory' => false, |
||||
'condition' => $imagickOK, |
||||
'by' => '<a href="https://www.yiiframework.com/doc-2.0/yii-captcha-captcha.html">Captcha</a>', |
||||
'memo' => $imagickMemo, |
||||
), |
||||
// PHP ini : |
||||
'phpExposePhp' => array( |
||||
'name' => 'Expose PHP', |
||||
'mandatory' => false, |
||||
'condition' => $requirementsChecker->checkPhpIniOff("expose_php"), |
||||
'by' => 'Security reasons', |
||||
'memo' => '"expose_php" should be disabled at php.ini', |
||||
), |
||||
'phpAllowUrlInclude' => array( |
||||
'name' => 'PHP allow url include', |
||||
'mandatory' => false, |
||||
'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"), |
||||
'by' => 'Security reasons', |
||||
'memo' => '"allow_url_include" should be disabled at php.ini', |
||||
), |
||||
'phpSmtp' => array( |
||||
'name' => 'PHP mail SMTP', |
||||
'mandatory' => false, |
||||
'condition' => strlen(ini_get('SMTP')) > 0, |
||||
'by' => 'Email sending', |
||||
'memo' => 'PHP mail SMTP server required', |
||||
), |
||||
); |
||||
|
||||
// OPcache check |
||||
if (!version_compare(phpversion(), '5.5', '>=')) { |
||||
$requirements[] = array( |
||||
'name' => 'APC extension', |
||||
'mandatory' => false, |
||||
'condition' => extension_loaded('apc'), |
||||
'by' => '<a href="https://www.yiiframework.com/doc-2.0/yii-caching-apccache.html">ApcCache</a>', |
||||
); |
||||
} |
||||
|
||||
$result = $requirementsChecker->checkYii()->check($requirements)->getResult(); |
||||
$requirementsChecker->render(); |
||||
exit($result['summary']['errors'] === 0 ? 0 : 1); |
@ -0,0 +1,6 @@
|
||||
<?php |
||||
define('YII_ENV', 'test'); |
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
|
||||
require_once __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; |
||||
require __DIR__ .'/../vendor/autoload.php'; |
@ -0,0 +1,26 @@
|
||||
<?php |
||||
|
||||
|
||||
/** |
||||
* Inherited Methods |
||||
* @method void wantToTest($text) |
||||
* @method void wantTo($text) |
||||
* @method void execute($callable) |
||||
* @method void expectTo($prediction) |
||||
* @method void expect($prediction) |
||||
* @method void amGoingTo($argumentation) |
||||
* @method void am($role) |
||||
* @method void lookForwardTo($achieveValue) |
||||
* @method void comment($description) |
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL) |
||||
* |
||||
* @SuppressWarnings(PHPMD) |
||||
*/ |
||||
class AcceptanceTester extends \Codeception\Actor |
||||
{ |
||||
use _generated\AcceptanceTesterActions; |
||||
|
||||
/** |
||||
* Define custom actions here |
||||
*/ |
||||
} |
@ -0,0 +1,23 @@
|
||||
<?php |
||||
|
||||
|
||||
/** |
||||
* Inherited Methods |
||||
* @method void wantToTest($text) |
||||
* @method void wantTo($text) |
||||
* @method void execute($callable) |
||||
* @method void expectTo($prediction) |
||||
* @method void expect($prediction) |
||||
* @method void amGoingTo($argumentation) |
||||
* @method void am($role) |
||||
* @method void lookForwardTo($achieveValue) |
||||
* @method void comment($description) |
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL) |
||||
* |
||||
* @SuppressWarnings(PHPMD) |
||||
*/ |
||||
class FunctionalTester extends \Codeception\Actor |
||||
{ |
||||
use _generated\FunctionalTesterActions; |
||||
|
||||
} |
@ -0,0 +1,26 @@
|
||||
<?php |
||||
|
||||
|
||||
/** |
||||
* Inherited Methods |
||||
* @method void wantToTest($text) |
||||
* @method void wantTo($text) |
||||
* @method void execute($callable) |
||||
* @method void expectTo($prediction) |
||||
* @method void expect($prediction) |
||||
* @method void amGoingTo($argumentation) |
||||
* @method void am($role) |
||||
* @method void lookForwardTo($achieveValue) |
||||
* @method void comment($description) |
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL) |
||||
* |
||||
* @SuppressWarnings(PHPMD) |
||||
*/ |
||||
class UnitTester extends \Codeception\Actor |
||||
{ |
||||
use _generated\UnitTesterActions; |
||||
|
||||
/** |
||||
* Define custom actions here |
||||
*/ |
||||
} |
@ -0,0 +1,10 @@
|
||||
actor: AcceptanceTester |
||||
modules: |
||||
enabled: |
||||
- WebDriver: |
||||
url: http://127.0.0.1:8080/ |
||||
browser: firefox |
||||
- Yii2: |
||||
part: orm |
||||
entryScript: index-test.php |
||||
cleanup: false |
@ -0,0 +1,12 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Url; |
||||
|
||||
class AboutCest |
||||
{ |
||||
public function ensureThatAboutWorks(AcceptanceTester $I) |
||||
{ |
||||
$I->amOnPage(Url::toRoute('/site/about')); |
||||
$I->see('About', 'h1'); |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Url; |
||||
|
||||
class ContactCest |
||||
{ |
||||
public function _before(\AcceptanceTester $I) |
||||
{ |
||||
$I->amOnPage(Url::toRoute('/site/contact')); |
||||
} |
||||
|
||||
public function contactPageWorks(AcceptanceTester $I) |
||||
{ |
||||
$I->wantTo('ensure that contact page works'); |
||||
$I->see('Contact', 'h1'); |
||||
} |
||||
|
||||
public function contactFormCanBeSubmitted(AcceptanceTester $I) |
||||
{ |
||||
$I->amGoingTo('submit contact form with correct data'); |
||||
$I->fillField('#contactform-name', 'tester'); |
||||
$I->fillField('#contactform-email', 'tester@example.com'); |
||||
$I->fillField('#contactform-subject', 'test subject'); |
||||
$I->fillField('#contactform-body', 'test content'); |
||||
$I->fillField('#contactform-verifycode', 'testme'); |
||||
|
||||
$I->click('contact-button'); |
||||
|
||||
$I->wait(2); // wait for button to be clicked |
||||
|
||||
$I->dontSeeElement('#contact-form'); |
||||
$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Url; |
||||
|
||||
class HomeCest |
||||
{ |
||||
public function ensureThatHomePageWorks(AcceptanceTester $I) |
||||
{ |
||||
$I->amOnPage(Url::toRoute('/site/index')); |
||||
$I->see('My Company'); |
||||
|
||||
$I->seeLink('About'); |
||||
$I->click('About'); |
||||
$I->wait(2); // wait for page to be opened |
||||
|
||||
$I->see('This is the About page.'); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
<?php |
||||
|
||||
use yii\helpers\Url; |
||||
|
||||
class LoginCest |
||||
{ |
||||
public function ensureThatLoginWorks(AcceptanceTester $I) |
||||
{ |
||||
$I->amOnPage(Url::toRoute('/site/login')); |
||||
$I->see('Login', 'h1'); |
||||
|
||||
$I->amGoingTo('try to login with correct credentials'); |
||||
$I->fillField('input[name="LoginForm[username]"]', 'admin'); |
||||
$I->fillField('input[name="LoginForm[password]"]', 'admin'); |
||||
$I->click('login-button'); |
||||
$I->wait(2); // wait for button to be clicked |
||||
|
||||
$I->expectTo('see user info'); |
||||
$I->see('Logout'); |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env php |
||||
<?php |
||||
/** |
||||
* Yii console bootstrap file. |
||||
* |
||||
* @link https://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license https://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
defined('YII_ENV') or define('YII_ENV', 'test'); |
||||
|
||||
require __DIR__ . '/../../vendor/autoload.php'; |
||||
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'; |
||||
|
||||
$config = yii\helpers\ArrayHelper::merge( |
||||
require __DIR__ . '/../../config/console.php', |
||||
[ |
||||
'components' => [ |
||||
'db' => require __DIR__ . '/../../config/test_db.php' |
||||
] |
||||
] |
||||
); |
||||
|
||||
|
||||
$application = new yii\console\Application($config); |
||||
$exitCode = $application->run(); |
||||
exit($exitCode); |
@ -0,0 +1,20 @@
|
||||
@echo off |
||||
|
||||
rem ------------------------------------------------------------- |
||||
rem Yii command line bootstrap script for Windows. |
||||
rem |
||||
rem @author Qiang Xue <qiang.xue@gmail.com> |
||||
rem @link https://www.yiiframework.com/ |
||||
rem @copyright Copyright (c) 2008 Yii Software LLC |
||||
rem @license https://www.yiiframework.com/license/ |
||||
rem ------------------------------------------------------------- |
||||
|
||||
@setlocal |
||||
|
||||
set YII_PATH=%~dp0 |
||||
|
||||
if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe |
||||
|
||||
"%PHP_COMMAND%" "%YII_PATH%yii" %* |
||||
|
||||
@endlocal |
@ -0,0 +1,14 @@
|
||||
# Codeception Test Suite Configuration |
||||
|
||||
# suite for functional (integration) tests. |
||||
# emulate web requests and make application process them. |
||||
# (tip: better to use with frameworks). |
||||
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. |
||||
#basic/web/index.php |
||||
actor: FunctionalTester |
||||
modules: |
||||
enabled: |
||||
- Filesystem |
||||
- Yii2 |
||||
- Asserts |
@ -0,0 +1,57 @@
|
||||
<?php |
||||
|
||||
class ContactFormCest |
||||
{ |
||||
public function _before(\FunctionalTester $I) |
||||
{ |
||||
$I->amOnRoute('site/contact'); |
||||
} |
||||
|
||||
public function openContactPage(\FunctionalTester $I) |
||||
{ |
||||
$I->see('Contact', 'h1'); |
||||
} |
||||
|
||||
public function submitEmptyForm(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#contact-form', []); |
||||
$I->expectTo('see validations errors'); |
||||
$I->see('Contact', 'h1'); |
||||
$I->see('Name cannot be blank'); |
||||
$I->see('Email cannot be blank'); |
||||
$I->see('Subject cannot be blank'); |
||||
$I->see('Body cannot be blank'); |
||||
$I->see('The verification code is incorrect'); |
||||
} |
||||
|
||||
public function submitFormWithIncorrectEmail(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#contact-form', [ |
||||
'ContactForm[name]' => 'tester', |
||||
'ContactForm[email]' => 'tester.email', |
||||
'ContactForm[subject]' => 'test subject', |
||||
'ContactForm[body]' => 'test content', |
||||
'ContactForm[verifyCode]' => 'testme', |
||||
]); |
||||
$I->expectTo('see that email address is wrong'); |
||||
$I->dontSee('Name cannot be blank', '.help-inline'); |
||||
$I->see('Email is not a valid email address.'); |
||||
$I->dontSee('Subject cannot be blank', '.help-inline'); |
||||
$I->dontSee('Body cannot be blank', '.help-inline'); |
||||
$I->dontSee('The verification code is incorrect', '.help-inline'); |
||||
} |
||||
|
||||
public function submitFormSuccessfully(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#contact-form', [ |
||||
'ContactForm[name]' => 'tester', |
||||
'ContactForm[email]' => 'tester@example.com', |
||||
'ContactForm[subject]' => 'test subject', |
||||
'ContactForm[body]' => 'test content', |
||||
'ContactForm[verifyCode]' => 'testme', |
||||
]); |
||||
$I->seeEmailIsSent(); |
||||
$I->dontSeeElement('#contact-form'); |
||||
$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); |
||||
} |
||||
} |
@ -0,0 +1,59 @@
|
||||
<?php |
||||
|
||||
class LoginFormCest |
||||
{ |
||||
public function _before(\FunctionalTester $I) |
||||
{ |
||||
$I->amOnRoute('site/login'); |
||||
} |
||||
|
||||
public function openLoginPage(\FunctionalTester $I) |
||||
{ |
||||
$I->see('Login', 'h1'); |
||||
|
||||
} |
||||
|
||||
// demonstrates `amLoggedInAs` method |
||||
public function internalLoginById(\FunctionalTester $I) |
||||
{ |
||||
$I->amLoggedInAs(100); |
||||
$I->amOnPage('/'); |
||||
$I->see('Logout (admin)'); |
||||
} |
||||
|
||||
// demonstrates `amLoggedInAs` method |
||||
public function internalLoginByInstance(\FunctionalTester $I) |
||||
{ |
||||
$I->amLoggedInAs(\app\models\User::findByUsername('admin')); |
||||
$I->amOnPage('/'); |
||||
$I->see('Logout (admin)'); |
||||
} |
||||
|
||||
public function loginWithEmptyCredentials(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#login-form', []); |
||||
$I->expectTo('see validations errors'); |
||||
$I->see('Username cannot be blank.'); |
||||
$I->see('Password cannot be blank.'); |
||||
} |
||||
|
||||
public function loginWithWrongCredentials(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#login-form', [ |
||||
'LoginForm[username]' => 'admin', |
||||
'LoginForm[password]' => 'wrong', |
||||
]); |
||||
$I->expectTo('see validations errors'); |
||||
$I->see('Incorrect username or password.'); |
||||
} |
||||
|
||||
public function loginSuccessfully(\FunctionalTester $I) |
||||
{ |
||||
$I->submitForm('#login-form', [ |
||||
'LoginForm[username]' => 'admin', |
||||
'LoginForm[password]' => 'admin', |
||||
]); |
||||
$I->see('Logout (admin)'); |
||||
$I->dontSeeElement('form#login-form'); |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
# Codeception Test Suite Configuration |
||||
|
||||
# suite for unit (internal) tests. |
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. |
||||
|
||||
actor: UnitTester |
||||
modules: |
||||
enabled: |
||||
- Asserts |
||||
- Yii2: |
||||
part: [orm, email, fixtures] |
@ -0,0 +1,3 @@
|
||||
<?php |
||||
|
||||
// add unit testing specific bootstrap code here |
@ -0,0 +1,41 @@
|
||||
<?php |
||||
|
||||
namespace tests\unit\models; |
||||
|
||||
use app\models\ContactForm; |
||||
use yii\mail\MessageInterface; |
||||
|
||||
class ContactFormTest extends \Codeception\Test\Unit |
||||
{ |
||||
/** |
||||
* @var \UnitTester |
||||
*/ |
||||
public $tester; |
||||
|
||||
public function testEmailIsSentOnContact() |
||||
{ |
||||
$model = new ContactForm(); |
||||
|
||||
$model->attributes = [ |
||||
'name' => 'Tester', |
||||
'email' => 'tester@example.com', |
||||
'subject' => 'very important letter subject', |
||||
'body' => 'body of current message', |
||||
'verifyCode' => 'testme', |
||||
]; |
||||
|
||||
verify($model->contact('admin@example.com'))->notEmpty(); |
||||
|
||||
// using Yii2 module actions to check email was sent |
||||
$this->tester->seeEmailIsSent(); |
||||
|
||||
/** @var MessageInterface $emailMessage */ |
||||
$emailMessage = $this->tester->grabLastSentEmail(); |
||||
verify($emailMessage)->instanceOf('yii\mail\MessageInterface'); |
||||
verify($emailMessage->getTo())->arrayHasKey('admin@example.com'); |
||||
verify($emailMessage->getFrom())->arrayHasKey('noreply@example.com'); |
||||
verify($emailMessage->getReplyTo())->arrayHasKey('tester@example.com'); |
||||
verify($emailMessage->getSubject())->equals('very important letter subject'); |
||||
verify($emailMessage->toString())->stringContainsString('body of current message'); |
||||
} |
||||
} |
@ -0,0 +1,51 @@
|
||||
<?php |
||||
|
||||
namespace tests\unit\models; |
||||
|
||||
use app\models\LoginForm; |
||||
|
||||
class LoginFormTest extends \Codeception\Test\Unit |
||||
{ |
||||
private $model; |
||||
|
||||
protected function _after() |
||||
{ |
||||
\Yii::$app->user->logout(); |
||||
} |
||||
|
||||
public function testLoginNoUser() |
||||
{ |
||||
$this->model = new LoginForm([ |
||||
'username' => 'not_existing_username', |
||||
'password' => 'not_existing_password', |
||||
]); |
||||
|
||||
verify($this->model->login())->false(); |
||||
verify(\Yii::$app->user->isGuest)->true(); |
||||
} |
||||
|
||||
public function testLoginWrongPassword() |
||||
{ |
||||
$this->model = new LoginForm([ |
||||
'username' => 'demo', |
||||
'password' => 'wrong_password', |
||||
]); |
||||
|
||||
verify($this->model->login())->false(); |
||||
verify(\Yii::$app->user->isGuest)->true(); |
||||
verify($this->model->errors)->arrayHasKey('password'); |
||||
} |
||||
|
||||
public function testLoginCorrect() |
||||
{ |
||||
$this->model = new LoginForm([ |
||||
'username' => 'demo', |
||||
'password' => 'demo', |
||||
]); |
||||
|
||||
verify($this->model->login())->true(); |
||||
verify(\Yii::$app->user->isGuest)->false(); |
||||
verify($this->model->errors)->arrayHasNotKey('password'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,44 @@
|
||||
<?php |
||||
|
||||
namespace tests\unit\models; |
||||
|
||||
use app\models\User; |
||||
|
||||
class UserTest extends \Codeception\Test\Unit |
||||
{ |
||||
public function testFindUserById() |
||||
{ |
||||
verify($user = User::findIdentity(100))->notEmpty(); |
||||
verify($user->username)->equals('admin'); |
||||
|
||||
verify(User::findIdentity(999))->empty(); |
||||
} |
||||
|
||||
public function testFindUserByAccessToken() |
||||
{ |
||||
verify($user = User::findIdentityByAccessToken('100-token'))->notEmpty(); |
||||
verify($user->username)->equals('admin'); |
||||
|
||||
verify(User::findIdentityByAccessToken('non-existing'))->empty(); |
||||
} |
||||
|
||||
public function testFindUserByUsername() |
||||
{ |
||||
verify($user = User::findByUsername('admin'))->notEmpty(); |
||||
verify(User::findByUsername('not-admin'))->empty(); |
||||
} |
||||
|
||||
/** |
||||
* @depends testFindUserByUsername |
||||
*/ |
||||
public function testValidateUser() |
||||
{ |
||||
$user = User::findByUsername('admin'); |
||||
verify($user->validateAuthKey('test100key'))->notEmpty(); |
||||
verify($user->validateAuthKey('test102key'))->empty(); |
||||
|
||||
verify($user->validatePassword('admin'))->notEmpty(); |
||||
verify($user->validatePassword('123456'))->empty(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,261 @@
|
||||
<?php |
||||
|
||||
namespace tests\unit\widgets; |
||||
|
||||
use app\widgets\Alert; |
||||
use Yii; |
||||
|
||||
class AlertTest extends \Codeception\Test\Unit |
||||
{ |
||||
public function testSingleErrorMessage() |
||||
{ |
||||
$message = 'This is an error message'; |
||||
|
||||
Yii::$app->session->setFlash('error', $message); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($message); |
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testMultipleErrorMessages() |
||||
{ |
||||
$firstMessage = 'This is the first error message'; |
||||
$secondMessage = 'This is the second error message'; |
||||
|
||||
Yii::$app->session->setFlash('error', [$firstMessage, $secondMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstMessage); |
||||
verify($renderingResult)->stringContainsString($secondMessage); |
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testSingleDangerMessage() |
||||
{ |
||||
$message = 'This is a danger message'; |
||||
|
||||
Yii::$app->session->setFlash('danger', $message); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($message); |
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testMultipleDangerMessages() |
||||
{ |
||||
$firstMessage = 'This is the first danger message'; |
||||
$secondMessage = 'This is the second danger message'; |
||||
|
||||
Yii::$app->session->setFlash('danger', [$firstMessage, $secondMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstMessage); |
||||
verify($renderingResult)->stringContainsString($secondMessage); |
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testSingleSuccessMessage() |
||||
{ |
||||
$message = 'This is a success message'; |
||||
|
||||
Yii::$app->session->setFlash('success', $message); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($message); |
||||
verify($renderingResult)->stringContainsString('alert-success'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testMultipleSuccessMessages() |
||||
{ |
||||
$firstMessage = 'This is the first danger message'; |
||||
$secondMessage = 'This is the second danger message'; |
||||
|
||||
Yii::$app->session->setFlash('success', [$firstMessage, $secondMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstMessage); |
||||
verify($renderingResult)->stringContainsString($secondMessage); |
||||
verify($renderingResult)->stringContainsString('alert-success'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testSingleInfoMessage() |
||||
{ |
||||
$message = 'This is an info message'; |
||||
|
||||
Yii::$app->session->setFlash('info', $message); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($message); |
||||
verify($renderingResult)->stringContainsString('alert-info'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testMultipleInfoMessages() |
||||
{ |
||||
$firstMessage = 'This is the first info message'; |
||||
$secondMessage = 'This is the second info message'; |
||||
|
||||
Yii::$app->session->setFlash('info', [$firstMessage, $secondMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstMessage); |
||||
verify($renderingResult)->stringContainsString($secondMessage); |
||||
verify($renderingResult)->stringContainsString('alert-info'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testSingleWarningMessage() |
||||
{ |
||||
$message = 'This is a warning message'; |
||||
|
||||
Yii::$app->session->setFlash('warning', $message); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($message); |
||||
verify($renderingResult)->stringContainsString('alert-warning'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
} |
||||
|
||||
public function testMultipleWarningMessages() |
||||
{ |
||||
$firstMessage = 'This is the first warning message'; |
||||
$secondMessage = 'This is the second warning message'; |
||||
|
||||
Yii::$app->session->setFlash('warning', [$firstMessage, $secondMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstMessage); |
||||
verify($renderingResult)->stringContainsString($secondMessage); |
||||
verify($renderingResult)->stringContainsString('alert-warning'); |
||||
|
||||
verify($renderingResult)->stringNotContainsString('alert-danger'); |
||||
verify($renderingResult)->stringNotContainsString('alert-success'); |
||||
verify($renderingResult)->stringNotContainsString('alert-info'); |
||||
} |
||||
|
||||
public function testSingleMixedMessages() { |
||||
$errorMessage = 'This is an error message'; |
||||
$dangerMessage = 'This is a danger message'; |
||||
$successMessage = 'This is a success message'; |
||||
$infoMessage = 'This is a info message'; |
||||
$warningMessage = 'This is a warning message'; |
||||
|
||||
Yii::$app->session->setFlash('error', $errorMessage); |
||||
Yii::$app->session->setFlash('danger', $dangerMessage); |
||||
Yii::$app->session->setFlash('success', $successMessage); |
||||
Yii::$app->session->setFlash('info', $infoMessage); |
||||
Yii::$app->session->setFlash('warning', $warningMessage); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($errorMessage); |
||||
verify($renderingResult)->stringContainsString($dangerMessage); |
||||
verify($renderingResult)->stringContainsString($successMessage); |
||||
verify($renderingResult)->stringContainsString($infoMessage); |
||||
verify($renderingResult)->stringContainsString($warningMessage); |
||||
|
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
verify($renderingResult)->stringContainsString('alert-success'); |
||||
verify($renderingResult)->stringContainsString('alert-info'); |
||||
verify($renderingResult)->stringContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testMultipleMixedMessages() { |
||||
$firstErrorMessage = 'This is the first error message'; |
||||
$secondErrorMessage = 'This is the second error message'; |
||||
$firstDangerMessage = 'This is the first danger message'; |
||||
$secondDangerMessage = 'This is the second'; |
||||
$firstSuccessMessage = 'This is the first success message'; |
||||
$secondSuccessMessage = 'This is the second success message'; |
||||
$firstInfoMessage = 'This is the first info message'; |
||||
$secondInfoMessage = 'This is the second info message'; |
||||
$firstWarningMessage = 'This is the first warning message'; |
||||
$secondWarningMessage = 'This is the second warning message'; |
||||
|
||||
Yii::$app->session->setFlash('error', [$firstErrorMessage, $secondErrorMessage]); |
||||
Yii::$app->session->setFlash('danger', [$firstDangerMessage, $secondDangerMessage]); |
||||
Yii::$app->session->setFlash('success', [$firstSuccessMessage, $secondSuccessMessage]); |
||||
Yii::$app->session->setFlash('info', [$firstInfoMessage, $secondInfoMessage]); |
||||
Yii::$app->session->setFlash('warning', [$firstWarningMessage, $secondWarningMessage]); |
||||
|
||||
$renderingResult = Alert::widget(); |
||||
|
||||
verify($renderingResult)->stringContainsString($firstErrorMessage); |
||||
verify($renderingResult)->stringContainsString($secondErrorMessage); |
||||
verify($renderingResult)->stringContainsString($firstDangerMessage); |
||||
verify($renderingResult)->stringContainsString($secondDangerMessage); |
||||
verify($renderingResult)->stringContainsString($firstSuccessMessage); |
||||
verify($renderingResult)->stringContainsString($secondSuccessMessage); |
||||
verify($renderingResult)->stringContainsString($firstInfoMessage); |
||||
verify($renderingResult)->stringContainsString($secondInfoMessage); |
||||
verify($renderingResult)->stringContainsString($firstWarningMessage); |
||||
verify($renderingResult)->stringContainsString($secondWarningMessage); |
||||
|
||||
verify($renderingResult)->stringContainsString('alert-danger'); |
||||
verify($renderingResult)->stringContainsString('alert-success'); |
||||
verify($renderingResult)->stringContainsString('alert-info'); |
||||
verify($renderingResult)->stringContainsString('alert-warning'); |
||||
} |
||||
|
||||
public function testFlashIntegrity() |
||||
{ |
||||
$errorMessage = 'This is an error message'; |
||||
$unrelatedMessage = 'This is a message that is not related to the alert widget'; |
||||
|
||||
Yii::$app->session->setFlash('error', $errorMessage); |
||||
Yii::$app->session->setFlash('unrelated', $unrelatedMessage); |
||||
|
||||
Alert::widget(); |
||||
|
||||
// Simulate redirect |
||||
Yii::$app->session->close(); |
||||
Yii::$app->session->open(); |
||||
|
||||
verify(Yii::$app->session->getFlash('error'))->empty(); |
||||
verify(Yii::$app->session->getFlash('unrelated'))->equals($unrelatedMessage); |
||||
} |
||||
} |
@ -0,0 +1,6 @@
|
||||
<?php |
||||
$html = file_get_contents(Yii::getAlias('@webroot/index.html')); |
||||
//$html = str_replace('http://localhost:9093', '/', $html); |
||||
?> |
||||
|
||||
<?= $html ?> |
@ -0,0 +1,18 @@
|
||||
<?php |
||||
|
||||
/** @var yii\web\View $this */ |
||||
|
||||
use yii\helpers\Html; |
||||
|
||||
$this->title = 'About'; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="site-about"> |
||||
<h1><?= Html::encode($this->title) ?></h1>
|
||||
|
||||
<p> |
||||
This is the About page. You may modify the following file to customize its content: |
||||
</p> |
||||
|
||||
<code><?= __FILE__ ?></code>
|
||||
</div> |
@ -0,0 +1,68 @@
|
||||
<?php |
||||
|
||||
/** @var yii\web\View $this */ |
||||
/** @var yii\bootstrap5\ActiveForm $form */ |
||||
/** @var app\models\ContactForm $model */ |
||||
|
||||
use yii\bootstrap5\ActiveForm; |
||||
use yii\bootstrap5\Html; |
||||
use yii\captcha\Captcha; |
||||
|
||||
$this->title = 'Contact'; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="site-contact"> |
||||
<h1><?= Html::encode($this->title) ?></h1>
|
||||
|
||||
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?> |
||||
|
||||
<div class="alert alert-success"> |
||||
Thank you for contacting us. We will respond to you as soon as possible. |
||||
</div> |
||||
|
||||
<p> |
||||
Note that if you turn on the Yii debugger, you should be able |
||||
to view the mail message on the mail panel of the debugger. |
||||
<?php if (Yii::$app->mailer->useFileTransport): ?> |
||||
Because the application is in development mode, the email is not sent but saved as |
||||
a file under <code><?= Yii::getAlias(Yii::$app->mailer->fileTransportPath) ?></code>.
|
||||
Please configure the <code>useFileTransport</code> property of the <code>mail</code> |
||||
application component to be false to enable email sending. |
||||
<?php endif; ?> |
||||
</p> |
||||
|
||||
<?php else: ?> |
||||
|
||||
<p> |
||||
If you have business inquiries or other questions, please fill out the following form to contact us. |
||||
Thank you. |
||||
</p> |
||||
|
||||
<div class="row"> |
||||
<div class="col-lg-5"> |
||||
|
||||
<?php $form = ActiveForm::begin(['id' => 'contact-form']); ?> |
||||
|
||||
<?= $form->field($model, 'name')->textInput(['autofocus' => true]) ?> |
||||
|
||||
<?= $form->field($model, 'email') ?> |
||||
|
||||
<?= $form->field($model, 'subject') ?> |
||||
|
||||
<?= $form->field($model, 'body')->textarea(['rows' => 6]) ?> |
||||
|
||||
<?= $form->field($model, 'verifyCode')->widget(Captcha::class, [ |
||||
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>', |
||||
]) ?> |
||||
|
||||
<div class="form-group"> |
||||
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<?php endif; ?> |
||||
</div> |
@ -0,0 +1,27 @@
|
||||
<?php |
||||
|
||||
/** @var yii\web\View $this */ |
||||
/** @var string $name */ |
||||
/** @var string $message */ |
||||
/** @var Exception$exception */ |
||||
|
||||
use yii\helpers\Html; |
||||
|
||||
$this->title = $name; |
||||
?> |
||||
<div class="site-error"> |
||||
|
||||
<h1><?= Html::encode($this->title) ?></h1>
|
||||
|
||||
<div class="alert alert-danger"> |
||||
<?= nl2br(Html::encode($message)) ?> |
||||
</div> |
||||
|
||||
<p> |
||||
The above error occurred while the Web server was processing your request. |
||||
</p> |
||||
<p> |
||||
Please contact us if you think this is a server error. Thank you. |
||||
</p> |
||||
|
||||
</div> |
@ -0,0 +1,53 @@
|
||||
<?php |
||||
|
||||
/** @var yii\web\View $this */ |
||||
|
||||
$this->title = 'My Yii Application'; |
||||
?> |
||||
<div class="site-index"> |
||||
|
||||
<div class="jumbotron text-center bg-transparent mt-5 mb-5"> |
||||
<h1 class="display-4">Congratulations!</h1> |
||||
|
||||
<p class="lead">You have successfully created your Yii-powered application.</p> |
||||
|
||||
<p><a class="btn btn-lg btn-success" href="https://www.yiiframework.com">Get started with Yii</a></p> |
||||
</div> |
||||
|
||||
<div class="body-content"> |
||||
|
||||
<div class="row"> |
||||
<div class="col-lg-4 mb-3"> |
||||
<h2>Heading</h2> |
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et |
||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip |
||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu |
||||
fugiat nulla pariatur.</p> |
||||
|
||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/doc/">Yii Documentation »</a></p> |
||||
</div> |
||||
<div class="col-lg-4 mb-3"> |
||||
<h2>Heading</h2> |
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et |
||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip |
||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu |
||||
fugiat nulla pariatur.</p> |
||||
|
||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/forum/">Yii Forum »</a></p> |
||||
</div> |
||||
<div class="col-lg-4"> |
||||
<h2>Heading</h2> |
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et |
||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip |
||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu |
||||
fugiat nulla pariatur.</p> |
||||
|
||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/extensions/">Yii Extensions »</a></p> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
@ -0,0 +1,55 @@
|
||||
<?php |
||||
|
||||
/** @var yii\web\View $this */ |
||||
/** @var yii\bootstrap5\ActiveForm $form */ |
||||
|
||||
/** @var app\models\LoginForm $model */ |
||||
|
||||
use yii\bootstrap5\ActiveForm; |
||||
use yii\bootstrap5\Html; |
||||
|
||||
$this->title = 'Login'; |
||||
$this->params['breadcrumbs'][] = $this->title; |
||||
?> |
||||
<div class="site-login"> |
||||
<h1><?= Html::encode($this->title) ?></h1>
|
||||
|
||||
<p>Please fill out the following fields to login:</p> |
||||
|
||||
<div class="row"> |
||||
<div class="col-lg-5"> |
||||
|
||||
<?php $form = ActiveForm::begin([ |
||||
'id' => 'login-form', |
||||
'fieldConfig' => [ |
||||
'template' => "{label}\n{input}\n{error}", |
||||
'labelOptions' => ['class' => 'col-lg-1 col-form-label mr-lg-3'], |
||||
'inputOptions' => ['class' => 'col-lg-3 form-control'], |
||||
'errorOptions' => ['class' => 'col-lg-7 invalid-feedback'], |
||||
], |
||||
]); ?> |
||||
|
||||
<?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?> |
||||
|
||||
<?= $form->field($model, 'password')->passwordInput() ?> |
||||
|
||||
<?= $form->field($model, 'rememberMe')->checkbox([ |
||||
'template' => "<div class=\"custom-control custom-checkbox\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>", |
||||
]) ?> |
||||
|
||||
<div class="form-group"> |
||||
<div> |
||||
<?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php ActiveForm::end(); ?> |
||||
|
||||
<div style="color:#999;"> |
||||
You may login with <strong>admin/admin</strong> or <strong>demo/demo</strong>.<br> |
||||
To modify the username/password, please check out the code <code>app\models\User::$users</code>. |
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,24 @@
|
||||
# Logs |
||||
logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
pnpm-debug.log* |
||||
lerna-debug.log* |
||||
|
||||
node_modules |
||||
dist |
||||
dist-ssr |
||||
*.local |
||||
|
||||
# Editor directories and files |
||||
.vscode/* |
||||
!.vscode/extensions.json |
||||
.idea |
||||
.DS_Store |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.sw? |
@ -0,0 +1,3 @@
|
||||
{ |
||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] |
||||
} |
@ -0,0 +1,7 @@
|
||||
# Vue 3 + Vite |
||||
|
||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. |
||||
|
||||
## Recommended IDE Setup |
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). |
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>Vite + Vue</title> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main.js"></script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,798 @@
|
||||
{ |
||||
"name": "yvv", |
||||
"version": "0.0.0", |
||||
"lockfileVersion": 3, |
||||
"requires": true, |
||||
"packages": { |
||||
"": { |
||||
"name": "yvv", |
||||
"version": "0.0.0", |
||||
"dependencies": { |
||||
"axios": "^1.4.0", |
||||
"vue": "^3.2.47" |
||||
}, |
||||
"devDependencies": { |
||||
"@vitejs/plugin-vue": "^4.1.0", |
||||
"vite": "^4.3.9" |
||||
} |
||||
}, |
||||
"node_modules/@babel/parser": { |
||||
"version": "7.22.5", |
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", |
||||
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", |
||||
"bin": { |
||||
"parser": "bin/babel-parser.js" |
||||
}, |
||||
"engines": { |
||||
"node": ">=6.0.0" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/android-arm": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", |
||||
"integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", |
||||
"cpu": [ |
||||
"arm" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"android" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/android-arm64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", |
||||
"integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", |
||||
"cpu": [ |
||||
"arm64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"android" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/android-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", |
||||
"integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"android" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/darwin-arm64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", |
||||
"integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", |
||||
"cpu": [ |
||||
"arm64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"darwin" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/darwin-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", |
||||
"integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"darwin" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/freebsd-arm64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", |
||||
"integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", |
||||
"cpu": [ |
||||
"arm64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"freebsd" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/freebsd-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", |
||||
"integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"freebsd" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-arm": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", |
||||
"integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", |
||||
"cpu": [ |
||||
"arm" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-arm64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", |
||||
"integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", |
||||
"cpu": [ |
||||
"arm64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-ia32": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", |
||||
"integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", |
||||
"cpu": [ |
||||
"ia32" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-loong64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", |
||||
"integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", |
||||
"cpu": [ |
||||
"loong64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-mips64el": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", |
||||
"integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", |
||||
"cpu": [ |
||||
"mips64el" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-ppc64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", |
||||
"integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", |
||||
"cpu": [ |
||||
"ppc64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-riscv64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", |
||||
"integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", |
||||
"cpu": [ |
||||
"riscv64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-s390x": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", |
||||
"integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", |
||||
"cpu": [ |
||||
"s390x" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/linux-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", |
||||
"integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"linux" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/netbsd-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", |
||||
"integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"netbsd" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/openbsd-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", |
||||
"integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"openbsd" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/sunos-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", |
||||
"integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"sunos" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/win32-arm64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", |
||||
"integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", |
||||
"cpu": [ |
||||
"arm64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"win32" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/win32-ia32": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", |
||||
"integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", |
||||
"cpu": [ |
||||
"ia32" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"win32" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@esbuild/win32-x64": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", |
||||
"integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", |
||||
"cpu": [ |
||||
"x64" |
||||
], |
||||
"dev": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"win32" |
||||
], |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/@jridgewell/sourcemap-codec": { |
||||
"version": "1.4.15", |
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", |
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" |
||||
}, |
||||
"node_modules/@vitejs/plugin-vue": { |
||||
"version": "4.2.3", |
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.3.tgz", |
||||
"integrity": "sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==", |
||||
"dev": true, |
||||
"engines": { |
||||
"node": "^14.18.0 || >=16.0.0" |
||||
}, |
||||
"peerDependencies": { |
||||
"vite": "^4.0.0", |
||||
"vue": "^3.2.25" |
||||
} |
||||
}, |
||||
"node_modules/@vue/compiler-core": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", |
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", |
||||
"dependencies": { |
||||
"@babel/parser": "^7.21.3", |
||||
"@vue/shared": "3.3.4", |
||||
"estree-walker": "^2.0.2", |
||||
"source-map-js": "^1.0.2" |
||||
} |
||||
}, |
||||
"node_modules/@vue/compiler-dom": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", |
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", |
||||
"dependencies": { |
||||
"@vue/compiler-core": "3.3.4", |
||||
"@vue/shared": "3.3.4" |
||||
} |
||||
}, |
||||
"node_modules/@vue/compiler-sfc": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", |
||||
"integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", |
||||
"dependencies": { |
||||
"@babel/parser": "^7.20.15", |
||||
"@vue/compiler-core": "3.3.4", |
||||
"@vue/compiler-dom": "3.3.4", |
||||
"@vue/compiler-ssr": "3.3.4", |
||||
"@vue/reactivity-transform": "3.3.4", |
||||
"@vue/shared": "3.3.4", |
||||
"estree-walker": "^2.0.2", |
||||
"magic-string": "^0.30.0", |
||||
"postcss": "^8.1.10", |
||||
"source-map-js": "^1.0.2" |
||||
} |
||||
}, |
||||
"node_modules/@vue/compiler-ssr": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", |
||||
"integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", |
||||
"dependencies": { |
||||
"@vue/compiler-dom": "3.3.4", |
||||
"@vue/shared": "3.3.4" |
||||
} |
||||
}, |
||||
"node_modules/@vue/reactivity": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", |
||||
"integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", |
||||
"dependencies": { |
||||
"@vue/shared": "3.3.4" |
||||
} |
||||
}, |
||||
"node_modules/@vue/reactivity-transform": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", |
||||
"integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", |
||||
"dependencies": { |
||||
"@babel/parser": "^7.20.15", |
||||
"@vue/compiler-core": "3.3.4", |
||||
"@vue/shared": "3.3.4", |
||||
"estree-walker": "^2.0.2", |
||||
"magic-string": "^0.30.0" |
||||
} |
||||
}, |
||||
"node_modules/@vue/runtime-core": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", |
||||
"integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", |
||||
"dependencies": { |
||||
"@vue/reactivity": "3.3.4", |
||||
"@vue/shared": "3.3.4" |
||||
} |
||||
}, |
||||
"node_modules/@vue/runtime-dom": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", |
||||
"integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", |
||||
"dependencies": { |
||||
"@vue/runtime-core": "3.3.4", |
||||
"@vue/shared": "3.3.4", |
||||
"csstype": "^3.1.1" |
||||
} |
||||
}, |
||||
"node_modules/@vue/server-renderer": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", |
||||
"integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", |
||||
"dependencies": { |
||||
"@vue/compiler-ssr": "3.3.4", |
||||
"@vue/shared": "3.3.4" |
||||
}, |
||||
"peerDependencies": { |
||||
"vue": "3.3.4" |
||||
} |
||||
}, |
||||
"node_modules/@vue/shared": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", |
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" |
||||
}, |
||||
"node_modules/asynckit": { |
||||
"version": "0.4.0", |
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", |
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" |
||||
}, |
||||
"node_modules/axios": { |
||||
"version": "1.4.0", |
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", |
||||
"integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", |
||||
"dependencies": { |
||||
"follow-redirects": "^1.15.0", |
||||
"form-data": "^4.0.0", |
||||
"proxy-from-env": "^1.1.0" |
||||
} |
||||
}, |
||||
"node_modules/combined-stream": { |
||||
"version": "1.0.8", |
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", |
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", |
||||
"dependencies": { |
||||
"delayed-stream": "~1.0.0" |
||||
}, |
||||
"engines": { |
||||
"node": ">= 0.8" |
||||
} |
||||
}, |
||||
"node_modules/csstype": { |
||||
"version": "3.1.2", |
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", |
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" |
||||
}, |
||||
"node_modules/delayed-stream": { |
||||
"version": "1.0.0", |
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", |
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", |
||||
"engines": { |
||||
"node": ">=0.4.0" |
||||
} |
||||
}, |
||||
"node_modules/esbuild": { |
||||
"version": "0.17.19", |
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", |
||||
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", |
||||
"dev": true, |
||||
"hasInstallScript": true, |
||||
"bin": { |
||||
"esbuild": "bin/esbuild" |
||||
}, |
||||
"engines": { |
||||
"node": ">=12" |
||||
}, |
||||
"optionalDependencies": { |
||||
"@esbuild/android-arm": "0.17.19", |
||||
"@esbuild/android-arm64": "0.17.19", |
||||
"@esbuild/android-x64": "0.17.19", |
||||
"@esbuild/darwin-arm64": "0.17.19", |
||||
"@esbuild/darwin-x64": "0.17.19", |
||||
"@esbuild/freebsd-arm64": "0.17.19", |
||||
"@esbuild/freebsd-x64": "0.17.19", |
||||
"@esbuild/linux-arm": "0.17.19", |
||||
"@esbuild/linux-arm64": "0.17.19", |
||||
"@esbuild/linux-ia32": "0.17.19", |
||||
"@esbuild/linux-loong64": "0.17.19", |
||||
"@esbuild/linux-mips64el": "0.17.19", |
||||
"@esbuild/linux-ppc64": "0.17.19", |
||||
"@esbuild/linux-riscv64": "0.17.19", |
||||
"@esbuild/linux-s390x": "0.17.19", |
||||
"@esbuild/linux-x64": "0.17.19", |
||||
"@esbuild/netbsd-x64": "0.17.19", |
||||
"@esbuild/openbsd-x64": "0.17.19", |
||||
"@esbuild/sunos-x64": "0.17.19", |
||||
"@esbuild/win32-arm64": "0.17.19", |
||||
"@esbuild/win32-ia32": "0.17.19", |
||||
"@esbuild/win32-x64": "0.17.19" |
||||
} |
||||
}, |
||||
"node_modules/estree-walker": { |
||||
"version": "2.0.2", |
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", |
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" |
||||
}, |
||||
"node_modules/follow-redirects": { |
||||
"version": "1.15.2", |
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", |
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", |
||||
"funding": [ |
||||
{ |
||||
"type": "individual", |
||||
"url": "https://github.com/sponsors/RubenVerborgh" |
||||
} |
||||
], |
||||
"engines": { |
||||
"node": ">=4.0" |
||||
}, |
||||
"peerDependenciesMeta": { |
||||
"debug": { |
||||
"optional": true |
||||
} |
||||
} |
||||
}, |
||||
"node_modules/form-data": { |
||||
"version": "4.0.0", |
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", |
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", |
||||
"dependencies": { |
||||
"asynckit": "^0.4.0", |
||||
"combined-stream": "^1.0.8", |
||||
"mime-types": "^2.1.12" |
||||
}, |
||||
"engines": { |
||||
"node": ">= 6" |
||||
} |
||||
}, |
||||
"node_modules/fsevents": { |
||||
"version": "2.3.2", |
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", |
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", |
||||
"dev": true, |
||||
"hasInstallScript": true, |
||||
"optional": true, |
||||
"os": [ |
||||
"darwin" |
||||
], |
||||
"engines": { |
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" |
||||
} |
||||
}, |
||||
"node_modules/magic-string": { |
||||
"version": "0.30.0", |
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", |
||||
"integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", |
||||
"dependencies": { |
||||
"@jridgewell/sourcemap-codec": "^1.4.13" |
||||
}, |
||||
"engines": { |
||||
"node": ">=12" |
||||
} |
||||
}, |
||||
"node_modules/mime-db": { |
||||
"version": "1.52.0", |
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", |
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", |
||||
"engines": { |
||||
"node": ">= 0.6" |
||||
} |
||||
}, |
||||
"node_modules/mime-types": { |
||||
"version": "2.1.35", |
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", |
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", |
||||
"dependencies": { |
||||
"mime-db": "1.52.0" |
||||
}, |
||||
"engines": { |
||||
"node": ">= 0.6" |
||||
} |
||||
}, |
||||
"node_modules/nanoid": { |
||||
"version": "3.3.6", |
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", |
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", |
||||
"funding": [ |
||||
{ |
||||
"type": "github", |
||||
"url": "https://github.com/sponsors/ai" |
||||
} |
||||
], |
||||
"bin": { |
||||
"nanoid": "bin/nanoid.cjs" |
||||
}, |
||||
"engines": { |
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" |
||||
} |
||||
}, |
||||
"node_modules/picocolors": { |
||||
"version": "1.0.0", |
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", |
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" |
||||
}, |
||||
"node_modules/postcss": { |
||||
"version": "8.4.24", |
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", |
||||
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", |
||||
"funding": [ |
||||
{ |
||||
"type": "opencollective", |
||||
"url": "https://opencollective.com/postcss/" |
||||
}, |
||||
{ |
||||
"type": "tidelift", |
||||
"url": "https://tidelift.com/funding/github/npm/postcss" |
||||
}, |
||||
{ |
||||
"type": "github", |
||||
"url": "https://github.com/sponsors/ai" |
||||
} |
||||
], |
||||
"dependencies": { |
||||
"nanoid": "^3.3.6", |
||||
"picocolors": "^1.0.0", |
||||
"source-map-js": "^1.0.2" |
||||
}, |
||||
"engines": { |
||||
"node": "^10 || ^12 || >=14" |
||||
} |
||||
}, |
||||
"node_modules/proxy-from-env": { |
||||
"version": "1.1.0", |
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", |
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" |
||||
}, |
||||
"node_modules/rollup": { |
||||
"version": "3.24.1", |
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.24.1.tgz", |
||||
"integrity": "sha512-REHe5dx30ERBRFS0iENPHy+t6wtSEYkjrhwNsLyh3qpRaZ1+aylvMUdMBUHWUD/RjjLmLzEvY8Z9XRlpcdIkHA==", |
||||
"dev": true, |
||||
"bin": { |
||||
"rollup": "dist/bin/rollup" |
||||
}, |
||||
"engines": { |
||||
"node": ">=14.18.0", |
||||
"npm": ">=8.0.0" |
||||
}, |
||||
"optionalDependencies": { |
||||
"fsevents": "~2.3.2" |
||||
} |
||||
}, |
||||
"node_modules/source-map-js": { |
||||
"version": "1.0.2", |
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", |
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", |
||||
"engines": { |
||||
"node": ">=0.10.0" |
||||
} |
||||
}, |
||||
"node_modules/vite": { |
||||
"version": "4.3.9", |
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", |
||||
"integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", |
||||
"dev": true, |
||||
"dependencies": { |
||||
"esbuild": "^0.17.5", |
||||
"postcss": "^8.4.23", |
||||
"rollup": "^3.21.0" |
||||
}, |
||||
"bin": { |
||||
"vite": "bin/vite.js" |
||||
}, |
||||
"engines": { |
||||
"node": "^14.18.0 || >=16.0.0" |
||||
}, |
||||
"optionalDependencies": { |
||||
"fsevents": "~2.3.2" |
||||
}, |
||||
"peerDependencies": { |
||||
"@types/node": ">= 14", |
||||
"less": "*", |
||||
"sass": "*", |
||||
"stylus": "*", |
||||
"sugarss": "*", |
||||
"terser": "^5.4.0" |
||||
}, |
||||
"peerDependenciesMeta": { |
||||
"@types/node": { |
||||
"optional": true |
||||
}, |
||||
"less": { |
||||
"optional": true |
||||
}, |
||||
"sass": { |
||||
"optional": true |
||||
}, |
||||
"stylus": { |
||||
"optional": true |
||||
}, |
||||
"sugarss": { |
||||
"optional": true |
||||
}, |
||||
"terser": { |
||||
"optional": true |
||||
} |
||||
} |
||||
}, |
||||
"node_modules/vue": { |
||||
"version": "3.3.4", |
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", |
||||
"integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", |
||||
"dependencies": { |
||||
"@vue/compiler-dom": "3.3.4", |
||||
"@vue/compiler-sfc": "3.3.4", |
||||
"@vue/runtime-dom": "3.3.4", |
||||
"@vue/server-renderer": "3.3.4", |
||||
"@vue/shared": "3.3.4" |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
{ |
||||
"name": "yvv", |
||||
"private": true, |
||||
"version": "0.0.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"build": "vite build", |
||||
"preview": "vite preview" |
||||
}, |
||||
"dependencies": { |
||||
"axios": "^1.4.0", |
||||
"vue": "^3.2.47" |
||||
}, |
||||
"devDependencies": { |
||||
"@vitejs/plugin-vue": "^4.1.0", |
||||
"vite": "^4.3.9" |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
<script setup> |
||||
import TestService from "./services/test.service.js" |
||||
import {ref} from "vue"; |
||||
|
||||
const records = ref([]) |
||||
|
||||
TestService.getRecords().then(response => { |
||||
records.value = response.data |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<div> |
||||
<a href="https://vitejs.dev" target="_blank"> |
||||
<img src="/vite.svg" class="logo" alt="Vite logo" /> |
||||
</a> |
||||
<a href="https://vuejs.org/" target="_blank"> |
||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> |
||||
</a> |
||||
</div> |
||||
|
||||
<hr> |
||||
<div v-for="record in records">{{record}}</div> |
||||
<hr> |
||||
|
||||
</template> |
||||
|
||||
<style scoped> |
||||
.logo { |
||||
height: 6em; |
||||
padding: 1.5em; |
||||
will-change: filter; |
||||
transition: filter 300ms; |
||||
} |
||||
.logo:hover { |
||||
filter: drop-shadow(0 0 2em #646cffaa); |
||||
} |
||||
.logo.vue:hover { |
||||
filter: drop-shadow(0 0 2em #42b883aa); |
||||
} |
||||
</style> |
@ -0,0 +1,7 @@
|
||||
import { createApp } from 'vue' |
||||
import './style.css' |
||||
import App from './App.vue' |
||||
|
||||
const app = createApp(App) |
||||
|
||||
app.mount('#app') |
@ -0,0 +1,9 @@
|
||||
import axios from "axios" |
||||
|
||||
const httpClient = axios.create({ |
||||
baseURL: '/api', |
||||
timeout: 15000, |
||||
headers: {"Content-Type": "application/json"}, |
||||
}) |
||||
|
||||
export default httpClient |
@ -0,0 +1,9 @@
|
||||
import httpClient from './http.client.js' |
||||
|
||||
class TestService { |
||||
getRecords() { |
||||
return httpClient.get('/test/index').then() |
||||
} |
||||
} |
||||
|
||||
export default new TestService() |
@ -0,0 +1,89 @@
|
||||
:root { |
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; |
||||
line-height: 1.5; |
||||
font-weight: 400; |
||||
|
||||
color-scheme: light dark; |
||||
color: rgba(255, 255, 255, 0.87); |
||||
background-color: #242424; |
||||
|
||||
font-synthesis: none; |
||||
text-rendering: optimizeLegibility; |
||||
-webkit-font-smoothing: antialiased; |
||||
-moz-osx-font-smoothing: grayscale; |
||||
-webkit-text-size-adjust: 100%; |
||||
} |
||||
|
||||
a { |
||||
font-weight: 500; |
||||
color: #646cff; |
||||
text-decoration: inherit; |
||||
} |
||||
a:hover { |
||||
color: #535bf2; |
||||
} |
||||
|
||||
a { |
||||
font-weight: 500; |
||||
color: #646cff; |
||||
text-decoration: inherit; |
||||
} |
||||
a:hover { |
||||
color: #535bf2; |
||||
} |
||||
|
||||
body { |
||||
margin: 0; |
||||
display: flex; |
||||
place-items: center; |
||||
min-width: 320px; |
||||
min-height: 100vh; |
||||
} |
||||
|
||||
h1 { |
||||
font-size: 3.2em; |
||||
line-height: 1.1; |
||||
} |
||||
|
||||
button { |
||||
border-radius: 8px; |
||||
border: 1px solid transparent; |
||||
padding: 0.6em 1.2em; |
||||
font-size: 1em; |
||||
font-weight: 500; |
||||
font-family: inherit; |
||||
background-color: #1a1a1a; |
||||
cursor: pointer; |
||||
transition: border-color 0.25s; |
||||
} |
||||
button:hover { |
||||
border-color: #646cff; |
||||
} |
||||
button:focus, |
||||
button:focus-visible { |
||||
outline: 4px auto -webkit-focus-ring-color; |
||||
} |
||||
|
||||
.card { |
||||
padding: 2em; |
||||
} |
||||
|
||||
#app { |
||||
max-width: 1280px; |
||||
margin: 0 auto; |
||||
padding: 2rem; |
||||
text-align: center; |
||||
} |
||||
|
||||
@media (prefers-color-scheme: light) { |
||||
:root { |
||||
color: #213547; |
||||
background-color: #ffffff; |
||||
} |
||||
a:hover { |
||||
color: #747bff; |
||||
} |
||||
button { |
||||
background-color: #f9f9f9; |
||||
} |
||||
} |
@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'vite' |
||||
import vue from '@vitejs/plugin-vue' |
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({ |
||||
server: { |
||||
proxy: { |
||||
"/api": { |
||||
target: "http://localhost:8001", |
||||
changeOrigin: true, |
||||
secure: false, |
||||
ws: true, |
||||
}, |
||||
}, |
||||
}, |
||||
build: { |
||||
outDir: '../web', |
||||
}, |
||||
plugins: [vue()], |
||||
}) |
@ -0,0 +1,4 @@
|
||||
RewriteEngine on |
||||
RewriteCond %{REQUEST_FILENAME} !-d |
||||
RewriteCond %{REQUEST_FILENAME} !-f |
||||
RewriteRule . index.php [L] |
@ -0,0 +1 @@
|
||||
:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;display:flex;place-items:center;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}.card{padding:2em}#app{max-width:1280px;margin:0 auto;padding:2rem;text-align:center}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}.logo[data-v-1d75a1d6]{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo[data-v-1d75a1d6]:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.vue[data-v-1d75a1d6]:hover{filter:drop-shadow(0 0 2em #42b883aa)} |
@ -0,0 +1 @@
|
||||
:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;display:flex;place-items:center;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}.card{padding:2em}#app{max-width:1280px;margin:0 auto;padding:2rem;text-align:center}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}.logo[data-v-46b2d863]{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo[data-v-46b2d863]:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.vue[data-v-46b2d863]:hover{filter:drop-shadow(0 0 2em #42b883aa)} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 318 B |
@ -0,0 +1,16 @@
|
||||
<?php |
||||
|
||||
// NOTE: Make sure this file is not accessible when deployed to production |
||||
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) { |
||||
die('You are not allowed to access this file.'); |
||||
} |
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
defined('YII_ENV') or define('YII_ENV', 'test'); |
||||
|
||||
require __DIR__ . '/../vendor/autoload.php'; |
||||
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; |
||||
|
||||
$config = require __DIR__ . '/../config/test.php'; |
||||
|
||||
(new yii\web\Application($config))->run(); |
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>Vite + Vue</title> |
||||
<script type="module" crossorigin src="/assets/index-e54ab67f.js"></script> |
||||
<link rel="stylesheet" href="/assets/index-c05be89e.css"> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,12 @@
|
||||
<?php |
||||
|
||||
// comment out the following two lines when deployed to production |
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
defined('YII_ENV') or define('YII_ENV', 'dev'); |
||||
|
||||
require __DIR__ . '/../vendor/autoload.php'; |
||||
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php'; |
||||
|
||||
$config = require __DIR__ . '/../config/web.php'; |
||||
|
||||
(new yii\web\Application($config))->run(); |
@ -0,0 +1,73 @@
|
||||
<?php |
||||
|
||||
namespace app\widgets; |
||||
|
||||
use Yii; |
||||
|
||||
/** |
||||
* Alert widget renders a message from session flash. All flash messages are displayed |
||||
* in the sequence they were assigned using setFlash. You can set message as following: |
||||
* |
||||
* ```php |
||||
* Yii::$app->session->setFlash('error', 'This is the message'); |
||||
* Yii::$app->session->setFlash('success', 'This is the message'); |
||||
* Yii::$app->session->setFlash('info', 'This is the message'); |
||||
* ``` |
||||
* |
||||
* Multiple messages could be set as follows: |
||||
* |
||||
* ```php |
||||
* Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']); |
||||
* ``` |
||||
* |
||||
* @author Kartik Visweswaran <kartikv2@gmail.com> |
||||
* @author Alexander Makarov <sam@rmcreative.ru> |
||||
*/ |
||||
class Alert extends \yii\bootstrap5\Widget |
||||
{ |
||||
/** |
||||
* @var array the alert types configuration for the flash messages. |
||||
* This array is setup as $key => $value, where: |
||||
* - key: the name of the session flash variable |
||||
* - value: the bootstrap alert type (i.e. danger, success, info, warning) |
||||
*/ |
||||
public $alertTypes = [ |
||||
'error' => 'alert-danger', |
||||
'danger' => 'alert-danger', |
||||
'success' => 'alert-success', |
||||
'info' => 'alert-info', |
||||
'warning' => 'alert-warning' |
||||
]; |
||||
/** |
||||
* @var array the options for rendering the close button tag. |
||||
* Array will be passed to [[\yii\bootstrap\Alert::closeButton]]. |
||||
*/ |
||||
public $closeButton = []; |
||||
|
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function run() |
||||
{ |
||||
$session = Yii::$app->session; |
||||
$appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; |
||||
|
||||
foreach (array_keys($this->alertTypes) as $type) { |
||||
$flash = $session->getFlash($type); |
||||
|
||||
foreach ((array) $flash as $i => $message) { |
||||
echo \yii\bootstrap5\Alert::widget([ |
||||
'body' => $message, |
||||
'closeButton' => $this->closeButton, |
||||
'options' => array_merge($this->options, [ |
||||
'id' => $this->getId() . '-' . $type . '-' . $i, |
||||
'class' => $this->alertTypes[$type] . $appendClass, |
||||
]), |
||||
]); |
||||
} |
||||
|
||||
$session->removeFlash($type); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env php |
||||
<?php |
||||
/** |
||||
* Yii console bootstrap file. |
||||
* |
||||
* @link https://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license https://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', true); |
||||
defined('YII_ENV') or define('YII_ENV', 'dev'); |
||||
|
||||
require __DIR__ . '/vendor/autoload.php'; |
||||
require __DIR__ . '/vendor/yiisoft/yii2/Yii.php'; |
||||
|
||||
$config = require __DIR__ . '/config/console.php'; |
||||
|
||||
$application = new yii\console\Application($config); |
||||
$exitCode = $application->run(); |
||||
exit($exitCode); |
@ -0,0 +1,20 @@
|
||||
@echo off |
||||
|
||||
rem ------------------------------------------------------------- |
||||
rem Yii command line bootstrap script for Windows. |
||||
rem |
||||
rem @author Qiang Xue <qiang.xue@gmail.com> |
||||
rem @link https://www.yiiframework.com/ |
||||
rem @copyright Copyright (c) 2008 Yii Software LLC |
||||
rem @license https://www.yiiframework.com/license/ |
||||
rem ------------------------------------------------------------- |
||||
|
||||
@setlocal |
||||
|
||||
set YII_PATH=%~dp0 |
||||
|
||||
if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe |
||||
|
||||
"%PHP_COMMAND%" "%YII_PATH%yii" %* |
||||
|
||||
@endlocal |
Loading…
Reference in new issue