* initial commit
This commit is contained in:
commit
b79cea9fb2
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
.idea
|
||||
composer.phar
|
||||
|
||||
test/coverage
|
||||
clover.xml
|
||||
coveralls-upload.json
|
||||
phpunit.xml
|
||||
vendor/
|
||||
7
README.md
Normal file
7
README.md
Normal file
@ -0,0 +1,7 @@
|
||||
## Getting Started
|
||||
|
||||
Install the required vendor libraries
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
```
|
||||
46
bin/clear-config-cache.php
Normal file
46
bin/clear-config-cache.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Script for clearing the configuration cache.
|
||||
*
|
||||
* Can also be invoked as `composer clear-config-cache`.
|
||||
*
|
||||
* @see https://github.com/zendframework/zend-expressive-skeleton for the canonical source repository
|
||||
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license https://github.com/zendframework/zend-expressive-skeleton/blob/master/LICENSE.md New BSD License
|
||||
*/
|
||||
|
||||
chdir(__DIR__ . '/../');
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
$config = include 'config/config.php';
|
||||
|
||||
if (! isset($config['config_cache_path'])) {
|
||||
echo "No configuration cache path found" . PHP_EOL;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (! file_exists($config['config_cache_path'])) {
|
||||
printf(
|
||||
"Configured config cache file '%s' not found%s",
|
||||
$config['config_cache_path'],
|
||||
PHP_EOL
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (false === unlink($config['config_cache_path'])) {
|
||||
printf(
|
||||
"Error removing config cache file '%s'%s",
|
||||
$config['config_cache_path'],
|
||||
PHP_EOL
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf(
|
||||
"Removed configured config cache file '%s'%s",
|
||||
$config['config_cache_path'],
|
||||
PHP_EOL
|
||||
);
|
||||
exit(0);
|
||||
61
composer.json
Normal file
61
composer.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "zendframework/zend-expressive-skeleton",
|
||||
"description": "Zend expressive skeleton. Begin developing PSR-7 middleware applications in seconds!",
|
||||
"type": "project",
|
||||
"homepage": "https://github.com/zendframework/zend-expressive-skeleton",
|
||||
"license": "BSD-3-Clause",
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"http-interop/http-middleware": "^0.4.1",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"zendframework/zend-component-installer": "^1.0",
|
||||
"zendframework/zend-config": "3.1.0",
|
||||
"zendframework/zend-config-aggregator": "^1.0",
|
||||
"zendframework/zend-expressive": "^2.0.5",
|
||||
"zendframework/zend-expressive-fastroute": "^2.0",
|
||||
"zendframework/zend-expressive-helpers": "^4.0",
|
||||
"zendframework/zend-expressive-platesrenderer": "^1.3.1",
|
||||
"zendframework/zend-servicemanager": "^3.3",
|
||||
"zendframework/zend-stdlib": "^3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "^2.1.7",
|
||||
"phpunit/phpunit": "^6.0.8 || ^5.7.15",
|
||||
"squizlabs/php_codesniffer": "^2.8.1",
|
||||
"zendframework/zend-expressive-tooling": "^0.4.5",
|
||||
"zfcampus/zf-development-mode": "^3.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/App/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"AppTest\\": "test/AppTest/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-create-project-cmd": [
|
||||
"@development-enable"
|
||||
],
|
||||
"development-disable": "zf-development-mode disable",
|
||||
"development-enable": "zf-development-mode enable",
|
||||
"development-status": "zf-development-mode status",
|
||||
"check": [
|
||||
"@cs-check",
|
||||
"@test"
|
||||
],
|
||||
"clear-config-cache": "php bin/clear-config-cache.php",
|
||||
"cs-check": "phpcs",
|
||||
"cs-fix": "phpcbf",
|
||||
"serve": "php -S 0.0.0.0:8888 -t public index.php",
|
||||
"test": "phpunit --colors=always",
|
||||
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
|
||||
"test-coverage-html": "phpunit --colors=always --coverage-html test/coverage",
|
||||
"upload-coverage": "coveralls -v"
|
||||
}
|
||||
}
|
||||
3487
composer.lock
generated
Normal file
3487
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
config/.gitignore
vendored
Normal file
1
config/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
development.config.php
|
||||
2
config/autoload/.gitignore
vendored
Normal file
2
config/autoload/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
local.php
|
||||
*.local.php
|
||||
39
config/autoload/dependencies.global.php
Normal file
39
config/autoload/dependencies.global.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Zend\Expressive\Application;
|
||||
use Zend\Expressive\Container;
|
||||
use Zend\Expressive\Delegate;
|
||||
use Zend\Expressive\Helper;
|
||||
use Zend\Expressive\Middleware;
|
||||
|
||||
return [
|
||||
// Provides application-wide services.
|
||||
// We recommend using fully-qualified class names whenever possible as
|
||||
// service names.
|
||||
'dependencies' => [
|
||||
// Use 'aliases' to alias a service name to another service. The
|
||||
// key is the alias name, the value is the service to which it points.
|
||||
'aliases' => [
|
||||
'Zend\Expressive\Delegate\DefaultDelegate' => Delegate\NotFoundDelegate::class,
|
||||
],
|
||||
// Use 'invokables' for constructor-less services, or services that do
|
||||
// not require arguments to the constructor. Map a service name to the
|
||||
// class name.
|
||||
'invokables' => [
|
||||
// Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class,
|
||||
Helper\ServerUrlHelper::class => Helper\ServerUrlHelper::class,
|
||||
],
|
||||
// Use 'factories' for services provided by callbacks/factory classes.
|
||||
'factories' => [
|
||||
Application::class => Container\ApplicationFactory::class,
|
||||
Delegate\NotFoundDelegate::class => Container\NotFoundDelegateFactory::class,
|
||||
Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
|
||||
Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
|
||||
Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
|
||||
|
||||
Zend\Stratigility\Middleware\ErrorHandler::class => Container\ErrorHandlerFactory::class,
|
||||
Middleware\ErrorResponseGenerator::class => Container\ErrorResponseGeneratorFactory::class,
|
||||
Middleware\NotFoundHandler::class => Container\NotFoundHandlerFactory::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
34
config/autoload/development.local.php.dist
Normal file
34
config/autoload/development.local.php.dist
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Development-only configuration.
|
||||
*
|
||||
* Put settings you want enabled when under development mode in this file, and
|
||||
* check it into your repository.
|
||||
*
|
||||
* Developers on your team will then automatically enable them by calling on
|
||||
* `composer development-enable`.
|
||||
*/
|
||||
|
||||
use Zend\Expressive\Container;
|
||||
use Zend\Expressive\Middleware\ErrorResponseGenerator;
|
||||
|
||||
return [
|
||||
'dependencies' => [
|
||||
'invokables' => [
|
||||
],
|
||||
'factories' => [
|
||||
ErrorResponseGenerator::class => Container\WhoopsErrorResponseGeneratorFactory::class,
|
||||
'Zend\Expressive\Whoops' => Container\WhoopsFactory::class,
|
||||
'Zend\Expressive\WhoopsPageHandler' => Container\WhoopsPageHandlerFactory::class,
|
||||
],
|
||||
],
|
||||
|
||||
'whoops' => [
|
||||
'json_exceptions' => [
|
||||
'display' => true,
|
||||
'show_trace' => true,
|
||||
'ajax_only' => true,
|
||||
],
|
||||
],
|
||||
];
|
||||
16
config/autoload/local.php.dist
Normal file
16
config/autoload/local.php.dist
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Local configuration.
|
||||
*
|
||||
* Copy this file to `local.php` and change its settings as required.
|
||||
* `local.php` is ignored by git and safe to use for local and sensitive data like usernames and passwords.
|
||||
*/
|
||||
|
||||
return [
|
||||
'application' => [
|
||||
'changeDelay' => 8000,
|
||||
'refreshInterval' => 2000,
|
||||
'cameraImageBaseFolder' => 'data/cameraimages',
|
||||
],
|
||||
];
|
||||
12
config/autoload/router.global.php
Normal file
12
config/autoload/router.global.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Zend\Expressive\Router\FastRouteRouter;
|
||||
use Zend\Expressive\Router\RouterInterface;
|
||||
|
||||
return [
|
||||
'dependencies' => [
|
||||
'invokables' => [
|
||||
RouterInterface::class => FastRouteRouter::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
16
config/autoload/templates.global.php
Normal file
16
config/autoload/templates.global.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Zend\Expressive\Plates\PlatesRendererFactory;
|
||||
use Zend\Expressive\Template\TemplateRendererInterface;
|
||||
|
||||
return [
|
||||
'dependencies' => [
|
||||
'factories' => [
|
||||
TemplateRendererInterface::class => PlatesRendererFactory::class,
|
||||
],
|
||||
],
|
||||
|
||||
'templates' => [
|
||||
'extension' => 'phtml',
|
||||
],
|
||||
];
|
||||
27
config/autoload/zend-expressive.global.php
Normal file
27
config/autoload/zend-expressive.global.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Zend\ConfigAggregator\ConfigAggregator;
|
||||
|
||||
return [
|
||||
// Toggle the configuration cache. Set this to boolean false, or remove the
|
||||
// directive, to disable configuration caching. Toggling development mode
|
||||
// will also disable it by default; clear the configuration cache using
|
||||
// `composer clear-config-cache`.
|
||||
ConfigAggregator::ENABLE_CACHE => true,
|
||||
|
||||
// Enable debugging; typically used to provide debugging information within templates.
|
||||
'debug' => false,
|
||||
|
||||
'zend-expressive' => [
|
||||
// Enable programmatic pipeline: Any `middleware_pipeline` or `routes`
|
||||
// configuration will be ignored when creating the `Application` instance.
|
||||
'programmatic_pipeline' => true,
|
||||
|
||||
// Provide templates for the error handling middleware to use when
|
||||
// generating responses.
|
||||
'error_handler' => [
|
||||
'template_404' => 'error::404',
|
||||
'template_error' => 'error::error',
|
||||
],
|
||||
],
|
||||
];
|
||||
32
config/config.php
Normal file
32
config/config.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Zend\ConfigAggregator\ArrayProvider;
|
||||
use Zend\ConfigAggregator\ConfigAggregator;
|
||||
use Zend\ConfigAggregator\PhpFileProvider;
|
||||
|
||||
// To enable or disable caching, set the `ConfigAggregator::ENABLE_CACHE` boolean in
|
||||
// `config/autoload/local.php`.
|
||||
$cacheConfig = [
|
||||
'config_cache_path' => 'data/config-cache.php',
|
||||
];
|
||||
|
||||
$aggregator = new ConfigAggregator([
|
||||
// Include cache configuration
|
||||
new ArrayProvider($cacheConfig),
|
||||
|
||||
// Default App module config
|
||||
App\ConfigProvider::class,
|
||||
|
||||
// Load application config in a pre-defined order in such a way that local settings
|
||||
// overwrite global settings. (Loaded as first to last):
|
||||
// - `global.php`
|
||||
// - `*.global.php`
|
||||
// - `local.php`
|
||||
// - `*.local.php`
|
||||
new PhpFileProvider(realpath(__DIR__) . '/autoload/{{,*.}global,{,*.}local}.php'),
|
||||
|
||||
// Load development config if it exists
|
||||
new PhpFileProvider(realpath(__DIR__) . '/development.config.php'),
|
||||
], $cacheConfig['config_cache_path']);
|
||||
|
||||
return $aggregator->getMergedConfig();
|
||||
16
config/container.php
Normal file
16
config/container.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Zend\ServiceManager\Config;
|
||||
use Zend\ServiceManager\ServiceManager;
|
||||
|
||||
// Load configuration
|
||||
$config = require __DIR__ . '/config.php';
|
||||
|
||||
// Build container
|
||||
$container = new ServiceManager();
|
||||
(new Config($config['dependencies']))->configureServiceManager($container);
|
||||
|
||||
// Inject config
|
||||
$container->setService('config', $config);
|
||||
|
||||
return $container;
|
||||
29
config/development.config.php.dist
Normal file
29
config/development.config.php.dist
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* File required to allow enablement of development mode.
|
||||
*
|
||||
* For use with the zf-development-mode tool.
|
||||
*
|
||||
* Usage:
|
||||
* $ composer development-disable
|
||||
* $ composer development-enable
|
||||
* $ composer development-status
|
||||
*
|
||||
* DO NOT MODIFY THIS FILE.
|
||||
*
|
||||
* Provide your own development-mode settings by editing the file
|
||||
* `config/autoload/development.local.php.dist`.
|
||||
*
|
||||
* Because this file is aggregated last, it simply ensures:
|
||||
*
|
||||
* - The `debug` flag is _enabled_.
|
||||
* - Configuration caching is _disabled_.
|
||||
*/
|
||||
|
||||
use Zend\ConfigAggregator\ConfigAggregator;
|
||||
|
||||
return [
|
||||
'debug' => true,
|
||||
ConfigAggregator::ENABLE_CACHE => false,
|
||||
];
|
||||
57
config/pipeline.php
Normal file
57
config/pipeline.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Zend\Expressive\Helper\ServerUrlMiddleware;
|
||||
use Zend\Expressive\Helper\UrlHelperMiddleware;
|
||||
use Zend\Expressive\Middleware\ImplicitHeadMiddleware;
|
||||
use Zend\Expressive\Middleware\ImplicitOptionsMiddleware;
|
||||
use Zend\Expressive\Middleware\NotFoundHandler;
|
||||
use Zend\Stratigility\Middleware\ErrorHandler;
|
||||
|
||||
/**
|
||||
* Setup middleware pipeline:
|
||||
*/
|
||||
|
||||
/** @var \Zend\Expressive\Application $app */
|
||||
|
||||
// The error handler should be the first (most outer) middleware to catch
|
||||
// all Exceptions.
|
||||
$app->pipe(ErrorHandler::class);
|
||||
$app->pipe(ServerUrlMiddleware::class);
|
||||
|
||||
// Pipe more middleware here that you want to execute on every request:
|
||||
// - bootstrapping
|
||||
// - pre-conditions
|
||||
// - modifications to outgoing responses
|
||||
//
|
||||
// Piped Middleware may be either callables or service names. Middleware may
|
||||
// also be passed as an array; each item in the array must resolve to
|
||||
// middleware eventually (i.e., callable or service name).
|
||||
//
|
||||
// Middleware can be attached to specific paths, allowing you to mix and match
|
||||
// applications under a common domain. The handlers in each middleware
|
||||
// attached this way will see a URI with the MATCHED PATH SEGMENT REMOVED!!!
|
||||
//
|
||||
// - $app->pipe('/api', $apiMiddleware);
|
||||
// - $app->pipe('/docs', $apiDocMiddleware);
|
||||
// - $app->pipe('/files', $filesMiddleware);
|
||||
|
||||
// Register the routing middleware in the middleware pipeline
|
||||
$app->pipeRoutingMiddleware();
|
||||
$app->pipe(ImplicitHeadMiddleware::class);
|
||||
$app->pipe(ImplicitOptionsMiddleware::class);
|
||||
$app->pipe(UrlHelperMiddleware::class);
|
||||
|
||||
// Add more middleware here that needs to introspect the routing results; this
|
||||
// might include:
|
||||
//
|
||||
// - route-based authentication
|
||||
// - route-based validation
|
||||
// - etc.
|
||||
|
||||
// Register the dispatch middleware in the middleware pipeline
|
||||
$app->pipeDispatchMiddleware();
|
||||
|
||||
// At this point, if no Response is returned by any middleware, the
|
||||
// NotFoundHandler kicks in; alternately, you can provide other fallback
|
||||
// middleware to execute.
|
||||
$app->pipe(NotFoundHandler::class);
|
||||
33
config/routes.php
Normal file
33
config/routes.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Setup routes with a single request method:
|
||||
*
|
||||
* $app->get('/', App\Action\HomePageAction::class, 'home');
|
||||
* $app->post('/album', App\Action\AlbumCreateAction::class, 'album.create');
|
||||
* $app->put('/album/:id', App\Action\AlbumUpdateAction::class, 'album.put');
|
||||
* $app->patch('/album/:id', App\Action\AlbumUpdateAction::class, 'album.patch');
|
||||
* $app->delete('/album/:id', App\Action\AlbumDeleteAction::class, 'album.delete');
|
||||
*
|
||||
* Or with multiple request methods:
|
||||
*
|
||||
* $app->route('/contact', App\Action\ContactAction::class, ['GET', 'POST', ...], 'contact');
|
||||
*
|
||||
* Or handling all request methods:
|
||||
*
|
||||
* $app->route('/contact', App\Action\ContactAction::class)->setName('contact');
|
||||
*
|
||||
* or:
|
||||
*
|
||||
* $app->route(
|
||||
* '/contact',
|
||||
* App\Action\ContactAction::class,
|
||||
* Zend\Expressive\Router\Route::HTTP_METHOD_ANY,
|
||||
* 'contact'
|
||||
* );
|
||||
*/
|
||||
|
||||
/** @var \Zend\Expressive\Application $app */
|
||||
|
||||
$app->get('/', App\Action\HomePageAction::class, 'home');
|
||||
$app->get('/show-image/{camera}/{image}', App\Action\ShowCameraImageAction::class, 'api.show-image');
|
||||
$app->get('/api/get-latest-camera-pictures', App\Action\GetLatestCameraPicturesAction::class, 'api.get-camera-pictures');
|
||||
2
data/.gitignore
vendored
Normal file
2
data/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
20
phpcs.xml.dist
Normal file
20
phpcs.xml.dist
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Expressive Skeleton coding standard">
|
||||
<description>Expressive Skeleton coding standard</description>
|
||||
|
||||
<!-- display progress -->
|
||||
<arg value="p"/>
|
||||
<arg name="colors"/>
|
||||
|
||||
<!-- inherit rules from: -->
|
||||
<rule ref="PSR2"/>
|
||||
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
|
||||
<properties>
|
||||
<property name="ignoreBlankLines" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- Paths to check -->
|
||||
<file>src</file>
|
||||
</ruleset>
|
||||
17
phpunit.xml.dist
Normal file
17
phpunit.xml.dist
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="App\\Tests">
|
||||
<directory>./test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
19
public/.htaccess
Normal file
19
public/.htaccess
Normal file
@ -0,0 +1,19 @@
|
||||
RewriteEngine On
|
||||
# The following rule allows authentication to work with fast-cgi
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
# The following rule tells Apache that if the requested filename
|
||||
# exists, simply serve it.
|
||||
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -l [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^.*$ - [NC,L]
|
||||
|
||||
# The following rewrites all other queries to index.php. The
|
||||
# condition ensures that if you are using Apache aliases to do
|
||||
# mass virtual hosting, the base path will be prepended to
|
||||
# allow proper resolution of the index.php file; it will work
|
||||
# in non-aliased environments as well, providing a safe, one-size
|
||||
# fits all solution.
|
||||
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
|
||||
RewriteRule ^(.*) - [E=BASE:%1]
|
||||
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
|
||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
27
public/index.php
Normal file
27
public/index.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
// Delegate static file requests back to the PHP built-in webserver
|
||||
if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
|
||||
return false;
|
||||
}
|
||||
|
||||
chdir(dirname(__DIR__));
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Self-called anonymous function that creates its own scope and keep the global namespace clean.
|
||||
*/
|
||||
call_user_func(function () {
|
||||
/** @var \Psr\Container\ContainerInterface $container */
|
||||
$container = require 'config/container.php';
|
||||
|
||||
/** @var \Zend\Expressive\Application $app */
|
||||
$app = $container->get(\Zend\Expressive\Application::class);
|
||||
|
||||
// Import programmatic/declarative middleware pipeline and routing
|
||||
// configuration statements
|
||||
require 'config/pipeline.php';
|
||||
require 'config/routes.php';
|
||||
|
||||
$app->run();
|
||||
});
|
||||
4
public/lib/jquery-3.2.1.min.js
vendored
Normal file
4
public/lib/jquery-3.2.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
37
public/scripts/camera-image-handler.js
Normal file
37
public/scripts/camera-image-handler.js
Normal file
@ -0,0 +1,37 @@
|
||||
jQuery(document).ready(function () {
|
||||
var cameraImages = [];
|
||||
var cameraPointer = 0;
|
||||
|
||||
function changeImage(pointer) {
|
||||
$('#cameraImage').css(
|
||||
'background-image',
|
||||
'url(' + cameraImageBaseUrl + cameraImages[pointer].camera + '/' + cameraImages[pointer].imageName + ')'
|
||||
);
|
||||
$('#cameraText').text(cameraImages[pointer].text);
|
||||
}
|
||||
|
||||
function refreshCameraImages() {
|
||||
jQuery.get(cameraImageApiUrl, function (data) {
|
||||
cameraImages = data;
|
||||
}).always(function() {
|
||||
window.setTimeout(refreshCameraImages, refreshInterval);
|
||||
});
|
||||
}
|
||||
|
||||
// initial image load
|
||||
jQuery.get(cameraImageApiUrl, function (data) {
|
||||
cameraImages = data;
|
||||
|
||||
changeImage(0);
|
||||
window.setTimeout(refreshCameraImages, refreshInterval);
|
||||
|
||||
// change displayed image
|
||||
window.setInterval(function () {
|
||||
cameraPointer = cameraPointer === cameraImages.length - 1
|
||||
? 0
|
||||
: cameraPointer + 1;
|
||||
changeImage(cameraPointer);
|
||||
}, changeDelay);
|
||||
});
|
||||
|
||||
});
|
||||
BIN
public/zf-logo.png
Normal file
BIN
public/zf-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 600 B |
25
src/App/Action/GetLatestCameraPicturesAction.php
Normal file
25
src/App/Action/GetLatestCameraPicturesAction.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class GetLatestCameraPicturesAction implements ServerMiddlewareInterface
|
||||
{
|
||||
/** @var CameraPictureManagerService */
|
||||
private $cameraPictureManager;
|
||||
|
||||
public function __construct(CameraPictureManagerService $cameraPictureManager)
|
||||
{
|
||||
$this->cameraPictureManager = $cameraPictureManager;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
|
||||
{
|
||||
return new JsonResponse($this->cameraPictureManager->getLatestCameraPictures());
|
||||
}
|
||||
}
|
||||
21
src/App/Action/GetLatestCameraPicturesFactory.php
Normal file
21
src/App/Action/GetLatestCameraPicturesFactory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class GetLatestCameraPicturesFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return GetLatestCameraPicturesAction
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$cameraPictureManager = $container->get(CameraPictureManagerService::class);
|
||||
return new GetLatestCameraPicturesAction($cameraPictureManager);
|
||||
}
|
||||
}
|
||||
43
src/App/Action/HomePageAction.php
Normal file
43
src/App/Action/HomePageAction.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response\HtmlResponse;
|
||||
use Zend\Expressive\Router;
|
||||
use Zend\Expressive\Template;
|
||||
|
||||
class HomePageAction implements ServerMiddlewareInterface
|
||||
{
|
||||
/** @var Router\RouterInterface */
|
||||
private $router;
|
||||
|
||||
/** @var Template\TemplateRendererInterface */
|
||||
private $template;
|
||||
|
||||
/** @var Config */
|
||||
private $config;
|
||||
|
||||
public function __construct(
|
||||
Router\RouterInterface $router,
|
||||
Template\TemplateRendererInterface $template,
|
||||
Config $config
|
||||
) {
|
||||
|
||||
$this->router = $router;
|
||||
$this->template = $template;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
|
||||
{
|
||||
$data = [
|
||||
'changeDelay' => $this->config->get("changeDelay", 10000),
|
||||
'refreshInterval' => $this->config->get("refreshInterval", 10000),
|
||||
];
|
||||
return new HtmlResponse($this->template->render('app::home-page', $data));
|
||||
}
|
||||
}
|
||||
25
src/App/Action/HomePageFactory.php
Normal file
25
src/App/Action/HomePageFactory.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Expressive\Router\RouterInterface;
|
||||
use Zend\Expressive\Template\TemplateRendererInterface;
|
||||
|
||||
class HomePageFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return HomePageAction
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$router = $container->get(RouterInterface::class);
|
||||
$template = $container->get(TemplateRendererInterface::class);
|
||||
$config = $container->get("config");
|
||||
return new HomePageAction($router, $template, new Config($config['application']));
|
||||
}
|
||||
}
|
||||
26
src/App/Action/ShowCameraImageAction.php
Normal file
26
src/App/Action/ShowCameraImageAction.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
class ShowCameraImageAction implements ServerMiddlewareInterface
|
||||
{
|
||||
/** @var CameraPictureManagerService */
|
||||
private $cameraPictureManager;
|
||||
|
||||
public function __construct(CameraPictureManagerService $cameraPictureManager)
|
||||
{
|
||||
$this->cameraPictureManager = $cameraPictureManager;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
|
||||
{
|
||||
$camera = $request->getAttribute('camera');
|
||||
$image = $request->getAttribute('image');
|
||||
return $this->cameraPictureManager->getCameraImage($camera, $image);
|
||||
}
|
||||
}
|
||||
21
src/App/Action/ShowCameraImageFactory.php
Normal file
21
src/App/Action/ShowCameraImageFactory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Action;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class ShowCameraImageFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return ShowCameraImageAction
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$cameraPictureManager = $container->get(CameraPictureManagerService::class);
|
||||
return new ShowCameraImageAction($cameraPictureManager);
|
||||
}
|
||||
}
|
||||
62
src/App/ConfigProvider.php
Normal file
62
src/App/ConfigProvider.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
/**
|
||||
* The configuration provider for the App module
|
||||
*
|
||||
* @see https://docs.zendframework.com/zend-component-installer/
|
||||
*/
|
||||
class ConfigProvider
|
||||
{
|
||||
/**
|
||||
* Returns the configuration array
|
||||
*
|
||||
* To add a bit of a structure, each section is defined in a separate
|
||||
* method which returns an array with its configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __invoke()
|
||||
{
|
||||
return [
|
||||
'dependencies' => $this->getDependencies(),
|
||||
'templates' => $this->getTemplates(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the container dependencies
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return [
|
||||
'invokables' => [],
|
||||
'factories' => [
|
||||
Action\HomePageAction::class => Action\HomePageFactory::class,
|
||||
Action\GetLatestCameraPicturesAction::class => Action\GetLatestCameraPicturesFactory::class,
|
||||
Action\ShowCameraImageAction::class => Action\ShowCameraImageFactory::class,
|
||||
|
||||
Service\CameraPictureManagerService::class => Service\CameraPictureManagerServiceFactory::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the templates configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplates()
|
||||
{
|
||||
return [
|
||||
'paths' => [
|
||||
'app' => ['templates/app'],
|
||||
'error' => ['templates/error'],
|
||||
'layout' => ['templates/layout'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
108
src/App/Entity/CameraImage.php
Normal file
108
src/App/Entity/CameraImage.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
class CameraImage implements \JsonSerializable
|
||||
{
|
||||
/** @var string */
|
||||
private $camera;
|
||||
|
||||
/** @var string */
|
||||
private $imageName;
|
||||
|
||||
/** @var \DateTime */
|
||||
private $createdAt;
|
||||
|
||||
/** @var string */
|
||||
private $text;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCamera(): string
|
||||
{
|
||||
return $this->camera;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $camera
|
||||
* @return CameraImage
|
||||
*/
|
||||
public function setCamera(string $camera): CameraImage
|
||||
{
|
||||
$this->camera = $camera;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImageName(): string
|
||||
{
|
||||
return $this->imageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $imageName
|
||||
* @return CameraImage
|
||||
*/
|
||||
public function setImageName(string $imageName): CameraImage
|
||||
{
|
||||
$this->imageName = $imageName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreatedAt(): \DateTime
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $createdAt
|
||||
* @return CameraImage
|
||||
*/
|
||||
public function setCreatedAt(\DateTime $createdAt): CameraImage
|
||||
{
|
||||
$this->createdAt = $createdAt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getText(): ?string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @return CameraImage
|
||||
*/
|
||||
public function setText(string $text): CameraImage
|
||||
{
|
||||
$this->text = $text;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||
* which is a value of any type other than a resource.
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return [
|
||||
'camera' => $this->getCamera(),
|
||||
'imageName' => $this->getImageName(),
|
||||
'createdAt' => $this->getCreatedAt()->format("Y-m-d H:i:s"),
|
||||
'text' => $this->getText(),
|
||||
];
|
||||
}
|
||||
}
|
||||
89
src/App/Service/CameraPictureManagerService.php
Normal file
89
src/App/Service/CameraPictureManagerService.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\CameraImage;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response;
|
||||
use Zend\Diactoros\Stream;
|
||||
|
||||
class CameraPictureManagerService
|
||||
{
|
||||
/** @var Config */
|
||||
private $config;
|
||||
|
||||
public function __construct(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLatestCameraPictures()
|
||||
{
|
||||
$cameraImageBaseFolder = $this->config->get('cameraImageBaseFolder', false);
|
||||
if (!is_dir($cameraImageBaseFolder)) {
|
||||
throw new \InvalidArgumentException("Wrong cameraImageBaseFolder setting.");
|
||||
}
|
||||
|
||||
$cameraImages = [];
|
||||
$cameraImageFolders = array_diff(scandir($cameraImageBaseFolder), ['.', '..']);
|
||||
|
||||
foreach ($cameraImageFolders as $cameraImageFolder) {
|
||||
$cameraImages[] = $this->getLatestImageInDirectory("{$cameraImageBaseFolder}/{$cameraImageFolder}");
|
||||
}
|
||||
|
||||
return $cameraImages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $camera
|
||||
* @param string $image
|
||||
* @return Response
|
||||
*/
|
||||
public function getCameraImage(string $camera, string $image): Response
|
||||
{
|
||||
$cameraImageBaseFolder = $this->config->get('cameraImageBaseFolder');
|
||||
$imageFile = "{$cameraImageBaseFolder}/{$camera}/{$image}";
|
||||
|
||||
if (!file_exists($imageFile)) {
|
||||
throw new \InvalidArgumentException("");
|
||||
}
|
||||
|
||||
$imageStream = new Stream(fopen($imageFile, 'r'));
|
||||
$response = new Response();
|
||||
return $response->withBody($imageStream)
|
||||
->withHeader('Content-Type', (new \finfo(FILEINFO_MIME))->file($imageFile))
|
||||
->withHeader('Content-Disposition', 'inline; filename=' . basename($imageFile))
|
||||
->withHeader('Content-Transfer-Encoding', 'Binary')
|
||||
->withHeader('Content-Description', 'File Transfer')
|
||||
->withHeader('Pragma', 'public')
|
||||
->withHeader('Content-Length', $imageStream->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
* @return CameraImage
|
||||
*/
|
||||
private function getLatestImageInDirectory(string $directory): CameraImage
|
||||
{
|
||||
$cameraImage = new CameraImage();
|
||||
$cameraImage->setCamera(basename($directory));
|
||||
|
||||
$allImages = glob("{$directory}/*.{png,jpeg,jpg}", GLOB_NOSORT | GLOB_BRACE);
|
||||
$latestImage = array_pop($allImages);
|
||||
|
||||
$cameraImage->setImageName(pathinfo($latestImage, PATHINFO_BASENAME))
|
||||
->setCreatedAt(new \DateTime(sprintf("@%s", filemtime($latestImage))));
|
||||
|
||||
$textFile = sprintf("{$directory}/%s.txt", pathinfo($latestImage, PATHINFO_FILENAME));
|
||||
if (file_exists($textFile)) {
|
||||
$cameraImage->setText(file_get_contents($textFile));
|
||||
} elseif (file_exists("{$directory}/overlay.txt")) {
|
||||
$cameraImage->setText(file_get_contents("{$directory}/overlay.txt"));
|
||||
}
|
||||
|
||||
return $cameraImage;
|
||||
}
|
||||
}
|
||||
21
src/App/Service/CameraPictureManagerServiceFactory.php
Normal file
21
src/App/Service/CameraPictureManagerServiceFactory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Zend\Config\Config;
|
||||
|
||||
class CameraPictureManagerServiceFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return CameraPictureManagerService
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$config = $container->get("config");
|
||||
return new CameraPictureManagerService(new Config($config['application']));
|
||||
}
|
||||
}
|
||||
36
templates/app/home-page.phtml
Normal file
36
templates/app/home-page.phtml
Normal file
@ -0,0 +1,36 @@
|
||||
<?php $this->layout('layout::default', ['title' => 'Home']) ?>
|
||||
|
||||
<?php $this->push('stylesheets') ?>
|
||||
<style>
|
||||
#cameraImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: black no-repeat fixed center center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
#cameraText {
|
||||
margin: 0;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
font-size: 3em;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
text-shadow: -1px 0 #999999, 0 1px #999999, 1px 0 #999999, 0 -1px #999999;
|
||||
}
|
||||
</style>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->push('javascript') ?>
|
||||
<script>
|
||||
var changeDelay = <?=$changeDelay ?>;
|
||||
var refreshInterval = <?=$refreshInterval ?>;
|
||||
var cameraImageApiUrl = '<?=$this->serverurl("/api/get-latest-camera-pictures") ?>';
|
||||
var cameraImageBaseUrl = '<?=$this->serverurl("/show-image/") ?>';
|
||||
</script>
|
||||
<script src="<?= $this->serverurl("scripts/camera-image-handler.js") ?>"></script>
|
||||
<?php $this->end() ?>
|
||||
<div id="cameraImage">
|
||||
<h1 id="cameraText"></h1>
|
||||
</div>
|
||||
9
templates/error/404.phtml
Normal file
9
templates/error/404.phtml
Normal file
@ -0,0 +1,9 @@
|
||||
<?php $this->layout('layout::default', ['title' => '404 Not Found']) ?>
|
||||
|
||||
<h1>Oops!</h1>
|
||||
<h2>This is awkward.</h2>
|
||||
<p>We encountered a 404 Not Found error.</p>
|
||||
<p>
|
||||
You are looking for something that doesn't exist or may have moved. Check out one of the links on this page
|
||||
or head back to <a href="/">Home</a>.
|
||||
</p>
|
||||
11
templates/error/error.phtml
Normal file
11
templates/error/error.phtml
Normal file
@ -0,0 +1,11 @@
|
||||
<?php $this->layout('layout::default', ['title' => sprintf('%d %s', $status, $reason)]) ?>
|
||||
|
||||
<h1>Oops!</h1>
|
||||
<h2>This is awkward.</h2>
|
||||
<p>We encountered a <?=$this->e($status)?> <?=$this->e($reason)?> error.</p>
|
||||
<?php if ($status == 404) : ?>
|
||||
<p>
|
||||
You are looking for something that doesn't exist or may have moved. Check out one of the links on this page
|
||||
or head back to <a href="/">Home</a>.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
23
templates/layout/default.phtml
Normal file
23
templates/layout/default.phtml
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<title><?= $this->e($title) ?> - Camera Slide</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<style>
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<?= $this->section('stylesheets') ?>
|
||||
</head>
|
||||
<body class="app">
|
||||
<?= $this->section('content') ?>
|
||||
<script src="<?=$this->serverurl("lib/jquery-3.2.1.min.js") ?>"></script>
|
||||
<?= $this->section('javascript') ?>
|
||||
</body>
|
||||
</html>
|
||||
38
test/AppTest/Action/GetLatestCameraPicturesActionTest.php
Normal file
38
test/AppTest/Action/GetLatestCameraPicturesActionTest.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\GetLatestCameraPicturesAction;
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class GetLatestCameraPicturesActionTest extends TestCase
|
||||
{
|
||||
/** @var CameraPictureManagerService */
|
||||
protected $cameraPictureManager;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->cameraPictureManager = $this->prophesize(CameraPictureManagerService::class);
|
||||
// $this->cameraPictureManager->getLatestCameraPictures()
|
||||
// ->willReturn([]);
|
||||
}
|
||||
|
||||
public function testReturnsJsonResponse()
|
||||
{
|
||||
$homePage = new GetLatestCameraPicturesAction(
|
||||
$this->cameraPictureManager->reveal()
|
||||
);
|
||||
|
||||
$response = $homePage->process(
|
||||
$this->prophesize(ServerRequestInterface::class)->reveal(),
|
||||
$this->prophesize(DelegateInterface::class)->reveal()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(JsonResponse::class, $response);
|
||||
}
|
||||
}
|
||||
39
test/AppTest/Action/GetLatestCameraPicturesFactoryTest.php
Normal file
39
test/AppTest/Action/GetLatestCameraPicturesFactoryTest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\GetLatestCameraPicturesAction;
|
||||
use App\Action\GetLatestCameraPicturesFactory;
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class GetLatestCameraPicturesFactoryTest extends TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
$cameraPictureManager = $this->prophesize(CameraPictureManagerService::class);
|
||||
$this->container->get(CameraPictureManagerService::class)->willReturn($cameraPictureManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function testFactory()
|
||||
{
|
||||
$factory = new GetLatestCameraPicturesFactory();
|
||||
$this->assertInstanceOf(GetLatestCameraPicturesFactory::class, $factory);
|
||||
|
||||
$getLatestCameraPicturesAction = $factory($this->container->reveal());
|
||||
$this->assertInstanceOf(GetLatestCameraPicturesAction::class, $getLatestCameraPicturesAction);
|
||||
}
|
||||
}
|
||||
48
test/AppTest/Action/HomePageActionTest.php
Normal file
48
test/AppTest/Action/HomePageActionTest.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\HomePageAction;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response\HtmlResponse;
|
||||
use Zend\Expressive\Router\RouterInterface;
|
||||
use Zend\Expressive\Template\TemplateRendererInterface;
|
||||
|
||||
class HomePageActionTest extends TestCase
|
||||
{
|
||||
/** @var RouterInterface */
|
||||
protected $router;
|
||||
|
||||
/** @var TemplateRendererInterface */
|
||||
protected $renderer;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->router = $this->prophesize(RouterInterface::class);
|
||||
$this->renderer = $this->prophesize(TemplateRendererInterface::class);
|
||||
}
|
||||
|
||||
public function testReturnsHtmlResponse()
|
||||
{
|
||||
$this->renderer
|
||||
->render('app::home-page', Argument::type('array'))
|
||||
->willReturn('');
|
||||
|
||||
$homePage = new HomePageAction(
|
||||
$this->router->reveal(),
|
||||
$this->renderer->reveal(),
|
||||
$this->prophesize(Config::class)->reveal()
|
||||
);
|
||||
|
||||
$response = $homePage->process(
|
||||
$this->prophesize(ServerRequestInterface::class)->reveal(),
|
||||
$this->prophesize(DelegateInterface::class)->reveal()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(HtmlResponse::class, $response);
|
||||
}
|
||||
}
|
||||
45
test/AppTest/Action/HomePageFactoryTest.php
Normal file
45
test/AppTest/Action/HomePageFactoryTest.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\HomePageAction;
|
||||
use App\Action\HomePageFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Zend\Expressive\Router\RouterInterface;
|
||||
use Zend\Expressive\Template\TemplateRendererInterface;
|
||||
|
||||
class HomePageFactoryTest extends TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
|
||||
$router = $this->prophesize(RouterInterface::class);
|
||||
$templateRenderer = $this->prophesize(TemplateRendererInterface::class);
|
||||
|
||||
$this->container->get(TemplateRendererInterface::class)->willReturn($templateRenderer);
|
||||
$this->container->get(RouterInterface::class)->willReturn($router);
|
||||
$this->container->get("config")->willReturn(['application'=>[]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function testFactory()
|
||||
{
|
||||
$factory = new HomePageFactory();
|
||||
$this->assertInstanceOf(HomePageFactory::class, $factory);
|
||||
|
||||
$homePage = $factory($this->container->reveal());
|
||||
$this->assertInstanceOf(HomePageAction::class, $homePage);
|
||||
}
|
||||
}
|
||||
47
test/AppTest/Action/ShowCameraImageActionTest.php
Normal file
47
test/AppTest/Action/ShowCameraImageActionTest.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\ShowCameraImageAction;
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use Interop\Http\ServerMiddleware\DelegateInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class ShowCameraImageActionTest extends TestCase
|
||||
{
|
||||
const CAM_DIR = "cam1";
|
||||
const IMG_FILE = "img1.png";
|
||||
|
||||
/** @var CameraPictureManagerService */
|
||||
protected $cameraPictureManager;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->cameraPictureManager = $this->prophesize(CameraPictureManagerService::class);
|
||||
$this->cameraPictureManager->getCameraImage(self::CAM_DIR, self::IMG_FILE)
|
||||
->willReturn($this->prophesize(JsonResponse::class));
|
||||
}
|
||||
|
||||
public function testReturnsJsonResponse()
|
||||
{
|
||||
$homePage = new ShowCameraImageAction(
|
||||
$this->cameraPictureManager->reveal()
|
||||
);
|
||||
|
||||
$request = $this->prophesize(ServerRequestInterface::class);
|
||||
$request->getAttribute('camera')
|
||||
->willReturn('cam1');
|
||||
$request->getAttribute('image')
|
||||
->willReturn('img1.png');
|
||||
|
||||
$response = $homePage->process(
|
||||
$request->reveal(),
|
||||
$this->prophesize(DelegateInterface::class)->reveal()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(JsonResponse::class, $response);
|
||||
}
|
||||
}
|
||||
39
test/AppTest/Action/ShowCameraImageFactoryTest.php
Normal file
39
test/AppTest/Action/ShowCameraImageFactoryTest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Action;
|
||||
|
||||
use App\Action\ShowCameraImageAction;
|
||||
use App\Action\ShowCameraImageFactory;
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class ShowCameraImageFactoryTest extends TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
$cameraPictureManager = $this->prophesize(CameraPictureManagerService::class);
|
||||
$this->container->get(CameraPictureManagerService::class)->willReturn($cameraPictureManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function testFactory()
|
||||
{
|
||||
$factory = new ShowCameraImageFactory();
|
||||
$this->assertInstanceOf(ShowCameraImageFactory::class, $factory);
|
||||
|
||||
$showCameraImageAction = $factory($this->container->reveal());
|
||||
$this->assertInstanceOf(ShowCameraImageAction::class, $showCameraImageAction);
|
||||
}
|
||||
}
|
||||
17
test/AppTest/ConfigProviderTest.php
Normal file
17
test/AppTest/ConfigProviderTest.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest;
|
||||
|
||||
use App\ConfigProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConfigProviderTest extends TestCase
|
||||
{
|
||||
public function testFactory()
|
||||
{
|
||||
$factory = new ConfigProvider();
|
||||
$configProvided = $factory();
|
||||
$this->assertArrayHasKey('dependencies', $configProvided);
|
||||
$this->assertArrayHasKey('templates', $configProvided);
|
||||
}
|
||||
}
|
||||
54
test/AppTest/Entity/CameraImageTest.php
Normal file
54
test/AppTest/Entity/CameraImageTest.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Entity;
|
||||
|
||||
use App\Entity\CameraImage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CameraImageTest extends TestCase
|
||||
{
|
||||
private static $testData;
|
||||
|
||||
/** @var CameraImage */
|
||||
private $cameraImage;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$testData = [
|
||||
"camera" => "cam1",
|
||||
"imageName" => "img1.png",
|
||||
"createdAt" => new \DateTime(),
|
||||
"text" => "cam1",
|
||||
];
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->cameraImage = new CameraImage();
|
||||
}
|
||||
|
||||
public function testCanGetAndSet()
|
||||
{
|
||||
$this->cameraImage
|
||||
->setCamera(self::$testData["camera"])
|
||||
->setImageName(self::$testData["imageName"])
|
||||
->setCreatedAt(self::$testData["createdAt"])
|
||||
->setText(self::$testData["text"]);
|
||||
|
||||
$this->assertEquals(self::$testData["camera"], $this->cameraImage->getCamera());
|
||||
$this->assertEquals(self::$testData["imageName"], $this->cameraImage->getImageName());
|
||||
$this->assertEquals(self::$testData["createdAt"], $this->cameraImage->getCreatedAt());
|
||||
$this->assertEquals(self::$testData["text"], $this->cameraImage->getText());
|
||||
}
|
||||
|
||||
public function testJsonSerialize()
|
||||
{
|
||||
$this->cameraImage
|
||||
->setCamera(self::$testData["camera"])
|
||||
->setImageName(self::$testData["imageName"])
|
||||
->setCreatedAt(self::$testData["createdAt"])
|
||||
->setText(self::$testData["text"]);
|
||||
$result = json_encode($this->cameraImage);
|
||||
$this->assertInternalType("string", $result);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Service;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use App\Service\CameraPictureManagerServiceFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class CameraPictureManagerServiceFactoryTest extends TestCase
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->container = $this->prophesize(ContainerInterface::class);
|
||||
$this->container->get("config")->willReturn(['application'=>[]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
public function testFactory()
|
||||
{
|
||||
$factory = new CameraPictureManagerServiceFactory();
|
||||
$this->assertInstanceOf(CameraPictureManagerServiceFactory::class, $factory);
|
||||
|
||||
$cameraPictureManager = $factory($this->container->reveal());
|
||||
$this->assertInstanceOf(CameraPictureManagerService::class, $cameraPictureManager);
|
||||
}
|
||||
}
|
||||
69
test/AppTest/Service/CameraPictureManagerServiceTest.php
Normal file
69
test/AppTest/Service/CameraPictureManagerServiceTest.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace AppTest\Service;
|
||||
|
||||
use App\Service\CameraPictureManagerService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response;
|
||||
|
||||
class CameraPictureManagerServiceTest extends TestCase
|
||||
{
|
||||
const EXISTING_CAM_DIR = 'cam1';
|
||||
const EXISTING_IMAGE = 'img1.png';
|
||||
const MISSING_IMAGE = 'img9.png';
|
||||
const TEST_DATA_DIR = 'test/data';
|
||||
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @throws \Psr\Container\ContainerExceptionInterface
|
||||
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->config = $this->prophesize(Config::class);
|
||||
}
|
||||
|
||||
public function testThrowsExceptionOnMissingConfig()
|
||||
{
|
||||
$this->config->get('cameraImageBaseFolder', Argument::any())->willReturn(false);
|
||||
$cameraPictureManager = new CameraPictureManagerService($this->config->reveal());
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$cameraPictureManager->getLatestCameraPictures();
|
||||
}
|
||||
|
||||
public function testThrowsExceptionOnBadConfig()
|
||||
{
|
||||
$this->config->get('cameraImageBaseFolder', Argument::any())->willReturn("--sadf");
|
||||
$cameraPictureManager = new CameraPictureManagerService($this->config->reveal());
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$cameraPictureManager->getLatestCameraPictures();
|
||||
}
|
||||
|
||||
public function testReturnsImages()
|
||||
{
|
||||
$this->config->get('cameraImageBaseFolder', Argument::any())->willReturn(self::TEST_DATA_DIR);
|
||||
$cameraPictureManager = new CameraPictureManagerService($this->config->reveal());
|
||||
$result = $cameraPictureManager->getLatestCameraPictures();
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
|
||||
public function testThrowsExceptionOnBadImage()
|
||||
{
|
||||
$this->config->get('cameraImageBaseFolder', Argument::any())->willReturn(self::TEST_DATA_DIR);
|
||||
$cameraPictureManager = new CameraPictureManagerService($this->config->reveal());
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$cameraPictureManager->getCameraImage(self::EXISTING_CAM_DIR, self::MISSING_IMAGE);
|
||||
}
|
||||
|
||||
public function testReturnsResponseOnExistingImage()
|
||||
{
|
||||
$this->config->get('cameraImageBaseFolder', Argument::any())->willReturn(self::TEST_DATA_DIR);
|
||||
$cameraPictureManager = new CameraPictureManagerService($this->config->reveal());
|
||||
$result = $cameraPictureManager->getCameraImage(self::EXISTING_CAM_DIR, self::EXISTING_IMAGE);
|
||||
$this->assertInstanceOf(Response::class, $result);
|
||||
}
|
||||
}
|
||||
BIN
test/data/cam1/img1.png
Normal file
BIN
test/data/cam1/img1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
1
test/data/cam1/overlay.txt
Normal file
1
test/data/cam1/overlay.txt
Normal file
@ -0,0 +1 @@
|
||||
img1
|
||||
BIN
test/data/cam2/img2.jpg
Normal file
BIN
test/data/cam2/img2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
1
test/data/cam2/img2.txt
Normal file
1
test/data/cam2/img2.txt
Normal file
@ -0,0 +1 @@
|
||||
img2
|
||||
BIN
test/data/cam3/img3.jpeg
Normal file
BIN
test/data/cam3/img3.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
1
test/data/cam3/img3.txt
Normal file
1
test/data/cam3/img3.txt
Normal file
@ -0,0 +1 @@
|
||||
img2
|
||||
Loading…
x
Reference in New Issue
Block a user