private function getCacheDir($key) { // use the first 2 characters of the hash as a directory prefix // this should prevent slowdowns due to huge directory listings // and thus give some basic amount of scalability return Shindig_Config::get('cache_root') . '/' . $this->prefix . '/' . substr($key, 0, 2); }
public function doPost() { try { // we support both a raw http post (without application/x-www-form-urlencoded headers) like java does // and a more php / curl safe version of a form post with 'request' as the post field that holds the request json data if (isset($GLOBALS['HTTP_RAW_POST_DATA']) || isset($_POST['request'])) { $requestParam = urldecode(isset($_POST['request']) ? $_POST['request'] : $GLOBALS['HTTP_RAW_POST_DATA']); if (get_magic_quotes_gpc()) { $requestParam = stripslashes($requestParam); } $request = json_decode($requestParam); if ($request == $requestParam) { throw new Exception("Malformed json string"); } $handler = new MetadataHandler(); $response = $handler->process($request); echo json_encode(array('gadgets' => $response)); } else { throw new Exception("No post data set"); } } catch (Exception $e) { header("HTTP/1.0 500 Internal Server Error", true, 500); echo "<html><body><h1>Internal Server Error</h1><br />"; if (Shindig_Config::get('debug')) { echo $e->getMessage() . "<br /><pre>"; print_r(debug_backtrace()); echo "</pre>"; } echo "</body></html>"; } }
/** * Enables output buffering so we can do correct header handling in the destructor * */ public function __construct() { // set our default cache time (config cache time defaults to 24 hours aka 1 day) $this->cacheTime = Shindig_Config::get('cache_time'); // to do our header magic, we need output buffering on ob_start(); }
public function getDb() { try { $fileName = sys_get_temp_dir() . '/' . $this->jsonDbFileName; if (file_exists($fileName)) { if (!is_readable($fileName)) { throw new SocialSpiException("Could not read temp json db file: {$fileName}, check permissions", ResponseError::$INTERNAL_ERROR); } $cachedDb = file_get_contents($fileName); $jsonDecoded = json_decode($cachedDb, true); if ($jsonDecoded == $cachedDb || $jsonDecoded == null) { throw new SocialSpiException("Failed to decode the json db", ResponseError::$INTERNAL_ERROR); } return $jsonDecoded; } else { $jsonDb = Shindig_Config::get('jsondb_path'); if (!file_exists($jsonDb) || !is_readable($jsonDb)) { throw new SocialSpiException("Could not read json db file: {$jsonDb}, check if the file exists & has proper permissions", ResponseError::$INTERNAL_ERROR); } $dbConfig = @file_get_contents($jsonDb); $contents = preg_replace('/(?<!http:|https:)\\/\\/.*$/m', '', preg_replace('@/\\*.*?\\*/@s', '', $dbConfig)); $jsonDecoded = json_decode($contents, true); if ($jsonDecoded == $contents || $jsonDecoded == null) { throw new SocialSpiException("Failed to decode the json db", ResponseError::$INTERNAL_ERROR); } $this->saveDb($jsonDecoded); return $jsonDecoded; } } catch (Exception $e) { throw new SocialSpiException("An error occured while reading/writing the json db: " . $e->getMessage(), ResponseError::$INTERNAL_ERROR); } }
/** * generates the library string (core:caja:etc.js) including a checksum of all the * javascript content (?v=<md5 of js>) for cache busting * * @param array $features * @param Gadget $gadget * @return string the list of libraries in core:caja:etc.js?v=checksum> format */ protected function getJsUrl($features) { if (!is_array($features) || !count($features)) { return 'null'; } $registry = $this->context->getRegistry(); // Given the JsServlet automatically expends the js library, we just need // to include the "leaf" nodes of the features. $ret = $features; foreach ($features as $feature) { $depFeatures = $registry->features[$feature]['deps']; $ret = array_diff($ret, $depFeatures); } $ret = implode(':', $ret); $cache = Cache::createCache(Shindig_Config::get('feature_cache'), 'FeatureCache'); if (($md5 = $cache->get(md5('getJsUrlMD5'))) === false) { $features = $registry->features; // Build a version string from the md5() checksum of all included javascript // to ensure the client always has the right version $inlineJs = ''; foreach ($features as $feature => $content) { $inlineJs .= $registry->getFeatureContent($feature, $this->context, true); } $md5 = md5($inlineJs); $cache->set(md5('getJsUrlMD5'), $md5); } $ret .= ".js?v=" . $md5; return $ret; }
/** * Merges the given array with the config array. It uses the keys/values from config/container.php. */ static function setConfig($tconfig) { if (!is_array(self::$config)) { self::loadConfig(); } self::$config = array_merge(self::$config, $tconfig); }
protected function fetch_private_cert(&$request) { $file = Shindig_Config::get('private_key_file'); if (!(file_exists($file) && is_readable($file))) { throw new Exception("Error loding private key"); } $private_key = @file_get_contents($file); if (!$private_key) { throw new Exception("Error loding private key"); } $phrase = Shindig_Config::get('private_key_phrase'); if (strpos($private_key, '-----BEGIN') === false) { $tmp .= "-----BEGIN PRIVATE KEY-----\n"; $chunks .= str_split($private_key, 64); foreach ($chunks as $chunk) { $tmp .= $chunk . "\n"; } $tmp .= "-----END PRIVATE KEY-----"; $private_key = $tmp; } if (!($rsa_private_key = @openssl_pkey_get_private($private_key, $phrase))) { throw new Exception("Could not create the key"); } return $rsa_private_key; }
/** * Register our dom node observers that will remove the javascript, but only * if this view should be sanitized * * @param GadgetRewriter $gadgetRewriter */ public function register(GadgetRewriter &$gadgetRewriter) { $sanitizeViews = Shindig_Config::get('sanitize_views'); // Only hook up our dom node observers if this view should be sanitized if (in_array($this->context->getView(), $sanitizeViews)) { $gadgetRewriter->addObserver('script', $this, 'rewriteScript'); } }
/** * Handles the get file request, only called on url = /public.crt * so this function has no logic other then to output the cert */ public function doGet() { $file = Shindig_Config::get('public_key_file'); if (!file_exists($file) || !is_readable($file)) { throw new Exception("Invalid public key location ({$file}), check config and file permissions"); } $this->setLastModified(filemtime($file)); readfile($file); }
public static function readable($file) { // only really check if check_file_exists == true, big performance hit on production systems, but also much safer :) if (Shindig_Config::get('check_file_exists')) { return is_readable($file); } else { return true; } }
public function fetchRequest(RemoteContentRequest $request) { $outHeaders = array(); if ($request->hasHeaders()) { $headers = explode("\n", $request->getHeaders()); foreach ($headers as $header) { if (strpos($header, ':')) { $key = trim(substr($header, 0, strpos($header, ':'))); $val = trim(substr($header, strpos($header, ':') + 1)); if (strcmp($key, "User-Agent") != 0 && strcasecmp($key, "Transfer-Encoding") != 0 && strcasecmp($key, "Cache-Control") != 0 && strcasecmp($key, "Expries") != 0 && strcasecmp($key, "Content-Length") != 0) { $outHeaders[$key] = $val; } } } } $outHeaders['User-Agent'] = "Shindig PHP"; $options = array(); $options['timeout'] = Shindig_Config::get('curl_connection_timeout'); // configure proxy $proxyUrl = Shindig_Config::get('proxy'); if (!empty($proxyUrl)) { $options['adapter'] = 'Zend_Http_Client_Adapter_Proxy'; $proxy = parse_url($proxyUrl); if (isset($proxy['host'])) { $options['proxy_host'] = $proxy['host']; } if (isset($proxy['port'])) { $options['proxy_port'] = $proxy['port']; } if (isset($proxy['user'])) { $options['proxy_user'] = $proxy['user']; } if (isset($proxy['pass'])) { $options['proxy_pass'] = $proxy['pass']; } } $client = new Zend_Http_Client(); $client->setConfig($options); $client->setUri($request->getUrl()); $client->setHeaders($outHeaders); if ($request->getContentType()) { $client->setHeaders(Zend_Http_Client::CONTENT_TYPE, $request->getContentType()); } if ($request->isPost()) { $client->setMethod(Zend_Http_Client::POST); $client->setRawData($request->getPostBody()); } else { $client->setMethod(Zend_Http_Client::GET); } $response = $client->request(); $request->setHttpCode($response->getStatus()); $request->setContentType($response->getHeader('Content-Type')); $request->setResponseHeaders($response->getHeaders()); $request->setResponseContent($response->getBody()); $request->setResponseSize(strlen($response->getBody())); return $request; }
public function __construct($file = false) { if (!$file) { $file = Shindig_Config::get('base_path') . '/blacklist.txt'; } if (Shindig_File::exists($file)) { $this->rules = explode("\n", @file_get_contents($file)); } }
public function handleListMethods(RequestItem $request) { $containerConfig = new ContainerConfig(Shindig_Config::get('container_path')); $gadgetConfig = $containerConfig->getConfig('default', 'gadgets.features'); if (!isset($gadgetConfig['osapi.services']) || count($gadgetConfig['osapi.services']) == 1) { // this should really be set in config/container.js, but if not, we build a complete default set so at least most of it works out-of-the-box $gadgetConfig['osapi.services'] = array('gadgets.rpc' => array('container.listMethods'), 'http://%host%/social/rpc' => array("messages.update", "albums.update", "activities.delete", "activities.update", "activities.supportedFields", "albums.get", "activities.get", "mediaitems.update", "messages.get", "appdata.get", "system.listMethods", "people.supportedFields", "messages.create", "mediaitems.delete", "mediaitems.create", "people.get", "people.create", "albums.delete", "messages.delete", "appdata.update", "activities.create", "mediaitems.get", "albums.create", "appdata.delete", "people.update", "appdata.create"), 'http://%host%/gadgets/api/rpc' => array('cache.invalidate')); } return $gadgetConfig['osapi.services']; }
public function __construct($context, MakeRequest $makeRequest = null) { $this->context = $context; if (isset($makeRequest)) { $this->makeRequest = $makeRequest; } else { $makeRequestClass = Shindig_Config::get('makerequest_class'); $this->makeRequest = new $makeRequestClass(); } }
/** * Produces the proxied version of a URL if it falls within the content-rewrite params and * will append a refresh param to the proxied url based on the expires param, and the gadget * url so that the proxy server knows to rewrite it's content or not * * @param string $url */ private function getProxyUrl($url) { if (strpos(strtolower($url), 'http://') === false && strpos(strtolower($url), 'https://') === false) { $url = $this->baseUrl . $url; } $url = Shindig_Config::get('web_prefix') . '/gadgets/proxy?url=' . urlencode($url); $url .= '&refresh=' . (isset($this->rewrite['expires']) && is_numeric($this->rewrite['expires']) ? $this->rewrite['expires'] : '3600'); $url .= '&gadget=' . urlencode($this->context->getUrl()); return $url; }
/** * Retrieves a gadget specification from the Internet, processes its views and * adds it to the cache. */ private function fetchFromWeb($url, $ignoreCache) { $remoteContentRequest = new RemoteContentRequest($url); $remoteContentRequest->getOptions()->ignoreCache = $ignoreCache; $remoteContent = new BasicRemoteContent(); $spec = $remoteContent->fetch($remoteContentRequest); $gadgetSpecParserClass = Shindig_Config::get('gadget_spec_parser'); $gadgetSpecParser = new $gadgetSpecParserClass(); $gadgetSpec = $gadgetSpecParser->parse($spec->getResponseContent(), $this->context); return $gadgetSpec; }
/** * Fetches the content and returns it as-is using the headers as returned * by the remote host. * * @param string $url the url to retrieve */ public function fetch($url) { // TODO: Check to see if we can just use MakeRequestOptions::fromCurrentRequest $st = isset($_GET['st']) ? $_GET['st'] : (isset($_POST['st']) ? $_POST['st'] : false); $body = isset($_GET['postData']) ? $_GET['postData'] : (isset($_POST['postData']) ? $_POST['postData'] : false); $authz = isset($_GET['authz']) ? $_GET['authz'] : (isset($_POST['authz']) ? $_POST['authz'] : null); $headers = isset($_GET['headers']) ? $_GET['headers'] : (isset($_POST['headers']) ? $_POST['headers'] : null); $params = new MakeRequestOptions($url); $params->setSecurityTokenString($st)->setAuthz($authz)->setRequestBody($body)->setHttpMethod('GET')->setFormEncodedRequestHeaders($headers)->setNoCache($this->context->getIgnoreCache()); $result = $this->makeRequest->fetch($this->context, $params); $httpCode = (int) $result->getHttpCode(); $cleanedResponseHeaders = $this->makeRequest->cleanResponseHeaders($result->getResponseHeaders()); $isShockwaveFlash = false; foreach ($cleanedResponseHeaders as $key => $val) { header("{$key}: {$val}", true); if (strtoupper($key) == 'CONTENT-TYPE' && strtolower($val) == 'application/x-shockwave-flash') { // We're skipping the content disposition header for flash due to an issue with Flash player 10 // This does make some sites a higher value phishing target, but this can be mitigated by // additional referer checks. $isShockwaveFlash = true; } } if (!$isShockwaveFlash && !Shindig_Config::get('debug')) { header('Content-Disposition: attachment;filename=p.txt'); } $lastModified = $result->getResponseHeader('Last-Modified') != null ? $result->getResponseHeader('Last-Modified') : gmdate('D, d M Y H:i:s', $result->getCreated()) . ' GMT'; $notModified = false; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $lastModified && !isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $if_modified_since = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); // Use the request's Last-Modified, otherwise fall back on our internal time keeping (the time the request was created) $lastModified = strtotime($lastModified); if ($lastModified <= $if_modified_since) { $notModified = true; } } if ($httpCode == 200) { // only set caching headers if the result was 'OK' $this->setCachingHeaders($lastModified); // was the &gadget=<gadget url> specified in the request? if so parse it and check the rewrite settings if (isset($_GET['gadget'])) { $this->rewriteContent($_GET['gadget'], $result); } } // If the cached file time is within the refreshInterval params value, return not-modified if ($notModified) { header('HTTP/1.0 304 Not Modified', true); header('Content-Length: 0', true); } else { header("HTTP/1.1 {$httpCode} " . $result->getHttpCodeMsg()); // then echo the content echo $result->getResponseContent(); } }
/** * Returns the user preferences in &up_<name>=<val> format * * @param array $libs array of features this gadget requires * @param Gadget $gadget * @return string the up_<name>=<val> string to use in the redirection url */ private function getPrefsQueryString($prefs) { $ret = ''; foreach ($prefs as $pref) { $ret .= '&'; $ret .= Shindig_Config::get('userpref_param_prefix'); $ret .= urlencode($pref['name']); $ret .= '='; $ret .= urlencode($pref['value']); } return $ret; }
private function getIframeURL(Shindig_Gadget $gadget, GadgetContext $context) { $v = $gadget->getChecksum(); $view = $gadget->getView($context->getView()); $up = ''; foreach ($gadget->gadgetSpec->userPrefs as $pref) { $up .= '&up_' . urlencode($pref['name']) . '=' . urlencode($pref['value']); } $locale = $context->getLocale(); //Note: putting the URL last, else some browsers seem to get confused (reported by hi5) return Shindig_Config::get('default_iframe_prefix') . 'container=' . $context->getContainer() . ($context->getIgnoreCache() ? '&nocache=1' : '&v=' . $v) . ($context->getModuleId() != 0 ? '&mid=' . $context->getModuleId() : '') . '&lang=' . $locale['lang'] . '&country=' . $locale['country'] . '&view=' . $view['view'] . $up . '&url=' . urlencode($context->getUrl()); }
public function __construct() { try { $service = trim(Shindig_Config::get('invalidate_service')); if (!empty($service)) { $cache = Cache::createCache(Shindig_Config::get('data_cache'), 'RemoteContent'); $this->service = new $service($cache); } } catch (ConfigException $e) { // Do nothing. If invalidate service is not specified in the config file. // All the requests to the handler will throw not implemented exception. } }
/** * Initialize the OAuth factory with a default implementation of * BlobCrypter and consumer keys/secrets read from oauth.js */ public function OAuthFetcherFactoryInit($fetcher) { try { $BBC = new BasicBlobCrypter(); $this->oauthCrypter = new BasicBlobCrypter(srand($BBC->MASTER_KEY_MIN_LEN)); $specFactory = new BasicGadgetSpecFactory(); $OAuthStore = Shindig_Config::get('oauth_store'); $basicStore = new BasicGadgetOAuthTokenStore(new $OAuthStore(), $specFactory); $basicStore->initFromConfigFile($fetcher); $this->tokenStore = $basicStore; } catch (Exeption $e) { } }
public function __construct(Cache $cache) { $this->cache = $cache; $this->invalidationEntry = Cache::createCache(Shindig_Config::get('data_cache'), 'InvalidationEntry'); if (self::$makerCache == null) { self::$makerCache = Cache::createCache(Shindig_Config::get('data_cache'), 'MarkerCache'); $value = self::$makerCache->expiredGet('marker'); if ($value['found']) { self::$marker = $value['data']; } else { self::$marker = 0; self::$makerCache->set('marker', self::$marker); } } }
public function renderGadget(Shindig_Gadget $gadget, $view) { $this->setGadget($gadget); // Was a privacy policy header configured? if so set it if (Shindig_Config::get('P3P') != '') { header("P3P: " . Shindig_Config::get('P3P')); } $content = ''; // Set doctype if quirks = false or empty in the view if (!empty($view['quirks']) || !$view['quirks']) { $content .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n"; } // Rewriting the gadget's content using the libxml library does impose some restrictions to the validity of the input html, so // for the time being (until either gadgets are all fixed, or we find a more tolerant html parsing lib), we try to avoid it when we can $domRewrite = false; if (isset($gadget->gadgetSpec->rewrite) || Shindig_Config::get('rewrite_by_default')) { $domRewrite = true; } elseif ((strpos($view['content'], 'text/os-data') !== false || strpos($view['content'], 'text/os-template') !== false) && $gadget->gadgetSpec->templatesDisableAutoProcessing == false) { $domRewrite = true; } if (!$domRewrite) { // Manually generate the html document using basic string concatinations instead of using our DOM based functions $content .= "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n"; $content .= '<style>' . Shindig_Config::get('gadget_css') . "</style>\n"; $scripts = $this->getJavaScripts(); foreach ($scripts as $script) { if ($script['type'] == 'inline') { $content .= "<script type=\"text/javascript\">{$script['content']}</script>\n"; } else { $content .= "<script type=\"text/javascript\" src=\"{$script['content']}\"></script>\n"; } } $content .= "</head>\n<body>\n"; $content .= $gadget->substitutions->substitute($view['content']); $content .= '<script type="text/javascript">' . $this->getBodyScript() . "</script>\n"; $content .= "\n</body>\n</html>\n"; } else { // Use the (libxml2 based) DOM rewriter $content .= "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>\n"; // Append the content for the selected view $content .= $gadget->substitutions->substitute($view['content']); $content .= "\n</body>\n</html>"; $content = $this->parseTemplates($content); $content = $this->rewriteContent($content); $content = $this->addTemplates($content); } echo $content; }
private static function loadConfig() { global $shindigConfig; if (!self::$config) { // load default configuration include_once 'config/container.php'; self::$config = $shindigConfig; $localConfigPath = realpath(dirname(__FILE__) . "/../../config/local.php"); if (file_exists($localConfigPath)) { // include local.php if it exists and merge the config arrays. // the second array values overwrites the first one's include_once $localConfigPath; self::$config = array_merge(self::$config, $shindigConfig); } } }
/** * * @see BasicSecurityTokenDecoder::createToken() */ public function createToken($stringToken) { if (empty($stringToken) && !empty($_GET['authz'])) { throw new GadgetException('INVALID_GADGET_TOKEN'); } try { if (Shindig_Config::get('allow_plaintext_token') && count(explode(':', $stringToken)) == 6) { $tokens = explode(":", $stringToken); return new opShindigSecurityToken(null, null, urldecode($tokens[$this->OWNER_INDEX]), urldecode($tokens[$this->VIEWER_INDEX]), urldecode($tokens[$this->APP_ID_INDEX]), urldecode($tokens[$this->CONTAINER_INDEX]), urldecode($tokens[$this->APP_URL_INDEX]), urldecode($tokens[$this->MODULE_ID_INDEX])); } else { return opShindigSecurityToken::createFromToken($stringToken, Shindig_Config::get('token_max_age')); } } catch (Exception $e) { throw new GadgetException('INVALID_GADGET_TOKEN'); } }
public function doGet() { $this->noHeaders = true; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { header("HTTP/1.1 304 Not Modified"); header('Content-Length: 0'); ob_end_clean(); die; } $uri = strtolower($_SERVER["REQUEST_URI"]); $uri = substr($uri, strrpos($uri, '/') + 1); // remove any params that would confuse our parser if (strpos($uri, '?')) { $uri = substr($uri, 0, strpos($uri, '?')); } if (strpos($uri, '.js') !== false) { $uri = substr($uri, 0, strlen($uri) - 3); } $needed = array(); if (strpos($uri, ':')) { $needed = explode(':', $uri); } else { $needed[] = $uri; } $found = array(); $missing = array(); $contextClass = Shindig_Config::get('gadget_context_class'); $context = new $contextClass('GADGET'); $registry = new GadgetFeatureRegistry(Shindig_Config::get('features_path')); if ($registry->resolveFeatures($needed, $found, $missing)) { $isGadgetContext = !isset($_GET["c"]) || $_GET['c'] == 0 ? true : false; $jsData = ''; foreach ($found as $feature) { $jsData .= $registry->getFeatureContent($feature, $context, $isGadgetContext); } if (!strlen($jsData)) { header("HTTP/1.0 404 Not Found", true); die; } $this->setCachingHeaders(); header("Content-Type: text/javascript"); echo $jsData; } else { header("HTTP/1.0 404 Not Found", true); } die; }
public function getFeatureContent($feature, GadgetContext $context, $isGadgetContext) { if (empty($feature)) { return ''; } if (!isset($this->features[$feature])) { throw new GadgetException("Invalid feature: " . htmlentities($feature)); } $featureName = $feature; $feature = $this->features[$feature]; $filesContext = $isGadgetContext ? 'gadgetJs' : 'containerJs'; if (!isset($feature[$filesContext])) { // no javascript specified for this context return ''; } $ret = ''; if (Shindig_Config::get('compress_javascript')) { $featureCache = Cache::createCache(Shindig_Config::get('feature_cache'), 'FeatureCache'); if ($featureContent = $featureCache->get(md5('features:' . $featureName . $isGadgetContext))) { return $featureContent; } } foreach ($feature[$filesContext] as $entry) { switch ($entry['type']) { case 'URL': $request = new RemoteContentRequest($entry['content']); $request->getOptions()->ignoreCache = $context->getIgnoreCache(); $context->getHttpFetcher()->fetch($request); if ($request->getHttpCode() == '200') { $ret .= $request->getResponseContent() . "\n"; } break; case 'FILE': $file = $feature['basePath'] . '/' . $entry['content']; $ret .= file_get_contents($file) . "\n"; break; case 'INLINE': $ret .= $entry['content'] . "\n"; break; } } if (Shindig_Config::get('compress_javascript')) { $ret = JsMin::minify($ret); $featureCache->set(md5('features:' . $featureName . $isGadgetContext), $ret); } return $ret; }
/** * Does the actual rewrite option scanning and performs the dom parsing * * @param string $content * @param Gadget $gadget */ public function rewrite($content, Shindig_Gadget &$gadget, $checkDocument = false) { // Check to see if the gadget requested rewriting, or if rewriting is forced in the configuration if (is_array($gadget->gadgetSpec->rewrite) || Shindig_Config::get('rewrite_by_default')) { require_once "src/gadgets/rewrite/ContentRewriter.php"; $contentRewriter = new ContentRewriter($this->context, $gadget); $contentRewriter->register($this); } // Are we configured to sanitize certain views? (if so the config should be an array of view names to sanitize, iaw: array('profile', 'home')) if (is_array(Shindig_Config::get('sanitize_views'))) { require_once "src/gadgets/rewrite/SanitizeRewriter.php"; $sanitizeRewriter = new SanitizeRewriter($this->context, $gadget); $sanitizeRewriter->register($this); } // no observers registered, return the original content, otherwise parse the DOM tree and call the observers if (!count($this->domObservers)) { return $content; } else { libxml_use_internal_errors(true); $this->doc = new DOMDocument(null, 'utf-8'); $this->doc->preserveWhiteSpace = true; $this->doc->formatOutput = false; $this->doc->strictErrorChecking = false; $this->doc->recover = false; $this->doc->resolveExternals = false; if (!$this->doc->loadHtml($content)) { //TODO parse and output libxml_get_errors(); libxml_clear_errors(); // parsing failed, return the unmodified content return $content; } if ($checkDocument) { $this->checkDocument(); } // find and parse all nodes in the dom document $rootNodes = $this->doc->getElementsByTagName('*'); $this->parseNodes($rootNodes); // DomDocument tries to make the document a valid html document, so added the html/body/head elements to it.. so lets strip them off before returning the content $html = $this->doc->saveHTML(); // If the gadget specified the caja feature, cajole it if (in_array('caja', $gadget->features)) { //TODO : use the caja daemon to cajole the content (experimental patch is available and will be added soon) } return $html; } }
public function __construct($name) { $this->prefix = $name; if (!self::$memcache) { self::$memcache = new Memcache(); $host = Shindig_Config::get('cache_host'); $port = Shindig_Config::get('cache_port'); if (Shindig_Config::get('cache_memcache_pconnect')) { if (!@self::$memcache->pconnect($host, $port)) { throw new CacheException("Couldn't connect to memcache server"); } } else { if (!@self::$memcache->connect($host, $port)) { throw new CacheException("Couldn't connect to memcache server"); } } } }
public function set($key, $value, $ttl = false) { if (!$ttl) { $ttl = Shindig_Config::Get('cache_time'); } if ($this->storage->isLocked($key)) { $this->storage->waitForLock($key); } $data = serialize(array('time' => $this->time->getRequestTime(), 'ttl' => $ttl, 'valid' => true, 'data' => $value)); $this->storage->lock($key); try { $this->storage->store($key, $data); $this->storage->unlock($key); } catch (Exception $e) { $this->storage->unlock($key); throw $e; } }