public function build() { $file = getTmpFile("phar"); $phar = new \Phar($file); $phar->setStub("<?php __HALT_COMPILER(); ?>"); $phar->setSignatureAlgorithm(\Phar::SHA1); $phar->startBuffering(); $namespace = "_{$this->name}" . randomClass(8, "\\_"); $class = randomClass(8); $main = "{$namespace}\\{$class}"; $manifest = ["name" => $this->name, "version" => $this->version, "authors" => $this->authors, "api" => "1.9.0", "main" => $main, "commands" => []]; foreach ($this->cmds as $cmd) { $manifest["commands"][$cmd->name] = ["description" => $cmd->desc, "usage" => $cmd->usage]; } $phar->addFromString("plugin.yml", yaml_emit($manifest)); $mainClass = <<<EOS <?php namespace {$namespace}; use pocketmine\\command as cmd; use pocketmine\\event as evt; class {$class} extends \\pocketmine\\plugin\\PluginBase implements evt\\Listener{ public function onCommand(cmd\\CommandSender \$sender, cmd\\Command\\ \$cmd, \$lbl, array \$args){ switch(\$cmd->getName()){ EOS; foreach ($this->cmds as $cmd) { $mainClass .= "case " . var_export($cmd->name, true) . ":" . PHP_EOL; $mainClass .= "return \$this->onCommand_{$cmd->name}(\$args, \$sender);" . PHP_EOL; } $mainClass .= "}" . PHP_EOL . "return false;" . PHP_EOL . "}" . PHP_EOL; foreach ($this->cmds as $cmd) { $mainClass .= $cmd->executor->toPhp(); } $mainClass .= "}"; $phar->addFromString("src/" . str_replace("\\", "/", $main) . ".php", $mainClass); // $phar->compressFiles(\Phar::GZ); $phar->stopBuffering(); $path = $phar->getPath(); header("Content-Type: application/octet-stream"); echo file_get_contents($path); // unlink($path); }
function unphar_toZip($tmpName, &$result, $name = "") { $result = ["tmpDir" => null, "zipPath" => null, "zipRelativePath" => null, "basename" => null, "error" => false]; rename($tmpName, "{$tmpName}.phar"); $tmpName .= ".phar"; try { $phar = new Phar($tmpName); $result["tmpDir"] = $tmpDir = getTmpDir(); $pharPath = "phar://{$phar->getPath()}/"; foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharPath)) as $f) { $subpath = substr($f, strlen($pharPath)); @mkdir(dirname($realSubpath = $tmpDir . $subpath), 0777, true); copy($f, $realSubpath); } $zip = new ZipArchive(); $dir = "/data/phars/"; while (is_file($file = htdocs . ($rel = $dir . randomClass(16, "zip_" . $name . "_") . ".zip"))) { } $result["zipPath"] = $file; $result["zipRelativePath"] = $rel; $result["basename"] = substr($rel, 12); $err = $zip->open($file, ZipArchive::CREATE); if ($err !== true) { $msg = "Error creating zip file: "; switch ($err) { case ZipArchive::ER_EXISTS: $msg .= "ER_EXISTS ({$err}) File already exists ({$file})"; break; case ZipArchive::ER_INCONS: $msg .= "ER_INCONS ({$err}) Zip archive inconsistent."; break; case ZipArchive::ER_INVAL: $msg .= "ER_INVAL ({$err}) Invalid argument."; break; case ZipArchive::ER_MEMORY: $msg .= "ER_MEMORY ({$err}) Malloc failure."; break; case ZipArchive::ER_NOENT: $msg .= "ER_NOENT ({$err}) No such file."; break; case ZipArchive::ER_NOZIP: $msg .= "ER_NOZIP ({$err}) Not a zip archive."; break; case ZipArchive::ER_OPEN: $msg .= "ER_OPEN ({$err}) Can't open file."; break; case ZipArchive::ER_READ: $msg .= "ER_READ ({$err}) Read error."; break; case ZipArchive::ER_SEEK: $msg .= "ER_SEEK ({$err}) Seek error."; } throw new RuntimeException($msg . " Dump: " . var_export($result, true)); } $tmpDir = realpath($tmpDir); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tmpDir)) as $file) { if (!is_file($file)) { continue; } $file = realpath($file); $rel = substr($file, strlen($tmpDir) + 1); $zip->addFile($file, str_replace("\\", "/", $rel)); } $zip->setArchiveComment(json_encode($phar->getMetadata(), JSON_PRETTY_PRINT)); $zip->close(); } catch (Exception $e) { echo "<pre>"; echo get_class($e) . ": {$e->getMessage()}"; echo "\r\n\tat {$e->getFile()}:{$e->getLine()}</pre>"; $result["error"] = true; } }