api.emotionhero.com/src/Api/InterfaceControllerProvider...

193 lines
7.5 KiB
PHP

<?php
namespace EmotionHero\Api;
use EmotionHero\Application as EH;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Silex\Api\ControllerProviderInterface;
use EmotionHero\Models;
use EmotionHero\Server\Websockets;
class InterfaceControllerProvider implements ControllerProviderInterface
{
/** @var EH */
protected $_eh;
public function __construct()
{
$this->_eh = EH::getInstance();
}
public function connect(Application $app)
{
// creates a new controller based on the default route
$controllers = $app['controllers_factory'];
// /interface/game/last
$controllers->get('/games/last', function (Application $app) {
$http_origin = $_SERVER['HTTP_ORIGIN'] ?? null;
if ($http_origin == "https://emotionhero.com" || $http_origin == "http://emotionhero.com")
{
header("Access-Control-Allow-Origin: $http_origin");
// header("Access-Control-Allow-Origin: https://emotionhero.com");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: X-PINGOTHER");
header("Access-Control-Max-Age: 1728000");
}
$gameRepo = $this->_eh->getEm()->getRepository(\EmotionHero\Models\Game::class);
/* @var $hitRepo EmotionHero\Models\HitRepository */
$hitRepo = $this->_eh->getEm()->getRepository(\EmotionHero\Models\Hit::class);
$game = $gameRepo->findOneBy([], ['createdAt'=>'DESC']);
// id
// score
// achievements, level, time, ranking, hits
// TODO: make this difference on db-level
$timeToOutput = $game->getCreatedAt()->add(new \DateInterval("PT1H"));
$output = [
'id' => $game->getId(),
'level' => $game->getLevel()->getName(),
'ranking' => $gameRepo->getPositionForGame($game),
'score' => $game->getScore(),
'achievements' => $game->getAchievements()->count(),
'time' => $timeToOutput->format("Y-m-d H:i:s"),
'hits' => [],
];
// of one hit is on the same time as another, skip it
// as it is part of the same target group (which has been
// taken into account)
$times = [];
foreach ($game->getHits() as $hit) {
$time = $hit->getTarget()->getTime();
if(in_array($time, $times)) {
continue;
}
$times[] = $time;
$targetSet = $hitRepo->getTargetSetForTarget($hit->getTarget());
$betterHit = $hitRepo->getBetterHit($hit);
// score, emotions, expressions, points
$hitOutput = [
'id' => $hit->getId(),
'score' => $hit->getScore(),
'emotions' => [],
'expressions' => [],
'points' => [],
];
foreach($targetSet as $target) {
$hitOutput['emotions'][$target->getEmotion()->getName()]['target_value'] = $target->getScore();
$hitOutput['emotions'][$target->getEmotion()->getName()]['player_value'] = $hit->getEmotions()->getEmotionScore($target->getEmotion());
}
$expressions = array_keys($hit->getExpressions()::$EXPRESSIONS_2ND_PERSON);
sort($expressions);
foreach ($expressions as $expression) {
$score = $hit->getExpressions()->getExpressionScore($expression);
// if there is no better hit, better score == score
$betterScore = $betterHit ? $betterHit->getExpressions()->getExpressionScore($expression) : $score;
$hitOutput['expressions'][$expression]['target_value'] = $betterScore;
$hitOutput['expressions'][$expression]['player_value'] = $score;
}
foreach($hit->getPoints()->getNormalisedPoints() as $i => $point) {
$hitOutput['points']['player'][$i] = ['x'=> $point->getX(), 'y' => $point->getY()];
}
if(!empty($betterHit)) {
foreach($betterHit->getPoints()->getNormalisedPoints() as $i => $point) {
$hitOutput['points']['target'][$i] = ['x'=> $point->getX(), 'y' => $point->getY()];
}
}
$output['hits'][$time] = $hitOutput;
}
return $app['serializer']->serialize($output, 'json');
});
$controllers->get('/images', function (Application $app) {
$http_origin = $_SERVER['HTTP_ORIGIN'] ?? null;
if ($http_origin == "https://emotionhero.com" || $http_origin == "http://emotionhero.com")
{
header("Access-Control-Allow-Origin: $http_origin");
// header("Access-Control-Allow-Origin: https://emotionhero.com");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: X-PINGOTHER");
header("Access-Control-Max-Age: 1728000");
}
$getEmoBlocks = function($emotion, $feature, $steps = 6) {
$hitRepo = $this->_eh->getEm()->getRepository(Models\Hit::class);
$blocks = [];
$position = 1;
foreach(range(0, 100, 100/($steps-1)) as $i) {
/* @var $hitRepo EmotionHero\Models\HitRepository */
$hit = $hitRepo->getClosestHitWithImage($emotion, $i);
$img = "data:image/x-icon;base64,".$hit->getFeatureImgAsString($feature);
$score = $hit->getEmotions()->getEmotionScore($emotion);
$percentage = sprintf("%.0f %%",$score);
$blocks[$position] = [
'hit_id' => $hit->getId(),
'img_data' => $img,
'percentage' => $percentage,
];
$position++;
}
return $blocks;
};
$features = ['brows' => 6, 'nose' => 5, 'mouth' => 8];
$output = [];
foreach($features as $feature => $steps) {
foreach(Models\Emotions::$EMOTIONS as $emotion) {
$output[$feature][$emotion] = $getEmoBlocks(
$emotion,
$feature == 'mouth' ? 'mouth_left':$feature,
$steps
);
}
}
return $app['serializer']->serialize($output, 'json');
});
// /interface/images
$controllers->get('/trigger/game', function (Application $app) {
// trigger update of client:
try{
Websockets::triggerUpdate('game');
}catch(\Throwable $e) {
return false;
}
return true;
});
// /interface/images
$controllers->get('/trigger/images', function (Application $app) {
// trigger update of client:
try{
Websockets::triggerUpdate('images');
}catch(\Throwable $e) {
return false;
}
return true;
});
return $controllers;
}
}