function perform() { WorkbenchContext::get()->getApexConnection()->setDebugLevels($this->logCategory, $this->logCategoryLevel); $executeAnonymousResultWithDebugLog = WorkbenchContext::get()->getApexConnection()->executeAnonymous($this->executeAnonymousBlock); ob_start(); if ($executeAnonymousResultWithDebugLog->executeAnonymousResult->success) { if (isset($executeAnonymousResultWithDebugLog->debugLog) && $executeAnonymousResultWithDebugLog->debugLog != "") { print "<pre>" . addLinksToIds(htmlspecialchars($executeAnonymousResultWithDebugLog->debugLog, ENT_QUOTES)) . '</pre>'; } else { displayInfo("Execution was successful, but returned no results. Confirm log category and level."); } } else { $error = null; if (isset($executeAnonymousResultWithDebugLog->executeAnonymousResult->compileProblem)) { $error .= "COMPILE ERROR: " . $executeAnonymousResultWithDebugLog->executeAnonymousResult->compileProblem; } if (isset($executeAnonymousResultWithDebugLog->executeAnonymousResult->exceptionMessage)) { $error .= "\nEXCEPTION: " . $executeAnonymousResultWithDebugLog->executeAnonymousResult->exceptionMessage; } if (isset($executeAnonymousResultWithDebugLog->executeAnonymousResult->exceptionStackTrace)) { $error .= "\nSTACKTRACE: " . $executeAnonymousResultWithDebugLog->executeAnonymousResult->exceptionStackTrace; } if (isset($executeAnonymousResultWithDebugLog->executeAnonymousResult->line)) { $error .= "\nLINE: " . $executeAnonymousResultWithDebugLog->executeAnonymousResult->line; } if (isset($executeAnonymousResultWithDebugLog->executeAnonymousResult->column)) { $error .= " COLUMN: " . $executeAnonymousResultWithDebugLog->executeAnonymousResult->column; } displayError($error); print '<pre style="color: red;">' . addLinksToIds(htmlspecialchars($executeAnonymousResultWithDebugLog->debugLog, ENT_QUOTES)) . '</pre>'; } $result = ob_get_contents(); ob_end_clean(); return $result; }
function query($soqlQuery, $queryAction, $queryLocator = null, $suppressScreenOutput = false) { if (!WorkbenchConfig::get()->value("allowParentRelationshipQueries") && preg_match("/SELECT.*?(\\w+\\.\\w+).*FROM/i", $soqlQuery, $matches)) { $msg = "Parent relationship queries are disabled in Workbench: " . $matches[1]; if (WorkbenchConfig::get()->overrideable("allowParentRelationshipQueries")) { $msg .= "\n\nDue to issues rendering query results, parent relationship queries are disabled by default. " . "If you understand these limitations, parent relationship queries can be enabled under Settings. " . "Alternatively, parent relationship queries can be run with REST Explorer under the Utilities menu without issue."; } throw new WorkbenchHandledException($msg); } try { if ($queryAction == 'Query') { $queryResponse = WorkbenchContext::get()->getPartnerConnection()->query($soqlQuery); } if ($queryAction == 'QueryAll') { $queryResponse = WorkbenchContext::get()->getPartnerConnection()->queryAll($soqlQuery); } } catch (SoapFault $e) { foreach (array("MALFORMED_QUERY", "INVALID_FIELD", "INVALID_TYPE", "INVALID_QUERY_FILTER_OPERATOR", "QUERY_TIMEOUT", "EXCEEDED_ID_LIMIT") as $known) { if (strpos($e->getMessage(), $known) > -1) { throw new WorkbenchHandledException($e->getMessage(), 0, $e); } } throw $e; } if ($queryAction == 'QueryMore' && isset($queryLocator)) { $queryResponse = WorkbenchContext::get()->getPartnerConnection()->queryMore($queryLocator); } if (stripos($soqlQuery, "count()") && $suppressScreenOutput == false) { return $queryResponse->size; } else { if (!isset($queryResponse->records)) { return null; } } $records = $queryResponse->records; $this->totalQuerySize = $queryResponse->size; if (!$queryResponse->done) { $this->nextQueryLocator = $queryResponse->queryLocator; } //correction for documents and attachments with body. issue #176 if ($queryResponse->size > 0 && !is_array($records)) { $records = array($records); } $memLimitBytes = toBytes(ini_get("memory_limit")); $memWarningThreshold = WorkbenchConfig::get()->value("memoryUsageWarningThreshold") / 100; while (($suppressScreenOutput || WorkbenchConfig::get()->value("autoRunQueryMore")) && !$queryResponse->done) { if ($memLimitBytes != 0 && memory_get_usage() / $memLimitBytes > $memWarningThreshold) { displayError("Workbench almost exhausted all its memory after only processing " . count($records) . " rows of data.\n When performing a large queries, it is recommended to export as Bulk CSV or Bulk XML.", $suppressScreenOutput, true); return; // bail out } $queryResponse = WorkbenchContext::get()->getPartnerConnection()->queryMore($queryResponse->queryLocator); if (!is_array($queryResponse->records)) { $queryResponse->records = array($queryResponse->records); } $records = array_merge($records, $queryResponse->records); //todo: do memory check here } return $records; }
function login($un, $pw) { print "Logging in as " . getenv('SFDC_USERNAME') . "... "; WorkbenchContext::get()->agreeToTerms(); WorkbenchContext::get()->login($un, $pw, null, null); print "done\n"; $W = WorkbenchContext::get(); $ui = $W->getUserInfo(); print "-----> " . $ui->userFullName . " at " . $ui->organizationName . " on API " . $W->getApiVersion() . "\n"; print "-----> " . "Use \$W to access WorkbenchContext\n"; print "\n"; }
public function __construct($baseUrl) { $restBasePattern = '/services/data/v\\d+\\.\\d'; $this->insturmentations[] = new XssProtectionInsturmentation(); // add link url to id services $this->insturmentations[] = new RegexInsturmentation("https?://.*(/id/00D.*/005.*)", "<a class=\\'RestLinkable\\' href=" . $baseUrl . "?url=\$1&autoExec=1>\$1</a>"); // add link url to any rest url $this->insturmentations[] = new RegexInsturmentation("(" . $restBasePattern . ".*)", "<a class=\\'RestLinkable\\' href=" . $baseUrl . "?url=\$1&autoExec=0>\$1</a>"); // add autoExec to everything but query and search $this->insturmentations[] = new RegexInsturmentation('(url=' . $restBasePattern . '(?!/query|/search|.*/.*\\{ID\\}).*&)autoExec=0', '$1autoExec=1'); // query more $this->insturmentations[] = new RegexInsturmentation('(url=' . $restBasePattern . '/query/01g\\w{15}-\\d+&)autoExec=0', '$1autoExec=1'); // sample query url $this->insturmentations[] = new RegexInsturmentation('(' . $restBasePattern . '/query)<', '$1</a> <a class=\'miniLink RestLinkable\' href=' . $baseUrl . '?url=$1?q=SELECT%2Bid,name,profile.name%2BFROM%2Buser%2BWHERE%2Busername=\'' . WorkbenchContext::get()->getUserInfo()->userName . '\'&autoExec=1>[SAMPLE]<'); // sample search url $this->insturmentations[] = new RegexInsturmentation('(' . $restBasePattern . '/search)<', '$1</a> <a class=\'miniLink RestLinkable\' href=' . $baseUrl . '?url=$1?q=FIND%2B%7B' . WorkbenchContext::get()->getUserInfo()->userName . '%7D%2BIN%2BALL%2BFIELDS&autoExec=1>[SAMPLE]<'); }
function establish(ConnectionConfiguration $connConfig) { $connection = new SforcePartnerClient(); $connection->createConnection($this->buildWsdlPath($connConfig)); $connection->setEndpoint($this->buildEndpoint($connConfig)); $connection->setSessionHeader($connConfig->getSessionId()); $connection->setCallOptions(new CallOptions($connConfig->getClientId(), WorkbenchConfig::get()->value('callOptions_defaultNamespace'))); if (WorkbenchContext::get()->isApiVersionAtLeast(27.0)) { if (!WorkbenchConfig::get()->value('ownerChangeOptions_transferAttachments') || !WorkbenchConfig::get()->value('ownerChangeOptions_transferOpenActivities')) { $connection->setOwnerChangeOptionsHeader(new OwnerChangeOptionsHeader(WorkbenchConfig::get()->value('ownerChangeOptions_transferAttachments'), WorkbenchConfig::get()->value('ownerChangeOptions_transferOpenActivities'))); } } if (WorkbenchConfig::get()->value('assignmentRuleHeader_assignmentRuleId') || WorkbenchConfig::get()->value('assignmentRuleHeader_useDefaultRule')) { $connection->setAssignmentRuleHeader(new AssignmentRuleHeader(WorkbenchConfig::get()->value('assignmentRuleHeader_assignmentRuleId'), WorkbenchConfig::get()->value('assignmentRuleHeader_useDefaultRule'))); } if (WorkbenchConfig::get()->value('mruHeader_updateMru')) { $connection->setMruHeader(new MruHeader(WorkbenchConfig::get()->value('mruHeader_updateMru'))); } if (WorkbenchConfig::get()->value('queryOptions_batchSize')) { $connection->setQueryOptions(new QueryOptions(WorkbenchConfig::get()->value('queryOptions_batchSize'))); } if (WorkbenchConfig::get()->value('emailHeader_triggerAutoResponseEmail') || WorkbenchConfig::get()->value('emailHeader_triggerOtherEmail') || WorkbenchConfig::get()->value('emailHeader_triggertriggerUserEmail')) { $connection->setEmailHeader(new EmailHeader(WorkbenchConfig::get()->value('emailHeader_triggerAutoResponseEmail'), WorkbenchConfig::get()->value('emailHeader_triggerOtherEmail'), WorkbenchConfig::get()->value('emailHeader_triggertriggerUserEmail'))); } if (WorkbenchConfig::get()->value('UserTerritoryDeleteHeader_transferToUserId')) { $connection->setUserTerritoryDeleteHeader(new UserTerritoryDeleteHeader(WorkbenchConfig::get()->value('UserTerritoryDeleteHeader_transferToUserId'))); } if (WorkbenchConfig::get()->value('allowFieldTruncationHeader_allowFieldTruncation')) { $connection->setAllowFieldTruncationHeader(new AllowFieldTruncationHeader(WorkbenchConfig::get()->value('allowFieldTruncationHeader_allowFieldTruncation'))); } if (WorkbenchConfig::get()->value('allOrNoneHeader_allOrNone')) { $connection->setAllOrNoneHeader(new AllOrNoneHeader(WorkbenchConfig::get()->value('allOrNoneHeader_allOrNone'))); } if (WorkbenchConfig::get()->value('disableFeedTrackingHeader_disableFeedTracking')) { $connection->setDisableFeedTrackingHeader(new DisableFeedTrackingHeader(WorkbenchConfig::get()->value('disableFeedTrackingHeader_disableFeedTracking'))); } if (WorkbenchConfig::get()->value('localOptions_language')) { $connection->setLocaleOptions(new LocaleOptions(WorkbenchConfig::get()->value('localOptions_language'))); } if (WorkbenchConfig::get()->value('packageVersionHeader_include') && WorkbenchConfig::get()->value('packageVersion_namespace') && WorkbenchConfig::get()->value('packageVersion_majorNumber') && WorkbenchConfig::get()->value('packageVersion_minorNumber')) { $connection->setPackageVersionHeader(WorkbenchConfig::get()->value("packageVersion_namespace"), WorkbenchConfig::get()->value("packageVersion_majorNumber"), WorkbenchConfig::get()->value("packageVersion_minorNumber")); } return $connection; }
function load($types) { $describeCache =& $this->getCacheLocation(); $typesToLoad = array(); foreach ($types as $type) { if (!array_key_exists($type, $describeCache)) { $typesToLoad[] = $type; } } if (count($typesToLoad) > 100) { throw new Exception("Too many object types to load: " . count($typesToLoad)); } $rawLoadedTypes = WorkbenchContext::get()->getPartnerConnection()->describeSObjects($typesToLoad); $loadedTypes = array(); if ($rawLoadedTypes instanceof stdClass) { $loadedTypes = array($rawLoadedTypes->name => $rawLoadedTypes); } else { if (is_array($rawLoadedTypes)) { foreach ($rawLoadedTypes as $rawLoadedType) { $loadedTypes[$rawLoadedType->name] = $rawLoadedType; } } else { throw new Exception("Unknown Describe SObject results"); } } foreach ($loadedTypes as $name => $result) { if (!is_array($result->fields)) { $loadedTypes[$name]->fields = array($result->fields); } if (WorkbenchConfig::get()->value("abcOrder")) { $loadedTypes[$name] = $this->alphaOrderFields($result); } } $requestedTypes =& $loadedTypes; foreach ($types as $type) { if (array_key_exists($type, $describeCache)) { $requestedTypes[$type] = $describeCache[$type]; } } return $requestedTypes; }
function load($args) { $describeGlobalResponse = WorkbenchContext::get()->getPartnerConnection()->describeGlobal(); //Change to pre-17.0 format if (isset($describeGlobalResponse->sobjects) && !isset($describeGlobalResponse->types)) { $describeGlobalResponse->types = array(); //create the array foreach ($describeGlobalResponse->sobjects as $sobject) { //todo: do we really need both of these? $describeGlobalResponse->types[] = $sobject->name; //migrate to pre 17.0 format $describeGlobalResponse->attributeMap["{$sobject->name}"] = $sobject; //recreate into a map for faster lookup later $describeGlobalResponse->byKeyPrefix["{$sobject->keyPrefix}"] = $sobject->name; //recreate into a map for faster lookup later } unset($describeGlobalResponse->sobjects); //remove from array, since not needed } return $describeGlobalResponse; }
public function __construct($baseUrl) { $restBasePattern = '/services/data/v\\d+\\.\\d'; $this->insturmentations[] = new XssProtectionInsturmentation(); // add link url to id services $this->insturmentations[] = new RegexInsturmentation("https?://.*(/id/00D.*/005.*)", "<a class=\\'RestLinkable\\' href=" . $baseUrl . "?url=\$1&autoExec=1>\$1</a>"); // add link url to any rest url $this->insturmentations[] = new RegexUrlInsturmentation("(" . $restBasePattern . ".*)", function ($matches) { // This is a fix for https://github.com/ryanbrainard/forceworkbench/issues/581 $urlencoded = str_replace('&', '%26', $matches[1]); return "<a class=\\'RestLinkable\\' href=" . $baseUrl . "?url={$urlencoded}&autoExec=0>" . $matches[1] . "</a>"; }); // add autoExec to everything but query and search $this->insturmentations[] = new RegexInsturmentation('(url=' . $restBasePattern . '(?!/query|/search|.*/.*\\{ID\\}).*&)autoExec=0', '$1autoExec=1'); // query more $this->insturmentations[] = new RegexInsturmentation('(url=' . $restBasePattern . '/query/01g\\w{15}-\\d+&)autoExec=0', '$1autoExec=1'); // sample query url $this->insturmentations[] = new RegexInsturmentation('(' . $restBasePattern . '/query)<', '$1</a> <a class=\'miniLink RestLinkable\' href=' . $baseUrl . '?url=$1?q=SELECT%2Bid,name,profile.name%2BFROM%2Buser%2BWHERE%2Busername=\'' . WorkbenchContext::get()->getUserInfo()->userName . '\'&autoExec=1>[SAMPLE]<'); // sample search url $this->insturmentations[] = new RegexInsturmentation('(' . $restBasePattern . '/search)<', '$1</a> <a class=\'miniLink RestLinkable\' href=' . $baseUrl . '?url=$1?q=FIND%2B%7B' . WorkbenchContext::get()->getUserInfo()->userName . '%7D%2BIN%2BALL%2BFIELDS&autoExec=1>[SAMPLE]<'); }
function changePassword($passwordChangeType) { $infos = null; $errors = null; try { if ($passwordChangeType == 'set' && isset($_POST['userId']) && isset($_POST['passwordOne'])) { if ($_POST['passwordOne'] == $_POST['passwordConfirm']) { WorkbenchContext::get()->getPartnerConnection()->setPassword($_POST['userId'], $_POST['passwordOne']); $infos[] = "Successfully set password for " . $_POST['userId']; } else { $errors[] = "Passwords must match, and don't be sneaky and turn off JavaScript"; } } else { if ($passwordChangeType == 'reset' && isset($_POST['userId'])) { $changePasswordResult = WorkbenchContext::get()->getPartnerConnection()->resetPassword($_POST['userId']); $infos[] = "Successfully reset password for " . $_POST['userId']; } } } catch (Exception $e) { $errors[] = $e->getMessage(); } displayForm($infos, $errors); }
/** * Executes the task within the user's config and context. * The result or any thrown exception is redeemed to a FutureResult with the same async id. * Only to be called by CLI. Will error if called from a web process. */ function execute() { verifyCallingFromCLI(); $execStartTime = time(); $future = new FutureResult($this->asyncId); try { WorkbenchConfig::destroy(); // destroy the WorkbenchConfig, if one happens to exist $_SERVER['HTTP_X_REQUEST_ID'] = $this->requestId; // reestablish the original requestId for logging $_COOKIE = $this->cookies; // reestablish the user's cookies so they'll be picked up by new WorkbenchConfig, if required WorkbenchContext::establish($this->connConfig); WorkbenchContext::get()->agreeToTerms(); workbenchLog(LOG_INFO, "FutureTaskExecuteStart", array("async_id" => $this->asyncId, "source" => get_class($this), "measure.async.queue_time" => $execStartTime - $this->enqueueTime . "sec")); $future->redeem($this->perform()); } catch (Exception $e) { $future->redeem($e); } workbenchLog(LOG_INFO, "FutureTaskExecuteEnd", array("async_id" => $this->asyncId, "source" => get_class($this), "measure.async.exec_time" => time() - $execStartTime . "sec")); WorkbenchContext::get()->release(); WorkbenchConfig::destroy(); $_COOKIE = array(); }
$sessionInfo['Connection'] = array('API Version' => WorkbenchContext::get()->getApiVersion(), 'Client Id' => isset($_SESSION['tempClientId']) ? $_SESSION['tempClientId'] : WorkbenchConfig::get()->value('callOptions_client'), 'Endpoint' => WorkbenchContext::get()->getPartnerConnection()->getLocation(), 'Session Id' => WorkbenchContext::get()->getPartnerConnection()->getSessionId()); $errors = array(); try { foreach (WorkbenchContext::get()->getUserInfo() as $uiKey => $uiValue) { if (stripos($uiKey, 'org') !== 0) { $sessionInfo['User'][$uiKey] = $uiValue; } else { $sessionInfo['Organization'][$uiKey] = $uiValue; } } } catch (Exception $e) { $errors[] = "Partner API Error: " . $e->getMessage(); } if (WorkbenchContext::get()->isApiVersionAtLeast(10.0)) { try { foreach (WorkbenchContext::get()->getMetadataConnection()->describeMetadata(WorkbenchContext::get()->getApiVersion()) as $resultsKey => $resultsValue) { if ($resultsKey != 'metadataObjects' && !is_array($resultsValue)) { $sessionInfo['Metadata'][$resultsKey] = $resultsValue; } } } catch (Exception $e) { $sessionInfo['Metadata']['Error'] = $e->getMessage(); } } if (count($errors) > 0) { print "<p> </p>"; displayError($errors); print "</p>"; } $tree = new ExpandableTree("sessionInfoTree", $sessionInfo); $tree->setContainsDates(true);
httpError("403.4 SSL Required", "Secure connection to Workbench and Salesforce required"); //TODO: what do we want to do here? } //kick user back to login page for any page that requires a session and one isn't established $myPage = getMyPage(); if (!isLoggedIn() && $myPage->requiresSfdcSession) { session_unset(); session_destroy(); header('Location: login.php'); exit; } if (!$myPage->isReadOnly && isReadOnlyMode()) { throw new WorkbenchHandledException("This page is not accessible in read-only mode"); } if (WorkbenchContext::isEstablished() && !$myPage->isReadOnly && $_SERVER['REQUEST_METHOD'] == 'POST') { validateCsrfToken(); } if (WorkbenchContext::isEstablished() && isset($_POST['termsAccepted'])) { WorkbenchContext::get()->agreeToTerms(); } if (isLoggedIn()) { // todo: should this be in the ctx? if (!in_array(basename($_SERVER['PHP_SELF'], ".php"), array("login", "logout")) && isset($_SESSION['lastRequestTime'])) { $idleTime = microtime(true) - $_SESSION['lastRequestTime']; if ($idleTime > WorkbenchConfig::get()->value("sessionIdleMinutes") * 60) { // ping SFDC to check if session is still alive WorkbenchContext::get()->getPartnerConnection()->getServerTimestamp(); } } $_SESSION['lastRequestTime'] = microtime(true); }
if (!isset($_SESSION[$retrieveRequestId])) { throw new Exception("No retrieve request found. To re-retrieve, create a new retrieve request."); } $retrieveAsyncResults = WorkbenchContext::get()->getMetadataConnection()->retrieve($_SESSION[$retrieveRequestId]); if (!isset($retrieveAsyncResults->id)) { throw new Exception("Unknown retrieval error.\n" . isset($retrieveAsyncResults->message) ? $retrieveAsyncResults->message : ""); } unset($_SESSION[$retrieveRequestId]); header("Location: metadataStatus.php?asyncProcessId=" . $retrieveAsyncResults->id . "&op=R"); } else { if (isset($_POST['stageForRetrieval'])) { if (isset($_FILES["packageXmlFile"]["name"]) && $_FILES["packageXmlFile"]["name"] == "" && isset($_POST['packageNames']) && $_POST['packageNames'] == "") { throw new WorkbenchHandledException("Must specify at least an unpackaged manifest file or a package name."); } $retrieveRequest = new RetrieveRequest(); $retrieveRequest->apiVersion = WorkbenchContext::get()->getApiVersion(); $retrieveRequest->singlePackage = isset($_POST['singlePackage']); if (isset($_FILES["packageXmlFile"]["name"]) && $_FILES["packageXmlFile"]["name"] != "") { $validationErrors = validateUploadedFile($_FILES["packageXmlFile"]); if ($validationErrors) { throw new WorkbenchHandledException($validationErrors); } if (!endsWith($_FILES["packageXmlFile"]["name"], ".xml", true)) { throw new WorkbenchHandledException("The file uploaded is not a valid XML file. Please try again."); } $retrieveRequest->unpackaged = parseUnpackagedManifest($_FILES["packageXmlFile"]["tmp_name"]); } if (isset($_POST['packageNames']) && $_POST['packageNames'] != "") { $encodedPackageNames = array(); foreach (explodeCommaSeparated(htmlspecialchars($_POST['packageNames'])) as $p) { if ($p == "unpackaged") {
private function processLogin($username, $password, $serverUrl, $sessionId, $actionJump) { if ($username && $password && $sessionId) { $this->addError('Provide only username and password OR session id, but not all three.'); return; } //block connections to localhost if (stripos($serverUrl, 'localhost')) { if (isset($GLOBALS['internal']['localhostLoginError'])) { $this->addError($GLOBALS['internal']['localhostLoginError']); } else { $this->addError("Must not connect to 'localhost'"); } return; } if (WorkbenchContext::isEstablished()) { // cache clearing shouldn't be needed since we're releasing on the next line, // but doing it just in case someone puts a cache key outside the WbCtx scope WorkbenchContext::get()->clearCache(); WorkbenchContext::get()->release(); } // TODO: clean up this hackiness due to in-progress context refactoring... $savedOauthConfig = isset($_SESSION['oauth']) ? $_SESSION['oauth'] : null; session_unset(); session_destroy(); session_start(); session_regenerate_id(); $_SESSION['oauth'] = $savedOauthConfig; $overriddenClientId = isset($_REQUEST["clientId"]) ? $_REQUEST["clientId"] : null; if ($username && $password && !$sessionId) { if ($this->oauthRequired) { throw new WorkbenchHandledException("OAuth login is required"); } $orgId = isset($_REQUEST["orgId"]) ? $_REQUEST["orgId"] : WorkbenchConfig::get()->value("loginScopeHeader_organizationId"); $portalId = isset($_REQUEST["portalId"]) ? $_REQUEST["portalId"] : WorkbenchConfig::get()->value("loginScopeHeader_portalId"); WorkbenchContext::establish(ConnectionConfiguration::fromUrl($serverUrl, null, $overriddenClientId)); try { WorkbenchContext::get()->login($username, $password, $orgId, $portalId); } catch (Exception $e) { WorkbenchContext::get()->release(); $this->addError($e->getMessage()); return; } } else { if ($sessionId && $serverUrl && !($username && $password)) { $serverUrlHost = parse_url($serverUrl, PHP_URL_HOST); $loginHosts = array("login.salesforce.com", "test.salesforce.com", "prerellogin.pre.salesforce.com"); if (in_array($serverUrlHost, $loginHosts)) { $this->addError('Must not connect to login server (www, login, test, or prerellogin) if providing a session id. ' . 'Choose your specific Salesforce instance on the QuickSelect menu when using a session id; ' . 'otherwise, provide a username and password and choose the appropriate a login server.'); return; } WorkbenchContext::establish(ConnectionConfiguration::fromUrl($serverUrl, $sessionId, $overriddenClientId)); WorkbenchContext::get()->setIsUiSessionLikelySet(true); } else { $this->addError('Invalid login parameters.'); return; } } // todo: put in WbCtx? if (stripos(WorkbenchContext::get()->getHost(), 'localhost')) { if (isset($GLOBALS['internal']['localhostLoginRedirectError'])) { $this->addError($GLOBALS['internal']['localhostLoginRedirectError']); } else { $this->addError("Must not connect to 'localhost'"); } return; } if (isset($_POST['termsAccepted'])) { WorkbenchContext::get()->agreeToTerms(); } // test the connection and prime the UserInfo cache // exceptions will be caught by top-level handler $userInfo = WorkbenchContext::get()->getUserInfo(); // do org id whitelist/blacklisting $orgId15 = substr($userInfo->organizationId, 0, 15); $orgIdWhiteList = array_map('trim', explode(",", WorkbenchConfig::get()->value("orgIdWhiteList"))); $orgIdBlackList = array_map('trim', explode(",", WorkbenchConfig::get()->value("orgIdBlackList"))); $isAllowed = true; foreach ($orgIdWhiteList as $allowedOrgId) { if ($allowedOrgId === "") { continue; } else { if ($orgId15 === substr($allowedOrgId, 0, 15)) { $isAllowed = true; break; } else { // there is something on the whitelist that's not us // disallow and keep looking until we find our org id $isAllowed = false; } } } foreach ($orgIdBlackList as $disallowedOrgId) { if ($orgId15 === substr($disallowedOrgId, 0, 15)) { $isAllowed = false; break; } } if (!$isAllowed) { throw new WorkbenchAuthenticationException("Requests for organization {$orgId15} are not allowed"); } if (isset($_REQUEST['autoLogin'])) { $actionJump .= (strpos($actionJump, "?") > -1 ? "&" : "?") . "autoLogin=1"; if (isset($_REQUEST['skipVC'])) { $actionJump .= "&skipVC=1"; } if (isset($_GET['clientId'])) { $_SESSION['tempClientId'] = $_GET['clientId']; } } header("Location: {$actionJump}"); }
function queryAsync($queryRequest) { if ($queryRequest->getQueryAction() == "QueryAll") { throw new WorkbenchHandledException("Including deleted and archived records not supported by Bulk Queries."); } $asyncConnection = WorkbenchContext::get()->getAsyncBulkConnection(); $job = new JobInfo(); // try to find actual object in FROM clause in case it is different from object set in form preg_match("/FROM\\s(\\w+)/i", $queryRequest->getSoqlQuery(), $fromMatches); // if we can't find it, go ahead and use the object from the form. // it's probably a malformed query anyway, but let SFDC error on it instead of Workbench $job->setObject(isset($fromMatches[1]) ? $fromMatches[1] : $queryRequest->getObject()); $job->setOpertion("query"); $job->setContentType(substr($queryRequest->getExportTo(), strlen("async_"))); $job->setConcurrencyMode(WorkbenchConfig::get()->value("asyncConcurrencyMode")); try { $job = $asyncConnection->createJob($job); } catch (Exception $e) { if (strpos($e->getMessage(), 'Unable to find object') > -1 || strpos($e->getMessage(), 'InvalidEntity') > -1) { throw new WorkbenchHandledException($e->getMessage()); } else { throw $e; } } $asyncConnection->createBatch($job, $queryRequest->getSoqlQuery()); $job = $asyncConnection->updateJobState($job->getId(), "Closed"); header("Location: asyncStatus.php?jobId=" . $job->getId()); }
/** * Executes the task within the user's config and context. * The result or any thrown exception is redeemed to a FutureResult with the same async id. * Only to be called by CLI. Will error if called from a web process. */ function execute() { verifyCallingFromCLI(); $execStartTime = time(); $future = new FutureResult($this->asyncId); try { WorkbenchConfig::destroy(); // destroy the WorkbenchConfig, if one happens to exist $_COOKIE = $this->cookies; // reestablish the user's cookies so they'll be picked up by new WorkbenchConfig, if required WorkbenchContext::establish($this->connConfig); WorkbenchContext::get()->agreeToTerms(); workbenchLog(LOG_INFO, "FutureTaskExecuteStart", get_class($this) . "-" . $this->asyncId); $future->redeem($this->perform()); } catch (Exception $e) { $future->redeem($e); } workbenchLog(LOG_INFO, "FutureTaskExecuteEnd", get_class($this) . "-" . $this->asyncId . " queueTime=" . ($execStartTime - $this->enqueueTime) . " execTime=" . (time() - $execStartTime)); WorkbenchContext::get()->release(); WorkbenchConfig::destroy(); $_COOKIE = array(); }
<?php foreach (RestApiClient::getMethods() as $method) { echo "<label><input type='radio' name='requestMethod' value='{$method}'" . ($c->requestMethod == $method ? "checked='checked'" : "") . " onclick='toggleRequestBodyDisplay(this, " . (in_array($method, RestApiClient::getMethodsWithBodies()) ? 'true' : 'false') . ");'/> {$method} </label> "; } ?> <input id="headersButton" type="button" value="Headers" onclick="toggleRequestHeaders();"/> <input id="resetButton" type="button" value="Reset" onclick="resetUrl('<?php print WorkbenchContext::get()->getApiVersion(); ?> ');"/> <input id="upButton" type="button" value="Up" onclick="upUrl();"/> <span id='waitingIndicator'> <img src='<?php print getPathToStaticResource('/images/wait16trans.gif'); ?> '/> Processing... </span> </p>
function search($searchRequest) { try { $searchResponse = WorkbenchContext::get()->getPartnerConnection()->search($searchRequest->getSoslSearch()); if (isset($searchResponse->searchRecords)) { $records = $searchResponse->searchRecords; } else { $records = null; } return $records; } catch (Exception $e) { displayError($e->getMessage(), false, true); } }
static function template() { return new PushTopic(null, null, WorkbenchContext::get()->getApiVersion(), null); }
function defaultDeployOptions() { $deployOptions = new DeployOptions(); $deployOptions->allowMissingFiles = false; $deployOptions->autoUpdatePackage = false; $deployOptions->checkOnly = false; $deployOptions->ignoreWarnings = false; $deployOptions->performRetrieve = false; if (WorkbenchContext::get()->isApiVersionAtLeast(22.0)) { $deployOptions->purgeOnDelete = false; } $deployOptions->rollbackOnError = false; $deployOptions->singlePackage = false; if (WorkbenchContext::get()->isApiVersionAtLeast(34.0)) { $deployOptions->testLevel = "NoTestRun"; } else { $deployOptions->runAllTests = false; } $deployOptions->runTests = array(); return $deployOptions; }
<?php require_once 'session.php'; require_once 'shared.php'; try { if (!isset($_GET['jobId']) || !isset($_GET['batchId']) || !isset($_GET['op'])) { throw new Exception("'jobId', 'batchId', and 'op' parameters must be specified"); } else { if (!in_array($_GET['op'], array('request', 'result'))) { throw new Exception("Invalid operation specified"); } } $asyncConnection = WorkbenchContext::get()->getAsyncBulkConnection(); $jobInfo = $asyncConnection->getJobInfo($_GET['jobId']); $fileContext = fopen('php://output', 'w') or die("Error opening php://output"); if ($_GET['op'] == 'request' && $jobInfo->getOpertion() == "query") { $fileExt = "txt"; header("Content-Type: text/plain"); } else { if ($_GET['op'] == 'request' && stristr($jobInfo->getContentType(), "ZIP")) { $fileExt = "zip"; header("Content-Type: application/zip"); } else { if (stristr($jobInfo->getContentType(), "CSV")) { $fileExt = "csv"; header("Content-Type: application/csv"); } else { if (stristr($jobInfo->getContentType(), "XML")) { $fileExt = "xml"; header("Content-Type: application/xml"); } else {
function displayBulkApiOptions($action, $forceDoAsync, $recommendDoAsync = false) { //Hard Delete option if (WorkbenchContext::get()->isApiVersionAtLeast(19.0) && $action == 'Confirm Delete') { print "<p><label><input type='checkbox' id='doHardDelete' name='doHardDelete' onClick=\"" . "if (this.checked && " . ($forceDoAsync ? "false" : "true") . ") {" . " document.getElementById('doAsync').checked = true;" . " document.getElementById('asyncDeleteObjectSelection').style.display = 'inline';" . " document.getElementById('unsupportedBulkConfigList').style.display = 'inline';" . "}\"/> " . "Permanently hard delete records</label>" . " <img onmouseover=\"Tip('When specified, the deleted records are not stored in the Recycle Bin. " . "Instead, the records become immediately eligible for deletion, don\\'t count toward the storage space used " . "by your organization, and may improve performance. The Administrative permission for this operation, " . "\\'Bulk API Hard Delete\\', is disabled by default and must be enabled by an administrator. " . "A Salesforce user license is required for hard delete. Hard Delete is only available via Bulk API.')\" " . "align='absmiddle' src='" . getPathToStaticResource('/images/help16.png') . "'/>" . "</p>"; } //Async Options if (WorkbenchContext::get()->isApiVersionAtLeast(17.0) && in_array($action, array('Confirm Insert', 'Confirm Update', 'Confirm Upsert')) || WorkbenchContext::get()->isApiVersionAtLeast(18.0) && $action == 'Confirm Delete') { if ($forceDoAsync) { print "<input name='doAsync' type='hidden' value='true'/>"; } else { print "<p><label><input id='doAsync' name='doAsync' type='checkbox' " . ($recommendDoAsync ? "checked='checked' " : "") . "onClick=\"" . "var doHardDelete = document.getElementById('doHardDelete');" . "var asyncDeleteObjectSelection = document.getElementById('asyncDeleteObjectSelection');" . "var unsupportedBulkConfigList = document.getElementById('unsupportedBulkConfigList');" . "if (this.checked) {" . " if (asyncDeleteObjectSelection != null) asyncDeleteObjectSelection.style.display = 'inline';" . " if (unsupportedBulkConfigList != null) unsupportedBulkConfigList.style.display = 'inline';" . "} else {" . " if (doHardDelete != null) doHardDelete.checked = false;" . " if (asyncDeleteObjectSelection != null) asyncDeleteObjectSelection.style.display = 'none';" . " if (unsupportedBulkConfigList != null) unsupportedBulkConfigList.style.display = 'none';" . "}\"/> " . "Process records asynchronously via Bulk API</label>" . " <img onmouseover=\"Tip('Processing records asynchronously is recommended for large data loads. " . "The data will be uploaded to Salesforce via the Bulk API in batches and processed when server resources are available. " . "After batches have completed, results can be downloaded. Batch size and concurrency options are available in Settings.')\" " . "align='absmiddle' src='" . getPathToStaticResource('/images/help16.png') . "'/>" . "</p>"; } // object selection for Bulk API Delete if ($action == 'Confirm Delete') { print "<div id='asyncDeleteObjectSelection' style='display: " . ($forceDoAsync || $recommendDoAsync ? "inline" : "none; margin-left: 3em;") . "'>Object Type: "; printObjectSelection(WorkbenchContext::get()->getDefaultObject()); print "</div>"; } // all configs not supported by Bulk API $bulkUnsupportedConfigs = array("mruHeader_updateMru", "allOrNoneHeader_allOrNone", "emailHeader_triggerAutoResponseEmail", "emailHeader_triggertriggerUserEmail", "emailHeader_triggerOtherEmail", "allowFieldTruncationHeader_allowFieldTruncation", "UserTerritoryDeleteHeader_transferToUserId"); // find this user's settings that are in the unsupported config list $bulkUnsupportedSettings = array(); foreach ($bulkUnsupportedConfigs as $c) { if (WorkbenchConfig::get()->overridden($c)) { $bulkUnsupportedSettings[] = $c; } } // print out a warning if any settings were found if (count($bulkUnsupportedSettings) > 0) { print "<div id='unsupportedBulkConfigList' style='display: " . ($forceDoAsync || $recommendDoAsync ? "inline" : "none") . "; color: orange;'>" . "<p " . ($forceDoAsync ? "" : "style='margin-left: 3em;'") . ">" . "<img src='" . getPathToStaticResource('/images/warning24.png') . "' /> " . "The following settings are not supported by the Bulk API and will be ignored:" . "<ul " . ($forceDoAsync ? "" : "style='margin-left: 5em;'") . ">"; foreach ($bulkUnsupportedSettings as $s) { print "<li>" . WorkbenchConfig::get()->label($s) . "</li>"; } print "</ul>" . "</p>" . "</div>"; } } }
/** * @return bool true if binary is expected */ private function prepareBinaryResponseAsDownload() { if ($this->requestMethod != 'GET' || preg_match("@\\w{4}0{3}\\w{8}([A-Z]{3})?/(Body|VersionData|ContentData|Document|Binary)\$@", $this->url) == 0) { return false; } $expUrl = explode("/", $this->url); $binIdPos = count($expUrl) - 2; $binId = $expUrl[$binIdPos]; $binSobjectTypePos = count($expUrl) - 3; $binSobjectType = $expUrl[$binSobjectTypePos]; // Handle the different fields that support binary data in their own special way. if (in_arrayi($binSobjectType, array("Document", "Attachment", "StaticResource"))) { $binInfo = new SObject(WorkbenchContext::get()->getPartnerConnection()->retrieve("Name, ContentType, BodyLength", $binSobjectType, $binId)); $binFilename = $binInfo->fields->Name; $binContentType = $binInfo->fields->ContentType; $binContentLength = $binInfo->fields->BodyLength; } else { if ($binSobjectType == "ContentVersion") { $binInfo = new SObject(WorkbenchContext::get()->getPartnerConnection()->retrieve("PathOnClient, FileType, ContentSize", $binSobjectType, $binId)); $binFilename = basename($binInfo->fields->PathOnClient); $binContentType = "application/" . $binInfo->fields->FileType; $binContentLength = $binInfo->fields->ContentSize; } else { if (stripos($this->url, "ContentData")) { $binInfo = new SObject(WorkbenchContext::get()->getPartnerConnection()->retrieve("ContentFileName, ContentType, ContentSize", $binSobjectType, $binId)); $binFilename = $binInfo->fields->ContentFileName; $binContentType = $binInfo->fields->ContentType; $binContentLength = $binInfo->fields->ContentSize; } else { if ($binSobjectType == "MailmergeTemplate") { $binInfo = new SObject(WorkbenchContext::get()->getPartnerConnection()->retrieve("Filename, BodyLength", $binSobjectType, $binId)); $binFilename = $binInfo->fields->Filename; $binContentType = "application/msword"; $binContentLength = $binInfo->fields->BodyLength; } else { if ($binSobjectType == "QuoteDocument") { $binInfo = new SObject(WorkbenchContext::get()->getPartnerConnection()->retrieve("Name", $binSobjectType, $binId)); $binFilename = $binInfo->fields->Name; } else { return false; } } } } } header("Content-Disposition: attachment; filename=" . rawurlencode($binFilename)); if (isset($binContentType)) { header("Content-Type: " . $binContentType); } if (isset($binContentLength)) { header("Content-Length: " . $binContentLength); } return true; }
<?php require_once "context/WorkbenchContext.php"; require_once "util/PhpReverseProxy.php"; require_once "session.php"; if (!WorkbenchContext::isEstablished()) { httpError("401 Unauthorized", "CometD Proxy only available if Workbench Context has been established."); exit; } // dereference session-based vars so we can close the session before entering the proxy // this will allow concurrent long requests on the same session to work better $host = WorkbenchContext::get()->getHost(); $apiVersion = WorkbenchContext::get()->getApiVersion(); $forceSSL = WorkbenchContext::get()->isSecure(); $sessionId = WorkbenchContext::get()->getSessionId(); session_write_close(); $proxy = new PhpReverseProxy(); $proxy->headers[] = "Authorization: OAuth {$sessionId}"; $proxy->host = $host; $proxy->forceSSL = $forceSSL; $proxy->forward_path = "/cometd/{$apiVersion}"; $proxy->cookie_whitelist = array("sfdc-stream", "BAYEUX_BROWSER"); $proxy->proxy_settings = getProxySettings(); $proxy->is_forward_path_static = true; $proxy->connect(); $proxy->output();
<?php foreach ($GLOBALS["MENUS"] as $menu => $pages) { foreach ($pages as $href => $page) { if ($page->onMenuSelect) { print "<option value='" . $href . "'>" . $page->title . "</option>"; } } } ?> </select> </p> <p> <label for="default_object"><strong>Object: </strong></label> <?php printObjectSelection(WorkbenchContext::get()->getDefaultObject(), 'default_object'); ?> </p> <input type='submit' name='select' value='Select'/> </form> <script type="text/javascript"> function toggleObjectSelectDisabled() { var usesObject = new Array(); <?php foreach ($GLOBALS["MENUS"] as $menu => $pages) { foreach ($pages as $href => $page) { if ($page->onMenuSelect === 'usesObject') { print "usesObject['{$href}'] = '{$href}';\n"; }
function debug($showSuperVars = true, $showSoap = true, $customName = null, $customValue = null) { if (WorkbenchConfig::get()->value("debug") == true) { print "<script>\n function toggleDebugSection(title, sectionId) {\n var section = document.getElementById(sectionId);\n if (section.style.display == 'inline') {\n section.style.display = 'none';\n title.childNodes[0].nodeValue = title.childNodes[0].nodeValue.replace('-','+');\n } else {\n title.childNodes[0].nodeValue = title.childNodes[0].nodeValue.replace('+','-');\n section.style.display = 'inline';\n }\n }\n </script>"; print "<div style='text-align: left;'><h1>Debug Mode</h1>"; if ($customValue) { if ($customName) { print "<h2>{$customName}</h2>\n"; } else { print "<h2>CUSTOM</h2>\n"; } var_dump($customValue); print "<hr/>"; } if ($showSuperVars) { print "<h2 onclick=\"toggleDebugSection(this,'container_globals')\" class=\"debugHeader\">+ SUPERGLOBAL VARIABLES</h2>\n"; print "<div id='container_globals' class='debugContainer'>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_cookie')\" class=\"debugHeader\">+ SERVER SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_cookie' class='debugContainer'>"; print htmlspecialchars(var_export($_SERVER, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_cookie')\" class=\"debugHeader\">+ COOKIE SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_cookie' class='debugContainer'>"; print htmlspecialchars(var_export($_COOKIE, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_session')\" class=\"debugHeader\">+ SESSION SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_session' class='debugContainer'>"; print htmlspecialchars(var_export($_SESSION, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_post')\" class=\"debugHeader\">+ POST SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_post' class='debugContainer'>"; print htmlspecialchars(var_export($_POST, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_get')\" class=\"debugHeader\">+ GET SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_get' class='debugContainer'>"; print htmlspecialchars(var_export($_GET, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_files')\" class=\"debugHeader\">+ FILES SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_files' class='debugContainer'>"; print htmlspecialchars(var_export($_FILES, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "<strong onclick=\"toggleDebugSection(this,'container_globals_env')\" class=\"debugHeader\">+ ENVIRONMENT SUPERGLOBAL VARIABLE</strong>\n"; print "<div id='container_globals_env' class='debugContainer'>"; print htmlspecialchars(var_export($_ENV, true), ENT_QUOTES); print "<hr/>"; print "</div>"; print "</div>"; } // todo: contextify if ($showSoap && WorkbenchContext::isEstablished() && WorkbenchContext::get()->getPartnerConnection()->getLastRequestHeaders()) { try { print "<h2 onclick=\"toggleDebugSection(this,'partner_soap_container')\" class=\"debugHeader\">+ PARTNER SOAP MESSAGES</h2>\n"; print "<div id='partner_soap_container' class='debugContainer'>"; print "<strong>LAST REQUEST HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getPartnerConnection()->getLastRequestHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST REQUEST</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getPartnerConnection()->getLastRequest()), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getPartnerConnection()->getLastResponseHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getPartnerConnection()->getLastResponse()), ENT_QUOTES); print "<hr/>"; print "</div>"; } catch (Exception $e) { print "<strong>SOAP Error</strong>\n"; print_r($e); } } if ($showSoap && WorkbenchContext::isEstablished() && WorkbenchContext::get()->getMetadataConnection()->getLastRequestHeaders()) { try { print "<h2 onclick=\"toggleDebugSection(this,'metadata_soap_container')\" class=\"debugHeader\">+ METADATA SOAP MESSAGES</h2>\n"; print "<div id='metadata_soap_container' class='debugContainer'>"; print "<strong>LAST REQUEST HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getMetadataConnection()->getLastRequestHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST REQUEST</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getMetadataConnection()->getLastRequest()), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getMetadataConnection()->getLastResponseHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getMetadataConnection()->getLastResponse()), ENT_QUOTES); print "<hr/>"; print "</div>"; } catch (Exception $e) { print "<strong>SOAP Error</strong>\n"; print_r($e); } } if ($showSoap && WorkbenchContext::isEstablished() && WorkbenchContext::get()->getApexConnection()->getLastRequestHeaders()) { try { print "<h2 onclick=\"toggleDebugSection(this,'apex_soap_container')\" class=\"debugHeader\">+ APEX SOAP MESSAGES</h2>\n"; print "<div id='apex_soap_container' class='debugContainer'>"; print "<strong>LAST REQUEST HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getApexConnection()->getLastRequestHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST REQUEST</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getApexConnection()->getLastRequest()), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE HEADER</strong>\n"; print htmlspecialchars(WorkbenchContext::get()->getApexConnection()->getLastResponseHeaders(), ENT_QUOTES); print "<hr/>"; print "<strong>LAST RESPONSE</strong>\n"; print htmlspecialchars(prettyPrintXml(WorkbenchContext::get()->getApexConnection()->getLastResponse()), ENT_QUOTES); print "<hr/>"; print "</div>"; } catch (Exception $e) { print "<strong>SOAP Error</strong>\n"; htmlspecialchars(print_r($e)); } } // TODO: move into WbCtx if (isset($_SESSION['restDebugLog']) && $_SESSION['restDebugLog'] != "") { print "<h2 onclick=\"toggleDebugSection(this,'rest_debug_container')\" class=\"debugHeader\">+ REST/BULK API LOGS</h2>\n"; print "<div id='rest_debug_container' class='debugContainer'>"; print "<pre>" . $_SESSION['restDebugLog'] . "</pre>"; print "<hr/>"; print "</div>"; $_SESSION['restDebugLog'] = null; } print "</div>"; } }
</div> </body> <script type="text/javascript" src="<?php echo getPathToStaticResource('/script/wz_tooltip.js'); ?> "></script> <?php if (isset($_REQUEST["footerScripts"])) { foreach ($_REQUEST["footerScripts"] as $script) { print $script . "\n"; } } ?> </html> <?php $peak = memory_get_peak_usage(); workbenchLog(LOG_INFO, "MemoryUsageCheck", array("measure.memory.peak" => $peak . "byte")); if (WorkbenchContext::isEstablished() && $peak / toBytes(ini_get("memory_limit")) > 0.7) { WorkbenchContext::get()->clearCache(); workbenchLog(LOG_INFO, "MemoryUsageCacheClear", array("measure.memory.cache_clear" => 1)); } if (isset($GLOBALS['REDIS'])) { redis()->close(); } //USAGE: debug($showSuperVars = true, $showSoap = true, $customName = null, $customValue = null) debug(true, true, null, null);
function listMetadata($type) { try { if (isset($type->childXmlName)) { return processListMetadataResult(WorkbenchContext::get()->getMetadataConnection()->listMetadata($type->childXmlName, null, WorkbenchContext::get()->getApiVersion())); } if (!$type->inFolder) { return processListMetadataResult(WorkbenchContext::get()->getMetadataConnection()->listMetadata($type->xmlName, null, WorkbenchContext::get()->getApiVersion())); } $folderType = $type->xmlName == "EmailTemplate" ? "Email" : $type->xmlName; $folderQueryResult = WorkbenchContext::get()->getPartnerConnection()->query("SELECT DeveloperName FROM Folder WHERE Type = '" . $folderType . "' AND DeveloperName != null AND NamespacePrefix = null"); if ($folderQueryResult->size == 0) { return array(); } foreach ($folderQueryResult->records as $folderRecord) { $folder = new SObject($folderRecord); $folderName = $folder->fields->DeveloperName; $listMetadataResult["{$folderName}"] = processListMetadataResult(WorkbenchContext::get()->getMetadataConnection()->listMetadata($type->xmlName, $folder->fields->DeveloperName, WorkbenchContext::get()->getApiVersion())); } return $listMetadataResult; } catch (Exception $e) { displayError($e->getMessage(), false, true); } }
' align='absmiddle'/> Loading... </span> </form> <br/> <?php if (WorkbenchContext::get()->getDefaultObject()) { $describeSObjectResult = WorkbenchContext::get()->describeSObjects(WorkbenchContext::get()->getDefaultObject()); $alwaysArrayChildren = array("recordTypeInfos", "childRelationships"); foreach ($alwaysArrayChildren as $child) { if (isset($describeSObjectResult->{$child}) && !is_array($describeSObjectResult->{$child})) { $describeSObjectResult->{$child} = array($describeSObjectResult->{$child}); } } $forceCollapse = WorkbenchContext::get()->hasDefaultObjectChanged(); $processedResults = ExpandableTree::processResults($describeSObjectResult, "Attributes", true); ?> <div class="legend"> <strong>Legend:</strong> <ul> <li class="trueColor">True</li> <li class="falseColor">False</li> <li class="highlightCustomField">Custom Field</li> <li class="highlightSystemField">System Field</li> </ul> </div> <?php $tree = new ExpandableTree("describeTree", $processedResults); $tree->setForceCollapse($forceCollapse); $tree->setAdditionalMenus(ExpandableTree::getClearCacheMenu());
} preg_match("@((https?://)((.*)-api)?(.*))/services@", WorkbenchContext::get()->getPartnerConnection()->getLocation(), $sfdcApiHost); // [1] => https://na4-api.salesforce.com // [2] => https:// // [3] => na4-api // [4] => na4 // [5] => .salesforce.com if ($sfdcApiHost[3] != null) { //special cases switch ($sfdcApiHost[4]) { case "na0": $sfdcApiHost[4] = "ssl"; break; case "ap0": $sfdcApiHost[4] = "ap"; break; case "eu0": $sfdcApiHost[4] = "emea"; break; } $sfdcUiHost = $sfdcApiHost[2] . $sfdcApiHost[4] . $sfdcApiHost[5]; } else { $sfdcUiHost = $sfdcApiHost[1]; } if (WorkbenchConfig::get()->value("useSfdcFrontdoor") == 'ALWAYS' || WorkbenchConfig::get()->value("useSfdcFrontdoor") == 'AUTO' && !WorkbenchContext::get()->isUiSessionLikelySet()) { WorkbenchContext::get()->setIsUiSessionLikelySet(true); $jumpUrl = "{$sfdcUiHost}/secur/frontdoor.jsp?sid=" . WorkbenchContext::get()->getSessionId() . "&retURL=%2F" . $_GET['startUrl']; } else { $jumpUrl = "{$sfdcUiHost}/" . $_GET['startUrl']; } header("Location: " . $jumpUrl);