<?php

//include_once("_nemo.email.cls.php"); 

class NemoFIM 
{
   private $dirRoot = ""; 
   private $arrExcludeWildcard = array(); 
 
   public function __construct($dirRoot="")
   { 
      global $siteEnviroment, $siteSessionpath, $siteDirectory, $siteWildcards;
 
      $this->arrExcludeWildcard = explode(";", $siteWildcards);
      $this->dirRoot = $dirRoot;
   }
  
   // NEW INISETPERMISSIONS FUNCTION - IS CALLED PER RECORD ON THE RECORD FUNCTION INSTEAD OF OWN PROCESS  
   public function iniSetPermissions($type, $value)
   {
      if ($type == "Dir")
      {
         if(file_exists($value))
         {
            // CHECK THAT DIR PERMISSION IS 0755 
            if(substr(sprintf("%o", fileperms($value)), -4) != "0755")
            {
               // IF IT IS NOT 0755 THEN MAKE IT 0755
               chmod($value, 0755); 
            }  
            return "success";
         } 
      }
      else if($type == "File")
      { 
         if(file_exists($value))
         {
            //CHECK THAT FILE PERMISSION IS 0644 
            if(substr(sprintf("%o", fileperms($value)), -4) != "0644")
            {  
               // IF IT IS NOT 0644 THEN MAKE IT 0644
               chmod($value, 0644);   
            } 
            return "success";
         } 
      }
      return "failed";
   }

   // UPDATED RECORD FUNCTION - MAKES USE OF A TIMER / COUNTER SETUP
   public function Record(&$result = array(), $dirRoot = null)
   { 
      // INI GLOBALS 
      global $arrSession, $siteEnviroment, $siteDirectory, $siteWildcards, $intDirCounter, $intGlobalCounter, $processUseTimer, $ProcessMaxRuntime, $processUseCounter, $processStartTime, $ProcessMaxCount, $FIMCronPath;
 
      // $intDirCounter - ACTS LIKE AN ID FOR THE FILES AND DIRECTORY
      // $intProcessPausedID - VALUE WHERE $intDirCounter WAS PAUSED
      // $intGlobalCounter - JUST A NORMAL COUNTER TO KEEP TRACK OF PROCESS , ONLY COUNTS VALID SAVES
      
      // INI VARS
      $intProcessPausedID = 0;
      if($intGlobalCounter == "") $intGlobalCounter = 0;
      if($intDirCounter == "") $intDirCounter = 0;
      if($arrSession[0] == 0) 
      { 
         $intProcessPausedID = $arrSession[1];
      }
 
      $intProcessComplete = 1; 
      
      $sesFile = fopen("sesFile.txt", "r+") or die("Unable to open file!"); 
      fwrite($sesFile, "$intProcessComplete\n");   
      fclose($sesFile); 

      $I_RECURSIVE = 0;

      // GETTING THE BASE URL - PROCESS SHOULD NOT RUN BEFOR THIS URL  
      if($dirRoot == null)
      {
         $dirRoot = $siteDirectory; 
      }

      // GET DIRECTORY INTO AN ARRAY
      $arrDir = scandir($dirRoot); 

      // LOOP THROUGHT DIRECTORY
      foreach ($arrDir as $i => $value)
      {  
         $I_RECURSIVE++;
         
         // WRONG FILE/FOLDER EXTENSION CHECK
         $fileExtension = substr($value, strpos($value, "."));

         // CHECK IF FILE TYPE HAS BEEN EXCLUDED FROM LOGGING
         if(!$this->in_array_wildcard($value, $this->arrExcludeWildcard, 0))
         {  
            $RuntTime = strtotime(date("Y-m-d H:i:s"))-strtotime($processStartTime);
 
            // IS RUNTIME BASED ON TIME OR COUNT?
            if($processUseTimer == 1)
            {
               // IF RUN LIMIT IS REACH - EXIT LOOP
               if($RuntTime > $ProcessMaxRuntime)
               {  
                  $intProcessComplete = 0;

                  // UPDATE sesFile WITH LAST ID USED  
                  $sesFile = fopen("sesFile.txt", "r+") or die("Unable to open file!"); 
                  fwrite($sesFile, "0\n");  
                  fwrite($sesFile, $intGlobalCounter);
                  fclose($sesFile); 
 
                  exit;
               } 
            }
            else if($processUseCounter == 1)
            {
               // IF RUN LIMIT IS REACH - EXIT LOOP
               if($intDirCounter == $ProcessMaxCount)
               {  
                  $intProcessComplete = 0;

                  // UPDATE sesFile WITH LAST ID USED     
                  $sesFile = fopen("sesFile.txt", "r+") or die("Unable to open file!"); 
                  fwrite($sesFile, "$intProcessComplete\n");  
                  fwrite($sesFile, $intGlobalCounter);
                  fclose($sesFile); 
 
                  exit;
               } 
            }
             
            $intGlobalCounter++; 
             
            // CHECK IF ARRAY ITEM IS FILE OR FOLDER
            if (is_dir($dirRoot . DIRECTORY_SEPARATOR . $value))
            {    
               //SKIP FOLDER AND FILES UNTIL IT PASS THE PAUESED ID
               if($intGlobalCounter <= $intProcessPausedID) 
               {    
                  //print_rr($intGlobalCounter . " ------- " . $i . " - " . $value . " - [VOID] - " . $intProcessPausedID); 
                  $this->Record($result, $dirRoot . DIRECTORY_SEPARATOR . $value);
                  continue;
               }

               // DEBUG
               //print_rr($intGlobalCounter . " ------- " . $i . " - " . $value . " - [] - " . $intProcessPausedID);
                
               // THIS COUNTER ANLY STARTS WHEN THE LOGGING STARTS
               $intDirCounter++;

               // SAVE IF EXIST
               if(file_exists( $dirRoot . DIRECTORY_SEPARATOR . $value))
               {  
                  // SAVE RECORD IN DB
                  $this->Save("Dir", $dirRoot . DIRECTORY_SEPARATOR . $value);

                  // UPDATE PERMISSIONS OF DIR
                  $this->iniSetPermissions("Dir", $dirRoot . DIRECTORY_SEPARATOR . $value);
               }

               //continue; // TESTING PURPOSE ONLY - WILL ONLY RUN TOP LEVEL IF ACTIVE

               //RERUN FUNCTION: TO RUN FILES IN FOLDER 
               $this->Record($result, $dirRoot . DIRECTORY_SEPARATOR . $value);
            }
            else
            {   
               //SKIP FOLDER AND FILES UNTIL IT PASS THE PAUESED ID
               if($intGlobalCounter <= $intProcessPausedID) 
               {    
                  //print_rr($intGlobalCounter . " ------- " . $i . " - " . $value . " - [VOID] - " . $intProcessPausedID);
                  continue;
               }

               // DEBUG
               //print_rr($intGlobalCounter . " ------- " . $i . " - " . $value . " - [] - " . $intProcessPausedID);
 
               // THIS COUNTER ANLY STARTS WHEN THE LOGGING STARTS
               $intDirCounter++;

               // SAVE IF EXIST
               if(file_exists( $dirRoot . DIRECTORY_SEPARATOR . $value))
               {  
                  // SAVE RECORD IN DB
                  $this->Save("File", $dirRoot . DIRECTORY_SEPARATOR . $value);

                  // UPDATE PERMISSIONS OF FILE
                  $this->iniSetPermissions("File", $dirRoot . DIRECTORY_SEPARATOR . $value);
               }
            } 
         }
      }
   }
 
   protected function Save($type, $value)
   { 
      // INI GLOBALS 
      //global $DATABASE_SETTINGS, $BR, $SP, $TR, $SystemSettings, $DT, $MYSQLI, $xdb;
      global $siteEnviroment, $siteDirectory, $siteWildcards, $intDirCounter, $intGlobalCounter, $conn;
      
      // INI
      $dtAudit = date("Y-m-d H:i:s");
      $strType = $type;

      // STRING PATH TO ONLY SHOW PATH FROM SITE DIRECTORY
      if(strpos($value, $siteDirectory) !== false) 
      {
         $strPath = str_replace($siteDirectory, "", $value);
      }
      else
      {
         $strPath = str_replace($siteDirectory, "", realpath($value));
      }

      $strOwner = strval(fileowner($value));
      $strPermission = substr(sprintf("%o", fileperms($value)), -4);
      $dblSize = strval(filesize($value));
      $dtModify = date("Y-m-d H:i:s", filemtime($value));
      $strLastUser = $siteEnviroment; 

      switch($type)
      {
         case "Dir":
            $strHash = sha1($strPath . $strOwner . $strPermission);
            $strExtension = "";
            break;

         case "File":
            $strHash = sha1(sha1_file(realpath($value)). $strOwner . $strPermission . $dblSize . $dtModify);
            $strExtension = pathinfo($value, PATHINFO_EXTENSION);
            break;
      }

      // SAVE QUERY
      $sql = " INSERT INTO sysAudit_$siteEnviroment (dtAudit, strType, strPath, strOwner, strPermission, dblSize, dtModify, strLastUser, strHash, strExtension)
               VALUES (
                  '$dtAudit', 
                  '$strType', 
                  '$strPath',
                  '$strOwner',
                  '$strPermission',
                  '$dblSize',
                  '$dtModify',
                  '$strLastUser',
                  '$strHash',
                  '$strExtension'
               )";

      // RUN QUERY
      $rst = mysqli_query($conn, "$sql");
   }

   public static function Compare($strPathIgnore=0)
   {
      global $siteProjectName, $siteEnviroment, $siteDirectory, $siteWildcards, $FIMBaseURL, $emailParameters, $conn;

      // INI
      $sysAudit_ENV = "sysAudit_". $siteEnviroment;
      $excludeMASTER = "";
      $excludeENV = "";
      $arrFields = array("strOwner" , "strPermission" , "dblSize" , "dtModify" , "strHash");
      $arrayChangesID = array();
      $i = 0;
      $trMissing = "";
      $trNew = "";
      $trChanges = "";
      $strBody = "";

      // GET ENV MAX AUDIT DATE
      $rst = mysqli_query($conn, "SELECT MAX(dtAudit) AS maxAudit FROM $sysAudit_ENV");
      $maxAudit = mysqli_fetch_object($rst)->maxAudit;  
 
      // BUILD EXCLUDE STRING FOR QUERY
      $arrIgnorePaths = explode(";", $siteWildcards);
      foreach($arrIgnorePaths as $key){ 
         $excludeMASTER .= " AND sysAudit_master.strPath NOT LIKE '".$key."' ";
         $excludeENV .= " AND $sysAudit_ENV.strPath NOT LIKE '".$key."' ";
      }

      // GET THE NUMBER OF CHANGES FOR THE DAY //////////////////////////////////////////////////
      
      // MUST HAVE THE SAME FROM / WHERE AS THE QUERY BELOW
      $sqlSummaryChanges = " 
         SELECT   
            COUNT(*) AS 'CountChanges', 
            MAX(sysAudit_master.dtModify) AS 'maxDtChanges', 
            MIN(sysAudit_master.dtModify) AS 'minDtChanges', 
            sysAudit_master.strHash, $sysAudit_ENV.strHash, 
            sysAudit_master.strPath, $sysAudit_ENV.strPath
         FROM sysAudit_master 
            INNER JOIN $sysAudit_ENV ON (sysAudit_master.strHash <> $sysAudit_ENV.strHash) AND (sysAudit_master.strPath = $sysAudit_ENV.strPath)
         WHERE $sysAudit_ENV.dtAudit ='$maxAudit' AND sysAudit_master.strHash <> 'IGNORE' $excludeMASTER "; 

      $rstSummaryChanges = mysqli_query($conn, $sqlSummaryChanges);
      $rowSummaryChanges = mysqli_fetch_object($rstSummaryChanges);  

      // GET THE DATA QUERY
      $sql = "SELECT sysAudit_master.ID AS 'MASTER_ID', sysAudit_master.dtAudit AS 'MASTER_dtAudit'
            , sysAudit_master.strType AS 'MASTER_strType', sysAudit_master.strPath AS 'MASTER_strPath'
            , sysAudit_master.strExtension AS 'MASTER_strExtension', sysAudit_master.strOwner AS 'MASTER_strOwner'
            , sysAudit_master.strPermission AS 'MASTER_strPermission'
            , sysAudit_master.dblSize AS 'MASTER_dblSize', sysAudit_master.dtModify AS 'MASTER_dtModify'
            , sysAudit_master.strHash AS 'MASTER_strHash'
            , $sysAudit_ENV.ID AS 'LIVE_ID', $sysAudit_ENV.dtAudit AS 'LIVE_dtAudit'
            , $sysAudit_ENV.strType AS 'LIVE_strType'
            , $sysAudit_ENV.strPath AS 'LIVE_strPath'
            , $sysAudit_ENV.strExtension AS 'LIVE_strExtension', $sysAudit_ENV.strOwner AS 'LIVE_strOwner'
            , $sysAudit_ENV.strPermission AS 'LIVE_strPermission'
            , $sysAudit_ENV.dblSize AS 'LIVE_dblSize', $sysAudit_ENV.dtModify AS 'LIVE_dtModify'
            , $sysAudit_ENV.strHash AS 'LIVE_strHash'
            FROM sysAudit_master INNER JOIN $sysAudit_ENV ON (sysAudit_master.strHash <> $sysAudit_ENV.strHash) AND (sysAudit_master.strPath = $sysAudit_ENV.strPath)
            WHERE $sysAudit_ENV.dtAudit ='$maxAudit' AND sysAudit_master.strHash <> 'IGNORE'
               $excludeMASTER
            ORDER BY MASTER_strPath, LIVE_strPath
            LIMIT 0,50";

      $rst = mysqli_query($conn, $sql);

      while($row = mysqli_fetch_object($rst))
      {
         // INI
         $colour = array();
         $colour["strType"] = "";
         $colour["strPath"] = "";
         $colour["strExtension"] = "";
         $colour["dtAudit"] = "";
         $colour["strOwner"] = "";
         $colour["strPermission"] = "";
         $colour["dblSize"] = ""; 
         $colour["dtModify"] = ""; 
         $colour["strHash"] = "";
         
         $blnDisplay = 1; 
         $i++;
         $arrayChangesID[$i] = $row->LIVE_ID;
         

         // COMPARE AND HIGHLIGHT CHANGES
         foreach($arrFields as $key)
         {
            $rowMaster = ("MASTER_".$key);
            $rowLive = ("LIVE_".$key);
            $colour[$key] = "black";

            if($row->$rowMaster != $row->$rowLive)
               $colour[$key] = "red";
         }

         if($row->MASTER_strType == "Dir" ){
            $colour[dblSize] = "black";
         }

         $IDChanges[$i] = $row->LIVE_ID;

         $trChanges .= "
            <input id='arrIDChanges[]' type='hidden' name='arrIDChanges[]' value='$row->LIVE_ID' >
            <tr>
               <td rowspan='2' align='left' style='color:".$colour["strType"].";' >$row->MASTER_strType</td>
               <td rowspan='2' align='left' style='color:".$colour["strPath"].";' >$row->MASTER_strPath</td>
               <td rowspan='2' align='left' style='color:".$colour["strExtension"].";' >$row->MASTER_strExtension</td>
               <th align='left'>MASTER</th>
               <td align='left' style='color:".$colour["dtAudit"].";' >$row->MASTER_dtAudit</td>
               <td align='left' style='color:".$colour["strOwner"].";' >$row->MASTER_strOwner</td>
               <td align='left' style='color:".$colour["strPermission"].";' >$row->MASTER_strPermission</td>
               <td align='left' style='color:".$colour["dblSize"].";' >$row->MASTER_dblSize</td>
               <td align='left' style='color:".$colour["dtModify"].";' >$row->MASTER_dtModify</td>
               <td align='left' style='color:".$colour["strHash"].";' >$row->MASTER_strHash</td>
               <td rowspan='2' align='center'>
               <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: IGNORE&ID=$row->MASTER_ID&state=CHANGES' target='_blank'>Ignore</a></td>
               <td rowspan='2' align='center'>
               <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: UPDATE&ID=$row->LIVE_ID&state=CHANGES' target='_blank' >Update</a></td>
            </tr>
            <tr>
               <th align='left'>QA</th>
               <td align='left' style='color:".$colour["dtAudit"].";' >$row->LIVE_dtAudit</td>
               <td align='left' style='color:".$colour["strOwner"].";' >$row->LIVE_strOwner</td>
               <td align='left' style='color:".$colour["strPermission"].";' >$row->LIVE_strPermission</td>
               <td align='left' style='color:".$colour["dblSize"].";' >$row->LIVE_dblSize</td>
               <td align='left' style='color:".$colour["dtModify"].";' >$row->LIVE_dtModify</td>
               <td align='left' style='color:".$colour["strHash"].";' >$row->LIVE_strHash</td>
            </tr> "; 
      }

      //ENCODED ARRAY ID TO PASS ON URL FOR EMAIL
      $arrDataChanges = json_encode($arrayChangesID);
      
      // GET MISSING RECORDS FOR THE DAY ////////////////////////////////////////////////////////
      // [M=>L, W. L.ID is Null]

      // MUST HAVE THE SAME FROM / WHERE AS THE QUERY BELOW
      $sqlSummaryMissing = " 
         SELECT 
            COUNT(*) AS 'CountMissing', 
            MAX(sysAudit_master.dtModify) AS 'maxDtMissing',
            MIN(sysAudit_master.dtModify) AS 'minDtMissing', 
            sysAudit_master.strHash, 
            $sysAudit_ENV.strHash,
            sysAudit_master.strPath, 
            $sysAudit_ENV.strPath
         FROM sysAudit_master 
            LEFT JOIN $sysAudit_ENV ON sysAudit_master.strPath = $sysAudit_ENV.strPath
         WHERE $sysAudit_ENV.ID Is Null AND sysAudit_master.strHash <> 'IGNORE' $excludeMASTER"; 

      $rstSummaryMissing = mysqli_query($conn, $sqlSummaryMissing);
      $rowSummaryMissing = mysqli_fetch_object($rstSummaryMissing);  

      // GET THE DATA QUERY
      $sql = "SELECT sysAudit_master.ID AS 'MASTER_ID', sysAudit_master.dtAudit AS 'MASTER_dtAudit'
            , sysAudit_master.strType AS 'MASTER_strType', sysAudit_master.strPath AS 'MASTER_strPath'
            , sysAudit_master.strExtension AS 'MASTER_strExtension', sysAudit_master.strOwner AS 'MASTER_strOwner'
            , sysAudit_master.strPermission AS 'MASTER_strPermission'
            , sysAudit_master.dblSize AS 'MASTER_dblSize', sysAudit_master.dtModify AS 'MASTER_dtModify'
            , sysAudit_master.strHash AS 'MASTER_strHash'
            , $sysAudit_ENV.ID AS 'LIVE_ID', $sysAudit_ENV.dtAudit AS 'LIVE_dtAudit'
            , $sysAudit_ENV.strType AS 'LIVE_strType', $sysAudit_ENV.strPath AS 'LIVE_strPath'
            , $sysAudit_ENV.strExtension AS 'LIVE_strExtension', $sysAudit_ENV.strOwner AS 'LIVE_strOwner'
            , $sysAudit_ENV.strPermission AS 'LIVE_strPermission'
            , $sysAudit_ENV.dblSize AS 'LIVE_dblSize', $sysAudit_ENV.dtModify AS 'LIVE_dtModify'
            , $sysAudit_ENV.strHash AS 'LIVE_strHash'
            FROM sysAudit_master LEFT JOIN $sysAudit_ENV ON sysAudit_master.strPath = $sysAudit_ENV.strPath
            WHERE $sysAudit_ENV.ID Is Null AND sysAudit_master.strHash <> 'IGNORE'
               $excludeMASTER
            ORDER BY MASTER_strPath, LIVE_strPath
            LIMIT 0,50";

      $rst = mysqli_query($conn, $sql);

      while($row = mysqli_fetch_object($rst))
      { 
         //display
         $trMissing .= "
         <tr>
            <td rowspan='2' align='left'>".$row->MASTER_strType."</td>
            <td rowspan='2' align='left'>".$row->MASTER_strPath."</td>
            <td rowspan='2' align='left'>".$row->MASTER_strExtension."</td>
            <th align='left'>MASTER</th>
            <td align='left'>".$row->MASTER_dtAudit."</td>
            <td align='left'>".$row->MASTER_strOwner."</td>
            <td align='left'>".$row->MASTER_strPermission."</td>
            <td align='left'>".$row->MASTER_dblSize."</td>
            <td align='left'>".$row->MASTER_dtModify."</td>
            <td align='left' style='color:red;'>".$row->MASTER_strHash."</td>
            <td align='center' rowspan='2'>
            <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: IGNORE&ID=$row->MASTER_ID&state=MISSING' target='_blank'>Ignore</a></td>

         </tr>
         <tr>
            <th align='left'>QA</th>
            <td align='left'>$row->LIVE_dtAudit</td>
            <td align='left'>$row->LIVE_strOwner</td>
            <td align='left'>$row->LIVE_strPermission</td>
            <td align='left'>$row->LIVE_dblSize</td>
            <td align='left'>$row->LIVE_dtModify</td>
            <td align='left'>$row->LIVE_strHash</td>
         </tr>";
      }

      // GET NEW RECORDS FOR THE DAY ////////////////////////////////////////////////////////////
      // [M<=L, W. M.ID is Null]

      // MUST HAVE THE SAME FROM / WHERE AS THE QUERY BELOW
      $sqlSummaryNew = " 
         SELECT 
            COUNT(*) AS 'CountNew', 
            MAX($sysAudit_ENV.dtModify) AS 'maxDtNew', 
            MIN($sysAudit_ENV.dtModify) AS 'minDtNew', 
            sysAudit_master.strHash, 
            $sysAudit_ENV.strHash,
            sysAudit_master.strPath, 
            $sysAudit_ENV.strPath
         FROM sysAudit_master 
            RIGHT JOIN $sysAudit_ENV ON sysAudit_master.strPath = $sysAudit_ENV.strPath
         WHERE $sysAudit_ENV.dtAudit ='$maxAudit' AND sysAudit_master.ID Is Null $excludeENV"; 

      $rstSummaryNew = mysqli_query($conn, $sqlSummaryNew);
      $rowSummaryNew = mysqli_fetch_object($rstSummaryNew);  

      $sql = "SELECT sysAudit_master.ID AS 'MASTER_ID', sysAudit_master.dtAudit AS 'MASTER_dtAudit'
            , sysAudit_master.strType AS 'MASTER_strType', sysAudit_master.strPath AS 'MASTER_strPath'
            , sysAudit_master.strExtension AS 'MASTER_strExtension', sysAudit_master.strOwner AS 'MASTER_strOwner'
            , sysAudit_master.strPermission AS 'MASTER_strPermission', sysAudit_master.dblSize AS 'MASTER_dblSize'
            , sysAudit_master.dtModify AS 'MASTER_dtModify', sysAudit_master.strHash AS 'MASTER_strHash'
            , $sysAudit_ENV.ID AS 'LIVE_ID', $sysAudit_ENV.dtAudit AS 'LIVE_dtAudit', $sysAudit_ENV.strType AS 'LIVE_strType'
            , $sysAudit_ENV.strPath AS 'LIVE_strPath', $sysAudit_ENV.strExtension AS 'LIVE_strExtension'
            , $sysAudit_ENV.strOwner AS 'LIVE_strOwner', $sysAudit_ENV.strPermission AS 'LIVE_strPermission'
            , $sysAudit_ENV.dblSize AS 'LIVE_dblSize', $sysAudit_ENV.dtModify AS 'LIVE_dtModify'
            , $sysAudit_ENV.strHash AS 'LIVE_strHash'
            FROM sysAudit_master RIGHT JOIN $sysAudit_ENV ON sysAudit_master.strPath = $sysAudit_ENV.strPath
            WHERE $sysAudit_ENV.dtAudit ='$maxAudit' AND sysAudit_master.ID Is Null
               $excludeENV
            ORDER BY MASTER_strPath, LIVE_strPath
            LIMIT 0,50";

      $rst = mysqli_query($conn, $sql);

      while($row = mysqli_fetch_object($rst))
      {
         //output
         $trNew .= " <input id='arrIDNew[]' type='hidden' name='arrIDNew[]' value='$row->LIVE_ID' >
                        <tr>
                           <td rowspan='2' align='left'>$row->LIVE_strType</td>
                           <td rowspan='2' align='left'>$row->LIVE_strPath</td>
                           <td rowspan='2' align='left'>$row->LIVE_strExtension</td>
                           <th align='left'>MASTER</th>
                           <td align='left'>$row->MASTER_dtAudit</td>
                           <td align='left'>$row->MASTER_strOwner</td>
                           <td align='left'>$row->MASTER_strPermission</td>
                           <td align='left'>$row->MASTER_dblSize</td>
                           <td align='left'>$row->MASTER_dtModify</td>
                           <td align='left'>$row->MASTER_strHash</td>
                           <td align='center' rowspan='2'>
                           <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: IGNORE&ID=$row->LIVE_ID&state=NEW' target='_blank'>Ignore</a></td>
                           <td align='center' rowspan='2'>
                           <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: UPDATE&ID=$row->LIVE_ID&state=NEW' target='_blank'>Update</a></td>
                        </tr>
                        <tr>
                           <th align='left'>QA</th>
                           <td align='left'>$row->LIVE_dtAudit</td>
                           <td align='left'>$row->LIVE_strOwner</td>
                           <td align='left'>$row->LIVE_strPermission</td>
                           <td align='left'>$row->LIVE_dblSize</td>
                           <td align='left'>$row->LIVE_dtModify</td>
                           <td align='left' style='color:red;' >$row->LIVE_strHash</td>
                        </tr>";
      }


      //ENCODED ARRAY ID TO PASS ON URL FOR EMAIL
      //$arrDataNew = json_encode($arrayNewID);

      $thChanges = "
      <thead>
         <tr>
            <td colspan='100%'><h3>CHANGES</h3></td>
            <td colspan='2' >
            <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: UPDATE&ID=*&state=CHANGES' target='_blank' >UPDATE ALL</a>
            </td>
         </tr>
         <tr BGCOLOR='#7f8c8d'>
            <th align='left'>Type</th>
            <th align='left'>Path</th>
            <th align='left'>Extension</th>
            <th align='left'>ENV</th>
            <th align='left'>dtAudit</th>
            <th align='left'>strOwner</th>
            <th align='left'>strPermission</th>
            <th align='left'>dblSize</th>
            <th align='left'>dtModify</th>
            <th align='left'>strHash</th>
            <th align='left'>Ignore</th>
            <th align='left'>Update</th>
         </tr>

      </thead>";

      $thMissing = "
        <thead>
            <tr><td colspan='100%'><h3>MISSING</h3></td>
               <td colspan='2' >
                  <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: IGNORE&ID=*&state=MISSING' target='_blank' >IGNORE ALL</a>
               </td>
            </tr>
            <tr BGCOLOR='#7f8c8d'>
               <th align='left'>Type</th>
               <th align='left'>Path</th>
               <th align='left'>Extension</th>
               <th align='left'>ENV</th>
               <th align='left'>dtAudit</th>
               <th align='left'>strOwner</th>
               <th align='left'>strPermission</th>
               <th align='left'>dblSize</th>
               <th align='left'>dtModify</th>
               <th align='left'>strHash</th>
               <th align='left'>Ignore</th>
            </tr>

         </thead>";

      $thNew = "
         <thead>
            <tr><td colspan='100%'><h3>NEW</h3></td>
               <td colspan='2' >
                  <a href='".$FIMBaseURL."fim.config_$siteEnviroment.php?Action=FIM: UPDATE&ID=*&state=NEW' target='_blank' >UPDATE ALL</a>
               </td>
            </tr>
            <tr BGCOLOR='#7f8c8d'>
               <th align='left'>Type</th>
               <th align='left'>Path</th>
               <th align='left'>Extension</th>
               <th align='left'>ENV</th>
               <th align='left'>dtAudit</th>
               <th align='left'>strOwner</th>
               <th align='left'>strPermission</th>
               <th align='left'>dblSize</th>
               <th align='left'>dtModify</th>
               <th align='left'>strHash</th>
               <th align='left'>Ignore</th>
               <th align='left'>Update</th>
            </tr>

         </thead>";

      $strBody .= " <html><body>
            <table class='tblNemoList' border='1' style='-fs-table-paginate: paginate;'>
               <caption>FIM ".$siteEnviroment.": Summary: ".date("Y-m-d")."</caption>
               <tr>
                  <th align='left'>#</th>
                  <th align='left'>No. of files</th>
                  <th align='left'>Min Date</th>
                  <th align='left'>Max Date</th>
               </tr>
               <tr>
                  <td align='left'>CHANGES</td>
                  <td align='center'>$rowSummaryChanges->CountChanges</td>
                  <td align='center'>$rowSummaryChanges->minDtChanges</td>
                  <td align='center'>$rowSummaryChanges->maxDtChanges</td>
               </tr>
               <tr>
                  <td align='left'>MISSING</td>
                  <td align='center'>$rowSummaryMissing->CountMissing</td>
                  <td align='center'>$rowSummaryMissing->minDtMissing</td>
                  <td align='center'>$rowSummaryMissing->maxDtMissing</td>
               </tr>
               <tr>
                  <td align='left'>NEW</td>
                  <td align='center'>$rowSummaryNew->CountNew</td>
                  <td align='center'>$rowSummaryNew->minDtNew</td>
                  <td align='center'>$rowSummaryNew->maxDtNew</td>
               </tr>
            </table>
            <br>
            <table class='tblNemoList' border='1' cellpadding='2' cellspacing='0' width='100%' style='-fs-table-paginate: paginate;'>
               $thChanges
               $trChanges
               <tr class='detailRow2'><td colspan='100%' style=><HR /></td></tr>
               $thMissing
               $trMissing
               <tr class='detailRow2'><td colspan='100%' style=><HR /></td></tr>
               $thNew
               $trNew
            </table>
         </body>
         </html>
      ";

      // DEBUG VAR
      //print_rr($strBody);

      // EMAIL FIM REPORT TO ADMINS 
      $counter = 0;
      $counter += $rowSummaryChanges->CountChanges;
      $counter += $rowSummaryMissing->CountMissing;
      $counter += $rowSummaryNew->CountNew;
      
      // $email_message = "--{==Multipart_Boundary_x{".md5(time())."}x}".PHP_EOL;
      // $email_message .= "Content-Type:text/html; charset=UTF-8".PHP_EOL;
      // $email_message .= "Content-Transfer-Encoding: 7bit".PHP_EOL.PHP_EOL;
      $email_message .= $strBody .= "".PHP_EOL;

       mail(
            $emailParameters["recipients"],
            $emailParameters["title"],
            $email_message,
            $emailParameters["headers"],
            $emailParameters["parameters"]
         );
       
      // if( $counter > 0 )
      // { 
      //    mail(
      //       $emailParameters["recipients"],
      //       $emailParameters["title"],
      //       $email_message,
      //       $emailParameters["headers"],
      //       $emailParameters["parameters"]
      //    );
      // }

   }
  
   // GET AND PROCESS THE EXCLUDES STATED IN THE CONFIG FILE
   public static function in_array_wildcard($check, $arrWildcards, $Debug=0)
   {
      if($Debug) echo("<BR><BR><U>CHECK</U>: <B>$check</B>");

      $intCheckLength = strlen($check);

      //do exact match: "abc" == "abc": true
      if(in_array($check, $arrWildcards)){
         if($Debug) echo " <b>FOUND</b> (in_array)";
         return true;
      }
 
      foreach($arrWildcards as $valueWC)
      {
         //ini
         $intWordLength = strlen(str_replace("%", "", $valueWC));
         $value = str_replace("%", "", $valueWC); //vd($intWordLength);
         $intWordLengthWC = strlen($valueWC); //vd($intWordLength);
         if($Debug) echo "<BR>valueWC: $valueWC ($intWordLength)";

         if(strpos($valueWC, "%") === false) continue; //default fail

         if($intCheckLength < $intWordLength) continue; //default fail

         //go
         //vd(strpos($valueWC, "%", 1));
         if(strpos($valueWC, "%") === 0 && strpos($valueWC, "%", 1) === ($intWordLengthWC-1)){
            //echo " <B>check any.</b> ";
            if(strpos($check, $value) !== false){
               if($Debug) echo " <b>FOUND</b> (%check_any%)";
               return true;
            }
         }

         if(strpos($valueWC, "%") === 0){
            //echo " <B>check ending.</b> ";
            if(strpos($check, $value, $intCheckLength - $intWordLength) !== false){
               if($Debug) echo " <b>FOUND</b> (%check_ending)";
               return true;
            }
         }

         if(strpos($valueWC, "%", 1) === ($intWordLengthWC-1)){
            //echo " <B>check begining.</b> ";
            if(strpos($check, $value, 0) === 0){
               if($Debug) echo " <b>FOUND</b> (check_begining%)";
               return true;
            }
         }
      }

      //post / default fail
      return false;
   }

/////////////////// OTHER FUNCTIONS TO LOOK AT - DONT KNOW WHAT THEY ARE USED FOR //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   public static function PullData($server_name, $maxAudit=null)
   {
      global $DATABASE_SETTINGS, $BR, $SP, $TR, $SystemSettings, $DT, $MYSQLI, $xdb;

      //ini
      $env = $DATABASE_SETTINGS[$server_name]->environment;

      //get data
      $MYSQLI = mysqli_connect($DATABASE_SETTINGS[$server_name]->hostname
                       , $DATABASE_SETTINGS[$server_name]->username
                       , $DATABASE_SETTINGS[$server_name]->password
                       , $DATABASE_SETTINGS[$server_name]->database);
      if($maxAudit == null)
         $maxAudit = $xdb->getRowSQL("SELECT MAX(dtAudit) AS maxAudit FROM sysAudit_$env")->maxAudit;

      $rst = $xdb->doQuery("SELECT * FROM sysAudit_$env WHERE dtAudit = '$maxAudit' ");
      while($row = $xdb->fetch_array($rst))
      {
         $arrData[] = $row;
      }//print_rr($arrData);

      //save data
      $MYSQLI = mysqli_connect($DATABASE_SETTINGS[$_SERVER[SERVER_NAME]]->hostname
                       , $DATABASE_SETTINGS[$_SERVER[SERVER_NAME]]->username
                       , $DATABASE_SETTINGS[$_SERVER[SERVER_NAME]]->password
                       , $DATABASE_SETTINGS[$_SERVER[SERVER_NAME]]->database);
      if(is_array($arrData)){
         $xdb->doQuery("TRUNCATE TABLE sysAudit_$env;");
      foreach($arrData as $i => $row){

         $adb = new NemoDatabase("sysAudit_$env", null, null, 0);
         $adb->setValues($row);
         $adb->Fields["ID"] = "NULL";
         $adb->Save(0,0);


      }}
   }

   // FUNCTION TRIGGERED IN THE FIM REPORT EMAIL
   public static function Ignore($ID, $state){

      // GLOBALS 
      global $siteProjectName, $siteEnviroment, $siteDirectory, $siteWildcards, $FIMBaseURL, $emailParameters, $conn;
      

      switch ($state) {

         case "CHANGES":
            $sql = "UPDATE sysAudit_master SET strHash ='IGNORE' WHERE sysAudit_master.ID = '$ID'";
            
            mysqli_query($conn, $sql);
            break;

         case "MISSING":
            if($ID == "*")
            {
               $sql = "
                  UPDATE sysAudit_master 
                  LEFT JOIN sysAudit_$siteEnviroment ON sysAudit_master.strPath = sysAudit_$siteEnviroment.strPath
                  SET sysAudit_master.strHash = \"IGNORE\"
                  WHERE sysAudit_$siteEnviroment.ID Is Null 
                  AND sysAudit_master.strHash <> 'IGNORE'";
            }
            else
            {
               $sql = "UPDATE sysAudit_master SET strHash ='IGNORE' WHERE sysAudit_master.ID = '$ID'";
            }

            mysqli_query($conn, $sql);
            break;

         case "NEW":
            $sql = "
               INSERT INTO sysAudit_master ( dtAudit, strType, strPath, strExtension, strOwner, strPermission , dblSize, strHash, dtModify, strLastUser )
               SELECT NOW(), strType, strPath, strExtension, strOwner, strPermission, dblSize , 'IGNORE', dtModify, strLastUser
               FROM sysAudit_$siteEnviroment
               WHERE ID = '$ID'";

            mysqli_query($conn, $sql);
            break;
      }
   }

   // FUNCTION TRIGGERED IN THE FIM REPORT EMAIL
   public static function Update($ID, $state){
      
      print_rr($ID);
      print_rr($state);
      // GLOBALS 
      global $siteProjectName, $siteEnviroment, $siteDirectory, $siteWildcards, $FIMBaseURL, $emailParameters, $conn;
      
      // INI
      $sysAudit_ENV = "sysAudit_". $siteEnviroment;
      $rst = mysqli_query($conn, "SELECT MAX(dtAudit) AS maxAudit FROM $sysAudit_ENV");
      $maxAudit = mysqli_fetch_object($rst)->maxAudit; 
      
      //print_rr($maxAudit);

      $arrFields = array(
         "strOwner",
         "strPermission",
         "dblSize",
         "dtModify",
         "strHash"
      );

      // GET EXCLUDES
      $arrIgnorePaths = explode(";", $siteWildcards);

      foreach($arrIgnorePaths as $key)
      {
         $excludeMASTER .= " AND sysAudit_master.strPath NOT LIKE '".$key."' ";
         $excludeENV .= " AND sysAudit_$siteEnviroment.strPath NOT LIKE '".$key."' ";
      }

      switch ($state) {

         case "CHANGES":

            if($ID == "*")
            {
               $sqlWhere = "sysAudit_master.strHash <> sysAudit_$siteEnviroment.strHash
               AND sysAudit_$siteEnviroment.dtAudit = '$maxAudit'";
            }
            else
            {
               $sqlWhere = "sysAudit_$siteEnviroment.ID= '$ID'";
            }

            $sql = " UPDATE sysAudit_master INNER JOIN sysAudit_$siteEnviroment ON sysAudit_master.strPath = sysAudit_$siteEnviroment.strPath
                     SET sysAudit_master.dtAudit = Now(), sysAudit_master.strOwner = sysAudit_$siteEnviroment.strOwner
                        , sysAudit_master.strPermission = sysAudit_$siteEnviroment.strPermission
                        , sysAudit_master.dblSize = sysAudit_$siteEnviroment.dblSize
                        , sysAudit_master.strHash = sysAudit_$siteEnviroment.strHash
                        , sysAudit_master.dtModify = sysAudit_$siteEnviroment.dtModify
                        , sysAudit_master.strLastUser = 'CHANGES'
                     WHERE $sqlWhere";

            mysqli_query($conn, $sql); 
            break;

         case "MISSING": // n/a

            break;
         
         case "NEW":
         
            if( $ID == "*")
            {
               $sqlWhere = "sysAudit_$siteEnviroment.dtAudit ='$maxAudit' AND sysAudit_master.ID Is Null $excludeENV";
            }
            else
            {
               $sqlWhere = "sysAudit_$siteEnviroment.ID= '$ID'";
            }

            $sql = " INSERT INTO sysAudit_master ( dtAudit, strType, strPath, strExtension, strOwner, strPermission, dblSize, strHash, dtModify, strLastUser, dtLastEdit )
                     SELECT 
                        sysAudit_$siteEnviroment.dtAudit, 
                        sysAudit_$siteEnviroment.strType, 
                        sysAudit_$siteEnviroment.strPath,
                        sysAudit_$siteEnviroment.strExtension, 
                        sysAudit_$siteEnviroment.strOwner, 
                        sysAudit_$siteEnviroment.strPermission, 
                        sysAudit_$siteEnviroment.dblSize,
                        sysAudit_$siteEnviroment.strHash, 
                        sysAudit_$siteEnviroment.dtModify, 
                        sysAudit_$siteEnviroment.strLastUser, 
                        sysAudit_$siteEnviroment.dtLastEdit
                     FROM sysAudit_$siteEnviroment LEFT JOIN sysAudit_master ON sysAudit_master.strPath = sysAudit_$siteEnviroment.strPath
                     WHERE $sqlWhere
                     ORDER BY sysAudit_master.strPath, sysAudit_$siteEnviroment.strPath";

            mysqli_query($conn, $sql); 

            break;
      }
   }

   // USED TO UPDATE OR RESET THE MASTER MANUALLY 
   public static function ResetMaster()
   {
      // GLOBALS
      global $siteProjectName, $siteEnviroment, $siteDirectory, $siteWildcards, $FIMBaseURL, $emailParameters, $conn;
      global $DATABASE_SETTINGS, $BR, $SP, $TR, $SystemSettings, $DT, $MYSQLI, $xdb; 

      //process
      $sqlTruncate = "TRUNCATE TABLE sysAudit_master";
      mysqli_query($conn, $sqlTruncate); 

      $sqlReset = "INSERT INTO sysAudit_master SELECT * FROM sysAudit_$siteEnviroment WHERE LEFT(dtAudit,10) = CURDATE()";
      mysqli_query($conn, $sqlReset);
   }

   
}

 
?>