|
<?php |
|
class ControllerWebhookDeveo extends Controller { |
|
public function index() { |
|
ignore_user_abort(true); |
|
set_time_limit(0); |
|
|
|
// if signature is sent, verify it before proceeding |
|
if (isset($this->request->server['HTTP_X_HUB_SIGNATURE'])) { |
|
$signature_verified = false; |
|
|
|
if ($this->config->get('config_deveo_secret')) { |
|
list($algorithm, $hash) = explode('=', $this->request->server['HTTP_X_HUB_SIGNATURE'], 2) + array('', ''); |
|
|
|
if ($hash === hash_hmac($algorithm, file_get_contents('php://input'), $this->config->get('config_deveo_secret'))) { |
|
$signature_verified = true; |
|
} |
|
} |
|
|
|
if (!$signature_verified) { |
|
return; |
|
} |
|
} |
|
|
|
if (!empty($this->request->post)) { |
|
$payload = $this->request->post; |
|
} else { |
|
$payload = false; |
|
} |
|
|
|
// make sure this is a push request for the correct branch |
|
if ($payload && isset($payload['ref']) && $payload['ref'] == 'refs/heads/' . $this->config->get('config_deveo_branch_id')) { |
|
if (!empty($payload['commits'])) { |
|
$changes = []; |
|
$project_id = $this->config->get('config_deveo_project_id'); |
|
$repository_id = $this->config->get('config_deveo_repository_id'); |
|
$account_key = $this->config->get('config_deveo_account_key'); |
|
$company_key = $this->config->get('config_deveo_company_key'); |
|
$plugin_key = $this->config->get('config_deveo_plugin_key'); |
|
|
|
foreach ($payload['commits'] as $commit) { |
|
$time = new \DateTime($commit['timestamp']); |
|
$timestamp = $time->format('U'); |
|
|
|
if (!empty($commit['removed'])) { |
|
$dir_array = array(); |
|
|
|
foreach ($commit['removed'] as $file => $value) { |
|
// only use files in the upload folder and strip upload/ out |
|
if (strpos($value, 'upload/') === 0) { |
|
$file = substr($value, 7); |
|
} else { |
|
continue; |
|
} |
|
|
|
if (isset($changes[$file])) { |
|
if ($changes[$file]['timestamp'] < $timestamp) { |
|
unset($changes[$file]); |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'removed', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} else { |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'removed', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} |
|
} |
|
|
|
if (!empty($commit['added'])) { |
|
foreach ($commit['added'] as $file => $value) { |
|
|
|
// only use files in the upload folder and strip upload/ out |
|
if (strpos($value, 'upload/') === 0) { |
|
$file = substr($value, 7); |
|
} else { |
|
continue; |
|
} |
|
|
|
if (isset($changes[$file])) { |
|
if ($changes[$file]['timestamp'] < $timestamp) { |
|
unset($changes[$file]); |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'added', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} else { |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'added', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} |
|
} |
|
|
|
if (!empty($commit['modified'])) { |
|
foreach ($commit['modified'] as $file => $value) { |
|
|
|
// only use files in the upload folder and strip upload/ out |
|
if (strpos($value, 'upload/') === 0) { |
|
$file = substr($value, 7); |
|
} else { |
|
continue; |
|
} |
|
|
|
if (isset($changes[$file])) { |
|
if ($changes[$file]['timestamp'] < $timestamp) { |
|
unset($changes[$file]); |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'modified', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} else { |
|
$changes[$file] = array( |
|
'file' => $file, |
|
'timestamp' => $timestamp, |
|
'action' => 'modified', |
|
'id' => $commit['id'] |
|
); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (!empty($changes)) { |
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Update From Deveo Webhook'); |
|
$this->log->write('Commits Added: ' . $payload['commit_count']); |
|
} |
|
|
|
// Sort by Timestamp ascending |
|
function sortByTimestamp($a, $b) { |
|
return $a['timestamp'] - $b['timestamp']; |
|
} |
|
|
|
usort($changes, "sortByTimestamp"); |
|
|
|
// Perform all the changes based on action type |
|
foreach ($changes as $change) { |
|
if ($change['action'] == 'removed') { |
|
if (file_exists($change['file'])) { |
|
unlink($change['file']); |
|
} |
|
|
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Removed: ' . $change['file']); |
|
} |
|
|
|
$this->deleteDirectory(dirname($change['file'])); |
|
} |
|
|
|
if ($change['action'] == 'added') { |
|
$this->getFile($change['file'], $project_id, $repository_id, $change['id'], $account_key, $company_key, $plugin_key); |
|
|
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Added: ' . $change['file']); |
|
} |
|
} |
|
|
|
if ($change['action'] == 'modified') { |
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Modified: ' . $change['file']); |
|
} |
|
|
|
$this->getFile($change['file'], $project_id, $repository_id, $change['id'], $account_key, $company_key, $plugin_key); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
$this->response->setOutput('OK'); |
|
} |
|
|
|
private function getFile($file, $project, $repository, $id, $account_key, $company_key, $plugin_key) { |
|
$dirname = dirname($file); |
|
|
|
if (!is_dir($dirname)) { |
|
mkdir($dirname, 0775, true); |
|
} |
|
|
|
if (file_exists($file)) { |
|
unlink($file); |
|
} |
|
|
|
$fp = fopen($file, 'w'); |
|
|
|
$curl = curl_init('https://app.deveo.com/api/blob?path=upload/' . $file . '&project_id=' . $project . '&repository_id=' . $repository . '&id=' . $id . '&account_key=' . $account_key . '&company_key=' . $company_key . '&plugin_key=' . $plugin_key); |
|
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); |
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); |
|
curl_setopt($curl, CURLOPT_HEADER, false); |
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); |
|
curl_setopt($curl, CURLOPT_FORBID_REUSE, true); |
|
curl_setopt($curl, CURLOPT_FRESH_CONNECT, true); |
|
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); |
|
curl_setopt($curl, CURLOPT_TIMEOUT, 10); |
|
curl_setopt($curl, CURLOPT_FILE, $fp); |
|
|
|
curl_exec($curl); |
|
curl_close($curl); |
|
|
|
fclose($fp); |
|
chmod($file, 0664); |
|
} |
|
|
|
private function deleteDirectory($path) { |
|
$parts = explode('/', $path); |
|
|
|
while ($parts) { |
|
$dir = implode('/', $parts); |
|
|
|
if (file_exists($dir)) { |
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Checking if directory is empty: ' . $dir); |
|
} |
|
|
|
if (!(new \FilesystemIterator($dir))->valid()) { |
|
rmdir($dir); |
|
|
|
if ($this->config->get('config_deveo_debug')) { |
|
$this->log->write('Removed: ' . $dir); |
|
} |
|
} |
|
} |
|
|
|
array_pop($parts); |
|
} |
|
} |
|
} |