AuthShield = $AuthShield; $this->container=(null!==$container) ? $container : $AuthShield->getAppShield()->getContainer(); } public function auth(\UMA\JsonRpc\Request $request){ return 'admin' === $this->container->get('webfan.app.fsm.user')->getCurrentState()->getName(); } /** * {@inheritdoc} */ public function __invoke(\UMA\JsonRpc\Request $request): \UMA\JsonRpc\Response { $dir = getcwd(); $params = $request->params(); $AppShield = $this->AuthShield->getAppShield(); $config = $AppShield->config->export(); if(!isset($config['COMPOSER_PATH'])){ return new \UMA\JsonRpc\Error($request->id(), 'Composer is not setup correctly'); } if(!property_exists($params, 'dir')){ return new \UMA\JsonRpc\Error($request->id(), 'No `dir` specified'); } $path = str_replace('//', '/', $params->dir); $path = str_replace('/', \DIRECTORY_SEPARATOR, $path); $path = str_replace('composer.json', '', $path); $original_path=$path; if(!is_dir($path)){ $path = $config['wsdir'] . $original_path; } if(!is_dir($path)){ $path = $config['wsdir'] . \DIRECTORY_SEPARATOR . $original_path; } if(!is_dir($path)){ $path = $config['wsdir'] . 'frdl-projects' . $original_path; } if(!is_dir($path)){ $path = $config['wsdir'] . 'frdl-projects' . \DIRECTORY_SEPARATOR . $original_path; } if(!is_dir($path)){ return new \UMA\JsonRpc\Error($request->id(), '`dir` does not exist'); } chdir($path); /* $j = 'vendor'.\DIRECTORY_SEPARATOR.'composer'.\DIRECTORY_SEPARATOR.'installed.json'; if(file_exists($j)){ unlink($j); } */ $composer = json_decode(file_get_contents('composer.json')); if(!isset($composer->config))$composer->config=new \stdclass; if(!isset($composer->config->platform))$composer->config->platform=new \stdclass; $composer->config->platform->php = \PHP_VERSION; $composer->{'minimum-stability'} = 'dev'; $composer->{'prefer-stable'} = true; //if(isset($composer->{'minimum-stability'}))unset($composer->{'minimum-stability'}); file_put_contents('composer.json', json_encode($composer, \JSON_PRETTY_PRINT)); // set_time_limit(900); //exec(sprintf('%s install --working-dir=%s --no-progress 2>&1 ', $config['COMPOSER_PATH'], $path), $out, $status); // > /dev/null 2>/dev/null & // exec(sprintf('%s install --working-dir=%s --no-progress > /dev/null 2>/dev/null & ', $config['COMPOSER_PATH'], $path), $status); // if($status){ // return new \UMA\JsonRpc\Error($request->id(), implode(', ', $out)); // } $outputfile = rtrim($path, \DIRECTORY_SEPARATOR). \DIRECTORY_SEPARATOR.'logs'. \DIRECTORY_SEPARATOR.'apc.rpc.composer.log'; if(!is_dir(dirname($outputfile))){ mkdir(dirname($outputfile), 0755, true); } // if(!file_exists($outputfile)){ file_put_contents($outputfile, ''); // } \webfan\hps\patch\Fs::filePrune($outputfile,1024 * 1024, true); $datum = date('c', time()); // file_put_contents($outputfile, '@rpc>'.$request->method().' '.$datum, \FILE_APPEND/* | \LOCK_EX*/); $pidfile = tempnam(sys_get_temp_dir(), 'pid.rpc.'.$request->method()); //$cmd = sprintf('%s install --working-dir=%s --no-progress', 'COMPOSER_BIN="'.$config['COMPOSER_PATH'].'" '.(new \webfan\hps\patch\PhpBinFinder())->find().' '.$config['COMPOSER_PATH'], $path); // $cmd = sprintf('%s install --working-dir=%s --no-progress', $config['COMPOSER_PATH'], $path); // --optimize-autoloader //$cmd = sprintf('%s install --working-dir=%s --no-progress', (new \webfan\hps\patch\PhpBinFinder())->find().' -d memory_limit=-1 '.$config['COMPOSER_PATH'], $path); $cmd = sprintf('%s install --working-dir=%s --no-progress', (new \webfan\hps\patch\PhpBinFinder())->find().' -d memory_limit=-1 '.$config['COMPOSER_PATH'], $path); // set_time_limit(0); exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile)); $pid = file_get_contents($pidfile); unlink($pidfile); return new \UMA\JsonRpc\Success($request->id(),[ 'pid' => intval($pid), 'logfile' => $outputfile, ]); } public function getSpec(): ?\stdClass { return \json_decode(<<<'JSON' { "$schema": "https://json-schema.org/draft-07/schema#", "type": ["object"], "properties": { "dir" : { type : ["string"] } }, "required" : ["dir"], "additionalProperties": true } JSON ); } protected function getRepositorySchema(){ return <</.", "additionalProperties": { "\$ref": "#/definitions/versions" } }, "providers-url": { "type": "string", "description": "Endpoint to retrieve provider data from, e.g. '/p/%package%$%hash%.json'." }, "provider-includes": { "type": "object", "description": "A hashmap of provider listings.", "additionalProperties": { "\$ref": "#/definitions/provider" } }, "providers": { "type": "object", "description": "A hashmap of package names in the form of /.", "additionalProperties": { "\$ref": "#/definitions/provider" } }, "notify-batch": { "type": "string", "description": "Endpoint to call after multiple packages have been installed, e.g. '/downloads/'." }, "search": { "type": "string", "description": "Endpoint that provides search capabilities, e.g. '/search.json?q=%query%&type=%type%'." }, "warning": { "type": "string", "description": "A message that will be output by Composer as a warning when this source is consulted." } }, "definitions": { "versions": { "type": "object", "description": "A hashmap of versions and their metadata.", "additionalProperties": { "\$ref": "#/definitions/version" } }, "version": { "type": "object", "oneOf": [ { "\$ref": "#/definitions/package" }, { "\$ref": "#/definitions/metapackage" } ] }, "package-base": { "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "version": { "type": "string" }, "version_normalized": { "type": "string", "description": "Normalized version, optional but can save computational time on client side." }, "autoload": { "type": "object" }, "require": { "type": "object" }, "replace": { "type": "object" }, "conflict": { "type": "object" }, "provide": { "type": "object" }, "time": { "type": "string" } }, "additionalProperties": true }, "package": { "allOf": [ { "\$ref": "#/definitions/package-base" }, { "properties": { "dist": { "type": "object" }, "source": { "type": "object" } } }, { "oneOf": [ { "required": [ "name", "version", "source" ] }, { "required": [ "name", "version", "dist" ] } ] } ] }, "metapackage": { "allOf": [ { "\$ref": "#/definitions/package-base" }, { "properties": { "type": { "type": "string", "enum": [ "metapackage" ] } }, "required": [ "name", "version", "type" ] } ] }, "provider": { "type": "object", "properties": { "sha256": { "type": "string", "description": "Hash value that can be used to validate the resource." } } } } } JSONSCHEMA; } } __halt_compiler();----SIGNATURE:----Xwgg9McUkZzZCdJVNrqlOQwA5tXxrQCPnxfIcFFAdZj6cTQHsDgnZo0A2hN7fuDUKnm7AeWm8Pjzh4wj+8ExssQM6/QDqlx2wlmA8UxXZwpwPKANGg+CJnjdbfL4gAF91Me+FUAyv5V0O8FL6U2QhV6yoOKRZq/LfgCsyqv4nCmYxxZzeAXp0/6hvUdG1Dc7TiXtpdQeZx3HaDr/7Lygc+Xv6in5uQR06XR3wWuCnGnpvCX7q5O+Z8XUfVTRsQ+GU/TjCYmtOgOv0dp3Ov7wElrby7VuMvw2FtITwXDXoqyB6kxKNMi0sE0fChSpFuxi+OtCpPHTO9SqSiHuexTuBaW3EcYgHIVkd6rIbBcYZrRvG989ohYYOwVd+YEurm8TZscCOSnfrnpupvMXbEeOiexIrZnMbEDssSeNWYI9pnjaW52FVJzE1CrZNuqGU4HusOUXeFHqTYK5Ui45nq3SB+MFRrZOFyFQv9NuM/3HgNd8s8352gatzSHhemcvXm2jAbQTJYOttG2FBtA9qaBBHNghj7G0c/KuVF9XHnvAn4pIiUH2xIJmwl9eD63+jRxEKyU8MLty+sWtAYPRKQWAFnbfuiLI9MUjVfaBbeDo9bQ8mzrVA0Tq+vKQyZxv4PaTOhoz+SdmMr8MG6Q1ZaSWd9+6Ghd65bddXRwVH7t7oHw=----ATTACHMENT:----NDI2NDUyNzM1MTU4MTAyOCAxNTYxODI4NzA2NDE3MzEzIDIyMzM2NTY5NjU0MTI0NjM=