You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by li...@apache.org on 2008/03/05 20:43:20 UTC
svn commit: r633998 [2/2] - in /incubator/shindig/trunk: config/ php/
php/gadgets/ php/gadgets/src/ php/gadgets/src/http/ php/js/
Added: incubator/shindig/trunk/php/gadgets/src/JsLibraryFeatureFactory.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/JsLibraryFeatureFactory.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/JsLibraryFeatureFactory.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/JsLibraryFeatureFactory.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,73 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class JsLibraryFeatureFactory extends GadgetFeatureFactory {
+ private $JsLibraryFeature;
+
+ public function __construct($gadgetLibraries, $containerLibraries)
+ {
+ // since we don't do strict type checking, this is one constructor for both a class, or a array of classes
+ $this->JsLibraryFeature = new JsLibraryFeature($gadgetLibraries, $containerLibraries);
+ }
+
+ public function create()
+ {
+ return $this->JsLibraryFeature;
+ }
+
+ public function getLibraries($context)
+ {
+ return $context == 'GADGET' ? $this->JsLibraryFeature->gadgetLibraries : $this->JsLibraryFeature->containerLibraries;
+ }
+}
+
+class JsLibraryFeature extends GadgetFeature {
+ public $containerLibraries = array();
+ public $gadgetLibraries = array();
+
+ public function __construct($gadgetLibraries, $containerLibraries)
+ {
+ // we have a single constructor for both a single and multiple libraries, so handle it in code instead
+ if ($gadgetLibraries != null && is_array($gadgetLibraries)) {
+ $this->gadgetLibraries = array_merge($this->gadgetLibraries, $gadgetLibraries);
+ } elseif ($gadgetLibraries != null && $gadgetLibraries instanceof JsLibrary) {
+ $this->gadgetLibraries[] = $gadgetLibraries;
+ }
+ if ($containerLibraries != null && is_array($containerLibraries)) {
+ $this->containerLibraries = array_merge($this->containerLibraries, $containerLibraries);
+ } elseif ($containerLibraries != null && $containerLibraries instanceof JsLibrary) {
+ $this->containerLibraries[] = $containerLibraries;
+ }
+ }
+
+ public function prepare($gadget, $context, $params)
+ {
+ // do nothing
+ }
+
+ public function process($gadget, $context, $params)
+ {
+ $libraries = array();
+ $libraries = $context->getRenderingContext() == 'GADGET' ? $this->gadgetLibraries : $this->containerLibraries;
+ foreach ($libraries as $library) {
+ $gadget->addJsLibrary($library);
+ }
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/MessageBundle.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/MessageBundle.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/MessageBundle.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/MessageBundle.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,33 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class MessageBundle {
+ private $messages;
+
+ public function __construct($messages = array())
+ {
+ $this->messages = $messages;
+ }
+
+ public function getMessages()
+ {
+ return $this->messages;
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/MessageBundleParser.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/MessageBundleParser.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/MessageBundleParser.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/MessageBundleParser.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,39 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class MessageBundleParser {
+ private function processMessage(&$messages, $msg)
+ {
+ $attr = $msg->attributes();
+ if (isset($attr['name'])) {
+ $messages[trim($attr['name'])] = trim($msg);
+ }
+ }
+
+ public function parse($xml)
+ {
+ $doc = simplexml_load_string($xml);
+ $messages = array();
+ foreach ($doc->msg as $msg) {
+ $this->processMessage($messages, $msg);
+ }
+ return new MessageBundle($messages);
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/MessageBundleSubstituter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/MessageBundleSubstituter.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/MessageBundleSubstituter.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/MessageBundleSubstituter.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,100 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class MessageBundleSubstituter extends GadgetFeatureFactory {
+ public function create()
+ {
+ return new MessageBundleSubstituterFeature();
+ }
+}
+
+class MessageBundleSubstituterFeature extends GadgetFeature {
+ private $parser;
+ private $bundle = null;
+
+ public function __construct()
+ {
+ $this->parser = new MessageBundleParser();
+ }
+
+ private function getLocaleSpec($spec, $locale)
+ {
+ $localeSpecs = $spec->getLocaleSpecs();
+ foreach ( $localeSpecs as $locSpec ) {
+ //fix me
+ if ($locSpec->getLocale()->equals($locale)) {
+ return $locSpec;
+ }
+ }
+ return null;
+ }
+
+ public function prepare($gadget, $context, $params)
+ {
+ $locale = $context->getLocale();
+ // en-US
+ $localeData = $this->getLocaleSpec($gadget, $locale);
+ if ($localeData == null) {
+ // en-all
+ $localeData = $this->getLocaleSpec($gadget, new Locale($locale->getLanguage(), "all"));
+ }
+ if ($localeData == null) {
+ // all-all
+ $localeData = $this->getLocaleSpec($gadget, new Locale("all", "all"));
+ }
+ if ($localeData != null) {
+ $uri = $localeData->getURI();
+ if ($uri != null) {
+ // We definitely need a bundle, now we need to fetch it.
+ // Doing it a little different then the java version since our fetcher and cache are intergrated
+ $fetcher = $context->getHttpFetcher();
+ list($response) = $fetcher->fetch(new remoteContentRequest($uri), $context->getOptions());
+ //TODO caching the parsed bundle instead of just the xml data would be a lot more efficient and speedy
+ $this->bundle = $this->parser->parse($response->getResponseContent());
+ }
+ }
+ }
+
+ public function process($gadget, $context, $params)
+ {
+ $js = '';
+ $moduleId = $gadget->getId()->getModuleId();
+ $locale = $context->getLocale();
+ $setLangFmt = "gadgets.prefs_.setLanguage(%d, \"%s\");";
+ $setCountryFmt = "gadgets.prefs_.setCountry(%d, \"%s\");";
+ $js .= sprintf($setLangFmt, $moduleId, $locale->getLanguage());
+ $js .= sprintf($setCountryFmt, $moduleId, $locale->getCountry());
+ if ($this->bundle != null) {
+ $gadget->setCurrentMessageBundle($this->bundle);
+ $gadget->getSubstitutions()->addSubstitutions('MSG', $this->bundle->getMessages());
+ $rc = $context->getRenderingContext();
+ if ($rc == 'GADGET') {
+ $msgs = $this->bundle->getMessages();
+ $json = array();
+ foreach ( $msgs as $key => $value ) {
+ $json[$key] = $value;
+ }
+ $setMsgFmt = "gadgets.prefs_.setMsg(%d, %s);";
+ $js .= sprintf($setMsgFmt, $moduleId, json_encode($json));
+ }
+ }
+ $gadget->addJsLibrary(JsLibrary::create('INLINE', $js));
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/ModuleSubstituter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/ModuleSubstituter.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/ModuleSubstituter.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/ModuleSubstituter.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,50 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class ModuleSubstituter extends GadgetFeatureFactory {
+ private $feature;
+ public function __construct()
+ {
+ $this->feature = new ModuleSubstituterFeature();
+ }
+ public function create()
+ {
+ return $this->feature;
+ }
+}
+
+class ModuleSubstituterFeature extends GadgetFeature {
+
+ public function prepare($gadget, $context, $params)
+ {
+ //TODO Auto-generated method stub
+ }
+
+ public function process($gadget, $context, $params)
+ {
+ $gadget->getSubstitutions()->addSubstitution('MODULE', "ID", $gadget->getId()->getModuleId());
+ if ($context->getRenderingContext() == 'GADGET') {
+ $format = "gadgets.prefs_.setDefaultModuleId(%d);";
+ $fmtStr = sprintf($format, $gadget->getId()->getModuleId());
+ $gadget->addJsLibrary(JsLibrary::create('INLINE', $fmtStr));
+ }
+ }
+}
+
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/ProcessingOptions.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/ProcessingOptions.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/ProcessingOptions.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/ProcessingOptions.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,34 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class ProcessingOptions {
+ public $ignoreCache = false;
+ public $focedJsLibs = null;
+
+ public function getIgnoreCache()
+ {
+ return $this->ignoreCache;
+ }
+
+ public function getForcedJsLibs()
+ {
+ return $this->focedJsLibs;
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/RemoteContent.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/RemoteContent.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/RemoteContent.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/RemoteContent.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,31 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+/*
+ * remoteContent* classes, we departed from the shindig java base style a bit here
+ * We want to use curl_multi for our content fetching because we don't have any fancy
+ * worker queue's where the java variant does.
+ * So a different methodlogy which calls for a different working unfortunatly, however
+ * it's kept in the spirit of the java variant as much as possible
+ */
+
+abstract class RemoteContent {
+ abstract public function fetch($requests, $options);
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/RemoteContentException.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/RemoteContentException.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/RemoteContentException.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/RemoteContentException.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,22 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class RemoteContentException extends Exception {
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/RemoteContentFetcher.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/RemoteContentFetcher.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/RemoteContentFetcher.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/RemoteContentFetcher.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,26 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+abstract class RemoteContentFetcher {
+ abstract public function addRequests($requests);
+ abstract public function addRequest(remoteContentRequest $request);
+ abstract public function fetchRequests();
+ abstract public function pendingRequests();
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/RemoteContentRequest.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/RemoteContentRequest.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/RemoteContentRequest.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/RemoteContentRequest.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,138 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class RemoteContentRequest {
+ // these are used for making the request
+ private $url = '';
+ private $headers = false;
+ private $postBody = false;
+ // these fields are filled in once the request has completed
+ private $responseContent = false;
+ private $responseSize = false;
+ private $responseHeaders = false;
+ private $httpCode = false;
+ private $contentType = null;
+ public $handle = false;
+
+ public function __construct($url, $headers = false, $postBody = false)
+ {
+ $this->url = $url;
+ $this->headers = $headers;
+ $this->postBody = $postBody;
+ }
+
+ // returns a hash code which identifies this request, used for caching
+ // takes url, headers and postbody into account for constructing the md5 checksum
+ public function toHash()
+ {
+ return md5($this->url . $this->headers . $this->postBody);
+ }
+
+ public function getContentType()
+ {
+ return $this->contentType;
+ }
+
+ public function getHttpCode()
+ {
+ return $this->httpCode;
+ }
+
+ public function getResponseContent()
+ {
+ return $this->responseContent;
+ }
+
+ public function getResponseHeaders()
+ {
+ return $this->responseHeaders;
+ }
+
+ public function getResponseSize()
+ {
+ return $this->responseSize;
+ }
+
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ public function isPost()
+ {
+ return ! empty($this->postBody);
+ }
+
+ public function hasHeaders()
+ {
+ return ! empty($this->headers);
+ }
+
+ public function getPostBody()
+ {
+ return $this->postBody;
+ }
+
+ public function getUrl()
+ {
+ return $this->url;
+ }
+
+ public function setContentType($type)
+ {
+ $this->contentType;
+ }
+
+ public function setHttpCode($code)
+ {
+ $this->httpCode = intval($code);
+ }
+
+ public function setResponseContent($content)
+ {
+ $this->responseContent = $content;
+ }
+
+ public function setResponseHeaders($headers)
+ {
+ $this->responseHeaders = $headers;
+ }
+
+ public function setResponseSize($size)
+ {
+ $this->responseSize = intval($size);
+ }
+
+ public function setHeaders($headers)
+ {
+ $this->headers = $headers;
+ }
+
+ public function setPostBody($postBody)
+ {
+ $this->postBody = $postBody;
+ }
+
+ public function setUrl($url)
+ {
+ $this->url = $url;
+ }
+
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/SpecParserException.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/SpecParserException.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/SpecParserException.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/SpecParserException.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,22 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class SpecParserException extends Exception {
+}
Added: incubator/shindig/trunk/php/gadgets/src/Substitutions.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/Substitutions.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/Substitutions.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/Substitutions.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,78 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class Substitutions {
+ private $types = array(
+ 'MESSAGE' => 'MSG',
+ 'BIDI' => 'BIDI',
+ 'USER_PREF' => 'UP',
+ 'MODULE' => 'MODULE'
+ );
+
+ private $substitutions = array();
+
+ public function __construct()
+ {
+ foreach ($this->types as $key => $type) {
+ $this->substitutions[$type] = array();
+ }
+ }
+
+ public function addSubstitution($type, $key, $value)
+ {
+ $this->substitutions[$type][$key] = $value;
+ }
+
+ public function addSubstitutions($type, $array)
+ {
+ foreach ($array as $key => $value) {
+ $this->addSubstitution($type, $key, $value);
+ }
+ }
+
+ public function substitute($input)
+ {
+ foreach ($this->types as $key => $type) {
+ $input = $this->substituteType($type, $input);
+ }
+ return $input;
+ }
+
+ public function substituteType($type, $input)
+ {
+ $prefix = "__{$type}_";
+ if (empty($input) || (count($this->substitutions[$type]) == 0) || (strpos($input, $prefix) === false)) {
+ return $input;
+ }
+ while (($start = strpos($input, $prefix) + strlen($prefix)) !== false) {
+ $end = strpos($input, '__', $start);
+ if ($end !== false) {
+ $name = substr($input, $start, $end - $start);
+ if (isset($this->substitutions[$type][$name])) {
+ $replacement = $this->substitutions[$type][$name];
+ $input = str_replace("{$prefix}{$name}__", $replacement, $input);
+ }
+ } else {
+ break;
+ }
+ }
+ return $input;
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/UserPrefSubstituter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/UserPrefSubstituter.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/UserPrefSubstituter.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/UserPrefSubstituter.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,67 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class UserPrefSubstituter extends GadgetFeatureFactory {
+ private $feature;
+ public function __construct()
+ {
+ $this->feature = new UserPrefSubstituterFeature();
+ }
+
+ public function create()
+ {
+ return $this->feature;
+ }
+}
+
+class UserPrefSubstituterFeature extends GadgetFeature {
+
+ public function prepare($gadget, $context, $params)
+ {
+ }
+
+ public function process($gadget, $context, $params)
+ {
+ $substitutions = $gadget->getSubstitutions();
+ $upValues = $gadget->getUserPrefValues();
+ $json = array();
+ foreach ( $gadget->getUserPrefs() as $pref ) {
+ $name = $pref->getName();
+ $value = $upValues->getPref($name);
+ if ($value == null) {
+ $value = $pref->getDefaultValue();
+ }
+ if ($value == null) {
+ $value = "";
+ }
+ $substitutions->addSubstitution('USER_PREF', $name, $value);
+
+ if ($context->getRenderingContext() == 'GADGET') {
+ $json[$name] = $value;
+ }
+ }
+ if (count($json)) {
+ $setPrefFmt = "gadgets.prefs_.setPref(%d, %s);";
+ $moduleId = $gadget->getId()->getModuleId();
+ $setPrefStr = sprintf($setPrefFmt, $moduleId, json_encode($json));
+ $gadget->addJsLibrary(JsLibrary::create('INLINE', $setPrefStr));
+ }
+ }
+}
Added: incubator/shindig/trunk/php/gadgets/src/UserPrefs.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/UserPrefs.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/UserPrefs.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/UserPrefs.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,38 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class UserPrefs {
+ private $prefs = array();
+
+ public function __construct($prefs)
+ {
+ $this->prefs = $prefs;
+ }
+
+ public function getPrefs()
+ {
+ return $this->prefs;
+ }
+
+ public function getPref($name)
+ {
+ return isset($this->prefs[$name]) ? $this->prefs[$name] : null;
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/FilesServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,43 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class FilesServlet extends HttpServlet {
+
+ public function doGet()
+ {
+ global $config;
+ $file = str_replace($config['web_prefix'] . '/files/', '', $_SERVER["REQUEST_URI"]);
+ $file = $config['javascript_path'] . $file;
+ // make sure that the real path name is actually in the javascript_path, so people can't abuse this to read
+ // your private data from disk .. otherwise this would be a huge privacy and security issue
+ if (substr(realpath($file), 0, strlen(realpath($config['javascript_path']))) != realpath($config['javascript_path'])) {
+ header("HTTP/1.0 400 Bad Request", true);
+ echo "<html><body><h1>400 - Bad Request</h1></body></html>";
+ die();
+ }
+ // if the file doesn't exist or can't be read, give a 404 error
+ if (!file_exists($file) || !is_readable($file) || !is_file($file)) {
+ header("HTTP/1.0 404 Not Found", true);
+ echo "<html><body><h1>404 - Not Found</h1></body></html>";
+ die();
+ }
+ readfile($file);
+ }
+}
Added: incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/GadgetRenderingServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,260 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+include_once ('src/UserPrefs.php');
+include_once ('src/Gadget.php');
+include_once ('src/GadgetException.php');
+include_once ('src/GadgetServer.php');
+include_once ('src/GadgetSpecParser.php');
+include_once ('src/GadgetFeatureRegistry.php');
+include_once ('src/HttpProcessingOptions.php');
+include_once ("src/{$config['remote_content']}.php");
+
+class GadgetRenderingServlet extends HttpServlet {
+
+ public function doGet()
+ {
+ global $config;
+ try {
+ if (empty($_GET['url'])) {
+ throw new GadgetException("Missing required parameter: url");
+ }
+ $url = trim($_GET['url']);
+ $moduleId = isset($_GET['mid']) && is_numeric($_GET['mid']) ? intval($_GET['mid']) : 0;
+ $options = new HttpProcessingOptions();
+ $httpFetcher = new $config['remote_content']();
+ $view = ! empty($_GET['view']) ? $_GET['view'] : DEFAULT_VIEW;
+ $gadgetId = new GadgetId($url, $moduleId);
+ $prefs = $this->getPrefsFromRequest();
+ $locale = $this->getLocaleFromRequest();
+ $registry = new GadgetFeatureRegistry($config['features_path']);
+ // skipping the contentFilters bit, since there's no way to include caja yet
+ // hopefully a rpc service or command line version will be available at some point
+ $gadgetServer = new GadgetServer();
+ $gadget = $gadgetServer->processGadget($gadgetId, $prefs, $locale, 'GADGET', $options, $httpFetcher, $registry);
+ $this->outputGadget($gadget, $view, $options);
+ } catch ( Exception $e ) {
+ $this->outputError($e);
+ }
+ }
+ private function outputError($e)
+ {
+ global $config;
+ header("HTTP/1.0 400 Bad Request", true, 400);
+ echo "<html><body>";
+ echo "<h1>Error</h1>";
+ echo $e->getMessage();
+ if ($config['debug']) {
+ echo "<p><b>Debug info:</b></p><div style='overflow:auto; height:300px; border:1px solid #000000'><pre>";
+ print_r(debug_backtrace());
+ echo "</pre></div>>";
+ }
+ echo "</body></html>";
+ }
+
+ private function outputGadget($gadget, $view, $options)
+ {
+ switch ( $gadget->getContentType()) {
+ case 'HTML' :
+ $this->outputHtmlGadget($gadget, $view, $options);
+ break;
+ case 'URL' :
+ $this->outputUrlGadget($gadget, $options);
+ break;
+ }
+ }
+
+ private function outputHtmlGadget($gadget, $view, $options)
+ {
+ global $config;
+ $this->setContentType("text/html; charset=UTF-8");
+ $output = '';
+ $output .= "<html><head>";
+ // TODO: This is so wrong. (todo copied from java shindig, but i would agree with it :))
+ $output .= "<style type=\"text/css\">body,td,div,span,p{font-family:arial,sans-serif;} a {color:#0000cc;}a:visited {color:#551a8b;}a:active {color:#ff0000;}body{margin: 0px;padding: 0px;background-color:white;}</style>";
+ $output .= "</head><body>";
+ $externJs = "";
+ $inlineJs = "";
+ $externFmt = "<script src=\"%s\"></script>";
+ $forcedLibs = $options->getForcedJsLibs();
+ foreach ( $gadget->getJsLibraries() as $library ) {
+ $type = $library->getType();
+ if ($type == 'URL') {
+ // TODO: This case needs to be handled more gracefully by the js
+ // servlet. We should probably inline external JS as well.
+ $externJs .= sprintf($externFmt, $library->getContent());
+ } else if ($type == 'INLINE') {
+ $inlineJs .= $library->getContent() . "\n";
+ } else {
+ // FILE or RESOURCE
+ if ($forcedLibs == null) {
+ $inlineJs .= $library->getContent() . "\n";
+ }
+ // otherwise it was already included by options.forceJsLibs.
+ }
+ }
+ // Forced libs first.
+ //FIXME this doesnt make any sense to me yet, should make it actually do something :-)
+ if (! empty($forcedLibs)) {
+ $libs = explode(':', $forcedLibs);
+ $output .= sprintf($externFmt, $this->getJsUrl($libs));
+ }
+ if (strlen($inlineJs) > 0) {
+ $output .= "<script><!--\n" . $inlineJs . "\n-->\n</script>";
+ }
+ if (strlen($externJs) > 0) {
+ $output .= $externJs;
+ }
+ //FIXME quick hack to make it work with the new syndicator.js config, needs a propper implimentation later
+ if (!file_exists($config['syndicator_config']) || !is_readable($config['syndicator_config'])) {
+ throw new GadgetException("Invalid syndicator config");
+ }
+ // remove both /* */ and // style comments, they crash the json_decode function
+ $contents = preg_replace('/\/\/.*$/m','',preg_replace('@/\\*(?:.|[\\n\\r])*?\\*/@', '', file_get_contents($config['syndicator_config'])));
+ $syndData = json_decode($contents, true);
+ $output .= '<script>gadgets.config.init('.json_encode($syndData['gadgets.features']).');</script>';
+ $gadgetExceptions = array();
+ $content = $gadget->getContentData($view);
+ if (empty($content)) {
+ // unknown view
+ $gadgetExceptions[] = "View: '" . $view . "' invalid for gadget: " . $gadget->getId()->getKey();
+ }
+ if (count($gadgetExceptions)) {
+ throw new GadgetException(print_r($gadgetExceptions, true));
+ }
+ $output .= $content . "\n";
+ $output .= "<script>gadgets.util.runOnLoadHandlers();</script>";
+ $output .= "</body></html>";
+ echo $output;
+ }
+
+ private function outputUrlGadget($gadget, $options)
+ {
+ // Preserve existing query string parameters.
+ $redirURI = $gadget->getContentHref();
+ $queryStr = strpos($redirURI, '?') !== false ? substr($redirURI, strpos($redirURI, '?')) : '';
+ $query = $queryStr;
+ // TODO: userprefs on the fragment rather than query string
+ $query .= $this->getPrefsQueryString($gadget->getUserPrefValues());
+ $libs = array();
+ $forcedLibs = $options->getForcedJsLibs();
+ if ($forcedLibs == null) {
+ $reqs = $gadget->getRequires();
+ foreach ( $reqs as $key => $val ) {
+ $libs[] = $key;
+ }
+ } else {
+ $libs = explode(':', $forcedLibs);
+ }
+ $query .= $this->appendLibsToQuery($libs);
+ // code bugs out with me because of the invalid url syntax since we dont have a URI class to fix it for us
+ // this works around that
+ if (substr($query, 0, 1) == '&') {
+ $query = '?' . substr($query, 1);
+ }
+ $redirURI .= $query;
+ header('Location: ' . $redirURI);
+ die();
+ }
+
+ private function appendLibsToQuery($libs)
+ {
+ $ret = "&";
+ $ret .= LIBS_PARAM_NAME;
+ $ret .= "=";
+ $ret .= $this->getJsUrl($libs);
+ return $ret;
+ }
+
+ private function getPrefsQueryString($prefVals)
+ {
+ global $config;
+ $ret = '';
+ foreach ( $prefVals->getPrefs() as $key => $val ) {
+ $ret .= '&';
+ $ret .= $config['userpref_param_prefix'];
+ $ret .= urlencode($key);
+ $ret .= '=';
+ $ret .= urlencode($val);
+ }
+ return $ret;
+ }
+
+ private function getJsUrl($libs)
+ {
+ $buf = '';
+ if (! is_array($libs) || ! count($libs)) {
+ $buf = 'core';
+ } else {
+ $firstDone = false;
+ foreach ( $libs as $lib ) {
+ if ($firstDone) {
+ $buf .= ':';
+ } else {
+ $firstDone = true;
+ }
+ $buf .= $lib;
+ }
+ }
+ //FIXME add sha1 / md5 checksum of all js content as unique key as 'version'
+ $buf .= ".js?v=";
+ return $buf;
+ }
+
+ // since we don't have a java style request.locale. we create our own
+ // this parses formats like 'en', 'en-us', 'en-us;en-gb' etc
+ //TODO should really verify that this really works with all locale strings and that it doesn't trip over priority weight fields
+ private function getLocaleFromRequest()
+ {
+ $language = 'all';
+ $country = 'all';
+ if (! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ $acceptLanguage = explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
+ $acceptLanguage = $acceptLanguage[0];
+ if (strpos($acceptLanguage, '-') !== false) {
+ $lang = explode('-', $acceptLanguage);
+ $language = $lang[0];
+ $country = $lang[1];
+ if (strpos($country, ',') !== false) {
+ $country = explode(',', $country);
+ $country = $country[0];
+ }
+ } else {
+ $language = $acceptLanguage;
+ }
+
+ }
+ return new Locale($language, $country);
+ }
+
+ private function getPrefsFromRequest()
+ {
+ global $config;
+ $prefs = array();
+ foreach ( $_GET as $key => $val ) {
+ if (substr($key, 0, strlen($config['userpref_param_prefix'])) == $config['userpref_param_prefix']) {
+ $name = substr($key, strlen($config['userpref_param_prefix']));
+ $prefs[$name] = $val;
+ }
+ }
+ return new UserPrefs($prefs);
+ }
+
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/HttpServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,112 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+/*
+ * This is a somewhat liberal interpretation of the HttpServlet class
+ * Mixed with some essentials to make propper http header handling
+ * happen in php.
+ */
+
+class ServletException extends Exception {
+}
+
+class HttpServlet {
+ private $lastModified = false;
+ private $contentType = 'text/html';
+ private $charset = 'UTF-8';
+
+ public function __construct()
+ {
+ // to do our header magic, we need output buffering on
+ ob_start();
+ }
+
+ public function __destruct()
+ {
+ die();
+ // attempt at some propper header handling from php
+ // this departs a little from the shindig code but it should give is valid http protocol handling
+ header("Content-Type: $this->contentType; charset={$this->charset}");
+ header('Connection: Keep-Alive');
+ header('Keep-Alive: timeout=15, max=30');
+ header('Accept-Ranges: bytes');
+ header('Content-Length: ' . ob_get_length());
+ header('Cache-Control: public,max-age=' . CACHE_TIME . ',must-revalidate');
+ header("Expires: " . gmdate("D, d M Y H:i:s", time() + CACHE_TIME) . " GMT");
+ $content = ob_get_clean();
+ // Obey browsers (or proxy's) request to send a fresh copy if we recieve a no-cache pragma or cache-control request
+ if (! isset($_SERVER['HTTP_PRAGMA']) || ! strstr(strtolower($_SERVER['HTTP_PRAGMA']), 'no-cache') && (! isset($_SERVER['HTTP_CACHE_CONTROL']) || ! strstr(strtolower($_SERVER['HTTP_CACHE_CONTROL']), 'no-cache'))) {
+ // If the browser send us a E-TAG check if it matches (sha1 sum of content), if so send a not modified header instead of content
+ $etag = md5($content);
+ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
+ header("ETag: \"$etag\"");
+ if ($this->lastModified) {
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->lastModified));
+ }
+ header("HTTP/1.1 304 Not Modified");
+ header('Content-Length: 0');
+ die();
+ }
+ header("ETag: \"$etag\"");
+ // If no etag is present, then check if maybe this browser supports if_modified_since tags,
+ // check it against our lastModified (if it's set)
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $this->lastModified && ! isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
+ $if_modified_since = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ if ($this->lastModified <= $if_modified_since) {
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->lastModified));
+ header("HTTP/1.1 304 Not Modified");
+ header('Content-Length: 0');
+ die();
+ }
+ }
+ if ($this->lastModified) {
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->lastModified));
+ }
+ }
+ echo $content;
+ }
+
+ public function setContentType($type)
+ {
+ $this->contentType = $type;
+ }
+
+ public function getContentType()
+ {
+ return $this->contentType;
+ }
+
+ public function getLastModified()
+ {
+ return $this->lastModified;
+ }
+
+ public function setLastModified($modified)
+ {
+ $this->lastModified = max($this->lastModified, $modified);
+ }
+
+ public function error($msg)
+ {
+ @ob_end_clean();
+ header("HTTP/1.0 400 Bad Request", true);
+ echo "<html><body><h1>400 - $msg</h1></body></html>";
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/JsServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,102 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class JsServlet extends HttpServlet {
+
+ public function doGet()
+ {
+ global $config;
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
+ header("HTTP/1.1 304 Not Modified");
+ header('Content-Length: 0');
+ 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();
+ $registry = new GadgetFeatureRegistry($config['features_path']);
+ if ($registry->getIncludedFeatures($needed, $found, $missing)) {
+ $containerParam = isset($_GET["c"]) ? $_GET["c"] : '';
+ $context = $containerParam == '1' ? 'CONTAINER' : 'GADGET';
+ $jsData = '';
+ $done = array();
+ do {
+ foreach ( $found as $entry ) {
+ if (! in_array($entry, $done)) {
+ $feat = $registry->getEntry($entry);
+ $feature = $feat->getFeature();
+ if ($feature instanceof JsLibraryFeatureFactory) {
+ $jsLib = $feature;
+ foreach ( $jsLib->getLibraries($context) as $lib ) {
+ if ($lib->getType() != 'URL') {
+ $jsData .= $lib->getContent();
+ }
+ }
+ }
+ $done[] = $entry;
+ }
+ }
+ } while ( count($done) != count($found) );
+ if (! strlen($jsData)) {
+ header("HTTP/1.0 404 Not Found", true);
+ die();
+ }
+ if (!isset($_GET['c']) || $_GET['c'] != 1) {
+ $contents = preg_replace('/\/\/.*$/m','',preg_replace('@/\\*(?:.|[\\n\\r])*?\\*/@', '', file_get_contents($config['syndicator_config'])));
+ $syndData = json_decode($contents, true);
+ $jsData .= "\ngadgets.config.init(".json_encode($syndData['gadgets.features']).");\n";
+ }
+ $this->setCachingHeaders();
+ header('Content-Length: ' . strlen($jsData));
+ echo $jsData;
+ //FIXME quick hack to make it work with the new syndicator.js config, needs a propper implimentation later
+ if (!file_exists($config['syndicator_config']) || !is_readable($config['syndicator_config'])) {
+ throw new GadgetException("Invalid syndicator config");
+ }
+ } else {
+ header("HTTP/1.0 404 Not Found", true);
+
+ }
+ die();
+ }
+
+ private function setCachingHeaders()
+ {
+ header("Expires: Tue, 01 Jan 2030 00:00:01 GMT");
+ // IE seems to need this (10 years should be enough).
+ header("Cache-Control: public,max-age=315360000");
+ // Firefox requires this for certain cases.
+ header("Last-Modified: " . gmdate('D, d M Y H:i:s', time()));
+ }
+}
Added: incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/ProxyHandler.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,152 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+include_once ("src/{$config['gadget_token']}.php");
+include_once ("src/{$config['gadget_signer']}.php");
+include_once ("src/HttpProcessingOptions.php");
+
+//TODO make sure this all works, especially the header passthru and post parts
+
+// according to features/core/io.js, this is high on the list of things to scrap
+define('UNPARSEABLE_CRUFT', "throw 1; < don't be evil' >");
+
+class ProxyHandler {
+ private $fetcher;
+
+ public function __construct($fetcher)
+ {
+ $this->fetcher = $fetcher;
+ }
+
+ public function fetchJson($signer, $method)
+ {
+ $token = $this->extractAndValidateToken($signer);
+ $url = $_GET['url'];
+ $originalUrl = $this->validateUrl($url);
+ $signedUrl = $this->signUrl($originalUrl, $token);
+ // Fetch the content and convert it into JSON.
+ // TODO: Fetcher needs to handle variety of HTTP methods.
+ $result = $this->fetchContent($signedUrl, new HttpProcessingOptions(), $method);
+ $status = (int)$result->getHttpCode();
+ header("HTTP/1.1 $status", true);
+ if ($status == 200) {
+ $output = '';
+ $json = array('body' => $result->getResponseContent(), 'rc' => $status, 'url' => $url);
+ $json = json_encode($json);
+ $output = UNPARSEABLE_CRUFT . $json;
+ $this->setCachingHeaders();
+ header("application/json; charset=utf-8");
+ header("Content-Disposition", "attachment;filename=p.txt");
+ echo $output;
+ }
+ }
+
+ public function fetch($signer, $method)
+ {
+ $token = $this->extractAndValidateToken($signer);
+ $originalUrl = $this->validateUrl($_GET['url']);
+ $signedUrl = $this->signUrl($originalUrl, $token);
+ //TODO: Fetcher needs to handle variety of HTTP methods.
+ $result = $this->fetchContent($signedUrl, new HttpProcessingOptions(), $method);
+ // TODO: Fetcher needs to handle variety of HTTP methods.
+ $status = (int)$result->getHttpCode();
+ header("HTTP/1.1 $status", true);
+ if ($status == 200) {
+ $headers = explode("\n", $result->getResponseHeaders());
+ foreach ( $headers as $header ) {
+ header($header);
+ }
+ $this->setCachingHeaders();
+ // then echo the content
+ echo $result->getResponseContent();
+ }
+ }
+
+ private function fetchContent($signedUrl, $procOptions, $method)
+ {
+ //TODO get actual character encoding from the request
+
+ // Extract the request headers from the $_SERVER super-global (this -does- unfortunatly mean that any header that php doesn't understand won't be proxied thru though)
+ // if this turns out to be a problem we could add support for HTTP_RAW_HEADERS, but this depends on a php.ini setting, so i'd rather prevent that from being required
+ $headers = '';
+ foreach ( $_SERVER as $key => $val ) {
+ if (substr($key, 0, strlen('HTTP_')) == 'HTTP_') {
+ // massage the header key to something a bit more propper (example 'HTTP_ACCEPT_LANGUAGE' becomes 'Accept-Language')
+ // TODO: We probably need to test variations as well.
+ $key = str_replace(' ', '_', ucwords(strtolower(str_replace('-', ' ', substr($key, strlen('HTTP_'))))));
+ if ($key != 'Keep_alive' && $key != 'Connection' && $key != 'Host' && $key != 'Accept' && $key != 'Accept-Encoding') {
+ // propper curl header format according to http://www.php.net/manual/en/function.curl-setopt.php#80099
+ $headers .= "$key: $val\n";
+ }
+ }
+ }
+ if ($method == 'POST') {
+ $postData = '';
+ $first = true;
+ foreach ( $_POST as $key => $val ) {
+ if (! $first) {
+ $postData .= '&';
+ } else {
+ $first = false;
+ }
+ // make sure all the keys and val's are propperly encoded
+ $postData .= urlencode(urldecode($key)) . '=' . urlencode(urldecode($val));
+ }
+ $request = new RemoteContentRequest($signedUrl, $headers, $postData);
+ list($request) = $this->fetcher->fetch($request, $procOptions);
+ } else {
+ $request = new RemoteContentRequest($signedUrl, $headers);
+ list($request) = $this->fetcher->fetch($request, $procOptions);
+ }
+ return $request;
+ }
+
+ private function setCachingHeaders()
+ {
+ // TODO: Re-implement caching behavior if appropriate.
+ header("Cache-Control", "private; max-age=0");
+ header("Expires", time() - 30);
+ }
+
+ private function validateUrl($url)
+ {
+ //TODO should really make a PHP version of the URI class and validate in all the locations the java version does
+ return $url;
+ }
+
+ private function extractAndValidateToken($signer)
+ {
+ if ($signer == null) {
+ return null;
+ }
+ $token = isset($_GET["st"]) ? $_GET["st"] : '';
+ return $signer->createToken($token);
+ }
+
+ private function signUrl($originalUrl, $token)
+ {
+ if ($token == null || (isset($_GET['authz']) && $_GET['authz'] != 'signed')) {
+ return $originalUrl;
+ }
+ $method = isset($_GET['httpMethod']) ? $_GET['httpMethod'] : 'GET';
+ return $token->signUrl($originalUrl, $method);
+ }
+
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/ProxyServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,47 @@
+<?/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+include_once ("src/{$config['remote_content']}.php");
+include_once ("src/{$config['gadget_signer']}.php");
+include_once ("src/http/ProxyHandler.php");
+
+class ProxyServlet extends HttpServlet {
+
+ public function doGet($method = 'GET')
+ {
+ global $config;
+ if (empty($_GET['url'])) {
+ header("HTTP/1.0 400 Bad Request", true);
+ echo "<html><body><h1>400 - Missing url parameter</h1></body></html>";
+ }
+ $gadgetSigner = new $config['gadget_signer']();
+ $httpFetcher = new $config['remote_content']();
+ $proxyHandler = new ProxyHandler($httpFetcher);
+ if (! empty($_GET['output']) && $_GET['output'] == 'js') {
+ $proxyHandler->fetchJson($gadgetSigner, $method);
+ } else {
+ $proxyHandler->fetch($gadgetSigner, $method);
+ }
+ }
+
+ public function doPost()
+ {
+ $this->doGet('POST');
+ }
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/gadgets/src/http/RpcServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/gadgets/src/http/RpcServlet.php?rev=633998&view=auto
==============================================================================
--- incubator/shindig/trunk/php/gadgets/src/http/RpcServlet.php (added)
+++ incubator/shindig/trunk/php/gadgets/src/http/RpcServlet.php Wed Mar 5 11:43:14 2008
@@ -0,0 +1,23 @@
+<?
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ */
+
+class RpcServlet extends HttpServlet {
+//TODO this class ;)
+}
\ No newline at end of file