commit b692151385fbe4d615990e37455564d888d9059a Author: Yoshihiro OKUMURA Date: Tue Jun 9 16:02:25 2020 +0900 add initial project files. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d334863 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/vendor + +/db/*.rrd +/html/images/graph-*.png + +.php_cs.cache + +*~ +*.orig +*.bak +*.tmp +.DS_Store +Thumbs.db diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..bd4e43a --- /dev/null +++ b/.php_cs @@ -0,0 +1,16 @@ +exclude('vendor') + ->in(__DIR__) +; + +return PhpCsFixer\Config::create() + ->setRules([ + '@Symfony' => true, + '@DoctrineAnnotation' => true, + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + ]) + ->setFinder($finder) +; \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d6751cc --- /dev/null +++ b/composer.json @@ -0,0 +1,35 @@ +{ + "name": "niu-admin/temperature", + "type": "project", + "scripts": { + "fix-diff": [ + "./vendor/bin/php-cs-fixer fix --dry-run --diff" + ], + "fix": [ + "./vendor/bin/php-cs-fixer fix" + ] + }, + "autoload": { + "psr-4": { + "Orrisroot\\": "lib/" + } + }, + + "require": { + "php": ">=7.4.0", + "ext-mbstring": "*", + "ext-json": "*", + "phpmailer/phpmailer": "^6.1", + "twig/twig": "^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16" + }, + "license": "MIT", + "authors": [ + { + "name": "Yoshihiro OKUMURA", + "email": "orrisroot@gmail.com" + } + ] +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..84401d4 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2132 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "b766d7a4135dc7c7209935b75341a818", + "packages": [ + { + "name": "phpmailer/phpmailer", + "version": "v6.1.6", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "doctrine/annotations": "^1.2", + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "funding": [ + { + "url": "https://github.com/synchro", + "type": "github" + } + ], + "time": "2020-05-27T12:24:03+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "twig/twig", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3b88ccd180a6b61ebb517aea3b1a8906762a1dc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3b88ccd180a6b61ebb517aea3b1a8906762a1dc2", + "reference": "3b88ccd180a6b61ebb517aea3b1a8906762a1dc2", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "time": "2020-02-11T15:33:47+00:00" + } + ], + "packages-dev": [ + { + "name": "composer/semver", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2020-01-13T12:06:48+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-06-04T11:16:35+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.10.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d", + "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^7.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2020-05-25T17:24:27+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2020-05-25T17:44:05+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.16.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "83baf823a33a1cbd5416c8626935cf3f843c10b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/83baf823a33a1cbd5416c8626935cf3f843c10b0", + "reference": "83baf823a33a1cbd5416c8626935cf3f843c10b0", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.2", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || ^7.0", + "php-cs-fixer/diff": "^1.3", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^3.0 || ^4.0 || ^5.0", + "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.2", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.1", + "php-cs-fixer/accessible-object": "^1.0", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", + "phpunitgoodpractices/traits": "^1.8", + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/Test/IsIdenticalConstraint.php", + "tests/TestCase.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2020-04-15T18:51:10+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "php-cs-fixer/diff", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" + } + ], + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "time": "2018-02-15T16:58:55+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "symfony/console", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "00bed125812716d09b163f0727ef33bb49bf3448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/00bed125812716d09b163f0727ef33bb49bf3448", + "reference": "00bed125812716d09b163f0727ef33bb49bf3448", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" + }, + "conflict": { + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-27T08:34:37+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/cc0d059e2e997e79ca34125a52f3e33de4424ac7", + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^4.4|^5.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/405952c4e90941a17e52ef7489a2bd94870bb290", + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "6e4320f06d5f2cce0d96530162491f4465179157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6e4320f06d5f2cce0d96530162491f4465179157", + "reference": "6e4320f06d5f2cce0d96530162491f4465179157", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/4298870062bfc667cb78d2b379be4bf5dec5f187", + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "663f5dd5e14057d1954fe721f9709d35837f2447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/663f5dd5e14057d1954fe721f9709d35837f2447", + "reference": "663f5dd5e14057d1954fe721f9709d35837f2447", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-23T13:08:13+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "e094b0770f7833fdf257e6ba4775be4e258230b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e094b0770f7833fdf257e6ba4775be4e258230b2", + "reference": "e094b0770f7833fdf257e6ba4775be4e258230b2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "1357b1d168eb7f68ad6a134838e46b0b159444a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/1357b1d168eb7f68ad6a134838e46b0b159444a9", + "reference": "1357b1d168eb7f68ad6a134838e46b0b159444a9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/82225c2d7d23d7e70515496d249c0152679b468e", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a760d8964ff79ab9bf057613a5808284ec852ccc", + "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/5e30b2799bc1ad68f7feb62b60a73743589438dd", + "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd", + "shasum": "" + }, + "require": { + "php": ">=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/process", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/66a8f0957a3ca54e4f724e49028ab19d75a8918b", + "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0f7c58cf81dbb5dd67d423a89d577524a2ec0323", + "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1.0|^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/string", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "90c2a5103f07feb19069379f3abdcdbacc7753a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/90c2a5103f07feb19069379f3abdcdbacc7753a9", + "reference": "90c2a5103f07feb19069379f3abdcdbacc7753a9", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony String component", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.4.0", + "ext-mbstring": "*", + "ext-json": "*" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/db/.gitkeep b/db/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/etc/config.json b/etc/config.json new file mode 100644 index 0000000..15528d7 --- /dev/null +++ b/etc/config.json @@ -0,0 +1,18 @@ +{ + "url": "https://www.ni.riken.jp/temperature/", + "digitemp": "/bin/digitemp_DS9097", + "digitemp_config": "etc/digitemp.conf", + "database_dir": "db", + "images_dir": "html/images", + "templates_dir": "templates", + "mail_alert_upper": 35, + "mail_alert_lower": 15, + "mail_from": "cbs-is@ml.riken.jp", + "mail_from_name": "C407 温度監視プログラム", + "mail_info_to": "niu-logs@ml.riken.jp", + "mail_info_subject": "C407 温度監視 定期報告", + "mail_info_template": "mail_info.twig", + "mail_alert_to": "cbs-is@ml.riken.jp", + "mail_alert_subject": "C407 温度監視 警告", + "mail_alert_template": "mail_alert.twig" +} diff --git a/etc/crontab b/etc/crontab new file mode 100644 index 0000000..1495eb6 --- /dev/null +++ b/etc/crontab @@ -0,0 +1,9 @@ +# +# Server Room Temperature Monitoring System +# +# update minutely temperature sensor data +* * * * * niu-admin php /data/temperature/sbin/update.php +# send daily temperature informations +1 12 * * * niu-admin php /data/temperature/sbin/send_info.php +# check alert thresholds on every 15 minutes +0,15,30,45 * * * * niu-admin php /data/temperature/sbin/check_alert.php diff --git a/etc/digitemp.conf b/etc/digitemp.conf new file mode 100644 index 0000000..45f5c9b --- /dev/null +++ b/etc/digitemp.conf @@ -0,0 +1,9 @@ +TTY /dev/ttyS1 +READ_TIME 1000 +LOG_TYPE 1 +LOG_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F" +CNT_FORMAT "%b %d %H:%M:%S Sensor %s #%n %C" +HUM_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F H: %h%%" +SENSORS 2 +ROM 0 0x10 0xF5 0x89 0xB7 0x00 0x08 0x00 0x3B +ROM 1 0x10 0xA3 0x85 0xB7 0x00 0x08 0x00 0x86 diff --git a/html/css/default.css b/html/css/default.css new file mode 100644 index 0000000..dbffdf6 --- /dev/null +++ b/html/css/default.css @@ -0,0 +1,27 @@ +body { + margin: 2em 1em 2em 70px; + color: black; + background: white; + background-position: top left; + background-attachment: fixed; + background-repeat: no-repeat; + background-image: url(logo.png); + text-align: center; +} + +th.requirement { background-color: #ff66ff; color: black; } + +h1 {text-align: center} +h2, h3, h4, h5, h6 { text-align: left } +h1 { color: black; font: 120% sans-serif; font-weight: bold} +h2 { color: #005A9C; font: 110%; font-weight: medium} +h3 { color: #001A4C; font: 105% sans-serif; font-weight: medium} +h4 { color: #007A9C; font: 90% sans-serif; font-weight: medium} +h5 { color: #005A9C; font: italic 80% sans-serif } +h6 { font: small-caps 70% sans-serif } + +pre { + background-color: lightcyan; + text-color: black; +} + diff --git a/html/css/logo.png b/html/css/logo.png new file mode 100644 index 0000000..49fdb23 Binary files /dev/null and b/html/css/logo.png differ diff --git a/html/images/.gitkeep b/html/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..0528f70 --- /dev/null +++ b/html/index.html @@ -0,0 +1,33 @@ + + + + + + + + + +C047 Server Room Temperature + + +

C407 Server Room Temperature

+ + + + + + + + + + + + + + + + +
Hourly GraphDaily Graph
Weekly GraphMonthly Graph
Yearly Graph3 Years Graph
+ + + diff --git a/lib/DigiTemp.php b/lib/DigiTemp.php new file mode 100644 index 0000000..d47b903 --- /dev/null +++ b/lib/DigiTemp.php @@ -0,0 +1,131 @@ + '', + 'READ_TIME' => 0, + 'LOG_TYPE' => 0, + 'LOG_FORMAT' => '', + 'CNT_FORMAT' => '', + 'HUM_FORMAT' => '', + 'SENSORS' => 0, + 'ROM' => [], + ]; + + /** + * constructor. + * + * @param string $commandPath digitemp command path + * @param string $configPath config file path + */ + public function __construct(string $commandPath, string $configPath) + { + $this->commandPath = $commandPath; + $this->configPath = $configPath; + $this->parseConfig(); + } + + /** + * get number of sensors. + */ + public function getNumSensors(): int + { + return $this->config['SENSORS']; + } + + /** + * get sensor id. + * + * @param int $num sensor number + * + * @return ?string + */ + public function getSensorId(int $num): ?string + { + return isset($this->config['ROM'][$num]) ? $this->config['ROM'][$num] : null; + } + + /** + * read sensor. + * + * @param int $num sensor number + * + * @return ?float + */ + public function readSensor(int $num): ?float + { + $cmd = escapeshellcmd($this->commandPath.' -c '.$this->configPath.' -q -t '.$num.' -o"%.2C" 2>/dev/null'); + exec($cmd, $output, $ret); + if (0 !== $ret) { + return null; + } + + return (float) $output[0]; + } + + /** + * parse config file. + * + * @return false if failure + */ + private function parseConfig(): bool + { + foreach (file($this->configPath) as $line) { + preg_match_all('/"(?:\\\\.|[^\\\\"])*"|\S+/', trim($line), $matches); + if (empty($matches[0])) { + continue; + } + $cols = $matches[0]; + $key = array_shift($cols); + $value = array_shift($cols); + switch ($key) { + case 'TTY': + $this->config[$key] = $value; + break; + case 'READ_TIME': + $this->config[$key] = (int) $value; + break; + case 'LOG_TYPE': + $this->config[$key] = (int) $value; + break; + case 'LOG_FORMAT': + $this->config[$key] = '"' === substr($value, 0, 1) ? stripslashes(substr($value, 1, -1)) : $value; + break; + case 'CNT_FORMAT': + $this->config[$key] = '"' === substr($value, 0, 1) ? stripslashes(substr($value, 1, -1)) : $value; + break; + case 'HUM_FORMAT': + $this->config[$key] = '"' === substr($value, 0, 1) ? stripslashes(substr($value, 1, -1)) : $value; + break; + case 'SENSORS': + $this->config[$key] = (int) $value; + break; + case 'ROM': + $this->config[$key][(int) $value] = str_replace('0x', '', implode('', array_reverse($cols))); + break; + default: + return false; + } + } + + return true; + } +} diff --git a/lib/Mail/Address.php b/lib/Mail/Address.php new file mode 100644 index 0000000..6f13738 --- /dev/null +++ b/lib/Mail/Address.php @@ -0,0 +1,69 @@ +name = $name; + if (!$this->validateEmail($email)) { + throw new \Exception('Invalid email address found: '.$email); + } + $this->email = $email; + } + + /** + * get name. + * + * @return string name + */ + public function getName(): string + { + return $this->name; + } + + /** + * get email. + * + * @return string email + */ + public function getEmail(): string + { + return $this->email; + } + + /** + * check wheter string is email. + * + * @param string $text email + * + * @return bool false if not email string + */ + public function validateEmail(string $email): bool + { + return false !== preg_match('/^'.self::EMAIL_REGEX.'$/', $email); + } +} diff --git a/lib/Mail/UTF8_Mailer.php b/lib/Mail/UTF8_Mailer.php new file mode 100644 index 0000000..f68f182 --- /dev/null +++ b/lib/Mail/UTF8_Mailer.php @@ -0,0 +1,32 @@ +CharSet = 'UTF-8'; + $mailer->setFrom($from->getEmail(), $from->getName()); + $mailer->Subject = $subject; + $mailer->Body = $body; + foreach ($tos as $to) { + $mailer->AddAddress($to->getEmail(), $to->getName()); + } + + return $mailer->Send(); + } +} diff --git a/lib/Rrd/Temperature.php b/lib/Rrd/Temperature.php new file mode 100644 index 0000000..c97a9ea --- /dev/null +++ b/lib/Rrd/Temperature.php @@ -0,0 +1,188 @@ +databasePath = $fpath; + $this->sensorIds = []; + } + + /** + * add sensor. + * + * @param string $id sensor id + */ + public function addSensor(string $id) + { + $this->sensorIds[] = $id; + } + + /** + * update database. + * + * @param string $id sensor id + * @param int $time timestamp + * @param float $value temperature value + * + * @return bool false if failure + */ + public function update(string $id, int $time, float $value): bool + { + $fpath = $this->getFilePath($id); + if (!file_exists($fpath)) { + if (!$this->_createDatabase($fpath)) { + return false; + } + } + $options = [sprintf('%u:%lf', $time, $value)]; + + return rrd_update($fpath, $options); + } + + /** + * read last data. + * + * @param string $id sensor id + * + * @return ?array last data + */ + public function readLastData(string $id): ?array + { + static $options = [ + 'LAST', + ]; + $fpath = $this->getFilePath($id); + $res = rrd_fetch($fpath, $options); + if (false === $res) { + return null; + } + $latest = 0; + $start = $res['start']; + $step = $res['step']; + $data = []; + foreach ($res['data'][$id] as $key => $datum) { + if (!is_nan($datum) && 0 != $datum) { + $data[] = $datum; + $latest = $start + ($key + 1) * $step; + } + } + if (empty($data)) { + return null; + } + $ret['id'] = $id; + $ret['min'] = min($data); + $ret['max'] = max($data); + $ret['average'] = array_sum($data) / count($data); + $ret['latest'] = $data[count($data) - 1]; + $ret['timestamp'] = $latest; + + return $ret; + } + + /** + * create database. + * + * @param string $id sensor id + * + * @return bool false if failure + */ + private function create(string $id): boolean + { + $fpath = $this->getFilePath($id); + $options = [ + '--step', '60', // 1min step + sprintf('DS:%s:GAUGE:600:0:100', $this->id), // 10min hartbeat + 'RRA:LAST:0.5:1:1440', // last/m - 1day(1440min) + 'RRA:LAST:0.5:30:52560', // last/30m - 3years(365day=30min*17520)*3 + ]; + + return rrd_create($fpath, $options); + } + + /** + * get rrd file path. + * + * @param string $id sensor id + * + * @return string rrd file path + */ + private function getFilePath(string $id): string + { + return $this->databasePath.'/'.$id.'.rrd'; + } + + /** + * output graph. + * + * @param string $type output graph type + * @param string $fpath output image file path + * + * @return bool false if failure + */ + public function outputGraph(string $type, string $fpath): bool + { + static $colors = [ + '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', + '#FF9999', '#99FF99', '#9999FF', '#FFFF99', '#99FFFF', '#FF99FF', + ]; + static $types = ['hour', 'day', 'week', 'month', 'year', '3year']; + if (!in_array($type, $types)) { + return false; + } + $start = '3year' == $type ? '-3year' : '-1'.$type; + $options = [ + '--imgformat', 'PNG', + '--lower-limit', '10', + '--upper-limit', '40', + '--start', $start, + '--end', 'now', + '--width', '400', + '--height', '200', + '--units-exponent', '0', + '--vertical-label', "Temperature [\xc2\xb0C]", + '--title', 'Server Room Temperature - by '.$type, + ]; + $idlen = 0; + foreach ($this->sensorIds as $key => $id) { + if (strlen($id) > $idlen) { + $idlen = strlen($id); + } + $options[] = sprintf('DEF:B%d=%s:%s:LAST', $key, $this->getFilePath($id), $id); + } + $options[] = sprintf('COMMENT: %s Cur\: Min\: Avg\: Max\:', str_repeat(' ', $idlen)); + $options[] = sprintf('COMMENT:\l'); + foreach ($this->sensorIds as $key => $id) { + $color = $colors[$key % count($colors)]; + $options[] = sprintf('LINE2:B%d%s:%s%s', $key, $color, $id, str_repeat(' ', $idlen - strlen($id))); + $options[] = sprintf('GPRINT:B%d:LAST: %%-6.2lf', $key); + $options[] = sprintf('GPRINT:B%d:MIN: %%-6.2lf', $key); + $options[] = sprintf('GPRINT:B%d:AVERAGE: %%-6.2lf', $key); + $options[] = sprintf('GPRINT:B%d:MAX: %%-6.2lf\l', $key); + } + $options[] = sprintf('COMMENT:Last update\: %s\r', str_replace(':', '\:', date('Y-m-d H:i:s T'))); + + $res = rrd_graph($fpath, $options); + + return false !== $res; + } +} diff --git a/sbin/check_alert.php b/sbin/check_alert.php new file mode 100644 index 0000000..dc2f4bc --- /dev/null +++ b/sbin/check_alert.php @@ -0,0 +1,51 @@ +getNumSensors(); +$sensors = []; +for ($i = 0; $i < $num; ++$i) { + $id = $digitemp->getSensorId($i); + $rrdtemp->addSensor($id); + $sensors[] = $rrdtemp->readLastData($id); +} +$upper = $config['mail_alert_upper']; +$lower = $config['mail_alert_lower']; +$do_send = false; +foreach ($sensors as $sensor) { + if ($sensor['latest'] < $lower || $sensor['latest'] > $upper) { + $do_send = true; + break; + } +} +if ($do_send) { + $from = $config['mail_from']; + $from_name = $config['mail_from_name']; + $to = $config['mail_alert_to']; + $subject = $config['mail_alert_subject']; + $loader = new \Twig\Loader\FilesystemLoader(APPDIR.'/'.$config['templates_dir']); + $twig = new \Twig\Environment($loader); + $data = [ + 'range' => [ + 'upper' => $upper, + 'lower' => $lower, + ], + 'sensors' => $sensors, + 'from' => [ + 'name' => $from_name, + 'email' => $from, + ], + 'url' => $config['url'], + ]; + $body = $twig->render($config['mail_alert_template'], $data); + + $from = new \Orrisroot\Mail\Address($from_name, $from); + $tos = [new \Orrisroot\Mail\Address($to, $to)]; + \Orrisroot\Mail\UTF8_Mailer::sendMail($from, $tos, $subject, $body); +} diff --git a/sbin/send_info.php b/sbin/send_info.php new file mode 100644 index 0000000..150e36c --- /dev/null +++ b/sbin/send_info.php @@ -0,0 +1,37 @@ +getNumSensors(); +$sensors = []; +for ($i = 0; $i < $num; ++$i) { + $id = $digitemp->getSensorId($i); + $rrdtemp->addSensor($id); + $sensors[] = $rrdtemp->readLastData($id); +} + +$from = $config['mail_from']; +$from_name = $config['mail_from_name']; +$to = $config['mail_info_to']; +$subject = $config['mail_info_subject']; +$loader = new \Twig\Loader\FilesystemLoader(APPDIR.'/'.$config['templates_dir']); +$twig = new \Twig\Environment($loader); +$data = [ + 'from' => [ + 'name' => $from_name, + 'email' => $from, + ], + 'sensors' => $sensors, + 'url' => $config['url'], +]; +$body = $twig->render($config['mail_info_template'], $data); + +$from = new \Orrisroot\Mail\Address($from_name, $from); +$tos = [new \Orrisroot\Mail\Address($to, $to)]; +\Orrisroot\Mail\UTF8_Mailer::sendMail($from, $tos, $subject, $body); diff --git a/sbin/update.php b/sbin/update.php new file mode 100644 index 0000000..6791e14 --- /dev/null +++ b/sbin/update.php @@ -0,0 +1,22 @@ +getNumSensors(); +for ($i = 0; $i < $num; ++$i) { + $id = $digitemp->getSensorId($i); + $value = $digitemp->readSensor($i); + $rrdtemp->addSensor($id); + $now = time(); + $rrdtemp->update($id, $now, $value); +} +foreach ($types = ['hour', 'day', 'week', 'month', 'year', '3year'] as $type) { + $fpath = APPDIR.'/'.$config['images_dir'].'/graph-'.$type.'.png'; + $rrdtemp->outputGraph($type, $fpath); +} diff --git a/templates/mail_alert.twig b/templates/mail_alert.twig new file mode 100644 index 0000000..21d916e --- /dev/null +++ b/templates/mail_alert.twig @@ -0,0 +1,14 @@ +C407 温度監視 警告 + +警告温度に到達しました。 +許容範囲({{ '%5.2f'|format(range.lower) }} 〜 {{ '%5.2f'|format(range.upper) }} ℃)外の温度です。 + +C407 サーバ室の環境を確認してください。 + +{% for sensor in sensors %} +{{ include('mail_sensor.inc.twig') }} +{% endfor %} + +-- +{{ from.name }} <{{ from.email }}> +{{ url }} diff --git a/templates/mail_info.twig b/templates/mail_info.twig new file mode 100644 index 0000000..75991f5 --- /dev/null +++ b/templates/mail_info.twig @@ -0,0 +1,9 @@ +C407 温度監視 定期報告 + +{% for sensor in sensors %} +{{ include('mail_sensor.inc.twig') }} +{% endfor %} + +-- +{{ from.name }} <{{ from.email }}> +{{ url }} diff --git a/templates/mail_sensor.inc.twig b/templates/mail_sensor.inc.twig new file mode 100644 index 0000000..6635577 --- /dev/null +++ b/templates/mail_sensor.inc.twig @@ -0,0 +1,6 @@ +--- センサー #{{ sensor.id }} --- +最新測定日時:{{ sensor.date|date('Y-m-d H:i:s T') }} +最新温度:  {{ '%5.2f'|format(sensor.latest) }} ℃ +平均/日:  {{ '%5.2f'|format(sensor.average) }} ℃ +最高値/日: {{ '%5.2f'|format(sensor.max) }} ℃ +最低値/日: {{ '%5.2f'|format(sensor.min) }} ℃