src/Services/Logging.php line 39

Open in your IDE?
  1. <?php
  2. //----------------------------------------------------------------------
  3. // src/Services/Logging.php
  4. //----------------------------------------------------------------------
  5. namespace App\Services;
  6. use Doctrine\Persistence\ManagerRegistry;
  7. use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
  8. use Symfony\Contracts\Translation\TranslatorInterface;
  9. use Symfony\Component\Security\Core\Security;
  10. use App\Entity\Access;
  11. use App\Entity\AccessClient\AccessClient;
  12. use App\Entity\APIRest\AccessAPI;
  13. use App\Entity\Ding\AdvancedNotificationLog;
  14. use App\Entity\Ding\Notification as DingNotification;
  15. use App\Entity\Ding\NotificationType;
  16. use App\Entity\HR\Log as HRLog;
  17. use App\Entity\Ikea\Log as IkeaLog;
  18. use App\Entity\Log\Log;
  19. use App\Entity\Log\LogEntity;
  20. use App\Entity\ProjectManager\Log as ProjectManagerLog;
  21. use App\Services\Common\TextTools;
  22. class Logging
  23. {
  24.     const log_to_file_global 1;
  25.     const log_to_file_mission 2;
  26.     const log_to_file_client 3;
  27.     const log_to_file_human_resource 4;
  28.     const log_to_file_project_notebook 5;
  29.     public function __construct(ManagerRegistry $doctrineTranslatorInterface $translatorSecurity $securityTextTools $textTools)
  30.     {
  31.         $this->em $doctrine->getManager();
  32.         $this->translator $translator;
  33.         $this->security $security;
  34.         $this->textTools $textTools;
  35.         // Plan.io Task #3946
  36.         // This will only be set as true by isApi method, and only
  37.         // if the current user (this->security->getUser()) is not null and is instanceof AccessAPI
  38.         // Special case : Request incoming from Rekto/Jcaf
  39.         // In this case the AccessAPI is either AccessAPI::ACCESS_API_JCAF or AccessAPI::ACCESS_API_REKTO
  40.         // In this particular case, we set the $this->api to false
  41.         $this->api false;
  42.     }
  43.     public function ploopLog($msg)
  44.     {
  45.         error_log ("\n".$msg."\n"3"ploop.log");
  46.     }
  47.     //--------------------------------------------------------------------------
  48.     // Plan.io Task #3922 
  49.     // DMS Global, Email and Object Logs
  50.     //--------------------------------------------------------------------------
  51.     
  52.     // DMS/Logs/Global/
  53.     public function getDMS_GlobalLogsDir()
  54.     {
  55.         // $home = dirname(__FILE__, 3);
  56.         // $home .= "/custom_logs/global_logs/";
  57.         // Plan.io Task #3922
  58.         // Move file logging to DMS/Logs
  59.         $home dirname(__FILE__3);
  60.         $home .= "/DMS/Logs/Global/";
  61.         return $home;
  62.     }
  63.     
  64.     // DMS/Logs/Email/
  65.     public function getDMS_EmailLogsDir()
  66.     {        
  67.         $home dirname(__FILE__3);
  68.         $home .= "/DMS/Logs/Email/";
  69.         return $home;
  70.     }
  71.     // DMS/Logs/Mission/
  72.     public function getDMS_MissionLogsDir()
  73.     {        
  74.         $home dirname(__FILE__3);
  75.         $home .= "/DMS/Logs/Mission/";
  76.         return $home;
  77.     }
  78.     
  79.     // DMS/Logs/Client/
  80.     public function getDMS_ClientLogsDir()
  81.     {        
  82.         $home dirname(__FILE__3);
  83.         $home .= "/DMS/Logs/Client/";
  84.         return $home;
  85.     }
  86.     // DMS/Logs/HumanResource/
  87.     public function getDMS_HumanResourceLogsDir()
  88.     {        
  89.         $home dirname(__FILE__3);
  90.         $home .= "/DMS/Logs/HumanResource/";
  91.         return $home;
  92.     }
  93.     // DMS/Logs/ProjectManager/
  94.     public function getDMS_ProjectManagerDir()
  95.     {        
  96.         $home dirname(__FILE__3);
  97.         $home .= "/DMS/Logs/ProjectManager/";
  98.         return $home;
  99.     }
  100.     // DMS/Logs/ProjectManager/Notebook/
  101.     public function getDMS_ProjectManagerNotebookLogsDir()
  102.     {        
  103.         $home dirname(__FILE__3);
  104.         $home .= "/DMS/Logs/ProjectManager/Notebook/";
  105.         return $home;
  106.     }
  107.     //--------------------------------------------------------------------------
  108.     // Plan.io Task #3922
  109.     // No Persist, No Flush
  110.     // Returns the $log object
  111.     public function smartLog($args)
  112.     {
  113.         $emptyAccess $this->em->getRepository(Access::class)
  114.             ->findOneByEmail(Access::EMPTY_ACCESS);
  115.         // Get the arguments
  116.         if (array_key_exists("action"$args))                        $action $args["action"];
  117.         else                                                        $action null;
  118.         // Action is mandatory, all the rest isn't
  119.         if ($action === null)
  120.             return null;
  121.         if (array_key_exists("object_id"$args))                    $objectId $args["object_id"];
  122.         else                                                        $objectId null;
  123.         if (array_key_exists("object_bundle"$args))                $objectBundle $args["object_bundle"];
  124.         else                                                        $objectBundle null;
  125.         if (array_key_exists("object_entity"$args))                $objectEntity $args["object_entity"];
  126.         else                                                        $objectEntity null;
  127.         if (array_key_exists("object_display"$args))                $objectDisplay $this->textTools->cleanTextWithoutHtmlentities($args["object_display"]);
  128.         else                                                        $objectDisplay null;
  129.         if (array_key_exists("object_client_id"$args))            $objectClientId $args["object_client_id"];
  130.         else                                                        $objectClientId null;
  131.         if (array_key_exists("object_client_display"$args))        $objectClientDisplay $this->textTools->cleanTextWithoutHtmlentities($args["object_client_display"]);
  132.         else                                                        $objectClientDisplay null;
  133.         if (array_key_exists("object_mission_id"$args))            $objectMissionId $args["object_mission_id"];
  134.         else                                                        $objectMissionId null;
  135.         if (array_key_exists("object_mission_display"$args))        $objectMissionDisplay $this->textTools->cleanTextWithoutHtmlentities($args["object_mission_display"]);
  136.         else                                                        $objectMissionDisplay null;
  137.         if (array_key_exists("trace"$args))                        $trace $args["trace"];
  138.         else                                                         $trace null;
  139.         if (array_key_exists("old_value"$args))                    $oldValue $this->textTools->cleanTextWithoutHtmlentities($args["old_value"]);
  140.         else                                                        $oldValue null;
  141.         if (array_key_exists("new_value"$args))                    $newValue $this->textTools->cleanTextWithoutHtmlentities($args["new_value"]);
  142.         else                                                        $newValue null;
  143.         if (array_key_exists("info"$args))                        $info $args["info"];
  144.         else                                                        $info null;
  145.         if (array_key_exists("society_group"$args))                $societyGroup $args["society_group"];
  146.         else                                                        $societyGroup null;
  147.         if (array_key_exists("society"$args))                        $society $args["society"];
  148.         else                                                        $society null;
  149.         if (array_key_exists("special_author"$args))                $specialAuthor $args["special_author"];
  150.         else                                                        $specialAuthor null;
  151.         if (array_key_exists("object_human_resource_id"$args))    $objectHumanResourceId $args["object_human_resource_id"];
  152.         else                                                        $objectHumanResourceId null;
  153.         if (array_key_exists("object_human_resource_display"$args))    $objectHumanResourceDisplay $this->textTools->cleanTextWithoutHtmlentities($args["object_human_resource_display"]);
  154.         else                                                            $objectHumanResourceDisplay null;
  155.         // Plan.io Task #4624
  156.         if (array_key_exists("project_notebook_id"$args))    $projectNotebookId $args["project_notebook_id"];
  157.         else                                                $projectNotebookId null;
  158.         if (array_key_exists("module_code"$args))    $moduleCode $args["module_code"];
  159.         else                                            $moduleCode null;
  160.         if (array_key_exists("module_display"$args))    $moduleDisplay $args["module_display"];
  161.         else                                            $moduleDisplay null;
  162.         // Handle special authors better than passing data in the $info field
  163.         // if (array_key_exists("info_special_author", $args))            $infoSpecialAuthor = $args["info_special_author"];
  164.         // else                                                            $infoSpecialAuthor = null;
  165.         // Switch user case
  166.         // Plan.io Task #3621
  167.         $trueAccess null;
  168.         $falseAccess null;
  169.         // Plan.io Task #3946
  170.         $this->api $this->isApi();
  171.         if (array_key_exists("access"$args))
  172.         {
  173.             $access $args['access'];
  174.         }
  175.         else
  176.         {
  177.             if ($specialAuthor !== null && in_array($specialAuthor, ["api_action""jcaf_local""ikea_service_order""sms_client_response"]))
  178.             {
  179.                 $logData $this->handleSpecialCases($specialAuthor$action);
  180.                 $access $logData['access'];
  181.                 if (array_key_exists('info'$logData) && !empty($logData['info']))
  182.                 {
  183.                     $info $logData['info'];
  184.                 }
  185.             }
  186.             else
  187.             {
  188.                 $logData $this->handleNormalCases();
  189.                 $access $logData['access'];
  190.                 $trueAccess $logData['trueAccess'];
  191.                 $falseAccess $logData['falseAccess'];
  192.             }
  193.         }
  194.         // Plan.io Task #4327 : Handle logging for AccessClient users
  195.         // At this point $access holds a valid not null object
  196.         // However, this object can be either an Access or an AccessClient
  197.         if ($access instanceof Access)
  198.         {
  199.             // $this->ploopLog("[Logging][smartLog] access is Access");
  200.         }
  201.         else
  202.         {
  203.             if ($access instanceof AccessClient)
  204.             {
  205.                 // $this->ploopLog("[Logging][smartLog] access is AccessClient");
  206.             }
  207.         }
  208.         if ($trueAccess !== null)
  209.         {
  210.             // $this->ploopLog("[Logging][smartLog] trueAccess is ".$trueAccess->displayForLog());
  211.         }
  212.         if ($falseAccess !== null)
  213.         {
  214.             // $this->ploopLog("[Logging][smartLog] falseAccess is ".$falseAccess->displayForLog());
  215.         }
  216.         $logEntityRep $this->em->getRepository(LogEntity::class);
  217.         $log = new Log();    
  218.         
  219.         // $this->ploopLog("[smartLog] objectBundle = $objectBundle");
  220.         // Plan.io Task #3621 #3751 #3865 #4624
  221.         $specials = array("Ikea""Ding""HR""Equipment""ProjectManager");
  222.         if (!in_array($objectBundle$specials))
  223.         {
  224.             $log = new Log();
  225.             // $this->ploopLog("[smartLog] objectBundle = $objectBundle => Creating a Log object");
  226.         }
  227.         else
  228.         {
  229.             switch ($objectBundle)
  230.             {
  231.                 case "Ikea":
  232.                     $log = new IkeaLog();
  233.                     break;
  234.                 case "Ding":
  235.                     $log = new AdvancedNotificationLog();
  236.                     break;
  237.                 case "HR":
  238.                     $log = new HRLog();
  239.                     break;
  240.                 case "Equipment":
  241.                     $log = new HRLog();
  242.                     break;
  243.                 // Plan.io Task #4624
  244.                 case "ProjectManager":
  245.                 {
  246.                     // $this->ploopLog("[smartLog] objectBundle = $objectBundle => Creating a ProjectManagerLog object");
  247.                     $log = new ProjectManagerLog();
  248.                     break;
  249.                 }                    
  250.                 default:
  251.                     $log = new Log();
  252.                     break;
  253.             }
  254.         }
  255.         $log->setSmartLog(1);
  256.         $log->setAction($action);
  257.         $log->setObjectId($objectId);
  258.         $log->setObjectBundle($objectBundle);
  259.         $log->setObjectEntity($objectEntity);
  260.         $log->setObjectDisplay($objectDisplay);
  261.         $log->setObjectClientId($objectClientId);
  262.         $log->setObjectClientDisplay($objectClientDisplay);
  263.         $log->setObjectMissionId($objectMissionId);
  264.         $log->setObjectMissionDisplay($objectMissionDisplay);
  265.         $log->setTrace($trace);
  266.         $log->setOldValue($oldValue);
  267.         $log->setNewValue($newValue);
  268.         $log->setInfo($info);
  269.         if ($log instanceof HRLog)
  270.         {
  271.             $log->setObjectHumanResourceId($objectHumanResourceId);
  272.             $log->setObjectHumanResourceDisplay($objectHumanResourceDisplay);
  273.         }
  274.         if ($log instanceof ProjectManagerLog)
  275.         {
  276.             $log->setNotebookId($projectNotebookId);
  277.             $log->setModuleCode($moduleCode);
  278.             $log->setModuleDisplay($moduleDisplay);
  279.         }
  280.         if ($societyGroup !== null)
  281.         {
  282.             $log->setSocietyGroupId($societyGroup->getId());
  283.             $log->setSocietyGroupInternalRef($societyGroup->getInternalRef());
  284.             $log->setSocietyGroupRef($societyGroup->getRef());
  285.             $log->setSocietyGroupName($societyGroup->getName());
  286.         }
  287.         if ($society !== null)
  288.         {
  289.             $log->setSocietyId($society->getId());
  290.             $log->setSocietyRef($society->getRef());
  291.             $log->setSocietyName($society->getName());
  292.         }
  293.         if ($access !== null)
  294.         {
  295.             $log->setAccessId($access->getId());
  296.             $log->setAccessUsername($access->getUsername());
  297.         }
  298.         if ($trueAccess !== null)
  299.         {
  300.             // Plan.io Task #4327
  301.             if ($trueAccess instanceof Access)
  302.             {
  303.                 $log->setTrueAccessId($trueAccess->getId());
  304.                 $log->setTrueAccessUsername($trueAccess->getUsername());
  305.             }
  306.             else
  307.             {
  308.                 // Plan.io Task #4327
  309.                 if ($trueAccess instanceof AccessClient)
  310.                 {
  311.                     $log->setTrueAccessClientId($trueAccess->getId());
  312.                     $log->setTrueAccessClientUsername($trueAccess->getUsername());
  313.                 }
  314.             }
  315.         }
  316.         if ($falseAccess !== null)
  317.         {
  318.             if ($falseAccess instanceof Access)
  319.             {
  320.                 $log->setFalseAccessId($falseAccess->getId());
  321.                 $log->setFalseAccessUsername($falseAccess->getUsername());
  322.             }
  323.             else
  324.             {
  325.                 // Plan.io Task #4327
  326.                 if ($falseAccess instanceof AccessClient)
  327.                 {
  328.                     $log->setFalseAccessClientId($falseAccess->getId());
  329.                     $log->setFalseAccessClientUsername($falseAccess->getUsername());
  330.                 }
  331.             }
  332.         }
  333.         // Plan.io Task #4327
  334.         if ($access instanceof AccessClient)
  335.         {
  336.             if ($access->hasRoleAdmin())
  337.             {
  338.                 // Username is used for display : Do not display admin username
  339.                 $log->setAccessUsername("@rekapp");
  340.             }
  341.             else
  342.             {
  343.                 // Username is used for display : Use the username from the AccessClient
  344.                 $log->setAccessUsername("[Client] ".$access->getUsername());
  345.             }
  346.             // Keep the accessId not null by setting the ID of the EMPTY_ACCESS
  347.             $log->setAccessId($emptyAccess->getId());
  348.             // Set the correct AccessClient ID to the correct field
  349.             $log->setAccessClientId($access->getId());
  350.         }
  351.         // Log_Entity
  352.         $logEntity $logEntityRep->findOneByEntity($log->getObjectEntity());
  353.         if ($logEntity !== null)
  354.         {
  355.             $log->setLogEntityId($logEntity->getId());
  356.         }
  357.         // Translations
  358.         $identicalTranslations = array('Devis''Article''Note''Config');
  359.         if (!empty($log->getObjectEntity()))
  360.         {
  361.             $translation $this->translator->trans($log->getObjectEntity(), array(), 'logging');
  362.             if ($translation == $log->getObjectEntity() && !in_array($translation$identicalTranslations))
  363.             {
  364.                 // Translation not found
  365.                 // $this->createNotification($log->getObjectEntity());
  366.             }
  367.             $log->setObjectEntityTranslation($translation);
  368.         }
  369.         $translation $this->translator->trans($log->getAction(), array(), 'logging');
  370.         if ($translation == $log->getAction())
  371.         {
  372.             // Translation not found
  373.             // $this->createNotification($log->getAction());
  374.         }
  375.         $log->setActionTranslation($translation);
  376.         // Plan.io Task #3946
  377.         $log->setMobileApi($this->api);
  378.         // In all cases, log to file
  379.         // Nope, not in all cases
  380.         if (!($log instanceof ProjectManagerLog))
  381.         {
  382.             $this->logToFile($log);    
  383.         }
  384.         else
  385.         {
  386.             $this->logToProjectNotebookFile($log);
  387.         }        
  388.         // Also log to custom object files
  389.         $this->logToClientFile($log);
  390.         $this->logToMissionFile($log);
  391.         $this->logToHumanResourceFile($log);        
  392.         return $log;
  393.     }
  394.     public function handleSpecialCases($info$action)
  395.     {
  396.         if ($info == 'api_action')
  397.         {
  398.             $info null;
  399.             // Plan.io Task #3946
  400.             $access $this->getCustomApiAccess();
  401.             if ($access === null)
  402.             {
  403.                 $access $this->em->getRepository(Access::class)
  404.                     ->findOneByUsername(Access::API_ACCESS);
  405.             }
  406.             // Plan.io Task #3946
  407.             // Old Code
  408.             // $access = $this->em->getRepository(Access::class)
  409.             //     ->findOneByUsername(Access::API_ACCESS);
  410.         }
  411.         if ($info == 'jcaf_local')
  412.         {
  413.             $access $this->em->getRepository(Access::class)
  414.                 ->findOneByUsername(Access::JCAF_LOCAL);
  415.             $info null;
  416.         }
  417.         // Plan.io Task #3980
  418.         if ($info == 'sms_client_response')
  419.         {
  420.             $access $this->em->getRepository(Access::class)
  421.                 ->findOneByUsername(Access::EMPTY_ACCESS);
  422.             $info $this->translator->trans($info, array(), 'logging');
  423.         }
  424.         // Plan.io Task #3621
  425.         if ($info == 'ikea_service_order')
  426.         {
  427.             $access $this->em->getRepository(Access::class)
  428.                 ->findOneByUsername(Access::IKEA_SO);
  429.             $info null;
  430.         }
  431.         // Plan.io Task #3846
  432.         if ($action == "ikea_service_order_edit_status_forced")
  433.         {
  434.             // Plan.io Task #4040
  435.             // Desired display :
  436.             //      actual.user@rekapp.fr
  437.             //          If the actual user is logged in
  438.             //      @rekapp  |  brute_force_access : [1] oanalivia
  439.             //          If the user is impersonated by oanalivia, and an open_sesame user is viewing the page
  440.             //      @rekapp
  441.             //          If the user is impersonated by oanalivia, and a normal user is viewing the page
  442.             $originalUser $this->getOriginalUser();
  443.             // Switch user case
  444.             if ($originalUser !== null)
  445.             {
  446.                 // We have two users
  447.                 $bruteForceAccess $originalUser;
  448.                 // In this case we want to display a standard value in the user field
  449.                 $access $this->em->getRepository(Access::class)
  450.                     ->findOneByUsername(Access::REKAPP);
  451.                 $info "brute_force_access : ".$bruteForceAccess->displayForLog();
  452.             }
  453.             else
  454.             {
  455.                 // We only have one user, the real one
  456.                 $bruteForceAccess $this->getCurrentUser();
  457.                 $access $this->getCurrentUser();
  458.                 $info null;
  459.             }
  460.             // In this case we want to display a standard value in the user field
  461.             // $access = $this->em->getRepository(Access::class)
  462.             //     ->findOneByUsername(Access::REKAPP);
  463.         }
  464.         return array(
  465.             'access'    =>  $access,
  466.             'info'      =>  $info,
  467.         );
  468.     }
  469.     public function createNotification($msg)
  470.     {
  471.         $devs $this->em->getRepository(Access::class)->getDevs();
  472.         $origin "Services :: Logging :: log";
  473.         $type $this->em->getRepository(NotificationType::class)
  474.             ->findOneBy(array(
  475.                 'dev'        =>    1,
  476.                 'warning'    =>    1,
  477.             ));
  478.         if ($this->em->isOpen())
  479.         {
  480.             foreach ($devs as $dev)
  481.             {
  482.                 $notification = new DingNotification();
  483.                 $notification->setType($type);
  484.                 $notification->setAccess($dev);
  485.                 $notification->setTitle("Translation not found");
  486.                 $notification->setBody($msg);
  487.                 $notification->setOrigin($origin);
  488.                 $this->em->persist($notification);
  489.             }
  490.             return true;
  491.         }
  492.         else
  493.         {
  494.             error_log("Translation not found : ".$msg1'd.bernard@dvlpr.fr');
  495.         }
  496.         return false;
  497.     }
  498.     public function logToFile($log)
  499.     {
  500.         // Get the log directory
  501.         // Plan.io Task #3922 
  502.         // Old path : ROOT/custom_logs/global_logs
  503.         // New path : ROOT/DMS/Logs/Global/
  504.         $logPath $this->getDMS_GlobalLogsDir();
  505.         
  506.         // Construct path to file
  507.         $logFile $this->getLogFilePath($log$logPathself::log_to_file_global);
  508.         // $this->ploopLog("[Logging][logToFile] Logging to ".$logFile);
  509.         $this->logColumnHeaders($logFile);
  510.         $this->logLine($logFile$log);
  511.         return true;
  512.     }
  513.     private function logColumnHeaders($logFile)
  514.     {
  515.         // If the log file does not exist, create a first line with the column haders
  516.         if (file_exists($logFile))
  517.             return;
  518.         // Write title
  519.         error_log("\n",3,$logFile);
  520.         error_log("Date de creation",3,$logFile);
  521.         error_log(";",3,$logFile);
  522.         error_log("Id Utilisateur",3,$logFile);
  523.         error_log(";",3,$logFile);
  524.         error_log("Utilisateur",3,$logFile);
  525.         error_log(";",3,$logFile);
  526.         // Society Group
  527.         error_log("Id Groupe de sociétés",3,$logFile);
  528.         error_log(";",3,$logFile);
  529.         error_log("Référence interne groupe de sociétés",3,$logFile);
  530.         error_log(";",3,$logFile);
  531.         error_log("Référence groupe de sociétés",3,$logFile);
  532.         error_log(";",3,$logFile);
  533.         error_log("Nom groupe de sociétés",3,$logFile);
  534.         error_log(";",3,$logFile);
  535.         // Society
  536.         error_log("Id société",3,$logFile);
  537.         error_log(";",3,$logFile);
  538.         error_log("Référence société",3,$logFile);
  539.         error_log(";",3,$logFile);
  540.         error_log("Nom société",3,$logFile);
  541.         error_log(";",3,$logFile);
  542.         // Action
  543.         error_log("Action",3,$logFile);
  544.         error_log(";",3,$logFile);
  545.         error_log("Action (fr)",3,$logFile);
  546.         error_log(";",3,$logFile);
  547.         // Object
  548.         error_log("Id objet",3,$logFile);
  549.         error_log(";",3,$logFile);
  550.         error_log("Bundle objet",3,$logFile);
  551.         error_log(";",3,$logFile);
  552.         error_log("Entité objet",3,$logFile);
  553.         error_log(";",3,$logFile);
  554.         error_log("Entité objet (fr)",3,$logFile);
  555.         error_log(";",3,$logFile);
  556.         error_log("Objet",3,$logFile);
  557.         error_log(";",3,$logFile);
  558.         // Object Client
  559.         error_log("Id client",3,$logFile);
  560.         error_log(";",3,$logFile);
  561.         error_log("Client",3,$logFile);
  562.         error_log(";",3,$logFile);
  563.         // Values
  564.         error_log("Ancienne valeur",3,$logFile);
  565.         error_log(";",3,$logFile);
  566.         error_log("Nouvelle valeur",3,$logFile);
  567.         error_log(";",3,$logFile);
  568.         // Info
  569.         error_log("Info",3,$logFile);
  570.         error_log(";",3,$logFile);
  571.         // Log Entity Id
  572.         error_log("Id LogEntity",3,$logFile);
  573.         error_log(";",3,$logFile);
  574.         // Switch user
  575.         error_log("Id Utilisateur réel",3,$logFile);
  576.         error_log(";",3,$logFile);
  577.         error_log("Utilisateur réel",3,$logFile);
  578.         error_log(";",3,$logFile);
  579.         error_log("Id Utilisateur impersonifié",3,$logFile);
  580.         error_log(";",3,$logFile);
  581.         error_log("Utilisateur impersonifié",3,$logFile);
  582.         error_log(";",3,$logFile);
  583.         // Plan.io Task #3815
  584.         error_log("Trace",3,$logFile);
  585.         error_log(";",3,$logFile);
  586.         // Object Mission
  587.         // Add them at the end of the file
  588.         // to ensure backwards compatibility with older files
  589.         error_log("Id dossier",3,$logFile);
  590.         error_log(";",3,$logFile);
  591.         error_log("Dossier",3,$logFile);
  592.         error_log(";",3,$logFile);
  593.         // Object HumanResource
  594.         // Add them at the end of the file
  595.         // to ensure backwards compatibility with older files
  596.         error_log("Id ressource humaine",3,$logFile);
  597.         error_log(";",3,$logFile);
  598.         error_log("Ressource humaine",3,$logFile);
  599.         error_log(";",3,$logFile);
  600.         
  601.     }
  602.     // Modified by Plan.io Task #3953
  603.     private function logLine($logFile$log)
  604.     {
  605.         error_log("\n",3,$logFile);
  606.         error_log($this->formatForLog($log->getCreationDate()->format('Y-m-d H:i:s')),3,$logFile);
  607.         error_log(";",3,$logFile);
  608.         // Access
  609.         $value $log->getAccessId();
  610.         if (empty($value)) $value 0;
  611.         error_log($value,3,$logFile);
  612.         error_log(";",3,$logFile);
  613.         $value $this->formatForLog($log->getAccessUsername());
  614.         if (empty($value)) $value "";
  615.         error_log($value,3,$logFile);
  616.         error_log(";",3,$logFile);
  617.         // Society Group
  618.         $value $log->getSocietyGroupId();
  619.         if (empty($value)) $value 0;
  620.         error_log($value,3,$logFile);
  621.         error_log(";",3,$logFile);
  622.         $value $this->formatForLog($log->getSocietyGroupInternalRef());
  623.         if (empty($value)) $value "";
  624.         error_log($value,3,$logFile);
  625.         error_log(";",3,$logFile);
  626.         $value $this->formatForLog($log->getSocietyGroupRef());
  627.         if (empty($value)) $value "";
  628.         error_log($value,3,$logFile);
  629.         error_log(";",3,$logFile);
  630.         $value $this->formatForLog($log->getSocietyGroupName());
  631.         if (empty($value)) $value "";
  632.         error_log($value,3,$logFile);
  633.         error_log(";",3,$logFile);
  634.         // Society
  635.         $value $log->getSocietyId();
  636.         if (empty($value)) $value 0;
  637.         error_log($value,3,$logFile);
  638.         error_log(";",3,$logFile);
  639.         $value $this->formatForLog($log->getSocietyRef());
  640.         if (empty($value)) $value "";
  641.         error_log($value,3,$logFile);
  642.         error_log(";",3,$logFile);
  643.         $value $this->formatForLog($log->getSocietyName());
  644.         if (empty($value)) $value "";
  645.         error_log($value,3,$logFile);
  646.         error_log(";",3,$logFile);
  647.         // Action
  648.         $value $this->formatForLog($log->getAction());
  649.         if (empty($value)) $value "";
  650.         error_log($value,3,$logFile);
  651.         error_log(";",3,$logFile);
  652.         $value $this->formatForLog($log->getActionTranslation());
  653.         if (empty($value)) $value "";
  654.         error_log($value,3,$logFile);
  655.         error_log(";",3,$logFile);
  656.         // Object
  657.         $value $log->getObjectId();
  658.         if (empty($value)) $value 0;
  659.         error_log($value,3,$logFile);
  660.         error_log(";",3,$logFile);
  661.         $value $this->formatForLog($log->getObjectBundle());
  662.         if (empty($value)) $value "";
  663.         error_log($value,3,$logFile);
  664.         error_log(";",3,$logFile);
  665.         $value $this->formatForLog($log->getObjectEntity());
  666.         if (empty($value)) $value "";
  667.         error_log($value,3,$logFile);
  668.         error_log(";",3,$logFile);
  669.         $value $this->formatForLog($log->getObjectEntityTranslation());
  670.         if (empty($value)) $value "";
  671.         error_log($value,3,$logFile);
  672.         error_log(";",3,$logFile);
  673.         $value $this->formatForLog($log->getObjectDisplay());
  674.         if (empty($value)) $value "";
  675.         error_log($value,3,$logFile);
  676.         error_log(";",3,$logFile);
  677.         // Object Client
  678.         $value $log->getObjectClientId();
  679.         if (empty($value)) $value 0;
  680.         error_log($value,3,$logFile);
  681.         error_log(";",3,$logFile);
  682.         $value $this->formatForLog($log->getObjectClientDisplay());
  683.         if (empty($value)) $value "";
  684.         error_log($value,3,$logFile);
  685.         error_log(";",3,$logFile);
  686.         // Values
  687.         $value $this->formatForLog($log->getOldValue());
  688.         if (empty($value)) $value "";
  689.         error_log($value,3,$logFile);
  690.         error_log(";",3,$logFile);
  691.         $value $this->formatForLog($log->getNewValue());
  692.         if (empty($value)) $value "";
  693.         error_log($value,3,$logFile);
  694.         error_log(";",3,$logFile);
  695.         // Info
  696.         $value $this->formatForLog($log->getInfo());
  697.         if (empty($value)) $value "";
  698.         error_log($value,3,$logFile);
  699.         error_log(";",3,$logFile);
  700.         // Log Entity Id
  701.         $value $log->getLogEntityId();
  702.         if (empty($value)) $value 0;
  703.         error_log($value,3,$logFile);
  704.         error_log(";",3,$logFile);
  705.         // Switch user
  706.         $value $log->getTrueAccessId();
  707.         if (empty($value)) $value 0;
  708.         error_log($value,3,$logFile);
  709.         error_log(";",3,$logFile);
  710.         error_log($this->formatForLog($log->getTrueAccessUsername()),3,$logFile);
  711.         error_log(";",3,$logFile);
  712.         $value $log->getFalseAccessId();
  713.         if (empty($value)) $value 0;
  714.         error_log($value,3,$logFile);
  715.         error_log(";",3,$logFile);
  716.         $value $this->formatForLog($log->getFalseAccessUsername());
  717.         if (empty($value)) $value "";
  718.         error_log($value,3,$logFile);
  719.         error_log(";",3,$logFile);
  720.         // Plan.io Task #3815
  721.         $value $this->formatForLog($log->getTrace());
  722.         if (empty($value)) $value "";
  723.         error_log($value,3,$logFile);
  724.         error_log(";",3,$logFile);
  725.         // Object Mission
  726.         // Add them at the end of the file
  727.         // to ensure backwards compatibility with older files
  728.         $value $log->getObjectMissionId();
  729.         if (empty($value)) $value 0;
  730.         error_log($value,3,$logFile);
  731.         error_log(";",3,$logFile);
  732.         $value $this->formatForLog($log->getObjectMissionDisplay());
  733.         if (empty($value)) $value "";
  734.         error_log($value,3,$logFile);
  735.         error_log(";",3,$logFile);
  736.         // Object HumanResource
  737.         // Add them at the end of the file
  738.         // to ensure backwards compatibility with older files
  739.         if ($log instanceof HRLog)
  740.         {
  741.             $value $log->getObjectHumanResourceId();
  742.             if (empty($value)) $value 0;
  743.             error_log($value,3,$logFile);
  744.             error_log(";",3,$logFile);
  745.             $value $this->formatForLog($log->getObjectHumanResourceDisplay());
  746.             if (empty($value)) $value "";
  747.             error_log($value,3,$logFile);
  748.             error_log(";",3,$logFile);
  749.         }
  750.         else
  751.         {
  752.             $value 0;
  753.             error_log($value,3,$logFile);
  754.             error_log(";",3,$logFile);
  755.             
  756.             $value "";
  757.             error_log($value,3,$logFile);
  758.             error_log(";",3,$logFile);
  759.         }
  760.     }
  761.     private function formatForLog($text)
  762.     {
  763.         if (!empty($text))
  764.         {
  765.             $text str_replace('"'""$text);
  766.             $text str_replace(";"""$text);
  767.         }
  768.         $text "\"".$text."\"";
  769.         return $text;
  770.     }
  771.     // Plan.io Task #3946
  772.     public function isApi()
  773.     {
  774.         $this->api false;
  775.         $access $this->security->getUser();
  776.         if (!empty($access) && ($access instanceof AccessAPI))
  777.         {
  778.             $this->api true;
  779.             return true;
  780.         }
  781.         return false;
  782.     }
  783.     // Plan.io Task #3946
  784.     // Matches
  785.     //  AccessAPI::ACCESS_API_JCAF with Access::API_ACCESS_JCAF
  786.     //  AccessAPI::ACCESS_API_REKTO with Access::API_ACCESS_REKTO
  787.     public function getCustomApiAccess()
  788.     {
  789.         $access $this->security->getUser();
  790.         if (!empty($access) && ($access instanceof AccessAPI))
  791.         {
  792.             // Access is AccessAPI (maybe not in all cases),
  793.             // but either Jcaf or Rekto, so it does not count
  794.             $this->api false;
  795.             if ($access->getUsername() == AccessAPI::ACCESS_API_JCAF)
  796.             {
  797.                 $access $this->em->getRepository(Access::class)
  798.                     ->findOneByUsername(Access::API_ACCESS_JCAF);
  799.                 return $access;
  800.             }
  801.             if ($access->getUsername() == AccessAPI::ACCESS_API_REKTO)
  802.             {
  803.                 $access $this->em->getRepository(Access::class)
  804.                     ->findOneByUsername(Access::API_ACCESS_REKTO);
  805.                 return $access;
  806.             }
  807.         }
  808.         return null;
  809.     }
  810.     // Always return an object of type Access
  811.     // If the $this->security->getUser() is instanceof AccessAPI,
  812.     // the method returns the access corresponing to the AccessAPI
  813.     // Exception : JCAF and REKTO AccessAPI do not have corresponing accesses
  814.     // In this case we call the getCustomApiAccess() method,
  815.     // which identifies the two correct Accesses :
  816.     // Matches
  817.     //  AccessAPI::ACCESS_API_JCAF with Access::API_ACCESS_JCAF
  818.     //  AccessAPI::ACCESS_API_REKTO with Access::API_ACCESS_REKTO
  819.     public function getCurrentUser()
  820.     {
  821.         $emptyAccess $this->em->getRepository(Access::class)->findOneByEmail(Access::EMPTY_ACCESS);
  822.         // Get the Access|AccessAPI|AccessClient object returned by the security
  823.         $access $this->security->getUser();
  824.         if (empty($access))
  825.         {
  826.             // This occurs when the code is execuded by a Command (CRON Task for example)
  827.             // In this case there is no firewall, and thus no Access|AccessAPI
  828.             $access $emptyAccess;
  829.         }
  830.         else
  831.         {
  832.             // The firewall has been bypassed => We have an user provider,
  833.             // either Access or AccessAPI
  834.             // Plan.io Task #4327 ... or an AccessClient :)
  835.             if (!($access instanceof Access) && !($access instanceof AccessAPI) && !($access instanceof AccessClient))
  836.             {
  837.                 // This should not happen, but hey, life is weird, who knows
  838.                 // Even VSCode proved to be worse than Atom ;)
  839.                 $access $emptyAccess;
  840.             }
  841.         }
  842.         // Plan.io Task #3946
  843.         if ($access instanceof AccessAPI)
  844.         {
  845.             // Almost all AccessAPI have a corresponding Access, so retrive it
  846.             $access $access->getAccess();
  847.         }
  848.         // Plan.io Task #4327
  849.         if ($access instanceof AccessClient)
  850.         {
  851.             // Return it
  852.             return $access;
  853.         }
  854.         // Exception : AccessAPI used for Jcaf and Rekto Api
  855.         // In this case AccessAPI.access is null
  856.         if ($access === null)
  857.         {
  858.             // So now we know that we are in the special case of Jcaf or Rekto
  859.             // so try to match the correct Access
  860.             $access $this->getCustomApiAccess();
  861.             if ($access === null)
  862.             {
  863.                 // Once again this should not happen, but life is strange and impredictable
  864.                 $access $emptyAccess;
  865.             }
  866.             // Cas special Jcaf/Rekto
  867.             // Ah, by the way, if the api is the one used by Jcaf / Rekto
  868.             // we don't want to tag the log as being mobile api (reserve that title for Synertic for now)
  869.             $this->api false;
  870.         }
  871.         // if (empty($access) || !($access instanceof Access))
  872.         // {
  873.         //     $access = $this->em->getRepository(Access::class)->findOneByEmail(Access::EMPTY_ACCESS);
  874.         // }
  875.         return $access;
  876.     }
  877.     public function handleNormalCases()
  878.     {
  879.         $originalUser $this->getOriginalUser();
  880.         // Switch user case
  881.         if ($originalUser !== null)
  882.         {
  883.             // We have two users,
  884.             // an impersonator (trueAccess)
  885.             // and an impersonated one (falseAccess)
  886.             $trueAccess $originalUser;
  887.             $falseAccess $this->getCurrentUser();
  888.             // In this case we want to display a standard value in the user field
  889.             // depending on the type of user (Access or AccessClient)
  890.             if ($falseAccess instanceof Access)
  891.             {
  892.                 $access $this->em->getRepository(Access::class)
  893.                     ->findOneByUsername(Access::REKAPP);
  894.             }
  895.             else
  896.             {
  897.                 // Plan.io Task #4327
  898.                 // When impersonating an AccessClient we want to have some knowledge that
  899.                 // the modifications were done on the Client Platform and not the usual @rekapp user
  900.                 if ($falseAccess instanceof AccessClient)
  901.                 {
  902.                     $access $this->em->getRepository(Access::class)
  903.                         ->findOneByUsername(Access::CLIENT_PLATFORM);
  904.                 }
  905.             }
  906.         }
  907.         else
  908.         {
  909.             // We only have one user, the real one
  910.             $trueAccess null;
  911.             $falseAccess null;
  912.             $access $this->getCurrentUser();
  913.         }
  914.         return array(
  915.             'access'        =>  $access,
  916.             'trueAccess'    =>  $trueAccess,
  917.             'falseAccess'   =>  $falseAccess,
  918.         );
  919.     }
  920.     // https://symfony.com/doc/5.4/security/impersonating_user.html
  921.     // This is also in AdminVoter
  922.     // This is also in Logger
  923.     // This is also in LogTools
  924.     public function getOriginalUser()
  925.     {
  926.         $originalUser null;
  927.         // #3251 Fix to avoid infinity loop
  928.         $currentUser $this->getCurrentUser();
  929.         if ($currentUser === null || $currentUser->getEmail() == Access::EMPTY_ACCESS)
  930.         {
  931.             return null;
  932.         }
  933.         $token $this->security->getToken();
  934.         if ($token instanceof SwitchUserToken)
  935.         {
  936.             $originalUser $token->getOriginalToken()->getUser();
  937.         }
  938.         return $originalUser;
  939.     }
  940.     public function logToClientFile($log)
  941.     {
  942.         if (empty($log->getObjectClientId()))
  943.         {
  944.             // Nothing to do here
  945.             return true;
  946.         }
  947.         // Get the log directory
  948.         // ROOT/DMS/Logs/Client/
  949.         $logPath $this->getDMS_ClientLogsDir();
  950.         // Construct path to file
  951.         $logFile $this->getLogFilePath($log$logPathself::log_to_file_client);        
  952.         $this->logColumnHeaders($logFile);
  953.         $this->logLine($logFile$log);
  954.         return true;
  955.     }
  956.     public function logToMissionFile($log)
  957.     {
  958.         if (empty($log->getObjectMissionId()))
  959.         {
  960.             // Nothing to do here
  961.             return true;
  962.         }
  963.         if ($log instanceof ProjectManagerLog)
  964.         {
  965.             // Do not log ProjectNotebookItem actions to mission
  966.             // Only log the creation / removal of the actual notebook
  967.             if ($log->getObjectEntity() == "ProjectNotebookItem")
  968.             {
  969.                 return true;
  970.             }
  971.         }
  972.         // Get the log directory
  973.         // ROOT/DMS/Logs/Mission/
  974.         $logPath $this->getDMS_MissionLogsDir();
  975.         // Construct path to file
  976.         $logFile $this->getLogFilePath($log$logPathself::log_to_file_mission);
  977.         $this->logColumnHeaders($logFile);
  978.         $this->logLine($logFile$log);
  979.         return true;
  980.     }
  981.     public function logToHumanResourceFile($log)
  982.     {
  983.         if (!($log instanceof HRLog))
  984.         {
  985.             // Nothing to do here
  986.             return true;
  987.         }
  988.         if (empty($log->getObjectHumanResourceId()))
  989.         {
  990.             // Nothing to do here
  991.             return true;
  992.         }
  993.         // Get the log directory
  994.         // ROOT/DMS/Logs/HumanResource/
  995.         $logPath $this->getDMS_HumanResourceLogsDir();
  996.         // Construct path to file
  997.         $logFile $this->getLogFilePath($log$logPathself::log_to_file_human_resource);
  998.         $this->logColumnHeaders($logFile);
  999.         $this->logLine($logFile$log);
  1000.         return true;
  1001.     }
  1002.     public function logToProjectNotebookFile($log)
  1003.     {
  1004.         if (!($log instanceof ProjectManagerLog))
  1005.         {
  1006.             // $this->ploopLog("[logToProjectNotebookFile] log is not ProjectManagerLog");
  1007.             // Nothing to do here
  1008.             return true;
  1009.         }
  1010.         if (empty($log->getNotebookId()))
  1011.         {
  1012.             // $this->ploopLog("[logToProjectNotebookFile] notebookId is empty");
  1013.             // Nothing to do here
  1014.             return true;
  1015.         }
  1016.         // $this->ploopLog("[logToProjectNotebookFile] All looks good");
  1017.         // Get the log directory
  1018.         // DMS/Logs/ProjectManager/Notebook/
  1019.         $logPath $this->getDMS_ProjectManagerNotebookLogsDir();
  1020.         // Construct path to file
  1021.         $logFile $this->getLogFilePath($log$logPathself::log_to_file_project_notebook);
  1022.         $this->logColumnHeadersForProjectManager($logFile);
  1023.         $this->logLineForProjectManager($logFile$log);
  1024.         return true;
  1025.     }
  1026.     public function getLogFilePath($logstring $logPathint $type)
  1027.     {
  1028.         $logFileName null;
  1029.         $logFolderName null;
  1030.         // Get the log directory
  1031.         $today = new \DateTime();
  1032.         // Plan.io Task #3922 
  1033.         // Old path : ROOT/custom_logs/global_logs
  1034.         // New path : ROOT/DMS/Logs/Global/
  1035.         // $logPath = $this->getDMS_GlobalLogsDir();        
  1036.         $originalLogPath $logPath;
  1037.         if (!file_exists($originalLogPath))
  1038.         {
  1039.             // Create it
  1040.             $folderCreated mkdir($originalLogPath0755true);
  1041.             if (!$folderCreated)
  1042.             {
  1043.                 // This should not happen
  1044.                 error_log("mkdir fail for ".$originalLogPath1'oanalivia@gmail.com');
  1045.                 return false;
  1046.             }
  1047.         }
  1048.         // Get the society group
  1049.         $societyGroupId $log->getSocietyGroupId();
  1050.         $societyGroupRef strtoupper($log->getSocietyGroupInternalRef());
  1051.         if (!empty($societyGroupId) && !empty($societyGroupRef))
  1052.         {
  1053.             // If one is not empty the other is also not empty
  1054.             // Craft folder name
  1055.             $logFolderName $societyGroupId."_".$societyGroupRef;
  1056.             // Craft file name
  1057.             if ($type == self::log_to_file_global)
  1058.             {
  1059.                 // Global Logs
  1060.                 $logFileName "app_log_".$societyGroupId."_".$societyGroupRef;
  1061.                 $logFileName .= "_".$today->format("Y_m").".csv";
  1062.             }
  1063.             elseif ($type == self::log_to_file_mission)
  1064.             {
  1065.                 // Mission Logs
  1066.                 $id $log->getObjectMissionId();
  1067.                 $logFileName "mission_log_".$id.".csv";
  1068.             }
  1069.             elseif ($type == self::log_to_file_client)
  1070.             {
  1071.                 // Client Logs
  1072.                 $id $log->getObjectClientId();
  1073.                 $logFileName "client_log_".$id.".csv";
  1074.             }            
  1075.             elseif ($type == self::log_to_file_human_resource)
  1076.             {
  1077.                 // Client Logs
  1078.                 $id $log->getObjectHumanResourceId();
  1079.                 $logFileName "human_resource_log_".$id.".csv";
  1080.             }            
  1081.             elseif ($type == self::log_to_file_project_notebook)
  1082.             {
  1083.                 // Client Logs
  1084.                 $id $log->getNotebookId();
  1085.                 $logFileName "project_notebook_log_".$id.".csv";
  1086.             }            
  1087.         }
  1088.         else
  1089.         {
  1090.             $logFolderName null;
  1091.             $logFileName "app_log_".$today->format("Y_m").".csv";
  1092.         }
  1093.         if ($logFolderName !== null)
  1094.         {
  1095.             // Does the folder exist ?
  1096.             $folderPath $originalLogPath.$logFolderName;
  1097.             if (!file_exists($folderPath))
  1098.             {
  1099.                 // Create it
  1100.                 $folderCreated mkdir($folderPath0755true);
  1101.                 if ($folderCreated)
  1102.                 {
  1103.                     $logPath $originalLogPath.$logFolderName."/";
  1104.                 }
  1105.                 else
  1106.                 {
  1107.                     // This should not happen
  1108.                     error_log("mkdir fail for ".$folderPath1'oanalivia@gmail.com');
  1109.                     $logPath $originalLogPath;
  1110.                 }
  1111.             }
  1112.             else
  1113.             {
  1114.                 $logPath $originalLogPath.$logFolderName."/";
  1115.             }
  1116.         }
  1117.         else
  1118.         {
  1119.             $logPath $originalLogPath;
  1120.         }
  1121.         // In both cases, construct the log file path
  1122.         $logFile $logPath.$logFileName;
  1123.         return $logFile;
  1124.     }
  1125.     private function logColumnHeadersForProjectManager($logFile)
  1126.     {
  1127.         // If the log file does not exist, create a first line with the column haders
  1128.         if (file_exists($logFile))
  1129.             return;
  1130.         // Write title
  1131.         error_log("\n",3,$logFile);
  1132.         error_log("Date de creation",3,$logFile);
  1133.         error_log(";",3,$logFile);
  1134.         error_log("Id Utilisateur",3,$logFile);
  1135.         error_log(";",3,$logFile);
  1136.         error_log("Utilisateur",3,$logFile);
  1137.         error_log(";",3,$logFile);
  1138.         // Action
  1139.         error_log("Action",3,$logFile);
  1140.         error_log(";",3,$logFile);
  1141.         error_log("Action (fr)",3,$logFile);
  1142.         error_log(";",3,$logFile);
  1143.         // Object
  1144.         error_log("Id Notebook",3,$logFile);
  1145.         error_log(";",3,$logFile);
  1146.         error_log("Code Module",3,$logFile);
  1147.         error_log(";",3,$logFile);
  1148.         error_log("Objet Module",3,$logFile);
  1149.         error_log(";",3,$logFile);
  1150.         error_log("Id objet",3,$logFile);
  1151.         error_log(";",3,$logFile);
  1152.         error_log("Objet",3,$logFile);
  1153.         error_log(";",3,$logFile);
  1154.         // Values
  1155.         error_log("Ancienne valeur",3,$logFile);
  1156.         error_log(";",3,$logFile);
  1157.         error_log("Nouvelle valeur",3,$logFile);
  1158.         error_log(";",3,$logFile);
  1159.         // Info
  1160.         error_log("Info",3,$logFile);
  1161.         error_log(";",3,$logFile);
  1162.         // Switch user
  1163.         error_log("Id Utilisateur réel",3,$logFile);
  1164.         error_log(";",3,$logFile);
  1165.         error_log("Utilisateur réel",3,$logFile);
  1166.         error_log(";",3,$logFile);
  1167.         error_log("Id Utilisateur impersonifié",3,$logFile);
  1168.         error_log(";",3,$logFile);
  1169.         error_log("Utilisateur impersonifié",3,$logFile);
  1170.         error_log(";",3,$logFile);
  1171.     }
  1172.     private function logLineForProjectManager($logFile$log)
  1173.     {
  1174.         error_log("\n",3,$logFile);
  1175.         error_log($this->formatForLog($log->getCreationDate()->format('Y-m-d H:i:s')),3,$logFile);
  1176.         error_log(";",3,$logFile);
  1177.         // Access
  1178.         $value $log->getAccessId();
  1179.         if (empty($value)) $value 0;
  1180.         error_log($value,3,$logFile);
  1181.         error_log(";",3,$logFile);
  1182.         $value $this->formatForLog($log->getAccessUsername());
  1183.         if (empty($value)) $value "";
  1184.         error_log($value,3,$logFile);
  1185.         error_log(";",3,$logFile);        
  1186.         // Action
  1187.         $value $this->formatForLog($log->getAction());
  1188.         if (empty($value)) $value "";
  1189.         error_log($value,3,$logFile);
  1190.         error_log(";",3,$logFile);
  1191.         $value $this->formatForLog($log->getActionTranslation());
  1192.         if (empty($value)) $value "";
  1193.         error_log($value,3,$logFile);
  1194.         error_log(";",3,$logFile);
  1195.         // Object
  1196.         $value $log->getNotebookId();
  1197.         if (empty($value)) $value 0;
  1198.         error_log($value,3,$logFile);
  1199.         error_log(";",3,$logFile);        
  1200.         
  1201.         $value $log->getModuleCode();
  1202.         if (empty($value)) $value 0;
  1203.         error_log($value,3,$logFile);
  1204.         error_log(";",3,$logFile);     
  1205.         
  1206.         $value $this->formatForLog($log->getModuleDisplay());
  1207.         if (empty($value)) $value "";
  1208.         error_log($value,3,$logFile);
  1209.         error_log(";",3,$logFile);
  1210.         $value $log->getObjectId();
  1211.         if (empty($value)) $value 0;
  1212.         error_log($value,3,$logFile);
  1213.         error_log(";",3,$logFile);        
  1214.         $value $this->formatForLog($log->getObjectDisplay());
  1215.         if (empty($value)) $value "";
  1216.         error_log($value,3,$logFile);
  1217.         error_log(";",3,$logFile);        
  1218.         // Values
  1219.         $value $this->formatForLog($log->getOldValue());
  1220.         if (empty($value)) $value "";
  1221.         error_log($value,3,$logFile);
  1222.         error_log(";",3,$logFile);
  1223.         $value $this->formatForLog($log->getNewValue());
  1224.         if (empty($value)) $value "";
  1225.         error_log($value,3,$logFile);
  1226.         error_log(";",3,$logFile);
  1227.         // Info
  1228.         $value $this->formatForLog($log->getInfo());
  1229.         if (empty($value)) $value "";
  1230.         error_log($value,3,$logFile);
  1231.         error_log(";",3,$logFile);        
  1232.         // Switch user
  1233.         $value $log->getTrueAccessId();
  1234.         if (empty($value)) $value 0;
  1235.         error_log($value,3,$logFile);
  1236.         error_log(";",3,$logFile);
  1237.         error_log($this->formatForLog($log->getTrueAccessUsername()),3,$logFile);
  1238.         error_log(";",3,$logFile);
  1239.         $value $log->getFalseAccessId();
  1240.         if (empty($value)) $value 0;
  1241.         error_log($value,3,$logFile);
  1242.         error_log(";",3,$logFile);
  1243.         $value $this->formatForLog($log->getFalseAccessUsername());
  1244.         if (empty($value)) $value "";
  1245.         error_log($value,3,$logFile);
  1246.         error_log(";",3,$logFile);        
  1247.     }
  1248. }