private static function loadSkinSpecification($path) { $config_path = $path . DIRECTORY_SEPARATOR . 'skin.json'; $config = array(); if (Filesystem::pathExists($config_path)) { $config = Filesystem::readFile($config_path); try { $config = phutil_json_decode($config); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht("Skin configuration file '%s' is not a valid JSON file.", $config_path), $ex); } $type = idx($config, 'type', self::TYPE_BASIC); } else { $type = self::TYPE_BASIC; } $spec = new PhameSkinSpecification(); $spec->setRootDirectory($path); $spec->setConfig($config); switch ($type) { case self::TYPE_BASIC: $spec->setSkinClass('PhameBasicTemplateBlogSkin'); break; case self::TYPE_ADVANCED: $spec->setSkinClass($config['class']); $spec->addPhutilLibrary($path . DIRECTORY_SEPARATOR . 'src'); break; default: throw new Exception(pht('Unknown skin type!')); } $spec->setType($type); return $spec; }
protected function readBookConfiguration($book_path) { if ($book_path === null) { throw new PhutilArgumentUsageException(pht('Specify a Diviner book configuration file with %s.', '--book')); } $book_data = Filesystem::readFile($book_path); $book = phutil_json_decode($book_data); PhutilTypeSpec::checkMap($book, array('name' => 'string', 'title' => 'optional string', 'short' => 'optional string', 'preface' => 'optional string', 'root' => 'optional string', 'uri.source' => 'optional string', 'rules' => 'optional map<regex, string>', 'exclude' => 'optional regex|list<regex>', 'groups' => 'optional map<string, map<string, wild>>')); // If the book specifies a "root", resolve it; otherwise, use the directory // the book configuration file lives in. $full_path = dirname(Filesystem::resolvePath($book_path)); if (empty($book['root'])) { $book['root'] = '.'; } $book['root'] = Filesystem::resolvePath($book['root'], $full_path); if (!preg_match('/^[a-z][a-z-]*\\z/', $book['name'])) { $name = $book['name']; throw new PhutilArgumentUsageException(pht("Book configuration '%s' has name '%s', but book names must " . "include only lowercase letters and hyphens.", $book_path, $name)); } foreach (idx($book, 'groups', array()) as $group) { PhutilTypeSpec::checkmap($group, array('name' => 'string', 'include' => 'optional regex|list<regex>')); } $this->bookConfigPath = $book_path; $this->config = $book; }
/** * @phutil-external-symbol class PhabricatorStartup */ public function handleRequest(AphrontRequest $request) { $raw_body = PhabricatorStartup::getRawInput(); $body = phutil_json_decode($raw_body); $payload = $body['payload']; $parameters = idx($payload, 'build_parameters'); if (!$parameters) { $parameters = array(); } $target_phid = idx($parameters, 'HARBORMASTER_BUILD_TARGET_PHID'); // NOTE: We'll get callbacks here for builds we triggered, but also for // arbitrary builds the system executes for other reasons. So it's normal // to get some notifications with no Build Target PHID. We just ignore // these under the assumption that they're routine builds caused by events // like branch updates. if ($target_phid) { $viewer = PhabricatorUser::getOmnipotentUser(); $target = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->withPHIDs(array($target_phid))->needBuildSteps(true)->executeOne(); if ($target) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $this->updateTarget($target, $payload); } } $response = new AphrontWebpageResponse(); $response->setContent(pht("Request OK\n")); return $response; }
public function testParseRender() { $dir = $this->getTestDataDirectory(); foreach (Filesystem::listDirectory($dir, $show_hidden = false) as $file) { if (!preg_match('/\\.diff$/', $file)) { continue; } $data = Filesystem::readFile($dir . $file); $opt_file = $dir . $file . '.options'; if (Filesystem::pathExists($opt_file)) { $options = Filesystem::readFile($opt_file); try { $options = phutil_json_decode($options); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Invalid options file: %s.', $opt_file), $ex); } } else { $options = array(); } foreach (array('one', 'two') as $type) { $this->runParser($type, $data, $file, 'expect'); $this->runParser($type, $data, $file, 'unshielded'); $this->runParser($type, $data, $file, 'whitespace'); } } }
protected function didReceiveResult($result) { if ($this->profilerCallID !== null) { $profiler = PhutilServiceProfiler::getInstance(); $profiler->endServiceCall($this->profilerCallID, array()); } list($status, $body, $headers) = $result; if ($status->isError()) { throw $status; } $raw = $body; $shield = 'for(;;);'; if (!strncmp($raw, $shield, strlen($shield))) { $raw = substr($raw, strlen($shield)); } $data = null; try { $data = phutil_json_decode($raw); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Host returned HTTP/200, but invalid JSON data in response to ' . 'a Conduit method call.'), $ex); } if ($data['error_code']) { throw new ConduitClientException($data['error_code'], $data['error_info']); } $result = $data['result']; $result = $this->client->didReceiveResponse($this->conduitMethod, $result); return $result; }
/** * Decode a message received from the other end of the channel. Messages are * decoded as associative arrays. * * @task protocol */ protected function decodeStream($data) { $this->buf .= $data; $objects = array(); while (strlen($this->buf) >= $this->byteLengthOfNextChunk) { switch ($this->mode) { case self::MODE_LENGTH: $len = substr($this->buf, 0, self::SIZE_LENGTH); $this->buf = substr($this->buf, self::SIZE_LENGTH); $this->mode = self::MODE_OBJECT; $this->byteLengthOfNextChunk = (int) $len; break; case self::MODE_OBJECT: $data = substr($this->buf, 0, $this->byteLengthOfNextChunk); $this->buf = substr($this->buf, $this->byteLengthOfNextChunk); try { $objects[] = phutil_json_decode($data); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Failed to decode JSON object.'), $ex); } $this->mode = self::MODE_LENGTH; $this->byteLengthOfNextChunk = self::SIZE_LENGTH; break; } } return $objects; }
public function testDifferentialCommitMessageParser() { $dir = dirname(__FILE__) . '/messages/'; $list = Filesystem::listDirectory($dir, $include_hidden = false); foreach ($list as $file) { if (!preg_match('/.txt$/', $file)) { continue; } $data = Filesystem::readFile($dir . $file); $divider = "~~~~~~~~~~\n"; $parts = explode($divider, $data); if (count($parts) !== 4) { throw new Exception(pht('Expected test file "%s" to contain four parts (message, fields, ' . 'output, errors) divided by "%s".', $file, '~~~~~~~~~~')); } list($message, $fields, $output, $errors) = $parts; $fields = phutil_json_decode($fields); $output = phutil_json_decode($output); $errors = phutil_json_decode($errors); $parser = id(new DifferentialCommitMessageParser())->setLabelMap($fields)->setTitleKey('title')->setSummaryKey('summary'); $result_output = $parser->parseCorpus($message); $result_errors = $parser->getErrors(); $this->assertEqual($output, $result_output); $this->assertEqual($errors, $result_errors); } }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $tags = $request->getStr('tags'); try { $tags = phutil_json_decode($tags); } catch (PhutilJSONParserException $ex) { $tags = array(); } $refs = array(); $id_map = array(); foreach ($tags as $tag_spec) { $tag = $tag_spec['ref']; $ref = id(new DoorkeeperObjectRef())->setApplicationType($tag[0])->setApplicationDomain($tag[1])->setObjectType($tag[2])->setObjectID($tag[3]); $key = $ref->getObjectKey(); $id_map[$key] = $tag_spec['id']; $refs[$key] = $ref; } $refs = id(new DoorkeeperImportEngine())->setViewer($viewer)->setRefs($refs)->execute(); $results = array(); foreach ($refs as $key => $ref) { if (!$ref->getIsVisible()) { continue; } $uri = $ref->getExternalObject()->getObjectURI(); if (!$uri) { continue; } $id = $id_map[$key]; $tag = id(new PHUITagView())->setID($id)->setName($ref->getFullName())->setHref($uri)->setType(PHUITagView::TYPE_OBJECT)->setExternal(true)->render(); $results[] = array('id' => $id, 'markup' => $tag); } return id(new AphrontAjaxResponse())->setContent(array('tags' => $results)); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $keys = $request->getStr('keys'); try { $keys = phutil_json_decode($keys); } catch (PhutilJSONParserException $ex) { return new Aphront400Response(); } // There have been at least two users asking for a keyboard shortcut to // close the dialog, so be explicit that escape works since it isn't // terribly discoverable. $keys[] = array('keys' => array('esc'), 'description' => pht('Close any dialog, including this one.')); $stroke_map = array('left' => "←", 'right' => "→", 'up' => "↑", 'down' => "↓", 'return' => "⏎", 'tab' => "⇥", 'delete' => "⌫"); $rows = array(); foreach ($keys as $shortcut) { $keystrokes = array(); foreach ($shortcut['keys'] as $stroke) { $stroke = idx($stroke_map, $stroke, $stroke); $keystrokes[] = phutil_tag('kbd', array(), $stroke); } $keystrokes = phutil_implode_html(' or ', $keystrokes); $rows[] = phutil_tag('tr', array(), array(phutil_tag('th', array(), $keystrokes), phutil_tag('td', array(), $shortcut['description']))); } $table = phutil_tag('table', array('class' => 'keyboard-shortcut-help'), $rows); return $this->newDialog()->setTitle(pht('Keyboard Shortcuts'))->appendChild($table)->addCancelButton('#', pht('Close')); }
protected function parseLinterOutput($path, $err, $stdout, $stderr) { $messages = array(); $output = phutil_json_decode($stdout); // We are only linting a single file. if (count($output) != 1) { return false; } foreach ($output as $reports) { foreach ($reports as $report) { // Column number is not provided in the output. // See https://github.com/clutchski/coffeelint/issues/87 $message = id(new ArcanistLintMessage())->setPath($path)->setLine($report['lineNumber'])->setCode($this->getLinterName())->setName(ucwords(str_replace('_', ' ', $report['name'])))->setDescription($report['message'])->setOriginalText(idx($report, 'line')); switch ($report['level']) { case 'warn': $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); break; case 'error': $message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR); break; default: $message->setSeverity(ArcanistLintSeverity::SEVERITY_ADVICE); break; } $messages[] = $message; } } return $messages; }
public function run() { $method = $this->getArgument('method', array()); if (count($method) !== 1) { throw new ArcanistUsageException(pht('Provide exactly one Conduit method name.')); } $method = reset($method); $console = PhutilConsole::getConsole(); if (!function_exists('posix_isatty') || posix_isatty(STDIN)) { $console->writeErr("%s\n", pht('Waiting for JSON parameters on stdin...')); } $params = @file_get_contents('php://stdin'); try { $params = phutil_json_decode($params); } catch (PhutilJSONParserException $ex) { throw new ArcanistUsageException(pht('Provide method parameters on stdin as a JSON blob.')); } $error = null; $error_message = null; try { $result = $this->getConduit()->callMethodSynchronous($method, $params); } catch (ConduitClientException $ex) { $error = $ex->getErrorCode(); $error_message = $ex->getMessage(); $result = null; } echo json_encode(array('error' => $error, 'errorMessage' => $error_message, 'response' => $result)) . "\n"; return 0; }
public function handleRequest(AphrontRequest $request) { $phid = $request->getURIData('phid'); $file = id(new PhabricatorFileQuery())->setViewer($request->getUser())->withPHIDs(array($phid))->executeOne(); if (!$file) { return new Aphront404Response(); } $data = $file->loadFileData(); try { $data = phutil_json_decode($data); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Failed to unserialize XHProf profile!'), $ex); } $symbol = $request->getStr('symbol'); $is_framed = $request->getBool('frame'); if ($symbol) { $view = new PhabricatorXHProfProfileSymbolView(); $view->setSymbol($symbol); } else { $view = new PhabricatorXHProfProfileTopLevelView(); $view->setFile($file); $view->setLimit(100); } $view->setBaseURI($request->getRequestURI()->getPath()); $view->setIsFramed($is_framed); $view->setProfileData($data); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('%s Profile', $symbol)); return $this->buildStandardPageResponse(array($crumbs, $view), array('title' => pht('Profile'), 'frame' => $is_framed)); }
private function readTestCases($path) { $files = Filesystem::listDirectory($path, $include_hidden = false); $tests = array(); foreach ($files as $file) { $data = Filesystem::readFile($path . $file); $parts = preg_split('/^~{5,}$/m', $data); if (count($parts) < 2) { throw new Exception(pht('Expected test file "%s" to contain an input section in JSON, ' . 'then an expected result section in JSON, with the two sections ' . 'separated by a line of "~~~~~", but the divider is not present ' . 'in the file.', $file)); } else { if (count($parts) > 2) { throw new Exception(pht('Expected test file "%s" to contain exactly two sections, ' . 'but it has more than two sections.')); } } list($input, $expect) = $parts; try { $input = phutil_json_decode($input); $expect = phutil_json_decode($expect); } catch (Exception $ex) { throw new PhutilProxyException(pht('Exception while decoding test data for test "%s".', $file), $ex); } $tests[$file] = array('input' => $input, 'expect' => $expect); } return $tests; }
protected function didReceiveResult($result) { list($status, $body, $headers) = $result; if ($status->isError()) { if ($this->isRateLimitResponse($status, $headers)) { // Do nothing, this is a rate limit. } else { if ($this->isNotModifiedResponse($status)) { // Do nothing, this is a "Not Modified" response. } else { // This is an error condition we do not expect. throw $status; } } } try { if (strlen($body)) { $data = phutil_json_decode($body); } else { // This can happen for 304 responses. $data = array(); } } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Expected JSON response from GitHub.'), $ex); } return id(new PhutilGitHubResponse())->setStatus($status)->setHeaders($headers)->setBody($data); }
private function lintComposerJson($path) { $composer_hash = md5(Filesystem::readFile(dirname($path) . '/composer.json')); $composer_lock = phutil_json_decode(Filesystem::readFile(dirname($path) . '/composer.lock')); if ($composer_hash !== $composer_lock['hash']) { $this->raiseLintAtPath(self::LINT_OUT_OF_DATE, pht("The '%s' file seems to be out-of-date. " . "You probably need to run `%s`.", 'composer.lock', 'composer update')); } }
public function setValueFromStorage($json) { if ($json) { $dict = phutil_json_decode($json); $this->releephAction = idx($dict, 'releephAction'); $this->releephPHIDs = idx($dict, 'releephPHIDs'); } return $this; }
public function readSerializedValue($value) { $decoded = phutil_json_decode($value); $policy_value = $decoded[0]; $space_phid = $decoded[1]; $this->setValue($policy_value); $this->setSpacePHID($space_phid); return $this; }
public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $paths = $request->getStr('paths'); try { $paths = phutil_json_decode($paths); } catch (PhutilJSONParserException $ex) { return new Aphront400Response(); } $modified_map = $this->callConduitWithDiffusionRequest('diffusion.lastmodifiedquery', array('paths' => array_fill_keys($paths, $drequest->getCommit()))); if ($modified_map) { $commit_map = id(new DiffusionCommitQuery())->setViewer($viewer)->withRepository($drequest->getRepository())->withIdentifiers(array_values($modified_map))->needCommitData(true)->execute(); $commit_map = mpull($commit_map, null, 'getCommitIdentifier'); } else { $commit_map = array(); } $commits = array(); foreach ($paths as $path) { $modified_at = idx($modified_map, $path); if ($modified_at) { $commit = idx($commit_map, $modified_at); if ($commit) { $commits[$path] = $commit; } } } $phids = array(); foreach ($commits as $commit) { $data = $commit->getCommitData(); $phids[] = $data->getCommitDetail('authorPHID'); $phids[] = $data->getCommitDetail('committerPHID'); } $phids = array_filter($phids); $handles = $this->loadViewerHandles($phids); $branch = $drequest->loadBranch(); if ($branch && $commits) { $lint_query = id(new DiffusionLintCountQuery())->withBranchIDs(array($branch->getID()))->withPaths(array_keys($commits)); if ($drequest->getLint()) { $lint_query->withCodes(array($drequest->getLint())); } $lint = $lint_query->execute(); } else { $lint = array(); } $output = array(); foreach ($commits as $path => $commit) { $prequest = clone $drequest; $prequest->setPath($path); $output[$path] = $this->renderColumns($prequest, $handles, $commit, idx($lint, $path)); } return id(new AphrontAjaxResponse())->setContent($output); }
public function setValueFromStorage($value) { try { $this->setValue(phutil_json_decode($value)); } catch (PhutilJSONParserException $ex) { $this->setValue(array()); } return $this; }
protected function loadOAuthAccountData() { $uri = id(new PhutilURI($this->getPhabricatorURI('api/user.whoami')))->setQueryParam('access_token', $this->getAccessToken()); list($body) = id(new HTTPSFuture($uri))->resolvex(); try { $data = phutil_json_decode($body); return $data['result']; } catch (PhutilJSONParserException $ex) { throw new Exception(pht('Expected valid JSON response from Phabricator %s request.', 'user.whoami'), $ex); } }
public function loadDictionary($path) { $root = $this->getProjectRoot(); $path = Filesystem::resolvePath($path, $root); $dict = phutil_json_decode(Filesystem::readFile($path)); PhutilTypeSpec::checkMap($dict, array('rules' => 'map<string, map<string, string>>')); $rules = $dict['rules']; $this->dictionaries[] = $path; $this->exactWordRules = array_merge($this->exactWordRules, idx($rules, 'exact', array())); $this->partialWordRules = array_merge($this->partialWordRules, idx($rules, 'partial', array())); }
public static function newFromFile($path) { $pid_data = Filesystem::readFile($path); try { $dict = phutil_json_decode($pid_data); } catch (PhutilJSONParserException $ex) { $dict = array(); } $ref = self::newFromDictionary($dict); $ref->pidFile = $path; return $ref; }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.amazon.com/user/profile'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); list($body) = $future->resolvex(); try { return phutil_json_decode($body); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Expected valid JSON response from Amazon account data request.'), $ex); } }
protected function parseLinterOutput($path, $err, $stdout, $stderr) { $results = phutil_json_decode($stdout); $messages = array(); foreach ($results['files'] as $file) { foreach ($file['offenses'] as $offense) { $message = id(new ArcanistLintMessage())->setPath($file['path'])->setDescription($offense['message'])->setLine($offense['location']['line'])->setChar($offense['location']['column'])->setSeverity($this->getLintMessageSeverity($offense['severity']))->setName($this->getLinterName())->setCode($offense['cop_name']); $messages[] = $message; } } return $messages; }
/** * Reads and parses test data from a specified file. * * This method reads and parses test data from a file. The file is expected * to have the following structure * * ``` * <?php * // PHP code goes here. * ~~~~~~~~~~ * { * // JSON dictionary containing expected results from testing method. * } * ``` * * @param string The path to the test file. * @return pair<XHPASTTree, map> The first element of the pair is the * `XHPASTTree` contained within the test file. * The second element of the pair is the * "expect" data. */ private function readTestData($file) { $contents = Filesystem::readFile($file); $contents = preg_split('/^~{10}$/m', $contents); if (count($contents) < 2) { throw new Exception(pht("Expected '%s' separating test case and results.", '~~~~~~~~~~')); } list($data, $expect) = $contents; $tree = XHPASTTree::newFromData($data); $expect = phutil_json_decode($expect); return array($tree, $expect); }
public function execute(PhutilArgumentParser $args) { $time_start = microtime(true); $methodv = $args->getArg('method'); if (!$methodv) { throw new Exception(pht('No Conduit method provided.')); } else { if (count($methodv) > 1) { throw new Exception(pht('Too many Conduit methods provided.')); } } $method = head($methodv); $json = $this->readAllInput(); $raw_params = null; try { $raw_params = phutil_json_decode($json); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Invalid JSON input.'), $ex); } $params = idx($raw_params, 'params', '[]'); $params = phutil_json_decode($params); $metadata = idx($params, '__conduit__', array()); unset($params['__conduit__']); $call = null; $error_code = null; $error_info = null; try { $call = new ConduitCall($method, $params); $call->setUser($this->getUser()); $result = $call->execute(); } catch (ConduitException $ex) { $result = null; $error_code = $ex->getMessage(); if ($ex->getErrorDescription()) { $error_info = $ex->getErrorDescription(); } else { if ($call) { $error_info = $call->getErrorDescription($error_code); } } } $response = id(new ConduitAPIResponse())->setResult($result)->setErrorCode($error_code)->setErrorInfo($error_info); $json_out = json_encode($response->toDictionary()); $json_out = $json_out . "\n"; $this->getIOChannel()->write($json_out); // NOTE: Flush here so we can get an accurate result for the duration, // if the response is large and the receiver is slow to read it. $this->getIOChannel()->flush(); $time_end = microtime(true); $connection_id = idx($metadata, 'connectionID'); $log = id(new PhabricatorConduitMethodCallLog())->setCallerPHID($this->getUser()->getPHID())->setConnectionID($connection_id)->setMethod($method)->setError((string) $error_code)->setDuration(1000000 * ($time_end - $time_start))->save(); }
public function readRequest(PhabricatorConfigOption $option, AphrontRequest $request) { $e_value = null; $errors = array(); $storage_value = $request->getStr('value'); $in_value = phutil_json_decode($storage_value); // When we submit from JS, we submit a list (since maps are not guaranteed // to retain order). Convert it into a map for storage (since it's far more // convenient for us elsewhere). $storage_value = ipull($in_value, null, 'key'); $display_value = $storage_value; return array($e_value, $errors, $storage_value, $display_value); }
public function testMercurialClientWireProtocolParser() { $data = dirname(__FILE__) . '/hgwiredata/'; $dir = Filesystem::listDirectory($data, $include_hidden = false); foreach ($dir as $file) { $raw = Filesystem::readFile($data . $file); $raw = explode("\n~~~~~~~~~~\n", $raw, 2); $this->assertEqual(2, count($raw)); $expect = phutil_json_decode($raw[1]); $this->assertTrue(is_array($expect), $file); $this->assertParserResult($expect, $raw[0], $file); } }
public static final function getOpenSetupIssueKeysFromDatabase() { $db_cache = new PhabricatorKeyValueDatabaseCache(); try { $value = $db_cache->getKey('phabricator.setup.issue-keys'); if (!strlen($value)) { return null; } return phutil_json_decode($value); } catch (Exception $ex) { return null; } }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.github.com/user'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); // NOTE: GitHub requires a User-Agent string. $future->addHeader('User-Agent', __CLASS__); list($body) = $future->resolvex(); try { return phutil_json_decode($body); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Expected valid JSON response from GitHub account data request.'), $ex); } }