/** * Loads target task module with specified composer name, from the path * ".private/modules/$vendor/$name". * * @param {string} $identity "$vendor/$name" format respecting composer syntax. * @return {array} JSON decoded array of composer.json. */ function load($identity) { // todo; implement this // note; check identity format if (!preg_match('/^\\w+\\/[^\\:\\/\\.]+(?:@.+)?$/', $identity)) { return $this->data(array()); } @(list($identity, $version) = explode('@', $identity)); $composer = ".private/modules/{$identity}/composer.json"; if (!file_exists($composer)) { return $this->data(array()); } $composer = ContentDecoder::json(file_get_contents($composer)); // no specific version, or we have a newer one. if (!$version || (new version($composer['version']))->satisfies(new expression($version))) { $this->data($composer)->afterload(); } else { $this->data(array()); } return $this; }
/** * Query contents with current configuration key from the database, * and update the local stored value. */ function update() { // Root objects will get value from database upon creation if ($this->parentObject === null) { $confObj = array(); // Database support if (Database::isConnected()) { $res = (array) @Node::getOne(array(Node::FIELD_COLLECTION => FRAMEWORK_COLLECTION_CONFIGURATION, '@key' => $this->key)); unset($res['@key'], $res[Node::FIELD_COLLECTION]); $confObj += $res; unset($res); } // basenames to search $basenames = array('', gethostname()); array_walk($basenames, function ($basename) use(&$confObj) { if ($basename) { $basename = ".{$basename}"; } $basename = self::FALLBACK_DIRECTORY . "/{$this->key}{$basename}"; // JSON Support $res = "{$basename}.json"; if (is_readable($res)) { $res = (array) @ContentDecoder::json(file_get_contents($res), 1); if ($res) { $confObj = $res + $confObj; } else { throw new exceptions\FrameworkException('JSON file exists but decode failed.'); } } unset($res); // YAML support (symfony/yaml) if (class_exists('Yaml')) { $res = "{$basename}.yaml"; if (is_readable($res)) { $res = Yaml::parse($res); // Sorry mate, at least an array. if (is_array($res)) { $confObj = $res + $confObj; } else { throw new exceptions\FrameworkException('YAML file exists but decode failed.'); } } unset($res); } }); } else { $confObj =& $this->parentObject->__valueOf(); $confObj =& $confObj[$this->key]; } $this->contents =& $confObj; }
unset($processContents); $res = Database::query('UPDATE `' . FRAMEWORK_COLLECTION_PROCESS . '` SET `pid` = ? WHERE `id` = ? AND `pid` IS NULL LIMIT 1', [getmypid(), $process['id']]); // Commit transaction Database::unlockTables(true); Database::commit(); if ($res->rowCount() < 1) { Log::warning('Unable to update process pid, worker exits.'); die; } else { $process['pid'] = getmypid(); $process[Node::FIELD_COLLECTION] = FRAMEWORK_COLLECTION_PROCESS; } // Check if $env specified in option if (@$_SERVER['env']) { $_SERVER['env'] = ContentDecoder::json($_SERVER['env'], 1); } // More debug logs Log::debug("Execute process: {$process['command']}"); // Spawn process and retrieve the pid $proc = false; do { $proc = proc_open($process['command'], array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'e')), $pipes, null, @$_SERVER['env']); if ($proc) { break; } else { usleep(Process::$spawnCaptureInterval * 1000000); } } while (++$retryCount < Process::$spawnCaptureCount); if (!$proc) { throw new ProcessException('Unable to spawn process, please check error logs.');
/** * @constructor * * @param {?string|array} $options An array of request options, or the URI string. * @param {?string} $options['prefix'] Parameters keys start with this prefix * will be treated as meta-parameters and * not returned in param() related functions. * * Parameters values start with this prefix * will be tried to parsed as constants and * booleans. * * This defaults to the "@" character. * * @param {?string} $options['uri'] The request uri, defaults to $_SERVER['REQUEST_URI']. * @param {?string} $options['method'] Request method, defaults to $_SERVER['REQUEST_METHOD']. * @param {?array} $options['headers'] Request headers, defaults to the contents of getallhheaders() * if the function is available. * @param {?array} $options['client'] Request client details, defaults to everything from $_SERVER. * @param {?array} $options['get'] GET parameters in array format. * @param {?array} $options['post'] POST parameters in array format. * @param {?array} $options['cookies'] COOKIES in array format. * @param {?array} $options['files'] Upload files along with this request. (Use with care) * When doing CURL requests, files array must compatible with CURL. * Otherwise this must obey the resolver-request format. * @param {?string} $options['locale'] Requesting locale, defaults to en_US. */ public function __construct($options = array()) { global $argv; if ($options instanceof Resolver) { $this->resolver = $options; $options = array(); } if (@$options) { if (is_string($options)) { $options = array('uri' => $options); } // Special parameter prefix if (!empty($options['prefix'])) { $this->metaPrefix = $options['prefix']; } // Request URI if (empty($options['uri'])) { throw new FrameworkException('Request URI is required.'); } else { $this->setUri($options['uri']); } // Request method if (isset($options['method'])) { $this->method = strtolower($options['method']); } else { $this->method = 'get'; } // Request headers if (isset($options['headers'])) { $this->headers = (array) $options['headers']; } // Request client if (!empty($options['client'])) { $this->client = (array) $options['client']; } // Request parameters GET if (isset($options['get'])) { $this->paramCache['get'] = (array) $options['get']; } // Request parameters POST if (!empty($options['post'])) { $this->paramCache['post'] = (array) $options['post']; } // Cookies if (isset($options['cookies'])) { $this->paramCache['cookies'] = (array) $options['cookies']; } // File uploads if (isset($options['files'])) { $this->paramCache['files'] = (array) $options['files']; } // Request locale if (!empty($options['locale'])) { $this->locale = (string) $options['locale']; } } else { // Request client switch (constant('PHP_SAPI')) { case 'cli': $this->client = array('type' => 'cli', 'host' => gethostname(), 'user' => get_current_user()); break; default: $this->client = array_filter(array('type' => 'http', 'secure' => @$_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off', 'address' => @$_SERVER['REMOTE_ADDR'], 'host' => @$_SERVER['REMOTE_HOST'], 'port' => @$_SERVER['REMOTE_PORT'], 'user' => @$_SERVER['REMOTE_USER'], 'referer' => @$_SERVER['HTTP_REFERER'], 'version' => @$_SERVER['SERVER_PROTOCOL'], 'userAgent' => @$_SERVER['HTTP_USER_AGENT'], 'forwarder' => @$_SERVER['HTTP_X_FORWARDED_FOR'], 'isAjax' => strtolower(@$_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'), compose('not', 'is_null')); break; } // Request method switch ($this->client('type')) { case 'cli': $this->method = 'cli'; break; default: $this->method = strtolower(@$_SERVER['REQUEST_METHOD']); break; } // Request headers switch ($this->client('type')) { case 'cli': break; default: $this->headers = getallheaders(); break; } // Request parameters switch ($this->client('type')) { case 'cli': $this->paramCache['cli'] = new Optimist(); break; default: // Request parameters GET $this->paramCache['get'] = $_GET; // Request parameters POST if (preg_match('/^application\\/json/', $this->header('Content-Type'))) { $this->paramCache['post'] = ContentDecoder::json(file_get_contents('php://input'), true); } else { $this->paramCache['post'] = $_POST; } // Cookies $this->paramCache['cookies'] =& $_COOKIE; // File uploads if ($this->method() == 'put') { $this->paramCache['files'] = new RequestPutFile($this->header('Content-Type')); } else { util::filesFix(); $parseFile = function ($file) use(&$parseFile) { if (!is_array($file)) { return $file; } if (util::isAssoc($file)) { switch ($file['error']) { case UPLOAD_ERR_OK: return new RequestPostFile($file); case UPLOAD_ERR_NO_FILE: // Skip it. break; default: return $file['error']; } } else { return array_mapdef($file, $parseFile); } }; $this->paramCache['files'] = array_mapdef(array_filter_keys($_FILES, compose('not', startsWith('@'))), $parseFile); unset($parseFile); } break; } // Request URI // CLI requires request parameters switch ($this->client('type')) { case 'cli': /*! Note @ 9 May, 2015 * Usage: node-cli [OPTIONS] COMMAND * Only one command is supported, simply shift it out. */ $this->uri = @$this->paramCache['cli']['_'][0]; if (!$this->uri) { $this->uri = $argv[1]; } break; default: $uri = array('scheme' => $this->client('secure') ? 'https' : 'http', 'user' => @$_SERVER['REMOTE_USER'], 'host' => @$_SERVER['SERVER_NAME'], 'port' => @$_SERVER['SERVER_PORT'], 'path' => @$_SERVER['REQUEST_URI'], 'query' => $_GET); if (empty($uri['user'])) { $uri['user'] = @$_SERVER['PHP_AUTH_USER']; } $this->setUri(array_filter($uri)); // = parse_url(http_build_url($this->uri)); break; } // Parse special parameter values array_walk_recursive($this->paramCache, function (&$value) { if (is_string($value) && strpos($value, $this->metaPrefix) === 0) { $_value = substr($value, strlen($this->metaPrefix)); switch (strtolower($_value)) { case 'true': $value = true; break; case 'false': $value = false; break; default: if (defined($_value)) { $value = constant($_value); } break; } } }); // Request timestamp $this->timestamp = (double) @$_SERVER['REQUEST_TIME_FLOAT']; } // Unified params ($_REQUEST mimic) switch ($this->client('type')) { case 'cli': // $this->paramCache['request'] = $this->paramCache['cli']; break; default: $this->paramCache['request'] = array_merge((array) @$this->paramCache['cookies'], (array) @$this->paramCache['get'], (array) @$this->paramCache['post']); break; } // Failover in case of request time not exists. if (!$this->timestamp) { $this->timestamp = microtime(1); } }