<?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; } }