/** * @param string $path * @param string $targetDir * @param string $root path without trailing slash * @return boolean */ static function extractByRoot($path, $targetDir, $root) { //get items paths from within root $namesList = srokap_zip::getArchiveNameIndex($path); if ($namesList === false) { throw new IOException("Error while reading archive contents: {$path}"); } foreach ($namesList as $key => $item) { //keep only items within root path if (strpos($item, $root) !== 0) { unset($namesList[$key]); } } if (empty($namesList)) { throw new IOException("Invalid archive root path privided: {$root}"); } $targetDir .= '/'; if (!srokap_files::createDir($targetDir)) { throw new IOException("Unable to create target dir: {$targetDir}"); } $result = false; $zip = new ZipArchive(); if ($zip->open($path)) { foreach ($namesList as $key => $item) { $sufix = substr($item, strlen($root) + 1); if ($sufix === false) { continue; } $path = $targetDir . $sufix; $dirPath = dirname($path); if (!empty($dirPath) && !srokap_files::createDir($dirPath)) { throw new IOException("Unable to create dir: " . dirname($path)); } if ($item[strlen($item) - 1] == '/') { //not a file continue; } $content = stream_get_contents($zip->getStream($item)); if ($content === false) { throw new IOException("Error reading from archive path: {$item}"); } if (file_put_contents($path, $content) === false) { throw new IOException("Error extracting file from {$item} to {$path}"); } } $result = true; } $zip->close(); return $result; }
/** * @param string $version * @param string $root */ public function install($version, $root) { $path = $this->getPackagePath($version, 'package'); $pluginDir = basename($root); if (strpos($root, '.') !== false) { throw new IOException("Invalid plugin root directory: {$root}"); } $targetDir = elgg_get_config('pluginspath') . $pluginDir . '/'; if (!srokap_zip::extractByRoot($path, $targetDir, $root)) { throw new IOException("Error while extracting files from archive: {$path}"); } return true; }
<?php admin_gatekeeper(); $guid = get_input('guid'); $version = get_input('version'); $entity = ElggRemotePluginProject::getByPackage($guid, $version); $path = $entity->getPackagePath(null, 'package'); $contents = srokap_zip::getArchiveNameIndex($path); $possibleRoots = srokap_plugin_installer::getPossiblePluginRoots($contents); $body = '<div class="mtm">' . elgg_echo('srokap_plugin_installer:version', array($version)) . '</div>'; if ($possibleRoots !== false) { $body .= '<div class="mtm">' . elgg_echo('srokap_plugin_installer:best_root', array($possibleRoots[0])) . ' '; $targetPath = elgg_get_config('pluginspath') . $possibleRoots[0]; $dirExists = is_dir($targetPath); try { $url = $entity->getInstallActionURL($version, $possibleRoots[0]); if ($dirExists) { $body .= elgg_view('output/confirmlink', array('href' => $url, 'text' => elgg_echo('srokap_plugin_installer:reinstall'), 'class' => 'elgg-button elgg-button-cancel', 'confirm' => elgg_echo('srokap_plugin_installer:confirm:dir_exists', array($targetPath)))); } else { $body .= elgg_view('output/url', array('href' => $url, 'text' => elgg_echo('srokap_plugin_installer:install'), 'class' => 'elgg-button elgg-button-submit')); } } catch (IOException $e) { //just no output } $body .= '</div>'; } else { $body .= '<div class="mtm">' . elgg_echo('srokap_plugin_installer:no_root') . '</div>'; } if (is_array($contents)) { $body .= '<pre style="max-width:100%;max-height:500px;overflow:scroll">'; foreach ($contents as $file) {