<?php
// App/Services/Tools.php
namespace App\Services;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Symfony\Component\DependencyInjection\ContainerInterface;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\RequestStack;
use Geocoder\Dumper\GeoJson;
use Geocoder\Provider\Provider;
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;
use \DateTime;
//Load entity
use App\Entity\PositionGps;
use App\Entity\Hobit;
use App\Entity\HobitDate;
// Import the Twig Environment
use Twig\Environment;
class Tools
{
private $container;
private $em;
private $twig;
private $mail_no_reply;
private $acmeGeocoder;
private $geoJsonDumper;
public function __construct(ContainerInterface $container, \Doctrine\ORM\EntityManagerInterface $em, Environment $twig, Provider $acmeGeocoder, GeoJson $dumper) {
$this->container = $container;
$this->em = $em;
$this->twig = $twig;
$this->acmeGeocoder = $acmeGeocoder;
$this->geoJsonDumper = $dumper;
//$this->mail_no_reply = $container->getParameter('mail_no_reply');
}
/**
* sub Phone number for international
*
* @param string $phone
* @return string
*/
public function subPhoneInternational($phone)
{
$fr = "+33";
$phone_sub = substr($phone, 1);
$phone_international = $fr.$phone_sub;
return $phone_international;
}
/**
* Send json rest successData
*
* @param string $code, $message, $data
* @return json
*/
public function successData($code, $message, $data, $type = Response::HTTP_OK)
{
$response = \FOS\RestBundle\View\View::create([
'success' => true,
'code'=> $code,
'message' => $message,
'data'=> $data],
$type);
return $response;
}
/**
* Send json rest successBoolean
*
* @param string $code, $message
* @return json
*/
public function successBoolean($code, $message, $type = Response::HTTP_OK)
{
$response = \FOS\RestBundle\View\View::create([
'success' => true,
'code'=> $code,
'message' => $message],
$type);
return $response;
}
/**
* Send json rest errorData
*
* @param string $code, $message, $data
* @return json
*/
public function errorData($code, $message, $data)
{
$response = \FOS\RestBundle\View\View::create([
'success' => false,
'code'=> $code,
'message' => $message,
'errors'=> $data],
Response::HTTP_BAD_REQUEST);
return $response;
}
/**
* Send json rest errorBoolean
*
* @param string $code, $message
* @return json
*/
public function errorBoolean($code, $message, $type = Response::HTTP_BAD_REQUEST)
{
$response = \FOS\RestBundle\View\View::create([
'success' => false,
'code'=> $code,
'message' => $message],
$type);
return $response;
}
/**
* Get form errors
*
* @param Array $form
* @return Array
*/
/*public function getFormErrors($form)
{
$errorCollection = array();
foreach($form as $key => $child){
$errorCollection[$key] = array();
if(strstr($key, "Date") || strstr($key, "date") && ($key != "birthDateDay" && $key != "birthDateMonth" && $key != "birthDateYear")) {
foreach($child as $keyDate => $childDate){
if(count($childDate->getErrors()) > 0){
$errorCollection[$key][$keyDate]["code"] = $childDate->getErrors()[0]->getCause()['payload']['code'];
$errorCollection[$key][$keyDate]["message"] = $childDate->getErrors()[0]->getMessage();
}
}
}
else{
if(count($child->getErrors()) > 0){
$errorCollection[$key]['code'] = $child->getErrors()[0]->getCause()->getConstraint()->payload['code'];
$errorCollection[$key]['message'] = $child->getErrors()[0]->getMessage();
}
}
}
return $errorCollection;
}*/
public function getFormErrors(\Symfony\Component\Form\Form $form) {
$errors = array();
foreach ($form->getErrors() as $key => $error) {
if (!$form->isRoot()) {
$cause = $error->getCause();
if(array_key_exists("payload",$cause)){
$payload = $cause["payload"];
$code = $payload["code"];
}
else if ($cause instanceof \Symfony\Component\Validator\ConstraintViolation){
$code = $cause->getConstraint()->payload['code'];
}
else{
$code=null;
}
$errors['code'] = $code;
//$errors['code'] = $error->getCause()['payload']['code'];
$errors['message'] = $error->getMessage();
//$errors[] = $error->getMessage();
}
}
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$childErrors = $this->container->get('app.tools')->getFormErrors($child);
if(!empty($childErrors)){
$errors[$child->getName()] =$childErrors;
}
}
}
return $errors;
}
/**
* Set message encrypt
*
* @param string $message
* @return String
*/
public function encryptMessage($message)
{
$hash = "secretHashValue";
$method = "AES-256-CBC";
$iv_size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = openssl_encrypt($message, $method, $hash, 0, $iv);
return base64_encode($iv . $encrypted);
}
/**
* Get message encrypt
*
* @param string $message
* @return String
*/
public function decryptMessage($message)
{
$message = base64_decode($message);
$hash = "secretHashValue";
$method = "AES-256-CBC";
$iv_size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CBC);
$iv = substr($message, 0, $iv_size);
$decrypted = openssl_decrypt(substr($message, $iv_size), $method, $hash, 0, $iv);
return $decrypted;
}
/**
* Add notification
*
* @param string $message
* @return Int idUser, String type, String message, String url
*/
public function sendBasicEmail($user, $subject, $message, $emailDest = null)
{
//Load user
$user = $this->em->getRepository(User::class)->find($user);
if(!$user){
return false;
}
if($emailDest==null){
$emailDest = $user->getEmail();
}
//Create email
$bodyEmail = $this->twig->render(
'Emails/basicEmail.html.twig',
array('user' => $user, 'message' => $message)
);
/*
//Load email
$message = \Swift_Message::newInstance()
->setSubject($subject)
->setFrom($this->mail_no_reply)
->setTo($emailDest)
->setBody($bodyEmail,'text/html');
//Send email
$this->mailer->send($message);
*/
return true;
}
public function dreamHobit($debug, $debugAndFlush, $limitWidthHobit, $limitTimeHobit, $limitForCreateHobit, $limitStable, $maxSum, $numberIntervalPrintedAndServer, $userCurrent = null, $dateEndForce = null, $dateStartForce = null)
{
//Load base
$em = $this->container->get('doctrine.orm.entity_manager');
$positionGpsListTemp = $em
->getRepository(PositionGps::class)
->findBy(array("sync" => 0, "user" => $userCurrent, "activityType" => "still"), array('datePrinted' => 'ASC', 'dateCreatedByServer' => 'ASC'), 50000);
$positionGpsList = [];
//Keep the good locations, no error gps
foreach($positionGpsListTemp as $positionGpsTemp){
if($positionGpsTemp->getAccuracy() < 150){
$positionGpsList[] = $positionGpsTemp;
}
}
$hobitsTemp = [];
$keyCount = 1;
//Keep the good activity, check, return good array
$positionGpsList = $this->checkAccuracyPosition($positionGpsList, $limitTimeHobit, $userCurrent);
foreach($positionGpsList as $positionGps){
$lastPosition = false;
$nextPositions = [];
$nextPositionsKeep = [];
$activtiesBetween = [];
$activtiesBetweenNumber = 0;
$activtiesBetweenI = 1;
$activtiesBetweenType = [];
$nextPositionKeepEnd = false;
$nextStill = null;
if(count($positionGpsList) == $keyCount){
$lastPosition = true;
}
if($lastPosition){
//Current activity
}
else{
//determine the next position "still" for get the center positions
$nextStill = $positionGpsList[$keyCount]; // KeyCount are +1
//Get next positions
$nextPositions = $em
->getRepository(PositionGps::class)
->findPositionNext(0, $userCurrent->getId(), 100, $positionGps->getId(), $nextStill->getId(), 150, 200000);
//For all next positions between current position still and nex position still get
foreach($nextPositions as $nextPosition){
$distanceM = round($this->get_distance_m($positionGps, $nextPosition), 3);
//If end still, get activity between end stil and next still position
if($nextPositionKeepEnd == false){
if($distanceM < $limitWidthHobit){
$nextPositionsKeep[] = array("data" => $nextPosition, "distanceM" => $distanceM, "id" => $nextPosition->getId());
}
else{
$nextPositionsKeep[] = array("data" => $nextPosition, "distanceM" => $distanceM, "id" => $nextPosition->getId());
//End this hobit = break
$nextPositionKeepEnd = true;
}
}
else{
//Get Activity (bike, foot, car, etc...) between this hobit and next hobit.
if(!isset($activtiesBetweenType[$activtiesBetweenNumber][$nextPosition->getActivityType()])){
$activtiesBetweenType[$nextPosition->getActivityType()] = 1;
}
else{
$activtiesBetweenType[$nextPosition->getActivityType()]++;
}
// If activities has history (number > 1) and current activity same with last activity
if($activtiesBetweenI > 1 && $nextPosition->getActivityType() != $activtiesBetween[$activtiesBetweenNumber]['hobits'][$activtiesBetweenI - 2]['data']->getActivityType()){
//reset all variables
$activtiesBetweenNumber++;
$activtiesBetweenI = 0;
$activtiesBetweenType = [];
}
//Array for type by hobit
$activtiesBetween[$activtiesBetweenNumber]["activtiesBetweenType"] = $activtiesBetweenType;
//Default number is 0 (for 1 activity)
$activtiesBetween[$activtiesBetweenNumber]['hobits'][] =
array(
"data" => $nextPosition,
"dataGps" => array("longitude" => $nextPosition->getLongitude(), "latitude" => $nextPosition->getLatitude()),
"distanceM" => $distanceM,
"id" => $nextPosition->getId(),
"activityType" => $nextPosition->getActivityType(),
)
;
$activtiesBetweenI++;
}
//Debug and flush if this variable is : true
if($debugAndFlush == true){
$nextPosition->setSync(1);
$em->persist($nextPosition);
}
}
}
$nextPositionsKeepLast = null;
if(count($nextPositionsKeep) > 0){
$nextPositionsKeepLast = $nextPositionsKeep[count($nextPositionsKeep) - 1]["data"];
}
if($nextPositionsKeepLast){
$endDateTime = $nextPositionsKeepLast->getDatePrinted();
}
else{
if($lastPosition){
$endDateTime = new \DateTime();
}
else{
$endDateTime = $nextStill->getDatePrinted();
}
}
// REMOVE SMALL HOBIT (> $limitTimeHobit seconds)
if(($endDateTime->format("YmdHis") - $positionGps->getDatePrinted()->format("YmdHis")) > $limitTimeHobit){
$hobitsTemp[] = array(
"startDateTime" => $positionGps->getDatePrinted(),
"endDateTime" => $endDateTime,
"startDateTimeServer" => $positionGps->getDateCreatedByServer(),
"id" => $positionGps->getId(),
"activityType" => $positionGps->getActivityType(),
"data" => $positionGps,
"nextStillId" => ($nextStill) ? $nextStill->getId() : null,
"positions" => $nextPositionsKeep,
);
}
//For hobit activity between
if(count($activtiesBetween) > 0){
foreach($activtiesBetween as $key => $activityBetween){
if(count($activityBetween['hobits']) >= 10){
$activtyBetweenFirst = $activityBetween['hobits'][0]['data'];
$activtyBetweenLast = $activityBetween['hobits'][count($activityBetween['hobits']) - 1]['data'];
$maxValue = max($activityBetween['activtiesBetweenType']);
$activityType = array_search($maxValue, $activityBetween['activtiesBetweenType']);
$hobitsTemp[] = array(
"startDateTime" => $activtyBetweenFirst->getDatePrinted(),
"endDateTime" => $activtyBetweenLast->getDatePrinted(),
"startDateTimeServer" => $activtyBetweenFirst->getDateCreatedByServer(),
"activityType" => $activityType,
"firstPosition" => $activityBetween['hobits'][0],
"lastPosition" => $activityBetween['hobits'][count($activityBetween['hobits']) - 1],
"positions" => $activityBetween['hobits'],
);
}
}
}
if($debugAndFlush == true){
//Sync all positions, but no current position
if(!$lastPosition){
$positionGps->setSync(1);
$em->persist($positionGps);
}
}
$em->flush();
$keyCount++;
}
return $hobitsTemp;
}
//Check if positon less 100, then correct or no (for still)
public function checkAccuracyPosition($positionsGps, $limitTimeHobit, $userCurrent){
$positionsGpsGood = [];
$i = 1;
foreach($positionsGps as $positionGps){
if(!$positionGps || ($positionGps && !$positionGps->getId()) || !$userCurrent){
continue;
}
if($positionGps->getActivityConfidence() == 100 && !$positionGps->isIsMoving()){
//It's perfect activity
$positionsGpsGood[] = $positionGps;
}
else{
if(count($positionsGps) == $i){
//For last activity "still"
$positionsGpsGood[] = $positionGps;
}
else{
/*
if($positionGps->getFloor() == "-1"){
$positionsGpsGood[] = $positionGps;
continue;
}
*/
//Remove speed fail (-1) // See for motionChange ?
if($positionGps->getSpeed() != "-1"){
//If during postion bigger than $limitTimeHobit (in second)
$nextOnePosition = $this->em
->getRepository(PositionGps::class)
->findOnePositionNext(0, $userCurrent->getId(), $positionGps->getId(), 150);
if(($nextOnePosition[0]->getDatePrinted()->getTimestamp() - $positionGps->getDatePrinted()->getTimestamp()) > 600){
$positionsGpsGood[] = $positionGps;
}
}
}
}
$i++;
}
return $positionsGpsGood;
}
//LAST FUNCTION, NOT USE
public function dreamHobitLAST($debug, $debugAndFlush, $limitWidthHobit, $limitTimeHobit, $limitForCreateHobit, $limitStable, $maxSum, $numberIntervalPrintedAndServer, $userCurrent = null, $dateEndForce = null, $dateStartForce = null)
{
//Load base
$em = $this->container->get('doctrine.orm.entity_manager');
$tabHobit = [];
$tabHobitTemp = [];
$t = 0;
$a = 0;
$i = 0;
$hour = null;
$hourLast = null;
$isNewHobit = true;
$positionGpsList = [];
$testDump = false;
//remove fail date
$datetimeFail = new DateTime();
$newDateFail = $datetimeFail->createFromFormat('Y-m-d H:i:s', '1970-01-01 01:00:00');
$positionGpsListFails = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findBy(array("datePrinted" => $newDateFail, "user" => $userCurrent, "activityType" => "still"));
foreach ($positionGpsListFails as $fail) {
$fail->setSync(1);
$em->persist($fail);
}
$em->flush();
//Get all positions no sync
if($dateEndForce && $dateStartForce){
$positionGpsListTemp = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findBy(array("sync" => 0, "user" => $userCurrent), array('datePrinted' => 'ASC', 'dateCreatedByServer' => 'ASC'), 50000);
foreach($positionGpsListTemp as $pos){
if($pos->getDateCreatedByServer()->format("YmdHis") < $dateEndForce && $pos->getDateCreatedByServer()->format("YmdHis") > $dateStartForce){
$positionGpsList[] = $pos;
}
}
}
else if($dateEndForce){
$positionGpsListTemp = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findBy(array("sync" => 0, "user" => $userCurrent), array('datePrinted' => 'ASC', 'dateCreatedByServer' => 'ASC'), 50000);
foreach($positionGpsListTemp as $pos){
if($pos->getDateCreatedByServer()->format("YmdHis") < $dateEndForce){
$positionGpsList[] = $pos;
}
}
}
else if($dateStartForce){
$positionGpsListTemp = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findBy(array("sync" => 0, "user" => $userCurrent), array('datePrinted' => 'ASC', 'dateCreatedByServer' => 'ASC'), 50000);
foreach($positionGpsListTemp as $pos){
if($pos->getDateCreatedByServer()->format("YmdHis") > $dateStartForce){
$positionGpsList[] = $pos;
}
}
}
else{
$positionGpsList = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findBy(array("sync" => 0, "user" => $userCurrent), array('datePrinted' => 'ASC', 'dateCreatedByServer' => 'ASC'), 50000);
}
if($testDump){
var_dump("1 : ".count($positionGpsList));
}
if($positionGpsList){
$numberPosition = count($positionGpsList);
foreach ($positionGpsList as $keyPositionGps => $positionGps) {
$i++;
if(intval($positionGps->getAccuracy()) < 100){
$hour = $positionGps->getDatePrinted()->format("is");
//if($hourLast != $hour || $hourLast == null){
$hourLast = $hour;
if($positionGps->getSpeed() < 10){
//if($positionGps->getSpeed() == 0 || $positionGps->getSpeed() == -1){
$backgroundDuring = false;
if(($positionGps->getDateCreatedByServer()->format("YmdHis") - $positionGps->getDatePrinted()->format("YmdHis")) > $numberIntervalPrintedAndServer){
$backgroundDuring = true;
}
if(count($tabHobit) == 0){
$tabHobit[$a]['data'] = $positionGps;
$tabHobit[$a]['move'] = false;
$tabHobit[$a]['startDateTime'] = $positionGps->getDatePrinted();
$tabHobit[$a]['startDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
$tabHobit[$a]['number'] = 1;
$tabHobit[$a]['group'][] = $positionGps;
if($backgroundDuring){
$tabHobit[$a]['backgroundDuring'] = true;
}
else{
$tabHobit[$a]['backgroundDuring'] = false;
}
}
else{
//Number between last geo and new geo
$numberRayon = round($this->get_distance_m($tabHobit[$a]['data'], $positionGps) / 1000, 3);
$asExistHobit = false;
if($numberRayon < $limitWidthHobit){
$asExistHobit = true;
}
//For background data
if(!$backgroundDuring){
for($o = 1; $o <= $limitForCreateHobit; $o++){
if($asExistHobit == false){
if($numberPosition != ($i + $o) and $numberPosition > ($i + $o)){
$numberRayon = round($this->get_distance_m($tabHobit[$a]['data'], $positionGpsList[$keyPositionGps + $o]) / 1000, 3);
if($numberRayon < $limitWidthHobit){
$asExistHobit = true;
}
}
}
}
}
if($asExistHobit == true){
$tabHobit[$a]['number'] = $tabHobit[$a]['number'] + 1;
//echo "old - ".$positionGps->getDatePrinted()->format("d-m-Y H-i");
//echo "</br>";
//echo $numberRayon;
//echo "<br/>";
//It's sum on XX address number for a good data :)
if($tabHobit[$a]['number'] > 5){
if(isset($tabHobit[$a]['group'])){
if(count($tabHobit[$a]['group']) < $maxSum){
$tabHobit[$a]['group'][] = $positionGps;
}
}
else{
$tabHobit[$a]['group'][] = $positionGps;
}
}
$t = 0;
}
else{
if($isNewHobit == true){
if($keyPositionGps > 2){
//Review
if($backgroundDuring){
if(isset($tabHobit[$a]['group'])){
/*
$tabHobitTemp['last']['endDateTime'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServer();
$tabHobitTemp['last']['endDateTimeServer'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServerFormat();
*/
$tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDateCreatedByServer();
$tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
else{
$tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDateCreatedByServer();
$tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
}
else{
if(isset($tabHobit[$a]['group'])){
/*
$tabHobitTemp['last']['endDateTime'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDatePrinted();
$tabHobitTemp['last']['endDateTimeServer'] = $tabHobit[$a]['group'][(count($tabHobit[$a]['group']) - 1)]->getDateCreatedByServerFormat();
*/
$tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDatePrinted();
$tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
else{
$tabHobitTemp['last']['endDateTime'] = $positionGpsList[($i -2)]->getDatePrinted();
$tabHobitTemp['last']['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
}
$tabHobitTemp['last']['id'] = $a;
$isNewHobit = false;
}
}
//Let's go for a new hobit
$tabHobitTemp['new'][$t]['data'] = $positionGps;
$tabHobitTemp['new'][$t]['startDateTime'] = $positionGps->getDatePrinted();
if($backgroundDuring){
$tabHobitTemp['new'][$t]['startDateTimeServer'] = $positionGps->getDatePrintedFormat();
}
else{
$tabHobitTemp['new'][$t]['startDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
$tabHobitTemp['new'][$t]['number'] = 1;
$numberRayon = round($this->get_distance_m($tabHobitTemp['new'][0]['data'], $positionGps) / 1000, 3);
//default : 0.020
if($numberRayon < 0.010){
//echo "if : ".$numberRayon;
//echo "<br/>";
$t++;
}
else{
$t = 0;
//echo "else : ".$numberRayon;
//var_dump($positionGps);
//echo "<br/>";
//die;
//echo "current - ".$positionGps->getDatePrinted()->format("d-m-Y H-i");
//echo "</br>";
}
//New hobit TEMP
if($t > $limitStable || $backgroundDuring){
if(isset($tabHobitTemp['last'])){
// Set the end date for the last hobit
$tabHobit[$tabHobitTemp['last']['id']]['endDateTime'] = $tabHobitTemp['last']['endDateTime'];
$tabHobit[$tabHobitTemp['last']['id']]['endDateTimeServer'] = $tabHobitTemp['last']['endDateTimeServer'];
}
$isNewHobit = true;
//New hobit
$a++;
$tabHobit[$a]['number'] = 0;
if($backgroundDuring){
$tabHobit[$a]['backgroundDuring'] = true;
}
else{
$tabHobit[$a]['backgroundDuring'] = false;
}
foreach ($tabHobitTemp['new'] as $hobitTemp) {
//echo "new - ".$hobitTemp['startDateTime']->format("d-m-Y H-i");
//echo "</br>";
//Let's go for a new hobit
$tabHobit[$a]['data'] = $hobitTemp['data'];
$tabHobit[$a]['startDateTime'] = $tabHobitTemp['new'][0]['startDateTime'];
$tabHobit[$a]['startDateTimeServer'] = $tabHobitTemp['new'][0]['startDateTimeServer'];
$tabHobit[$a]['number'] = $limitStable + $tabHobit[$a]['number'];
}
}
}
}
}
else{
//For a travel
}
//}
}
else{
$em->persist($positionGps);
}
if(count($tabHobit) != 0){
if($numberPosition == $i){
//For the last line
$tabHobit[$a]['endDateTime'] = $positionGps->getDatePrinted();
$tabHobit[$a]['endDateTimeServer'] = $positionGps->getDateCreatedByServerFormat();
}
}
if($debugAndFlush == true || $debug == false){
$em->remove($positionGps);
}
}
$em->flush();
//Delete logs
//$em->flush();
//Find the actualy hobits
/* $actualyHobits = $this->get('doctrine.orm.entity_manager')
->getRepository('HobitBundle:Hobit')
->findBy(Array("status" => Hobit::NOW)); */
/*
foreach ($tabHobit as $hobit) {
$start = strtotime($hobit['startDateTime']->format("Y-m-d H:i:s"));
$end = strtotime($hobit['endDateTime']->format("Y-m-d H:i:s"));
$dateBetween = $end - $start;
$history = false;
//Just for debug with navigator html
if($dateBetween > $limitTimeHobit){
if($hobit['number'] >= $limitForCreateHobit){
//Set a new hobit
$newHobit = new Hobit();
foreach ($actualyHobits as $actualyHobit) {
if(round($this->get_distance_m($actualyHobit, $hobit['data']) / 1000, 3) < $limitWidthHobit){
$history = true;
}
}
if($history == true){
//Set type hystory
$newHobit->setStatus(Hobit::HISTORY);
}
else{
//Set type now
$newHobit->setStatus(Hobit::NOW);
}
$curl = new \Ivory\HttpAdapter\CurlHttpAdapter();
$geocoder = new \Geocoder\Provider\GoogleMaps($curl);
$adresse = $geocoder->reverse($hobit['data']->getLatitude(), $hobit['data']->getLongitude());
$fullAddress = $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
//Set property
$newHobit->setName("Habitude");
$newHobit->setAddress($fullAddress);
$newHobit->setLatitude($hobit['data']->getLatitude());
$newHobit->setLongitude($hobit['data']->getLongitude());
$newHobit->setType(Hobit::LEISURE);
$newHobit->setDateStartHobit($hobit['startDateTime']);
$newHobit->setDateEndHobit($hobit['endDateTime']);
$newHobit->setNumberRequest($hobit['number']);
$em->persist($newHobit);
}
}
}
if($debugAndFlush == true || $debug == false){
//Add hobit
$em->flush();
}
*/
}
//var_dump($tabHobit);
//die;
//remove small hobit
/*
$cleanHobit = [];
foreach ($tabHobit as $hobit) {
if(($hobit['endDateTime']->format("YmdHis") - $hobit['startDateTime']->format("YmdHis")) > $limitTimeHobit){
$cleanHobit[] = $hobit;
}
}
*/
//Just for debug
if($debug == true){
//return $cleanHobit;
return $tabHobit;
}
else{
return true;
}
}
public function createHobit($hobits, $limitWidthHobit, $limitTimeHobit, $limitForCreateHobit, $maxSum, $userCurrent){
/* TEST */
/*
$adresse = $this->container
->get('bazinga_geocoder.provider.acme')
->reverseQuery(ReverseQuery::fromCoordinates("47.798791858866", "3.5298856962337"));
var_dump($adresse->get(0)->getId());
die;
*/
/* TEST */
//Load base
$em = $this->container->get('doctrine.orm.entity_manager');
set_time_limit(0);
ini_set('max_execution_time', 300);
$limitWidthHobit = 0.030;
$numberHobitCurrent = 1;
$hobitPush = false;
$actualyHobits = $this->container->get('doctrine.orm.entity_manager')
->getRepository(Hobit::class)
->findBy(Array("status" => "NOW", "user" => $userCurrent));
$hobitsClean = $hobits;
/*
//remove no complete hobit
foreach ($hobits as $hobit) {
if($hobit['number'] >= $limitForCreateHobit || $hobit['backgroundDuring']){
if(isset($hobit['endDateTime'])){
$start = strtotime($hobit['startDateTime']->format("Y-m-d H:i:s"));
$end = strtotime($hobit['endDateTime']->format("Y-m-d H:i:s"));
$dateBetween = $end - $start;
if($dateBetween > $limitTimeHobit){
$hobitsClean[] = $hobit;
}
}
}
}
*/
$numberHobit = count($hobitsClean);
foreach($hobitsClean as $keyHobit => $hobit) {
$now = false;
//if($numberHobit > 0 && $numberHobit == $numberHobitCurrent && count($actualyHobits) > 0){
// $now = true;
//}
if($numberHobit > 0 && $keyHobit == 0 && count($actualyHobits) > 0){
if(round($this->get_distance_m($actualyHobits[0], $hobit['data']) / 1000, 3) < $limitWidthHobit){
$now = true;
}
}
$historyHobits = $this->container->get('doctrine.orm.entity_manager')
->getRepository(Hobit::class)
->findBy(array("user" => $userCurrent));
$history = false;
if($hobit['activityType'] == "still"){
$hobitTemp = [];
if($now == false){
foreach($historyHobits as $historyHobit) {
if(round($this->get_distance_m($historyHobit, $hobit['data']) / 1000, 3) < $limitWidthHobit){
$history = true;
$hobitTemp = $historyHobit;
$hobitDateLast = $this->container->get('doctrine.orm.entity_manager')
->getRepository(HobitDate::class)
->findOneBy(Array("hobit" => $historyHobit, "status" => "LAST"));
if($hobitDateLast){
$hobitDateLast->setStatus(HobitDate::HISTORY);
// FOR TEST TEMP
$em->persist($hobitDateLast);
$em->flush();
}
}
}
}
//Calc SUM IN XX ADDRESS
$totalLat = 0;
$totalLng = 0;
if($hobit['activityType'] == "still"){
$totalLat = $hobit['data']->getLatitude();
$totalLng = $hobit['data']->getLongitude();
}
$hobits[$keyHobit]['sumAddress']['latitude'] = $totalLat;
$hobits[$keyHobit]['sumAddress']['longitude'] = $totalLng;
if($history == true || $now == true){
//Set a new date hobit
if($now == false){
$newHobitDate = new HobitDate();
$newHobitDate->setDateStartHobit($hobit['startDateTime']);
// $newHobitDate->setNumberRequest($hobit['number']);
$newHobitDate->setHobit($hobitTemp);
}
else{
$newHobitDate = $actualyHobits[0];
//$newHobitDate->setNumberRequest($hobit['number'] + $actualyHobits[0]->getNumberRequest());
$newHobitDate->setHobit($actualyHobits[0]->getHobit());
}
$newHobitDate->setLatitude($totalLat);
$newHobitDate->setLongitude($totalLng);
$newHobitDate->setDateEndHobit($hobit['endDateTime']);
if($numberHobitCurrent == $numberHobit){
if($now == false){
if(count($actualyHobits) > 0){
$actualyHobits[0]->setStatus("LAST");
$em->persist($actualyHobits[0]);
}
}
$newHobitDate->setStatus("NOW");
}
else{
$newHobitDate->setStatus("LAST");
}
// FOR TEST TEMP
$em->persist($newHobitDate);
$em->flush();
}
else{
//Set a new hobit
$newHobit = new Hobit();
//Set type now
//$newHobit->setStatus("LAST");
$newHobit->setParent(NULL);
$adresse = $this->acmeGeocoder
->reverseQuery(ReverseQuery::fromCoordinates($totalLat, $totalLng));
//var_dump($adresse);
//die;
$goodAddress = "";
$zoneAddress = [];
$locationType = "";
$idPlace = "";
$addressTempTab = [];
if($adresse->count() > 1){
foreach ($adresse->all() as $keyAddress => $oneAddress) {
$addressTemp = $oneAddress->getStreetNumber()." ".$oneAddress->getStreetName().' '.$oneAddress->getLocality().' '.$oneAddress->getPostalCode().' '.$oneAddress->getCountry()->getName();
if($keyAddress < 3){
if($key = array_search($addressTemp, $addressTempTab, true)){
if($addressTempTab[$key] == $addressTemp){
$goodAddress = $addressTemp;
$locationType = $oneAddress->getLocationType();
$idPlace = $oneAddress->getId();
$zoneAddress['streetNumber'] = $oneAddress->getStreetNumber();
$zoneAddress['streetName'] = $oneAddress->getStreetName();
$zoneAddress['locality'] = $oneAddress->getLocality();
$zoneAddress['postalCode'] = $oneAddress->getPostalCode();
$zoneAddress['country'] = $oneAddress->getCountry()->getName();
}
}
}
$addressTempTab[] = $addressTemp;
}
if($goodAddress == ""){
$goodAddress = $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
$locationType = $adresse->get(0)->getLocationType();
$idPlace = $adresse->get(0)->getId();
$zoneAddress['streetNumber'] = $adresse->get(0)->getStreetNumber();
$zoneAddress['streetName'] = $adresse->get(0)->getStreetName();
$zoneAddress['locality'] = $adresse->get(0)->getLocality();
$zoneAddress['postalCode'] = $adresse->get(0)->getPostalCode();
$zoneAddress['country'] = $adresse->get(0)->getCountry()->getName();
}
}
else{
$goodAddress = $adresse->get(0)->getStreetNumber()." ".$adresse->get(0)->getStreetName().' '.$adresse->get(0)->getLocality().' '.$adresse->get(0)->getPostalCode().' '.$adresse->get(0)->getCountry()->getName();
$locationType = $adresse->get(0)->getLocationType();
$idPlace = $adresse->get(0)->getId();
$zoneAddress['streetNumber'] = $adresse->get(0)->getStreetNumber();
$zoneAddress['streetName'] = $adresse->get(0)->getStreetName();
$zoneAddress['locality'] = $adresse->get(0)->getLocality();
$zoneAddress['postalCode'] = $adresse->get(0)->getPostalCode();
$zoneAddress['country'] = $adresse->get(0)->getCountry()->getName();
}
//Set property
$newHobit->setName("Habitude");
$newHobit->setAddress($goodAddress);
$newHobit->setLatitude($totalLat);
$newHobit->setLongitude($totalLng);
$newHobit->setLocationType($locationType);
$newHobit->setIdPlace($idPlace);
$newHobit->setType($hobit['activityType']);
$newHobit->setStatus("LAST");
$newHobit->setUser($userCurrent);
$newHobit->setNumberStreet( $zoneAddress['streetNumber'] );
$newHobit->setStreet($zoneAddress['streetName']);
$newHobit->setCity($zoneAddress['locality']);
$newHobit->setCountry($zoneAddress['country']);
$newHobit->setPostalCode($zoneAddress['postalCode']);
//REMOVE FOR A VERSION 2, AFTER TEST
$newHobit->setDateStartHobit($hobit['startDateTime']);
$newHobit->setDateEndHobit($hobit['endDateTime']);
$newHobit->setNumberRequest(count($hobit['positions']));
//REMOVE FOR A VERSION 2, AFTER TEST
$em->persist($newHobit);
//Set a new date hobit
$newHobitDate = new HobitDate();
$newHobitDate->setLatitude($totalLat);
$newHobitDate->setLongitude($totalLng);
$newHobitDate->setDateStartHobit($hobit['startDateTime']);
$newHobitDate->setDateEndHobit($hobit['endDateTime']);
$newHobitDate->setNumberRequest(count($hobit['positions']));
$newHobitDate->setHobit($newHobit);
if($numberHobitCurrent == $numberHobit){
if($now == false){
if(count($actualyHobits) > 0){
$actualyHobits[0]->setStatus("LAST");
$em->persist($actualyHobits[0]);
}
}
$newHobitDate->setStatus("NOW");
}
else{
$newHobitDate->setStatus("LAST");
}
//FOR TEST TEMP
$em->persist($newHobitDate);
$em->flush();
}
$numberHobitCurrent++;
/*
if($numberHobit > 0){
//Enable the position sync
//$startDate = $hobits[0]['startDateTime'];
//$endDate = $hobits[$numberHobit - 2]['endDateTime'];
$startDate = $hobit['startDateTime'];
$endDate = $hobit['endDateTime'];
$hobitPush = true;
// FOR TEST TEMP
$positionsForSync = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findPositionByTwoDate($startDate, $endDate, $userCurrent);
//All positions no sync this is a "transition", transport... :) It's easy.
}
*/
$body = "Hobit create <br/><br/>";
}
else{
$body = "Hobit NO create (limit) <br/><br/>";
}
$body.= "Date start : ".$hobit['startDateTime']->format("d-m-Y H:i");
$body.= "<br/>Date end : ".$hobit['endDateTime']->format("d-m-Y H:i");
/*
$message = (new \Swift_Message('Life - dump hobit'))
->setFrom('noreply@69dev.io')
->setTo('grabettetristan@gmail.com')
->setBody(
$body,
'text/html'
)
;
*/
//$this->container->get('mailer')->send($message);
}
//For cut the "transition"
/*
if($numberHobit > 0 && $hobitPush == true){
$startDate = $hobits[0]['startDateTime'];
$endDate = $hobitsClean[count($hobitsClean) - 1]['endDateTime'];
// FOR TEST TEMP
$positionsTransitionSync = $this->container->get('doctrine.orm.entity_manager')
->getRepository(PositionGps::class)
->findPositionByTwoDate($startDate, $endDate, $userCurrent);
}
*/
return $hobitsClean;
}
function get_distance_m($lastHobit, $newHobit) {
$lat1 = $lastHobit->getLatitude();
$lng1 = $lastHobit->getLongitude();
$lat2 = $newHobit->getLatitude();
$lng2 = $newHobit->getLongitude();
$earth_radius = 6378137;
$rlo1 = deg2rad($lng1);
$rla1 = deg2rad($lat1);
$rlo2 = deg2rad($lng2);
$rla2 = deg2rad($lat2);
$dlo = ($rlo2 - $rlo1) / 2;
$dla = ($rla2 - $rla1) / 2;
$a = (sin($dla) * sin($dla)) + cos($rla1) * cos($rla2) * (sin($dlo) * sin($dlo));
$d = 2 * atan2(sqrt($a), sqrt(1 - $a));
return ($earth_radius * $d);
}
}