Your IP : 216.73.217.77


Current Path : /home/users/unlimited/www/foodbank.codeskitter.site/vendor/pragmarx/countries/src/update/
Upload File :
Current File : /home/users/unlimited/www/foodbank.codeskitter.site/vendor/pragmarx/countries/src/update/Helper.php

<?php

namespace PragmaRX\Countries\Update;

use Exception;
use IlluminateAgnostic\Str\Support\Str;
use PragmaRX\Countries\Package\Services\Command;
use PragmaRX\Countries\Package\Services\Helper as ServiceHelper;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ReflectionClass;
use Shapefile\Geometry\Polygon;
use Shapefile\Shapefile;
use Shapefile\ShapefileReader;

class Helper
{
    /**
     * @var Helper
     */
    protected $config;

    /**
     * @var ServiceHelper
     */
    protected $serviceHelper;

    /**
     * @var Command
     */
    protected $command;

    /**
     * Rinvex constructor.
     *
     * @param  object  $config
     */
    public function __construct($config)
    {
        $this->config = $config;

        $this->serviceHelper = new ServiceHelper($config);

        $this->command = new Command();
    }

    /**
     * Forward calls to the service helper.
     *
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array([$this->serviceHelper, $name], $arguments);
    }

    /**
     * Abort with message.
     *
     * @param $message
     *
     * @throws Exception
     */
    protected function abort($message)
    {
        echo "\n$message\n\nAborted.\n";

        exit;
    }

    /**
     * Add suffix to string.
     *
     * @param $suffix
     * @param $string
     * @return mixed
     */
    protected function addSuffix($suffix, $string)
    {
        if (substr($string, -strlen($suffix)) !== (string) $suffix) {
            $string .= $suffix;
        }

        return $string;
    }

    /**
     * @param $dir
     * @param $files
     */
    protected function deleteAllFiles($dir, $files)
    {
        foreach ($files as $file) {
            (is_dir("$dir/$file"))
                ? $this->delTree("$dir/$file")
                : unlink("$dir/$file");
        }
    }

    /**
     * Delete a whole directory.
     *
     * @param $dir
     */
    protected function deleteDirectory($dir)
    {
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $fileInfo) {
            $todo = ($fileInfo->isDir() ? 'rmdir' : 'unlink');

            $todo($fileInfo->getRealPath());
        }

        rmdir($dir);
    }

    protected function fopenOrFail($url, $string)
    {
        if (($handle = @fopen($url, $string)) === false) {
            $this->exception("Could not open file $url");
        }

        return $handle;
    }

    /**
     * Raise exception.
     *
     * @param $message
     *
     * @throws Exception
     */
    public function exception($message)
    {
        throw new Exception($message);
    }

    /**
     * Make a directory.
     *
     * @param $dir
     */
    public function mkDir($dir)
    {
        if (file_exists($dir)) {
            return;
        }

        mkdir($dir, 0755, true);
    }

    /**
     * Download one or more files.
     *
     * @param $url
     * @param $directory
     */
    public function download($url, $directory)
    {
        coollect((array) $url)->each(function ($url) use ($directory) {
            $filename = basename($url);

            $destination = $this->toDir("{$directory}/{$filename}");

            $this->message("Downloading to {$destination}");

            $this->mkDir($directory);

            $this->downloadFile($url, $destination);
        });
    }

    /**
     * @param $class
     * @return string
     */
    public function getClassDir($class)
    {
        $reflector = new ReflectionClass($class);

        return dirname($reflector->getFileName());
    }

    /**
     * @param $url
     * @param $destination
     */
    public function downloadFile($url, $destination)
    {
        if (file_exists($destination)) {
            return;
        }

        try {
            $this->downloadFopen($url, $destination);
        } catch (\Exception $exception) {
            try {
                $this->downloadCurl($url, $destination);
            } catch (\Exception $exception) {
                $this->abort("Could not download {$url} to {$destination}");
            }
        }

        chmod($destination, 0644);
    }

    /**
     * @param $url
     * @param $destination
     */
    public function downloadFopen($url, $destination)
    {
        $fr = $this->fopenOrFail($url, 'r');

        $fw = $this->fopenOrFail($destination, 'w');

        while (! feof($fr)) {
            fwrite($fw, fread($fr, 4096));
            flush();
        }

        fclose($fr);

        fclose($fw);
    }

    /**
     * @param $url
     * @param $destination
     */
    public function downloadCurl($url, $destination)
    {
        $nextStep = 8192;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function ($resource, $total, $downloaded) use (&$nextStep) {
            if ($downloaded > $nextStep) {
                echo '.';
                $nextStep += 8192;
            }
        });
        curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_USERAGENT, 'GuzzleHttp/6.2.1 curl/7.54.0 PHP/7.2.0');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        file_put_contents($destination, curl_exec($ch));
        curl_close($ch);

        echo "\n";
    }

    /**
     * @param $file
     * @param $subPath
     * @param $path
     * @param $exclude
     */
    protected function renameMasterToPackage($file, $subPath, $path, $exclude)
    {
        if (Str::endsWith($file, 'master.zip')) {
            $dir = coollect(scandir($path))->filter(function ($file) use ($exclude) {
                return $file !== '.' && $file !== '..' && $file !== $exclude;
            })->first();

            rename("$path/$dir", $subPath);
        }
    }

    /**
     * @param $file
     * @param $subPath
     */
    public function unzipFile($file, $subPath)
    {
        $path = dirname($file);

        if (! Str::endsWith($file, '.zip') || file_exists($subPath = "$path/$subPath")) {
            return;
        }

        chdir($path);

        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            $zip = new \ZipArchive;
            $res = $zip->open($file);
            if ($res === true) {
                $zip->extractTo('.');
                $zip->close();
            } else {
                throw new Exception('Cannot unzip');
            }
        } else {
            exec("unzip -o $file");
        }

        $this->renameMasterToPackage($file, $subPath, $path, basename($file));
    }

    /**
     * Delete a directory and all its files.
     *
     * @param $dir
     * @return bool
     */
    public function delTree($dir)
    {
        if (! file_exists($dir)) {
            return false;
        }

        $files = array_diff(scandir($dir), ['.', '..']);

        $this->deleteAllFiles($dir, $files);

        return rmdir($dir);
    }

    /**
     * Load a shapeFile.
     *
     * @param $dir
     * @return \PragmaRX\Coollection\Package\Coollection
     */
    public function shapeFile($dir)
    {
        $shapeRecords = new ShapefileReader($dir);

        $result = [];

        /** @var Polygon $record */
        foreach ($shapeRecords as $record) {
            if ($record->isDeleted()) {
                continue;
            }

            $data = $record->getDataArray();

            unset($data['_deleted']);

            $result[] = $data;
        }

        unset($shapeRecords);

        return coollect($result)->mapWithKeys(function ($fields, $key1) {
            return [
                strtolower($key1) => coollect($fields)->mapWithKeys(function ($value, $key2) {
                    return [strtolower($key2) => $value];
                }),
            ];
        });
    }

    /**
     * Recursively change all array keys case.
     *
     * @param  array|\PragmaRX\Coollection\Package\Coollection  $array
     * @return \PragmaRX\Coollection\Package\Coollection
     */
    public function arrayKeysSnakeRecursive($array)
    {
        $result = [];

        $array = arrayable($array) ? $array->toArray() : $array;

        array_walk($array, function ($value, $key) use (&$result) {
            $result[Str::snake($key)] = arrayable($value) || is_array($value)
                ? $this->arrayKeysSnakeRecursive($value)
                : $value;
        });

        return coollect($result);
    }

    /**
     * Load CSV file.
     *
     * @param $csv
     * @return \PragmaRX\Coollection\Package\Coollection
     */
    public function csvDecode($csv)
    {
        return coollect(array_map('str_getcsv', $csv));
    }

    /**
     * Fix a bad UTF8 string.
     *
     * @param $string
     * @return string
     */
    public function fixUtf8($string)
    {
        return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
            return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
        }, $string);
    }

    /**
     * Unzip a file.
     *
     * @param $file
     * @param $path
     */
    public function unzip($file, $path)
    {
        if (Str::endsWith($file, '.zip')) {
            $this->message("Unzipping to {$file}");

            $this->unzipFile($file, $path);
        }
    }

    /**
     * Return string to be used in keys.
     *
     * @param $admin
     * @return string
     */
    public function caseForKey($admin)
    {
        return Str::snake(strtolower(str_replace('-', '_', $admin)));
    }

    /**
     * Download files.
     */
    public function downloadDataFiles()
    {
        $this->config->get('downloadable')->each(function ($urls, $path) {
            if (! file_exists($destination = $this->dataDir("third-party/$path"))) {
                coollect($urls)->each(function ($url) use ($destination) {
                    $this->download($url, $destination);

                    $file = basename($url);

                    $this->unzip("$destination/$file", 'package');
                });
            }
        });
    }

    /**
     * Download, move and delete data files.
     */
    public function downloadFiles()
    {
        $this->progress('--- Download files');

        $this->downloadDataFiles();

        $this->moveDataFiles();
    }

    /**
     * Erase all files from states data dir.
     *
     * @param  string  $dir
     */
    public function eraseDataDir($dir)
    {
        $this->delTree($this->dataDir($dir));
    }

    /**
     * Load the shape file (DBF) to array.
     *
     * @param  string  $file
     * @return \PragmaRX\Coollection\Package\Coollection
     */
    public function loadShapeFile($file)
    {
        $this->progress('Loading shape file...');

        if (file_exists($sha = $this->dataDir('tmp/'.sha1($file = $this->dataDir($file))))) {
            $this->progress('Loaded.');

            return $this->loadJson($sha);
        }

        $this->progress($file);

        $shapeFile = $this->shapeFile($file);

        $this->mkDir(dirname($sha));

        file_put_contents($sha, $shapeFile->toJson());

        $this->progress('Loaded.');

        return $shapeFile;
    }

    /**
     * Load json files from dir.
     *
     * @param $dir
     * @return \PragmaRX\Coollection\Package\Coollection
     */
    public function loadJsonFiles($dir)
    {
        return coollect(glob("$dir/*.json*"))->mapWithKeys(function ($file) {
            $key = str_replace('.json', '', str_replace('.json5', '', basename($file)));

            return [$key => $this->loadJson($file)];
        });
    }

    /**
     * Move a data file or many using wildcards.
     *
     * @param $from
     * @param $to
     */
    public function moveDataFile($from, $to)
    {
        if (Str::contains($from, '*.')) {
            $this->moveFilesWildcard($from, $to);

            return;
        }

        if (file_exists($from = $this->dataDir($from))) {
            $this->mkDir(dirname($to = $this->dataDir($to)));

            rename($from, $to);
        }
    }

    /**
     * Move data files to the proper location.
     */
    public function moveDataFiles()
    {
        $this->config->get('moveable')->each(function ($to, $from) {
            $this->moveDataFile($from, $to);
        });
    }

    /**
     * Show the progress.
     *
     * @param  string  $string
     */
    public function progress($string = '')
    {
        if (is_null($this->command)) {
            dump($string);

            return;
        }

        $this->command->line($string);
    }

    /**
     * Display a message in console.
     *
     * @param $message
     * @param  string  $type
     */
    public function message($message, $type = 'line')
    {
        if (! is_null($this->command)) {
            $this->command->{$type}($message);
        }
    }

    /**
     * Get temp directory.
     *
     * @param  string  $path
     * @return string
     */
    public function tmpDir($path)
    {
        return __COUNTRIES_DIR__.$this->toDir("/tmp/{$path}");
    }

    /**
     * Loads a json file.
     *
     * @param $file
     * @param  string  $dir
     * @return \PragmaRX\Coollection\Package\Coollection
     *
     * @throws \Exception
     */
    public function loadCsv($file, $dir = null)
    {
        if (empty($file)) {
            $this->abort('loadCsv Error: File name not set');
        }

        if (! file_exists($file)) {
            $file = $this->dataDir($this->addSuffix('.csv', "/$dir/".strtolower($file)));
        }

        return coollect($this->csvDecode(file($file)));
    }

    /**
     * Make state json filename.
     *
     * @param $key
     * @param  string  $dir
     * @return string
     */
    public function makeJsonFileName($key, $dir = '')
    {
        if (! Str::endsWith($dir, (DIRECTORY_SEPARATOR))) {
            $dir .= DIRECTORY_SEPARATOR;
        }

        return $this->dataDir($this->addSuffix('.json', $this->toDir($dir).strtolower($key)));
    }

    /**
     * Put contents into a file.
     *
     * @param $file
     * @param $contents
     */
    public function putFile($file, $contents)
    {
        $this->mkdir(dirname($file));

        file_put_contents($file, $contents);
    }

    /**
     * Encode and pretty print json.
     *
     * @param  array|\PragmaRX\Coollection\Package\Coollection  $data
     * @return string
     */
    public function jsonEncode($data)
    {
        return json_encode($data, JSON_PRETTY_PRINT);
    }

    /**
     * Get package home dir.
     *
     * @return string
     */
    public function getHomeDir()
    {
        return $this->getClassDir(Service::class);
    }

    /**
     * Get data directory.
     *
     * @param $path
     * @return string
     */
    public function dataDir($path = '')
    {
        $path = (empty($path) || Str::startsWith($path, DIRECTORY_SEPARATOR)) ? $path : "/{$path}";

        return __COUNTRIES_DIR__.$this->toDir("/src/data$path");
    }

    /**
     * @param $contents
     * @return string
     */
    public function sanitizeFile($contents)
    {
        return str_replace('\n', '', $contents);
    }

    /**
     * Check if array is multidimensional.
     *
     * @param $string
     * @return string
     */
    public function toDir($string)
    {
        return str_replace('/', DIRECTORY_SEPARATOR, $string);
    }

    /**
     * Delete uneeded data files.
     */
    public function deleteTemporaryFiles()
    {
        $this->progress('--- Delete temporary files');

        $this->config->get('deletable')->each(function ($directory) {
            if (file_exists($directory = $this->dataDir($directory))) {
                $this->deleteDirectory($directory);
            }
        });
    }
}