<?php
/**
 * Created by PhpStorm.
 * User: 中闽 < 1464674022@qq.com >
 * Date: 2020/2/4
 * Time: 12:47
 */

namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class CheckBOM extends Command
{

    /**
     * 批量检测文件是否有bom
     * php think CheckBOM "D:\www\php"
     */
    protected function configure()
    {
        $this->setName('CheckBOM')
            ->addArgument('basedir', Argument::OPTIONAL, "base dir", ".")
            ->addOption('rewrite', 'r', Option::VALUE_NONE, 'delete bom')
            ->setDescription('check files if has bom');
    }

    protected function execute(Input $input, Output $output)
    {
        $basedir = $input->getArgument("basedir");//需要检测的目录，点表示当前目录
        $this->runDir($basedir, $output, $input->hasOption('rewrite'));
    }

    private function runDir($basedir, $output, $rewrite)
    {
        if (file_exists($basedir)) {
            if ($dh = opendir($basedir)) {
                while (($file = readdir($dh)) !== false) {
                    if ($file != '.' && $file != '..') {
                        $path = $basedir . DS . $file;
                        if (!is_dir($path)) {
                            $res = $this->checkBOM($path, $rewrite);
                            if ($res != "ok")
                                $output->writeln($path . ' - ' . $res);
                        } else {
                            $this->runDir($path, $output, $rewrite);
                        }
                    }
                }
                closedir($dh);
            }
        }
    }

    private function checkBOM($filename, $rewrite = false)
    {
        $contents = file_get_contents($filename);
        $charset[1] = substr($contents, 0, 1);
        $charset[2] = substr($contents, 1, 1);
        $charset[3] = substr($contents, 2, 1);

        if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) {
            if ($rewrite) {
                $rest = substr($contents, 3);
                $this->rewrite($filename, $rest);
                return ('BOM found, automatically removed');
            } else {
                return ('BOM found');
            }
        } else {
            return ("ok");
        }
    }

    private function rewrite($filename, $data)
    {
        $filenum = fopen($filename, "w");
        flock($filenum, LOCK_EX);
        fwrite($filenum, $data);
        fclose($filenum);
    }
}