Pull GitHub repository with code

15 June 2023 devHacksTechnology
Share with:

I’m currently developing a company WordPress plugin platform, which should allow you to update and manage company proprietary plugins without making them public in WP’s plugin repository.
As part of it – I need to be able to pull said plugins from their GitHub repositories. This is the method that does the heavy lifting:

    private function downloadFromGit($gitProject, $repo, $currentDir = "", $path = "")
    {
        if (empty($currentDir) && empty($path)) {
            chdir($this->pluginsDir);
            mkdir($repo);
            chdir($repo);
        }

        if (!empty($path)) {
            mkdir($path);
            chdir($path);
        }

        $currentDir = empty($currentDir)
            ? "{$path}"
            : "{$currentDir}/{$path}";

        $path = "repos/{$gitProject}/contents/{$currentDir}";

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => "https://api.github.com/{$path}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => array(
                'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0',
                'Accept:  application/vnd.github+json',
                "Authorization:  Bearer {$this->apiToken}",
                'X-GitHub-Api-Version:  2022-11-28'
            ),
        ));

        $response = curl_exec($curl);
        try {
            $response = json_decode($response, true);
        } catch (Exception $e) {
            $response = [];
        }

        foreach ($response as $item) {
            $name = $item['name'];
            $downloadLink = $item['download_url'];
            if (!empty($downloadLink)) {
                file_put_contents($name,file_get_contents($downloadLink));
            } else {
                $this->downloadFromGit($gitProject, $repo, $currentDir, $item['name']);
            }
        }

        if (!empty($path)) {
            chdir('../');
        }
    }

So as you can see – this is a recursive method – it downloads the repository file, or if it’s a directory – makes another request for it. For it to work – you need to have a GitHub token specified – in the current example – it’s part of the Class that calls this method ($this->apiToken).
So if you for instance want to pull the content of https://github.com/petar-stoyanov7/pest-art.com – the command should be called as:

$this->downloadFromGit("/petar-stoyanov7/pest-art.com", "pest-art.com");