/** * Fetch an http file from the URL * * @param string $url URL from where to fetch * @return string content, or NULL in case of error */ private function _fetch_http_file($url) { cbimport('cb.snoopy'); $s = new CBSnoopy(); $s->read_timeout = 20; @$s->fetch($url); if ($s->error || $s->status != 200) { // echo '<font color="red">Connection to update server failed: ERROR: ' . $s->error . ($s->status == -100 ? 'Timeout' : $s->status).'</font>'; $content = null; } else { $content = $s->results; } return $content; }
/** * returns plugins xml version * * @param null|PluginTable|int $plugin The plugin id or object to check version for * @param bool $raw 1/True: version only (no farm), 0/False: Formatted version (green/red/shortened), 2: array of version information ( $version, $latestVersion, $isLatest, $latestURL ) * @param int $duration The duration to cache the plugin version xml file (null/0 for no limit) * @param int $length The maximum version length to display (null/0 for no limit) * @return null|string */ public function getPluginVersion($plugin, $raw = false, $duration = 24, $length = 0) { global $_CB_framework, $ueConfig; cbimport('cb.snoopy'); static $plgVersions = null; if ($plgVersions === null) { $cacheFile = $_CB_framework->getCfg('absolute_path') . '/cache/cbpluginsversions.xml'; $plgVersionsXML = null; if (file_exists($cacheFile)) { if (!$duration || intval(($_CB_framework->now() - filemtime($cacheFile)) / 3600) > $duration) { $request = true; } else { $plgVersionsXML = new SimpleXMLElement(trim(file_get_contents($cacheFile))); $request = false; } } else { $request = true; } if ($request) { $s = new CBSnoopy(); $s->read_timeout = 30; $s->referer = $_CB_framework->getCfg('live_site'); @$s->fetch('http://update.joomlapolis.net/cbpluginsversions20.xml'); if ((int) $s->status == 200) { try { $plgVersionsXML = new SimpleXMLElement($s->results); $plgVersionsXML->saveXML($cacheFile); } catch (Exception $e) { } } } if ($plgVersionsXML) { $plgVersions = $plgVersionsXML->getElementByPath('cb_plugins/' . (checkJversion() >= 2 ? 'j30' : 'j15')); } else { $plgVersions = false; } } $plugin = $this->getCachedPluginObject($plugin); if (!$plugin) { return $raw === 2 ? array(null, null, null, null) : null; } static $cache = array(); $pluginId = (int) $plugin->id; if (!isset($cache[$pluginId][$raw])) { $xmlFile = $this->getPluginXmlPath($plugin); $version = null; $latestVersion = null; $isLatest = null; $latestURL = null; if (file_exists($xmlFile)) { try { $xml = new SimpleXMLElement(trim(file_get_contents($xmlFile))); } catch (\Exception $e) { $xml = null; echo "{$xmlFile} not an XML file!!!"; } if ($xml !== null) { $ver = null; if (isset($xml->release)) { // New release XML variable used by incubator projects: $ver = $xml->release; } elseif (isset($xml->cbsubsversion)) { // CBSubs plugin versions are same as the CBSubs version; lets grab them: $cbsubsVer = $xml->cbsubsversion->attributes(); if (isset($cbsubsVer['version'])) { $ver = $cbsubsVer['version']; } } elseif (isset($xml->description)) { // Attempt to parse plugin description for a version using logical naming: if (preg_match('/(?:plugin|field|fieldtype|ver|version|' . preg_quote($plugin->name) . ') ((?:[0-9]+(?:\\.)?(?:(?: )?RC)?(?:(?: )?B)?(?:(?: )?BETA)?)+)/i', $xml->description, $matches)) { $ver = $matches[1]; } } // Check if version was found; if it was lets clean it up: if ($ver) { if (preg_match('/^\\d+(\\.\\d+)+(-[a-z]+\\.\\d+)?(\\+\\w)?$/', $ver)) { $version = $ver; } else { $version = preg_replace('/\\.*([a-zA-Z]+)\\.*/i', '.$1.', preg_replace('/^[a-zA-Z]+/i', '', str_replace(array('-', '_', '+'), '.', str_replace(' ', '', strtoupper($ver))))); } if (is_integer($version)) { $version = implode('.', str_split($version)); } elseif (preg_match('/^(\\d{2,})(\\.[a-zA-Z].+)/i', $version, $matches)) { $version = implode('.', str_split($matches[1])) . $matches[2]; } $version = trim(str_replace('..', '.', $version), '.'); // Encase the version is too long lets cut it short for readability and display full version as mouseover title: if ($version && $length && cbIsoUtf_strlen($version) > $length) { $versionName = rtrim(trim(cbIsoUtf_substr($version, 0, $length)), '.') . '…'; $versionShort = true; } else { $versionName = $version; $versionShort = false; } // Lets try and parse out latest version and latest url from versions xml data: if ($plgVersions) { foreach ($plgVersions as $plgVersion) { $plgName = (string) $plgVersion->name; $plgFile = (string) $plgVersion->file; if ($plgName == $plugin->name || strpos($plgName, $plugin->name) !== false || strpos($plgFile, $plugin->folder) !== false) { $latestVersion = (string) $plgVersion->version; $latestURL = (string) $plgVersion->url; } } } if ($latestVersion) { if (version_compare($version, $latestVersion) >= 0) { $isLatest = true; } else { $isLatest = false; } } // Format version display: if (!$raw) { if ($latestVersion) { if ($isLatest) { $version = '<span class="text-success"' . ($versionShort ? ' title="' . htmlspecialchars($version) . '"' : null) . '><strong>' . $versionName . '</strong></span>'; } else { $version = '<span class="text-danger" title="' . htmlspecialchars($latestVersion) . '"><strong>' . $versionName . '</strong></span>'; if ($latestURL) { $version = '<a href="' . htmlspecialchars($latestURL) . '" target="_blank">' . $version . '</a>'; } } } else { if ($versionShort) { $version = '<span title="' . htmlspecialchars($version) . '">' . $versionName . '</span>'; } else { $version = $versionName; } } } } } } if (!$version && !$raw) { if ($plugin->iscore) { // core plugins are same version as CB it self: if ($length && cbIsoUtf_strlen($ueConfig['version']) > $length) { $version = '<span title="' . htmlspecialchars($ueConfig['version']) . '">' . rtrim(trim(cbIsoUtf_substr($ueConfig['version'], 0, $length)), '.') . '…</span>'; } else { $version = $ueConfig['version']; } } else { $version = '-'; } } if ($raw === 2) { $version = array($version, $latestVersion, $isLatest, $latestURL); } $cache[$pluginId][$raw] = $version; } return $cache[$pluginId][$raw]; }
/** * Uploads a file from a Url into a file on the filesystem * * @param string $userfileURL Url * @param string $userfile_name INPUT+OUTPUT: Destination filesname * @param string $msg OUTPUT: Message for user * @return boolean Success */ private function uploadFileURL($userfileURL, $userfile_name, &$msg) { global $_CB_framework; cbimport('cb.snoopy'); cbimport('cb.adminfilesystem'); $adminFS = cbAdminFileSystem::getInstance(); if ($adminFS->isUsingStandardPHP()) { $baseDir = _cbPathName($_CB_framework->getCfg('tmp_path')); } else { $baseDir = $_CB_framework->getCfg('absolute_path') . '/tmp'; } if (file_exists($baseDir)) { if ($adminFS->is_writable($baseDir) || !$adminFS->isUsingStandardPHP()) { $s = new CBSnoopy(); $fetchResult = @$s->fetch($userfileURL); if ($fetchResult && !$s->error && $s->status == 200) { cbimport('cb.adminfilesystem'); $adminFS = cbAdminFileSystem::getInstance(); if ($adminFS->file_put_contents($baseDir . $userfile_name, $s->results)) { if ($this->_cbAdmin_chmod($baseDir . $userfile_name)) { return true; } else { $msg = sprintf(CBTxt::T('Failed to change the permissions of the uploaded file %s'), $baseDir . $userfile_name); } } else { $msg = sprintf(CBTxt::T('Failed to create and write uploaded file in %s'), $baseDir . $userfile_name); } } else { $msg = $s->error ? sprintf(CBTxt::T('Failed to download package file from <code>%s</code> to webserver due to following error: %s'), $userfileURL, $s->error) : sprintf(CBTxt::T('Failed to download package file from <code>%s</code> to webserver due to following status: %s'), $userfileURL, $s->status . ': ' . $s->response_code); } } else { $msg = sprintf(CBTxt::T('Upload failed as %s directory is not writable.'), '<code>' . htmlspecialchars($baseDir) . '</code>'); } } else { $msg = sprintf(CBTxt::T('Upload failed as %s directory does not exist.'), '<code>' . htmlspecialchars($baseDir) . '</code>'); } return false; }
function latestVersion() { global $_CB_framework, $ueConfig; cbimport('cb.snoopy'); $s = new CBSnoopy(); $s->read_timeout = 90; $s->referer = $_CB_framework->getCfg('live_site'); @$s->fetch('http://www.joomlapolis.com/versions/comprofilerversion.php?currentversion=' . urlencode($ueConfig['version'])); $version_info = $s->results; $version_info_pos = strpos($version_info, ":"); if ($version_info_pos === false) { $version = $version_info; $info = null; } else { $version = substr($version_info, 0, $version_info_pos); $info = substr($version_info, $version_info_pos + 1); } if ($s->error || $s->status != 200) { echo '<span class="text-danger">' . CBTxt::T('Connection to update server failed') . ': ' . CBTxt::T('ERROR') . ': ' . $s->error . ($s->status == -100 ? CBTxt::T('Timeout') : $s->status) . '</span>'; } else { if ($version == $ueConfig['version']) { echo '<span class="text-success">' . $version . '</span>' . $info; } else { echo '<span class="text-danger">' . $version . '</span>' . $info; } } }
/** * @param string $url * @param string $file * @param int $duration * @return SimpleXMLElement|null */ public static function getFeedXML($url, $file, $duration = 12) { global $_CB_framework; cbimport('cb.snoopy'); $cache = $_CB_framework->getCfg('absolute_path') . '/cache/' . $file; $xml = null; if (file_exists($cache)) { if (!$duration || intval(($_CB_framework->now() - filemtime($cache)) / 3600) > $duration) { $request = true; } else { $xml = new SimpleXMLElement(trim(file_get_contents($cache))); $request = false; } } else { $request = true; } if ($request) { $s = new CBSnoopy(); $s->read_timeout = 30; $s->referer = $_CB_framework->getCfg('live_site'); @$s->fetch($url); if ((int) $s->status == 200) { try { $xml = new SimpleXMLElement($s->results); $xml->saveXML($cache); } catch (Exception $e) { } } } return $xml; }
/** * Posts a POST form by https if available, otherwise by http and gets result. * * @param string $urlNoHttpsPrefix URL without https:// in front (but works also with http:// or https:// in front, but it's ignored. * @param array|string $formvars Variables in form to post * @param int $timeout Timeout of the access * @param string $result RETURNING: the fetched access * @param int $status RETURNING: the status of the access (e.g. 200 is normal) * @param string $getPostType 'post' (default) or 'get' * @param string $contentType 'normal' (default) or 'xml' ($formvars['xml']=xml content) or 'json' (application/json) * @param string $acceptType '* / *' (default) or 'application/xml' or 'application/json' * @param boolean $https SSL protocol (default: true) * @param int $port port number (default: 443) * @param string $username HTTP username authentication * @param string $password HTTP password authentication * @param boolean $allowHttpFallback Allow fallback to http if https not available locally (default: false) * @param string $referer referrer * @return int $error error-code of access (0 for ok) */ public static function httpsRequest($urlNoHttpsPrefix, $formvars, $timeout, &$result, &$status, $getPostType = 'post', $contentType = 'normal', $acceptType = '*/*', $https = true, $port = 443, $username = '', $password = '', $allowHttpFallback = false, $referer = null) { $urlNoHttpsPrefix = preg_replace('/^https?:\\/\\//', '', $urlNoHttpsPrefix); /* This is broken on both KreativMedia servers, don't use it until proven to work: on Nick's it's php-maxexectime-timeouting, and on Janus, it's returning nothing and no error. if ( extension_loaded('curl') && is_callable( 'curl_init' ) ) { // try CURL library: $posturl = ( $https ? 'https://' : 'http://' ) . $urlNoHttpsPrefix; $ch = curl_init(); if ( $ch !== false ) { curl_setopt( $ch, CURLOPT_URL, $posturl ); curl_setopt( $ch, CURLOPT_PORT, $port ); curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); if ( $https ) { // curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); //TBD: check this! // curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); } else { curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); } if ( $getPostType == 'post' ) { curl_setopt($ch, CURLOPT_POST, 1 ); } if ( $contentType == 'normal' ) { curl_setopt( $ch, CURLOPT_POSTFIELDS, $formvars ); } elseif ( $contentType == 'xml' ) { $headers = array( 'Content-Type: text/xml' ); REMOVE THAT SPACE!!! if ( $acceptType != '* /*' ) { $headers[] = 'Accept: ' . $acceptType; } curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); curl_setopt( $ch, CURLOPT_HEADER, 0 ); curl_setopt( $ch, CURLOPT_POSTFIELDS, $formvars ); } elseif ( $contentType == 'json' ) { $headers = array( 'Content-Type: text/json' ); REMOVE THAT SPACE!!! if ( $acceptType != '* /*' ) { $headers[] = 'Accept: ' . $acceptType; } curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); //? curl_setopt( $ch, CURLOPT_HEADER, 0 ); curl_setopt( $ch, CURLOPT_POSTFIELDS, $formvars ); } if ( $referer ) { curl_setopt( $ch, CURLOPT_REFERER, $referer ); } if ( $username || $password ) { curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password ); } $result = curl_exec( $ch ); $error = curl_error( $ch ); $status = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); curl_close( $ch ); if ( $result !== false ) { return $error; } } } */ if (is_callable('fsockopen') && (!$https || version_compare(phpversion(), '4.3.0', '>') && extension_loaded('openssl') && defined('OPENSSL_VERSION_TEXT'))) { // otherwise try fsockopen: if (is_array($formvars)) { $formUrl = array(); foreach ($formvars as $k => $v) { $formUrl[$k] = urlencode($k) . '=' . urlencode($v); } $formUrl = implode('&', $formUrl); } else { $formUrl = $formvars; } $urlParts = explode('/', $urlNoHttpsPrefix, 2); $posturl = ($https ? 'ssl://' : 'tcp://') . $urlParts[0]; if ($getPostType == 'post') { $header = 'POST'; } else { $header = 'GET'; } $header .= ' /' . (count($urlParts) == 2 ? $urlParts[1] : '') . " HTTP/1.0\r\n"; $header .= 'Host: ' . $urlParts[0] . "\r\n"; if ($username || $password) { $header .= 'Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n"; } $header .= 'User-Agent: PHP Script' . "\r\n"; if ($referer) { $header .= 'Referer: ' . $referer . "\r\n"; } if ($contentType == 'xml') { $header .= 'Content-Type: application/xml' . "\r\n"; } elseif ($contentType == 'json') { $header .= 'Content-Type: application/json' . "\r\n"; } else { $header .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n"; //TODO: $header .= 'Content-Type: application/x-www-form-urlencoded;charset=\"utf-8\"' . "\r\n"; } if ($acceptType != '*/*') { $header .= 'Accept: ' . $acceptType . "\r\n"; } $header .= 'Content-Length: ' . strlen($formUrl) . "\r\n\r\n"; $error = null; $errstr = null; $status = 100; $fp = @fsockopen($posturl, $port, $error, $errstr, $timeout); if ($fp) { if (is_callable('stream_set_timeout')) { stream_set_timeout($fp, $timeout); } $bytesWritten = @fwrite($fp, $header . $formUrl); if ($bytesWritten !== false) { $response = array(); $result = ''; while (!feof($fp)) { $line = @fgets($fp, 8096); if (trim($line) == '') { break; } $response[] = $line; } while (!feof($fp)) { $result .= @fgets($fp, 8096); } @fclose($fp); if (count($response) > 0) { $parts = explode(' ', $response[0], 3); if (count($parts) == 3) { if (trim($parts[2]) == 'OK' || preg_match('/^\\s*\\d{3}\\s*/', $parts[1])) { $status = (int) $parts[1]; // 200 hopefully. } } } return $error; } else { fclose($fp); } } } // then try using curl executable: cbimport('cb.snoopy'); $curl_found = false; $path = null; if (function_exists('is_executable')) { $paths = array('/usr/bin/curl', '/usr/local/bin/curl', 'curl'); // IN SNOOPY ALREADY: '/usr/local/bin/curl' foreach ($paths as $path) { if (@is_executable($path)) { $curl_found = true; break; } } } // if ( $curl_found ) { // we will do http as last resort without using curl if curl_found == false: $s = new CBSnoopy(); $s->curl_path = $path; if (!is_array($formvars)) { if ($contentType == 'xml') { $formvars = array('xml' => $formvars); } else { $formarr = explode('&', $formvars); $formvars = array(); foreach ($formarr as $v) { $p = explode('=', $v, 2); if (count($p) == 2) { $formvars[$p[0]] = urldecode($p[1]); } } } } $s->read_timeout = $timeout; if ($username || $password) { $s->user = $username; $s->pass = $password; } if ($contentType == 'xml') { $s->set_submit_xml(); } elseif ($contentType == 'json') { // available after CB 1.2.1 : if (is_callable(array($s, 'set_submit_json'))) { $s->set_submit_json(); } } if ($acceptType) { $s->accept = $acceptType; } if ((int) $port && ($https & $port != 443 || !$https & $port != 80)) { $portPostfix = ':' . (int) $port; } else { $portPostfix = ''; } if ((int) $port) { $s->port = $port; } $posturl = ($https && ($curl_found || !$allowHttpFallback) ? 'https://' : 'http://') . $urlNoHttpsPrefix . $portPostfix; /* $return = */ if ($referer) { $s->referer = $referer; } @$s->submit($posturl, $formvars); $status = $s->status; $error = $s->error; $result = $s->results; // } return $error; }
/** * Called at each change of user subscription state due to a plan activation or deactivation * * @param UserTable $user * @param string $status * @param int $planId * @param int $replacedPlanId * @param ParamsInterface $integrationParams * @param string $cause 'PaidSubscription' (first activation only), 'SubscriptionActivated' (renewals, cancellation reversals), 'SubscriptionDeactivated', 'Denied' * @param string $reason 'N' new subscription, 'R' renewal, 'U'=update * @param int $now Unix time * @param cbpaidSomething $subscription */ public function onCPayUserStateChange( &$user, $status, $planId, $replacedPlanId, &$integrationParams, $cause, $reason, /** @noinspection PhpUnusedParameterInspection */ $now, &$subscription ) { global $_CB_framework; if ( ! $user ) { return; } $event = null; if ( ( $status == 'A' ) && ( $cause == 'PaidSubscription' ) && ( $reason != 'R' ) ) { $event = 'activation'; } elseif ( ( $status == 'A' ) && ( $cause == 'PaidSubscription' ) && ( $reason == 'R' ) ) { $event = 'renewal'; } elseif ( ( $status == 'X' ) && ( $cause != 'Pending' ) ) { $event = 'expiration'; } elseif ( ( $status == 'C' ) && ( $cause != 'Pending' ) ) { $event = 'deactivation'; } if ( $event ) { $path = $integrationParams->get( 'url_path_' . $event, null ); $method = $integrationParams->get( 'url_method_' . $event, 'GET' ); $results = $integrationParams->get( 'url_results_' . $event, 0 ); if ( $path ) { // add substitutions for: [plan_id], [replaced_plan_id], [subscription_id], [parent_plan_id], [parent_subscription_id] $extraStringsLocal = array( 'plan_id' => (int) $planId, 'replaced_plan_id' => (int) $replacedPlanId, 'subscription_id' => (int) $subscription->id, 'parent_plan_id' => (int) $subscription->parent_plan, 'parent_subscription_id' => (int) $subscription->parent_subscription ); $extraStrings = array_merge( $subscription->substitutionStrings( false ), $extraStringsLocal ); cbimport( 'cb.snoopy' ); $cbUser =& CBuser::getInstance( $user->id ); if ( ! $cbUser ) { return; } $path = trim( $cbUser->replaceUserVars( $path, array( $this, '_urlencode' ), false, $extraStrings, false ) ); $snoopy = new CBSnoopy(); $snoopy->read_timeout = 30; switch ($method ) { case 'POST': $post = $integrationParams->get( 'url_post_' . $event, null ); $formvar = array(); if ( $post ) { $formvars = explode( "\n", $post ); foreach ( $formvars as $vars ) { $var = explode( '=', trim( $vars ), 2 ); if ( count( $var ) == 2 ) { $key = trim( $var[0] ); $value = trim( $cbUser->replaceUserVars( $var[1], false, false, $extraStrings, false ) ); $formvar[$key] = $value; } } } $snoopy->submit( $path, $formvar ); break; case 'XML': $xmlText = $integrationParams->get( 'url_xml_' . $event, null ); $xmlText = trim( $cbUser->replaceUserVars( $xmlText, array( $this, '_htmlspecialchars' ), false, $extraStrings, false ) ); $formvar = array( 'xml' => $xmlText ); $snoopy->set_submit_xml(); $snoopy->submit( $path, $formvar ); break; case 'GET': default: $snoopy->fetch( $path ); break; } if ( $results && ( ! $snoopy->error ) && ( $snoopy->status == 200 ) && $snoopy->results && ( $_CB_framework->getUi() == 1 ) ) { // display only in frontend: echo '<div class="CBSubsURL_Results_' . (int) $planId . '">' . $snoopy->results . '</div>'; } } } }