<?php

/**
 * Class myPluginFileUtilClass
 *
 * ファイル関連の機能を実装します
 *
 * @author H.Matsubara
 * @version 0.01
 * @copyright Sincere Technology
 */
if(!class_exists('myPluginFileUtilClass')) {
  class myPluginFileUtilClass
  {
    const backupFileName = 'Latest DB & WP-Files';
    private $myPluginDomain;
    private $myPluginPageId;


    /**
     * myPluginFileUtilClass constructor.
     * @param $myPluginId
     */
    function __construct()
    {
      require_once(plugin_dir_path( __FILE__ ).'const.php');
    }


    /**
     * 対象ファイルのチェック
     *
     * 対象ファイルがすべてあるかどうかチェックする
     * NOTE: ファイル名に日付等を含む場合は除外してチェックする
     *
     *
     * @param $targetdir
     * @param $sourceFile
     * @param $originalFile
     * @param $fileSize
     * @param $errno
     * @param $errmsg
     * @return bool
     */
    function checkValidFiles($targetdir, $sourceFile, $originalFile, &$fileSize, &$errno, &$errmsg)
    {

      $filenames = array();
      $filenames[1] = str_replace('${SYSDATE}', '', get_option('backup_fnamemysqldata'));
      $filenames[2] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpthemes'));
      $filenames[4] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpplugins'));
      $filenames[8] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpuploads'));

      $retval = true;
      $errno = 0;
      $errmsg = '';
      $fileSize = 0;
      foreach ($filenames as $id => $filename) {
        $targetFile = str_replace($originalFile, $filename, $sourceFile);
        //ファイルが存在しない場合はFALSEを返す
        if (file_exists(ABSPATH . "/" . $targetdir . "/" . $targetFile)) {
          $fileSize += filesize(ABSPATH . "/" . $targetdir . "/" . $targetFile);
        } else {
          $retval = false;
          $errno += $id;
          $errmsg .= $targetFile . ', ';
        }
      }
      return $retval;
    }


    /**
     * 対象ディレクトリのファイルをすべて取得
     *
     * ABSPATH直下の指定されたディレクトリのファイルをすべて取得する
     *
     * @param $eeSFL_Files
     * @param $eeSFL_Titles
     * @param $eeSFL_Errors
     * @param $targetdir
     * @return int 正常時０、エラー時はエラーコードを返す
     */
    function getFileList(&$eeSFL_Files, &$eeSFL_Titles, &$eeSFL_Errors, $targetdir)
    {
      $eeSFL_UploadPath = ABSPATH . $targetdir; // Assemble the full path

      $eeSFL_Errors = array();
      $errcode = 0;

      // Ignore these
      $eeSFL_Excluded = array('.', '..', "", basename($_SERVER['PHP_SELF']), '.php', '.htaccess', '.ftpquota', 'error_log', '.DS_Store', 'index.html');

      // ここで指定された文字列を含むファイル名のファイルのみ取得する
      $eeSFL_Included = array();
      $eeSFL_Included[] = str_replace('${SYSDATE}', '', get_option('backup_fnamemysqldata'));
      //$eeSFL_Included[] = str_replace('${SYSDATE}','',get_option('backup_fnamewpthemes'));
      //$eeSFL_Included[]  = str_replace('${SYSDATE}','',get_option('backup_fnamewpplugins'));
      //$eeSFL_Included[]  = str_replace('${SYSDATE}','',get_option('backup_fnamewpuploads'));

      // List files in folder, add to array.
      if ($eeSFL_Handle = @opendir($eeSFL_UploadPath)) {

        while (false !== ($eeSFL_File = readdir($eeSFL_Handle))) {
          if (!@in_array($eeSFL_File, $eeSFL_Excluded)) {
            if (@is_file($eeSFL_UploadPath . '/' . $eeSFL_File)) { // Don't show directories.

              foreach ($eeSFL_Included as $includfile) {
                if (strpos($eeSFL_File, $includfile) !== false) {
                  // Get file info...
                  $eeSFL_Files[] = $eeSFL_File; // Add the file to the array
                  if ($eeSFL_File == $includfile) {
                    $eeSFL_Titles[] = self::backupFileName;
                  } else {
                    $eeSFL_Titles[] = $replaceText = str_replace("_", "", str_replace($includfile, "", $eeSFL_File)) . ' ' . self::backupFileName;
                  }
                }
              }
            }
          }
        }
        @closedir($eeSFL_Handle);

      } else {
        $eeSFL_Errors[] = "ERROR: Can't read the files in the Uploads folder.";
        $errcode = 1;
      }

      return $errcode;
    }


    /**
     * ファイルバイト数を表示用のサイズに変換する
     *
     * @param $bytes
     * @param int $precision
     * @return string
     */
    function eeSFL_BytesToSize($bytes, $precision = 2)
    {

      $kilobyte = 1024;
      $megabyte = $kilobyte * 1024;
      $gigabyte = $megabyte * 1024;
      $terabyte = $gigabyte * 1024;

      if (($bytes >= 0) && ($bytes < $kilobyte)) {
        return $bytes . ' B';

      } elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
        return round($bytes / $kilobyte, $precision) . ' KB';

      } elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
        return round($bytes / $megabyte, $precision) . ' MB';

      } elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
        return round($bytes / $gigabyte, $precision) . ' GB';

      } elseif ($bytes >= $terabyte) {
        return round($bytes / $terabyte, $precision) . ' TB';
      } else {
        return $bytes . ' B';
      }
    }


    /**
     * ファイルリストから表示用のHTMLを作成する
     *
     * ファイルリストから表示用のHTMLを作成する
     *
     * @param $eeSFL_Files
     * @param $mode
     * @param $action
     * @param $sortby
     * @param $sortorder
     * @param $targetdir
     * @param bool $radiobtn
     * @param bool $checked
     * @return string HTMLコードを出力する
     */
    function makeFileListHtml($eeSFL_Files, $action, $sortby, $sortorder, $targetdir, $radiobtn = true, $checked = false)
    {
      $eeSFL_UploadPath = ABSPATH . $targetdir; // Assemble the full path
      date_default_timezone_set('Asia/Tokyo');

      $last_backup_file = get_option('backup_last_backup_file');
      $last_restore_file = get_option('backup_last_restore_file');

      $eeSFL_ShowFileSize = 'YES';
      $eeSFL_ShowFileDate = 'YES';
      $eeSFL_ShowFileOwner = 'NO';
      $eeSFL_Admin = 'YES';
      $eeSFL_SortOrder = $sortorder;
      $eeSFL_SortBy = $sortby;

      $errno = 0;
      $errmsg = '';

      // バックアップ対象は複数あるが、そのうち表示の基本にするファイルを定義する
      // バックアップ対象ファイルはすべてそろっている必要があるため別関数でチェックする
      $DBFilename = str_replace('${SYSDATE}', '', get_option('backup_fnamemysqldata'));

      $dir_src = get_option('backup_srcdirname');
      $dir_dest = get_option('backup_destdirname');

      $retval = true;
      $filenames = array();
      $filenames[] = str_replace('${SYSDATE}', '', get_option('backup_fnamemysqldata'));
      $filenames[] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpthemes'));
      $filenames[] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpplugins'));
      $filenames[] = str_replace('${SYSDATE}', '', get_option('backup_fnamewpuploads'));

      if(is_array($eeSFL_Files)) {
        $eeSFL_FileCount = count($eeSFL_Files);
      }else{
        $eeSFL_FileCount = 0;
      }

      $eeLog[] = 'File Count: ' . $eeSFL_FileCount;

      // $eeLog[] = 'File: ' . $eeSFL_Files[0];

      if ($eeSFL_FileCount) {
        // Files by Name
        if ($eeSFL_SortBy == 'Date') { // Files by Date

          $eeSFL_FilesByDate = array();
          $uqid = 0;  //日付が同じ場合上書きされるため、重ならないように下3桁をユニークキーにする
          foreach ($eeSFL_Files as $eeSFL_File) {
            $eeSFL_FileDate = filemtime($eeSFL_UploadPath . '/' . $eeSFL_File); // Get byte Date, yum.
            $eeSFL_FilesByDate[$eeSFL_File] = $eeSFL_FileDate * 1000 + $uqid; // Associative Array
            $uqid++;
          }

          // Sort order
          if ($eeSFL_SortOrder == 'Descending') {
            arsort($eeSFL_FilesByDate);
          } else {
            asort($eeSFL_FilesByDate); // Sort by Date, ascending
          }

          $eeSFL_Files = array_flip($eeSFL_FilesByDate); // Swap keys & values

        } elseif ($eeSFL_SortBy == 'Size') { // Files by Size

          $eeSFL_FilesBySize = array();
          foreach ($eeSFL_Files as $eeSFL_File) {
            $eeSFL_FileSize = filesize($eeSFL_UploadPath . $eeSFL_File); // Get byte size, yum.
            $eeSFL_FilesBySize[$eeSFL_File] = $eeSFL_FileSize; // Associative Array
          }

          // Sort order
          if ($eeSFL_SortOrder == 'Descending') {
            arsort($eeSFL_FilesBySize);
          } else {
            asort($eeSFL_FilesBySize); // Sort by Date, ascending
          }

          $eeSFL_Files = array_flip($eeSFL_FilesBySize); // Swap keys & values

        } elseif ($eeSFL_SortBy == 'Name') { // Alpha

          @natcasesort($eeSFL_Files);

          // Sort order
          if ($eeSFL_SortOrder == 'Descending') {
            arsort($eeSFL_Files);
          }
        }
      }

      $eeSFL_Output = "<h3>$targetdir フォルダ</h3>";
      $eeSFL_Output .= '<table class="widefat dup-pack-table" style="table-layout:auto; white-space: normal;word-break: break-all;">
                <thead>
                  <tr>';
      $eeSFL_Output .= '<th><a href="' . esc_url(add_query_arg(array('page' => CONST_SIMPLE_BACKUP_RESTORE_ID, 'tabclicked' => $action, 'sortby' => 'Name', 'sortorder' => ($sortby == 'Name' ? ($sortorder == 'Descending' ? 'Ascending' : 'Descending') : $sortorder)), admin_url('admin.php'))) . '">' . __('Name', 'simple-backup-and-restore') . '</th>';
      $eeSFL_Output .= '<th><a href="' . esc_url(add_query_arg(array('page' => CONST_SIMPLE_BACKUP_RESTORE_ID, 'tabclicked' => $action, 'sortby' => 'Name', 'sortorder' => ($sortby == 'Description' ? ($sortorder == 'Descending' ? 'Ascending' : 'Descending') : $sortorder)), admin_url('admin.php'))) . '">' . __('Description', 'simple-backup-and-restore') . '</th>';

      if ($eeSFL_ShowFileSize == 'YES') {
        $eeSFL_Output .= '<th class="sortless">' . __('Size', 'simple-backup-and-restore') . '</th>';
      }

      if ($eeSFL_ShowFileDate == 'YES') {
        $eeSFL_Output .= '<th><a href="' . esc_url(add_query_arg(array('page' => CONST_SIMPLE_BACKUP_RESTORE_ID, 'tabclicked' => $action, 'sortby' => 'Date', 'sortorder' => ($sortby == 'Date' ? ($sortorder == 'Descending' ? 'Ascending' : 'Descending') : $sortorder)), admin_url('admin.php'))) . '">' . __('Date (JST)', 'simple-backup-and-restore') . '</a></th>';
      }

      if ($eeSFL_ShowFileOwner == 'YES') {
        $eeSFL_Output .= '<th>' . __('Owner', 'simple-backup-and-restore') . '</th>';
      }


      $eeSFL_Output .= '<th>' . __('Site URL', 'simple-backup-and-restore');
      // Current site prefix
      global $wpdb;
      $eeSFL_Output .= ' (' . $wpdb->prefix . ')</th>';


      $eeSFL_Output .= '<th>' . __('Mode', 'simple-backup-and-restore') . '</th>';

      if ($action == 'restore' && $radiobtn) {
        $eeSFL_Output .= '<th>' . __('Restore', 'simple-backup-and-restore') . '</th>';
      }

      if ($action == 'transfer' && $radiobtn) {
        $eeSFL_Output .= '<th>' . __('Reverse', 'simple-backup-and-restore') . '</th>';
      }


      if ($checked) {
        $eeSFL_Output .= '<th>' . __('to Trash box', 'simple-backup-and-restore') . '</th>';
      }
      $eeSFL_Output .= '</tr>
              </thead>
                <tbody>';

      //対象ファイルが存在する場合はループする、ない場合はNOTFOUNDを表示する
      if ($eeSFL_FileCount) {
        $eeSFL_FileCount = 0; // Reset

        // Loop through array
        $rowCount = 0;
        //ファイルディスクリプションを取得する
        $FileComment = '';
        foreach ($eeSFL_Files as $eeSFL_Key => $eeSFL_File) {

          //バックアップ対象の複数のファイルの内、表示対象以外はスキップする（全ファイルは表示しない）
          if (strpos($eeSFL_File, $DBFilename) === false) {
            continue;
          }

          $rowCount++;
          $css_alt = ($rowCount % 2 != 0) ? '' : ' alternate';
          $css_alt = ($action == 'backup' && $eeSFL_File == $last_backup_file) ? 'last-backup-file' : $css_alt;
          $css_alt = ($action == 'restore' && $eeSFL_File == $last_restore_file) ? 'last-restore-file' : $css_alt;

          if (strpos($eeSFL_File, '.') !== 0) { // Don't display hidden files

            $eeSFL_FileCount++;

            $eeSFL_Output .= '<tr class="dup-pack-info ' . esc_attr($css_alt) . '">';

            $eeSFL_Output .= '<td class="pack-name" style="word-break: break-all;">';

            $eeSFL_FileURL = get_site_url();// . '/' . $eeSFL_UploadDir . $eeSFL_File;

            $eeSFL_FileName = $eeSFL_File; // FileName is used for visible link, if we trim the owner info

            // Only check URLs if in Admin area (speed tweak)
            //if($eeSFL_Admin) { $eeSFL_FileURL = eeSFL_UrlExists($eeSFL_FileURL); } // Sets to FALSE if file not found.

            if (true) { // Show link only if file is within a public area.

              if ($eeSFL_ShowFileOwner == 'YES' AND strpos($eeSFL_File, '_Via-')) { // Remove it from the display name

                $eePOS1 = strpos($eeSFL_File, '.');
                $eeExt = substr($eeSFL_File, $eePOS1);

                $eePOS2 = strpos($eeSFL_File, '_Via-');

                $eeSFL_FileName = substr($eeSFL_File, 0, $eePOS2) . $eeExt;

                $eeExt = '';

              } else {
                $eePOS2 = FALSE;
              }


              //$eeSFL_Output .= '<a href="' . $eeSFL_FileURL .  '" target="_blank">' . $eeSFL_FileName . '</a>';


              $IsValidFiles = false;
              $IsLatestFile = false;
              $FileTitle = $DBFilename;
              if ($eeSFL_FileName == $DBFilename) {
                $IsLatestFile = true;
                //下記$FileTitleは現在未使用
                $FileTitle = self::backupFileName;
              } else {
                //下記$FileTitleは現在未使用
                $FileTitle = str_replace($DBFilename, '', $eeSFL_FileName) . ' ' . self::backupFileName;
              }

              $fileSize = 0;
              //バックアップに必要なファイルがすべて揃っているかチェックする
              $IsValidFiles = $this->checkValidFiles($targetdir, $eeSFL_FileName, $DBFilename, $fileSize, $errno, $errmsg);
              if ($IsValidFiles) {

                //ファイルディスクリプションを取得する
                $FileComment = '';
                $lines = array();
                //バックアップ情報ファイルがある場合は内容を表示する
                $originalFile = str_replace('${SYSDATE}', '', get_option('backup_fnamemysqldata'));
                $infoFile = str_replace('${SYSDATE}', '', get_option('backup_fnameinfodata'));
                $targetFile = str_replace($originalFile, $infoFile, $eeSFL_FileName);
                if (file_exists(ABSPATH . "/" . $targetdir . "/" . $targetFile)) {
                  // ファイルを配列に格納し、さらに変数に格納
                  $lines = file(ABSPATH . "/" . $targetdir . "/" . $targetFile);
                  $FileComment = strip_tags($lines[0]);
                  //改行を取り除く
                  $FileComment = str_replace(array("\r\n", "\r", "\n"), '', $FileComment);
                }

                //TODO: ここで設定しているツールチップが表示されない！！
                $eeSFL_Output .= '<div class="tooltip" title="' . $FileComment . '">';
                if ($IsLatestFile) {
                  $eeSFL_Output .= "<font color='red'>$FileTitle";
                  $eeSFL_Output .= strlen($FileComment) > 0 ? '*' : '';
                  $eeSFL_Output .= "</font>";
                } else {
                  $eeSFL_Output .= $FileTitle;
                  $eeSFL_Output .= strlen($FileComment) > 0 ? '*' : '';
                }
                $eeSFL_Output .= '</div>';

              } else {
                //ファイルが欠損している
                $eeSFL_Output .= 'Backup files are broken';
              }

            } else {

              $eeSFL_Output .= '<span style="color:red;">! &rarr;</span>  ' . $eeSFL_File; // Mark as error, No link if not accessible

              $eeSFL_Errors[] = __('File Not Found', 'simple-backup-and-restore') . ': ' . $eeSFL_FileURL;
            }

            $eeSFL_Output .= '</td>';

            //ファイルディスクリプションの表示用文字列を作成する
            $FileComment2 = mb_strimwidth($FileComment,0,60,'...','UTF-8');
            $eeSFL_Output .= "<td>{$FileComment2}</td>";

            // File Size
            if ($eeSFL_ShowFileSize == 'YES') {

              //$eeSFL_Output .= '<td>' . $this->eeSFL_BytesToSize(filesize($eeSFL_UploadPath . '/' . $eeSFL_File)) . '</td>';
              $eeSFL_Output .= '<td>' . $this->eeSFL_BytesToSize($fileSize) . '</td>';
            }

            // File Modification Date
            if ($eeSFL_ShowFileDate == 'YES') {

              $eeSFL_Output .= '<td>' . date('m-d-Y H:i:s', @filemtime($eeSFL_UploadPath . '/' . $eeSFL_File)) . '</td>';
            }

            // File Owner
            if ($eeSFL_ShowFileOwner == 'YES') {

              if ($eePOS2) { // If the file name had an owner
                $eePOS = strpos($eeSFL_File, '_Via-');
                $eeSFL_FileOwner = substr($eeSFL_File, ($eePOS + 5));

                $eePOS = strpos($eeSFL_FileOwner, '.');
                $eeSFL_FileOwner = substr($eeSFL_FileOwner, 0, $eePOS);

              } else {
                $eeSFL_FileOwner = '';
              }

              $eePOS2 = '';
              $eePOS1 = '';
              $eePOS = '';

              $eeSFL_Output .= '<td>' . $eeSFL_FileOwner . '</td>';
            }

            //URLを表示する（２行目）
            $FileUrl = (isset($lines) ? (count($lines) >= 3 ? $lines[1] : '') : '');
            //改行を取り除く
            $FileUrl = str_replace(array("\r\n", "\r", "\n"), '', $FileUrl);
            $eeSFL_Output .= '<td>' . $FileUrl . '</td>';

            //結果を表示する（最後の行）
            $FileResult = (isset($lines) ? (count($lines) >= 1 ? $lines[count($lines) - 1] : '') : '');
            //改行を取り除く
            $FileResult = str_replace(array("\r\n", "\r", "\n"), '', $FileResult);
            if($FileResult == 'Complete') {
              //正常時はコメントの内容により手動または自動バックアップを判定して表示する
              //TOOLTIPはコメントアウト $eeSFL_Output .= '<td class="tooltip" title="' . $FileComment . '">';
              $eeSFL_Output .= '<td>';
              if (strpos($FileComment, 'Auto backup executed.') === false) {
                $eeSFL_Output .= __('Manual', 'simple-backup-and-restore');
              }else{
                $eeSFL_Output .=  __('Auto', 'simple-backup-and-restore');
              }
              $eeSFL_Output .=  '</td>';
            }else {
              //エラー時はエラーの内容を表示する
              $eeSFL_Output .= '<td>' . $FileResult . '</td>';
            }
            if ($radiobtn) {
              $eeSFL_Output .= '<td>';
              if ($IsValidFiles) {
                $eeSFL_Output .= '<input id="dup-bulk-action-all" type="radio" name="selected-file" value="' . $eeSFL_File . ($action == "restore" ? ";${FileUrl}" : "") . '" />';
              }
              $eeSFL_Output .= '</td>';
            }

            if ($checked) {
              $eeSFL_Output .= '<td>';
              if ($IsValidFiles) {
                $eeSFL_Output .= '<input id="dup-bulk-action-all" type="checkbox" name="target-files[]" value="' . $eeSFL_File . '" />';
              }
              $eeSFL_Output .= '</td>';
            }


            $eeSFL_Output .= "</tr>\n";

          }

        } // END loop

        $eeSFL_Msg = __('Number of Files', 'simple-backup-and-restore') . ': ' . $eeSFL_FileCount . ' | ' . __('Sorted by', 'simple-backup-and-restore') . ' ' . $eeSFL_SortBy;

      } else {
        $eeSFL_Msg = 'No files found';
      }

      $eeSFL_Output .= '</tbody></table>
    
    <p class="eeFileListInfo">' . $eeSFL_Msg . '</p>';

      $eeLog[] = $eeSFL_Msg;


      return $eeSFL_Output;
    }
  }
}