CP_Ordermapmarker - Version 1.0.1

Version Notes

Stable Version

Download this release

Release Info

Developer Digisha
Extension CP_Ordermapmarker
Version 1.0.1
Comparing to
See all releases


Version 1.0.1

Files changed (43) hide show
  1. app/code/local/CP/Ordermapmarker/Block/Index.php +8 -0
  2. app/code/local/CP/Ordermapmarker/Helper/Data.php +65 -0
  3. app/code/local/CP/Ordermapmarker/Helper/Ordermapmarker.php +45 -0
  4. app/code/local/CP/Ordermapmarker/Model/Observer.php +26 -0
  5. app/code/local/CP/Ordermapmarker/controllers/IndexController.php +22 -0
  6. app/code/local/CP/Ordermapmarker/etc/adminhtml.xml +23 -0
  7. app/code/local/CP/Ordermapmarker/etc/config.xml +56 -0
  8. app/code/local/CP/Ordermapmarker/etc/system.xml +68 -0
  9. app/etc/modules/CP_Ordermapmarker.xml +10 -0
  10. lib/Googlefusiontables/Google_Client.php +471 -0
  11. lib/Googlefusiontables/Googleclient.php +471 -0
  12. lib/Googlefusiontables/auth/Google_AssertionCredentials.php +103 -0
  13. lib/Googlefusiontables/auth/Google_Auth.php +36 -0
  14. lib/Googlefusiontables/auth/Google_AuthNone.php +48 -0
  15. lib/Googlefusiontables/auth/Google_LoginTicket.php +63 -0
  16. lib/Googlefusiontables/auth/Google_OAuth2.php +453 -0
  17. lib/Googlefusiontables/auth/Google_P12Signer.php +70 -0
  18. lib/Googlefusiontables/auth/Google_PemVerifier.php +66 -0
  19. lib/Googlefusiontables/auth/Google_Signer.php +30 -0
  20. lib/Googlefusiontables/auth/Google_Verifier.php +31 -0
  21. lib/Googlefusiontables/cache/Google_ApcCache.php +98 -0
  22. lib/Googlefusiontables/cache/Google_Cache.php +55 -0
  23. lib/Googlefusiontables/cache/Google_FileCache.php +137 -0
  24. lib/Googlefusiontables/cache/Google_MemcacheCache.php +130 -0
  25. lib/Googlefusiontables/config.php +81 -0
  26. lib/Googlefusiontables/contrib/Google_FusiontablesService.php +1391 -0
  27. lib/Googlefusiontables/external/URITemplateParser.php +209 -0
  28. lib/Googlefusiontables/io/Google_CacheParser.php +173 -0
  29. lib/Googlefusiontables/io/Google_CurlIO.php +198 -0
  30. lib/Googlefusiontables/io/Google_HttpRequest.php +304 -0
  31. lib/Googlefusiontables/io/Google_HttpStreamIO.php +170 -0
  32. lib/Googlefusiontables/io/Google_IO.php +161 -0
  33. lib/Googlefusiontables/io/Google_REST.php +128 -0
  34. lib/Googlefusiontables/io/cacerts.pem +738 -0
  35. lib/Googlefusiontables/key/fusionmaps-681f7b1ccf74.p12 +0 -0
  36. lib/Googlefusiontables/key/fusionmaps-7915addd10af.p12 +0 -0
  37. lib/Googlefusiontables/service/Google_BatchRequest.php +110 -0
  38. lib/Googlefusiontables/service/Google_MediaFileUpload.php +262 -0
  39. lib/Googlefusiontables/service/Google_Model.php +115 -0
  40. lib/Googlefusiontables/service/Google_Service.php +22 -0
  41. lib/Googlefusiontables/service/Google_ServiceResource.php +205 -0
  42. lib/Googlefusiontables/service/Google_Utils.php +117 -0
  43. package.xml +18 -0
app/code/local/CP/Ordermapmarker/Block/Index.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class CP_Ordermapmarker_Block_Index extends Mage_Core_Block_Template{
3
+
4
+
5
+
6
+
7
+
8
+ }
app/code/local/CP/Ordermapmarker/Helper/Data.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class CP_Ordermapmarker_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ public function getOrderDataWithCoordinates($order)
5
+ {
6
+ $country = $order->getShippingAddress()->getCountry() == 'US' ? "United States" : $order->getShippingAddress()->getCountry();
7
+
8
+ $address = $order->getShippingAddress()->getStreet1(). " ". $order->getShippingAddress()->getStreet2()." ". $order->getShippingAddress()->getCity()." ".$order->getShippingAddress()->getRegion()." ".$order->getShippingAddress()->getPostcode() ." ". $country;
9
+
10
+ if($address)
11
+ {
12
+ if($result = $this->getCoordinatesFromAddress($address)){
13
+ $response = array('order_id' => $order->getIncrementId(),
14
+ 'order_address' => $address,
15
+ 'latitude' => $result['latitude'],
16
+ 'longitude' => $result['longitude'],
17
+ );
18
+ return $response;
19
+ }
20
+ return false;
21
+ }
22
+ return false;
23
+ }
24
+
25
+ public function getCoordinatesFromAddress($address)
26
+ {
27
+ $address = urlencode($address);
28
+ $url = $this->getgeoCodeApiUrl() . "&address=" . $address;
29
+ $response = file_get_contents($url);
30
+ $json = json_decode($response,true);
31
+
32
+ $lat = $json['results'][0]['geometry']['location']['lat'];
33
+ $lng = $json['results'][0]['geometry']['location']['lng'];
34
+
35
+ if($lat && $lng){
36
+ return array("latitude" => $lat,"longitude" => $lng);
37
+ }
38
+ return false;
39
+ }
40
+
41
+ public function getgeoCodeApiUrl()
42
+ {
43
+ return "http://maps.google.com/maps/api/geocode/json?sensor=false";
44
+ }
45
+
46
+ public function getApplicationName()
47
+ {
48
+ return Mage::getStoreConfig('ordermapmarker/config/googleapp', Mage::app()->getStore());
49
+ }
50
+
51
+ public function getTableId()
52
+ {
53
+ return Mage::getStoreConfig('ordermapmarker/config/fusiontable', Mage::app()->getStore());
54
+ }
55
+
56
+ public function getClientId()
57
+ {
58
+ return Mage::getStoreConfig('ordermapmarker/config/googleclient', Mage::app()->getStore());
59
+ }
60
+
61
+ public function getIsEnabled()
62
+ {
63
+ return Mage::getStoreConfig('ordermapmarker/config/status', Mage::app()->getStore());
64
+ }
65
+ }
app/code/local/CP/Ordermapmarker/Helper/Ordermapmarker.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/contrib/Google_FusiontablesService.php');
3
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/contrib/Google_Oauth2Service.php');
4
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/Google_Client.php');
5
+
6
+ class CP_Ordermapmarker_Helper_Ordermapmarker
7
+ {
8
+ private $helper;
9
+
10
+ public function __construct()
11
+ {
12
+ $this->helper = Mage::helper('ordermapmarker');
13
+ }
14
+ public function syncCoordinatesToFusionTable($location)
15
+ {
16
+ try{
17
+ $client = new Google_Client();
18
+ $client->setApplicationName($this->helper->getApplicationName());
19
+ session_start();
20
+ if (isset($_SESSION['token'])){
21
+ $client->setAccessToken($_SESSION['token']);
22
+ }
23
+
24
+ $tableid = $this->helper->getTableId();
25
+ $key = file_get_contents(Mage::getBaseDir('lib'). DS .'Googlefusiontables'. DS . 'key'. DS .'fusionmaps-7915addd10af.p12');
26
+
27
+ $client->setClientId($this->helper->getClientId());
28
+
29
+ $client->setAssertionCredentials(new Google_AssertionCredentials($this->helper->getClientId(), array('https://www.googleapis.com/auth/fusiontables'), $key,'notasecret','http://oauth.net/grant_type/jwt/1.0/bearer'));
30
+
31
+ $service = new Google_FusiontablesService($client);
32
+ $insert_statement = "Insert into $tableid (`order_id`,`order_address`,`latitude`,`longitude`) VALUES('".$location['order_id']."','".$location['order_address']."','".$location['latitude']."','".$location['longitude']."');";
33
+ $result = $service->query->sql($insert_statement);
34
+
35
+ if($result['columns'][0] && $result['rows'][0][0]){
36
+ return true;
37
+ }
38
+ return false;
39
+
40
+ }catch(Exception $e){
41
+ Mage::log($e->getMessage(), null, 'googleFusion.log');
42
+ return false;
43
+ }
44
+ }
45
+ }
app/code/local/CP/Ordermapmarker/Model/Observer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class CP_Ordermapmarker_Model_Observer
3
+ {
4
+ public function createOrderAddressPin(Varien_Event_Observer $observer)
5
+ {
6
+ $order = $observer->getOrder();
7
+
8
+ // Check if Google Map Maker is Available.
9
+ if(Mage::helper('ordermapmarker')->getIsEnabled()){
10
+
11
+ // Get an Array of Order with Id, Address and Location Coordinates.
12
+ $orderData = Mage::helper('ordermapmarker')->getOrderDataWithCoordinates($order);
13
+
14
+ // Insert the Order Array In Google-Fusion Table.
15
+ if($orderData){
16
+ $SyncProcessResult = Mage::helper('ordermapmarker/ordermapmarker')->syncCoordinatesToFusionTable($orderData);
17
+ if($SyncProcessResult){
18
+ Mage::log("Google Maps Sync Successful for Order: ".$order->getIncrementId(), null, 'googleFusion.log');
19
+ }else{
20
+ Mage::log("Google Maps Sync Failed for Order: ".$order->getIncrementId(), null, 'googleFusion.log');
21
+ }
22
+ }
23
+ return;
24
+ }
25
+ }
26
+ }
app/code/local/CP/Ordermapmarker/controllers/IndexController.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class CP_Ordermapmarker_IndexController extends Mage_Core_Controller_Front_Action{
3
+ public function IndexAction() {
4
+
5
+ $this->loadLayout();
6
+ $this->getLayout()->getBlock("head")->setTitle($this->__("Order Map"));
7
+ $breadcrumbs = $this->getLayout()->getBlock("breadcrumbs");
8
+ $breadcrumbs->addCrumb("home", array(
9
+ "label" => $this->__("Home Page"),
10
+ "title" => $this->__("Home Page"),
11
+ "link" => Mage::getBaseUrl()
12
+ ));
13
+
14
+ $breadcrumbs->addCrumb("order map", array(
15
+ "label" => $this->__("Order Map"),
16
+ "title" => $this->__("Order Map")
17
+ ));
18
+
19
+ $this->renderLayout();
20
+
21
+ }
22
+ }
app/code/local/CP/Ordermapmarker/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <ordermapmarker translate="title" module="ordermapmarker">
12
+ <title>Order Map Marker Section</title>
13
+ <sort_order>1</sort_order>
14
+ </ordermapmarker>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/local/CP/Ordermapmarker/etc/config.xml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <CP_Ordermapmarker>
5
+ <version>1.0.0</version>
6
+ </CP_Ordermapmarker>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <ordermapmarker>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>CP_Ordermapmarker</module>
14
+ <frontName>ordermapmarker</frontName>
15
+ </args>
16
+ </ordermapmarker>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <ordermapmarker>
21
+ <file>ordermapmarker.xml</file>
22
+ </ordermapmarker>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <global>
27
+ <helpers>
28
+ <ordermapmarker>
29
+ <class>CP_Ordermapmarker_Helper</class>
30
+ </ordermapmarker>
31
+ </helpers>
32
+ <blocks>
33
+ <ordermapmarker>
34
+ <class>CP_Ordermapmarker_Block</class>
35
+ </ordermapmarker>
36
+ </blocks>
37
+ <models>
38
+ <ordermapmarker>
39
+ <class>CP_Ordermapmarker_Model</class>
40
+ <resourceModel>ordermapmarker_mysql4</resourceModel>
41
+ </ordermapmarker>
42
+ </models>
43
+ <events>
44
+ <sales_order_place_after>
45
+ <observers>
46
+ <sales_order_place_after_handler>
47
+ <type>model</type>
48
+ <class>ordermapmarker/observer</class>
49
+ <method>createOrderAddressPin</method>
50
+ <args></args>
51
+ </sales_order_place_after_handler>
52
+ </observers>
53
+ </sales_order_place_after>
54
+ </events>
55
+ </global>
56
+ </config>
app/code/local/CP/Ordermapmarker/etc/system.xml ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <cp translate="label" module="ordermapmarker">
5
+ <label>cp Extensions</label>
6
+ <sort_order>150</sort_order>
7
+ </cp>
8
+ </tabs>
9
+ <sections>
10
+ <ordermapmarker translate="label" module="ordermapmarker">
11
+ <label>Order Map Marker</label>
12
+ <tab>cp</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>1</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <config translate="label">
20
+ <label>Configuration</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>1</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+ <fields>
27
+ <status translate="label">
28
+ <label>Enabled</label>
29
+ <frontend_type>select</frontend_type>
30
+ <source_model>adminhtml/system_config_source_yesno</source_model>
31
+ <sort_order>0</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </status>
36
+ <fusiontable translate="label">
37
+ <label>Google Fusiontable Id</label>
38
+ <frontend_type>text</frontend_type>
39
+ <sort_order>1</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ <comment>The synced Google Fusion Table</comment>
44
+ </fusiontable>
45
+ <googleapp translate="label">
46
+ <label>Google Application Name</label>
47
+ <frontend_type>text</frontend_type>
48
+ <sort_order>2</sort_order>
49
+ <show_in_default>1</show_in_default>
50
+ <show_in_website>1</show_in_website>
51
+ <show_in_store>1</show_in_store>
52
+ <comment>Google Application Name</comment>
53
+ </googleapp>
54
+ <googleclient translate="label">
55
+ <label>Google Client Id (Email)</label>
56
+ <frontend_type>text</frontend_type>
57
+ <sort_order>3</sort_order>
58
+ <show_in_default>1</show_in_default>
59
+ <show_in_website>1</show_in_website>
60
+ <show_in_store>1</show_in_store>
61
+ <comment>Google Application Client Id/Email</comment>
62
+ </googleclient>
63
+ </fields>
64
+ </config>
65
+ </groups>
66
+ </ordermapmarker>
67
+ </sections>
68
+ </config>
app/etc/modules/CP_Ordermapmarker.xml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <CP_Ordermapmarker>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ <version>1.0.0</version>
8
+ </CP_Ordermapmarker>
9
+ </modules>
10
+ </config>
lib/Googlefusiontables/Google_Client.php ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // Check for the json extension, the Google APIs PHP Client won't function
19
+ // without it.
20
+ if (! function_exists('json_decode')) {
21
+ throw new Exception('Google PHP API Client requires the JSON PHP extension');
22
+ }
23
+
24
+ if (! function_exists('http_build_query')) {
25
+ throw new Exception('Google PHP API Client requires http_build_query()');
26
+ }
27
+
28
+ if (! ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
29
+ date_default_timezone_set('UTC');
30
+ }
31
+
32
+ // hack around with the include paths a bit so the library 'just works'
33
+ set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
34
+
35
+ require_once "config.php";
36
+ // If a local configuration file is found, merge it's values with the default configuration
37
+ if (file_exists(dirname(__FILE__) . '/local_config.php')) {
38
+ $defaultConfig = $apiConfig;
39
+ require_once (dirname(__FILE__) . '/local_config.php');
40
+ $apiConfig = array_merge($defaultConfig, $apiConfig);
41
+ }
42
+
43
+ // Include the top level classes, they each include their own dependencies
44
+ require_once 'service/Google_Model.php';
45
+ require_once 'service/Google_Service.php';
46
+ require_once 'service/Google_ServiceResource.php';
47
+ require_once 'auth/Google_AssertionCredentials.php';
48
+ require_once 'auth/Google_Signer.php';
49
+ require_once 'auth/Google_P12Signer.php';
50
+ require_once 'service/Google_BatchRequest.php';
51
+ require_once 'external/URITemplateParser.php';
52
+ require_once 'auth/Google_Auth.php';
53
+ require_once 'cache/Google_Cache.php';
54
+ require_once 'io/Google_IO.php';
55
+ require_once('service/Google_MediaFileUpload.php');
56
+
57
+ /**
58
+ * The Google API Client
59
+ * http://code.google.com/p/google-api-php-client/
60
+ *
61
+ * @author Chris Chabot <chabotc@google.com>
62
+ * @author Chirag Shah <chirags@google.com>
63
+ */
64
+ class Google_Client {
65
+ /**
66
+ * @static
67
+ * @var Google_Auth $auth
68
+ */
69
+ static $auth;
70
+
71
+ /**
72
+ * @static
73
+ * @var Google_IO $io
74
+ */
75
+ static $io;
76
+
77
+ /**
78
+ * @static
79
+ * @var Google_Cache $cache
80
+ */
81
+ static $cache;
82
+
83
+ /**
84
+ * @static
85
+ * @var boolean $useBatch
86
+ */
87
+ static $useBatch = false;
88
+
89
+ /** @var array $scopes */
90
+ protected $scopes = array();
91
+
92
+ /** @var bool $useObjects */
93
+ protected $useObjects = false;
94
+
95
+ // definitions of services that are discovered.
96
+ protected $services = array();
97
+
98
+ // Used to track authenticated state, can't discover services after doing authenticate()
99
+ private $authenticated = false;
100
+
101
+ public function __construct($config = array()) {
102
+ global $apiConfig;
103
+ $apiConfig = array_merge($apiConfig, $config);
104
+ self::$cache = new $apiConfig['cacheClass']();
105
+ self::$auth = new $apiConfig['authClass']();
106
+ self::$io = new $apiConfig['ioClass']();
107
+ }
108
+
109
+ /**
110
+ * Add a service
111
+ */
112
+ public function addService($service, $version = false) {
113
+ global $apiConfig;
114
+ if ($this->authenticated) {
115
+ throw new Google_Exception('Cant add services after having authenticated');
116
+ }
117
+ $this->services[$service] = array();
118
+ if (isset($apiConfig['services'][$service])) {
119
+ // Merge the service descriptor with the default values
120
+ $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]);
121
+ }
122
+ }
123
+
124
+ public function authenticate($code = null) {
125
+ $service = $this->prepareService();
126
+ $this->authenticated = true;
127
+ return self::$auth->authenticate($service, $code);
128
+ }
129
+
130
+ /**
131
+ * @return array
132
+ * @visible For Testing
133
+ */
134
+ public function prepareService() {
135
+ $service = array();
136
+ $scopes = array();
137
+ if ($this->scopes) {
138
+ $scopes = $this->scopes;
139
+ } else {
140
+ foreach ($this->services as $key => $val) {
141
+ if (isset($val['scope'])) {
142
+ if (is_array($val['scope'])) {
143
+ $scopes = array_merge($val['scope'], $scopes);
144
+ } else {
145
+ $scopes[] = $val['scope'];
146
+ }
147
+ } else {
148
+ $scopes[] = 'https://www.googleapis.com/auth/' . $key;
149
+ }
150
+ unset($val['discoveryURI']);
151
+ unset($val['scope']);
152
+ $service = array_merge($service, $val);
153
+ }
154
+ }
155
+ $service['scope'] = implode(' ', $scopes);
156
+ return $service;
157
+ }
158
+
159
+ /**
160
+ * Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
161
+ * or Google_Client#getAccessToken().
162
+ * @param string $accessToken JSON encoded string containing in the following format:
163
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
164
+ * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
165
+ */
166
+ public function setAccessToken($accessToken) {
167
+ if ($accessToken == null || 'null' == $accessToken) {
168
+ $accessToken = null;
169
+ }
170
+ self::$auth->setAccessToken($accessToken);
171
+ }
172
+
173
+ /**
174
+ * Set the type of Auth class the client should use.
175
+ * @param string $authClassName
176
+ */
177
+ public function setAuthClass($authClassName) {
178
+ self::$auth = new $authClassName();
179
+ }
180
+
181
+ /**
182
+ * Construct the OAuth 2.0 authorization request URI.
183
+ * @return string
184
+ */
185
+ public function createAuthUrl() {
186
+ $service = $this->prepareService();
187
+ return self::$auth->createAuthUrl($service['scope']);
188
+ }
189
+
190
+ /**
191
+ * Get the OAuth 2.0 access token.
192
+ * @return string $accessToken JSON encoded string in the following format:
193
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
194
+ * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
195
+ */
196
+ public function getAccessToken() {
197
+ $token = self::$auth->getAccessToken();
198
+ return (null == $token || 'null' == $token) ? null : $token;
199
+ }
200
+
201
+ /**
202
+ * Returns if the access_token is expired.
203
+ * @return bool Returns True if the access_token is expired.
204
+ */
205
+ public function isAccessTokenExpired() {
206
+ return self::$auth->isAccessTokenExpired();
207
+ }
208
+
209
+ /**
210
+ * Set the developer key to use, these are obtained through the API Console.
211
+ * @see http://code.google.com/apis/console-help/#generatingdevkeys
212
+ * @param string $developerKey
213
+ */
214
+ public function setDeveloperKey($developerKey) {
215
+ self::$auth->setDeveloperKey($developerKey);
216
+ }
217
+
218
+ /**
219
+ * Set OAuth 2.0 "state" parameter to achieve per-request customization.
220
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
221
+ * @param string $state
222
+ */
223
+ public function setState($state) {
224
+ self::$auth->setState($state);
225
+ }
226
+
227
+ /**
228
+ * @param string $accessType Possible values for access_type include:
229
+ * {@code "offline"} to request offline access from the user. (This is the default value)
230
+ * {@code "online"} to request online access from the user.
231
+ */
232
+ public function setAccessType($accessType) {
233
+ self::$auth->setAccessType($accessType);
234
+ }
235
+
236
+ /**
237
+ * @param string $approvalPrompt Possible values for approval_prompt include:
238
+ * {@code "force"} to force the approval UI to appear. (This is the default value)
239
+ * {@code "auto"} to request auto-approval when possible.
240
+ */
241
+ public function setApprovalPrompt($approvalPrompt) {
242
+ self::$auth->setApprovalPrompt($approvalPrompt);
243
+ }
244
+
245
+ /**
246
+ * Set the application name, this is included in the User-Agent HTTP header.
247
+ * @param string $applicationName
248
+ */
249
+ public function setApplicationName($applicationName) {
250
+ global $apiConfig;
251
+ $apiConfig['application_name'] = $applicationName;
252
+ }
253
+
254
+ /**
255
+ * Set the OAuth 2.0 Client ID.
256
+ * @param string $clientId
257
+ */
258
+ public function setClientId($clientId) {
259
+ global $apiConfig;
260
+ $apiConfig['oauth2_client_id'] = $clientId;
261
+ self::$auth->clientId = $clientId;
262
+ }
263
+
264
+ /**
265
+ * Get the OAuth 2.0 Client ID.
266
+ */
267
+ public function getClientId() {
268
+ return self::$auth->clientId;
269
+ }
270
+
271
+ /**
272
+ * Set the OAuth 2.0 Client Secret.
273
+ * @param string $clientSecret
274
+ */
275
+ public function setClientSecret($clientSecret) {
276
+ global $apiConfig;
277
+ $apiConfig['oauth2_client_secret'] = $clientSecret;
278
+ self::$auth->clientSecret = $clientSecret;
279
+ }
280
+
281
+ /**
282
+ * Get the OAuth 2.0 Client Secret.
283
+ */
284
+ public function getClientSecret() {
285
+ return self::$auth->clientSecret;
286
+ }
287
+
288
+ /**
289
+ * Set the OAuth 2.0 Redirect URI.
290
+ * @param string $redirectUri
291
+ */
292
+ public function setRedirectUri($redirectUri) {
293
+ global $apiConfig;
294
+ $apiConfig['oauth2_redirect_uri'] = $redirectUri;
295
+ self::$auth->redirectUri = $redirectUri;
296
+ }
297
+
298
+ /**
299
+ * Get the OAuth 2.0 Redirect URI.
300
+ */
301
+ public function getRedirectUri() {
302
+ return self::$auth->redirectUri;
303
+ }
304
+
305
+ /**
306
+ * Fetches a fresh OAuth 2.0 access token with the given refresh token.
307
+ * @param string $refreshToken
308
+ * @return void
309
+ */
310
+ public function refreshToken($refreshToken) {
311
+ self::$auth->refreshToken($refreshToken);
312
+ }
313
+
314
+ /**
315
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
316
+ * token, if a token isn't provided.
317
+ * @throws Google_AuthException
318
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
319
+ * @return boolean Returns True if the revocation was successful, otherwise False.
320
+ */
321
+ public function revokeToken($token = null) {
322
+ self::$auth->revokeToken($token);
323
+ }
324
+
325
+ /**
326
+ * Verify an id_token. This method will verify the current id_token, if one
327
+ * isn't provided.
328
+ * @throws Google_AuthException
329
+ * @param string|null $token The token (id_token) that should be verified.
330
+ * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
331
+ * successful.
332
+ */
333
+ public function verifyIdToken($token = null) {
334
+ return self::$auth->verifyIdToken($token);
335
+ }
336
+
337
+ /**
338
+ * @param Google_AssertionCredentials $creds
339
+ * @return void
340
+ */
341
+ public function setAssertionCredentials(Google_AssertionCredentials $creds) {
342
+ self::$auth->setAssertionCredentials($creds);
343
+ }
344
+
345
+ /**
346
+ * This function allows you to overrule the automatically generated scopes,
347
+ * so that you can ask for more or less permission in the auth flow
348
+ * Set this before you call authenticate() though!
349
+ * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator')
350
+ */
351
+ public function setScopes($scopes) {
352
+ $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes;
353
+ }
354
+
355
+ /**
356
+ * Returns the list of scopes set on the client
357
+ * @return array the list of scopes
358
+ *
359
+ */
360
+ public function getScopes() {
361
+ return $this->scopes;
362
+ }
363
+
364
+ /**
365
+ * If 'plus.login' is included in the list of requested scopes, you can use
366
+ * this method to define types of app activities that your app will write.
367
+ * You can find a list of available types here:
368
+ * @link https://developers.google.com/+/api/moment-types
369
+ *
370
+ * @param array $requestVisibleActions Array of app activity types
371
+ */
372
+ public function setRequestVisibleActions($requestVisibleActions) {
373
+ self::$auth->requestVisibleActions =
374
+ join(" ", $requestVisibleActions);
375
+ }
376
+
377
+ /**
378
+ * Declare if objects should be returned by the api service classes.
379
+ *
380
+ * @param boolean $useObjects True if objects should be returned by the service classes.
381
+ * False if associative arrays should be returned (default behavior).
382
+ * @experimental
383
+ */
384
+ public function setUseObjects($useObjects) {
385
+ global $apiConfig;
386
+ $apiConfig['use_objects'] = $useObjects;
387
+ }
388
+
389
+ /**
390
+ * Declare if objects should be returned by the api service classes.
391
+ *
392
+ * @param boolean $useBatch True if the experimental batch support should
393
+ * be enabled. Defaults to False.
394
+ * @experimental
395
+ */
396
+ public function setUseBatch($useBatch) {
397
+ self::$useBatch = $useBatch;
398
+ }
399
+
400
+ /**
401
+ * @static
402
+ * @return Google_Auth the implementation of apiAuth.
403
+ */
404
+ public static function getAuth() {
405
+ return Google_Client::$auth;
406
+ }
407
+
408
+ /**
409
+ * @static
410
+ * @return Google_IO the implementation of apiIo.
411
+ */
412
+ public static function getIo() {
413
+ return Google_Client::$io;
414
+ }
415
+
416
+ /**
417
+ * @return Google_Cache the implementation of apiCache.
418
+ */
419
+ public function getCache() {
420
+ return Google_Client::$cache;
421
+ }
422
+ }
423
+
424
+ // Exceptions that the Google PHP API Library can throw
425
+ class Google_Exception extends Exception {}
426
+ class Google_AuthException extends Google_Exception {}
427
+ class Google_CacheException extends Google_Exception {}
428
+ class Google_IOException extends Google_Exception {}
429
+ class Google_ServiceException extends Google_Exception {
430
+ /**
431
+ * Optional list of errors returned in a JSON body of an HTTP error response.
432
+ */
433
+ protected $errors = array();
434
+
435
+ /**
436
+ * Override default constructor to add ability to set $errors.
437
+ *
438
+ * @param string $message
439
+ * @param int $code
440
+ * @param Exception|null $previous
441
+ * @param [{string, string}] errors List of errors returned in an HTTP
442
+ * response. Defaults to [].
443
+ */
444
+ public function __construct($message, $code = 0, Exception $previous = null,
445
+ $errors = array()) {
446
+ if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
447
+ parent::__construct($message, $code, $previous);
448
+ } else {
449
+ parent::__construct($message, $code);
450
+ }
451
+
452
+ $this->errors = $errors;
453
+ }
454
+
455
+ /**
456
+ * An example of the possible errors returned.
457
+ *
458
+ * {
459
+ * "domain": "global",
460
+ * "reason": "authError",
461
+ * "message": "Invalid Credentials",
462
+ * "locationType": "header",
463
+ * "location": "Authorization",
464
+ * }
465
+ *
466
+ * @return [{string, string}] List of errors return in an HTTP response or [].
467
+ */
468
+ public function getErrors() {
469
+ return $this->errors;
470
+ }
471
+ }
lib/Googlefusiontables/Googleclient.php ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // Check for the json extension, the Google APIs PHP Client won't function
19
+ // without it.
20
+ if (! function_exists('json_decode')) {
21
+ throw new Exception('Google PHP API Client requires the JSON PHP extension');
22
+ }
23
+
24
+ if (! function_exists('http_build_query')) {
25
+ throw new Exception('Google PHP API Client requires http_build_query()');
26
+ }
27
+
28
+ if (! ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
29
+ date_default_timezone_set('UTC');
30
+ }
31
+
32
+ // hack around with the include paths a bit so the library 'just works'
33
+ set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
34
+
35
+ require_once "config.php";
36
+ // If a local configuration file is found, merge it's values with the default configuration
37
+ if (file_exists(dirname(__FILE__) . '/local_config.php')) {
38
+ $defaultConfig = $apiConfig;
39
+ require_once (dirname(__FILE__) . '/local_config.php');
40
+ $apiConfig = array_merge($defaultConfig, $apiConfig);
41
+ }
42
+
43
+ // Include the top level classes, they each include their own dependencies
44
+ require_once 'service/Google_Model.php';
45
+ require_once 'service/Google_Service.php';
46
+ require_once 'service/Google_ServiceResource.php';
47
+ require_once 'auth/Google_AssertionCredentials.php';
48
+ require_once 'auth/Google_Signer.php';
49
+ require_once 'auth/Google_P12Signer.php';
50
+ require_once 'service/Google_BatchRequest.php';
51
+ require_once 'external/URITemplateParser.php';
52
+ require_once 'auth/Google_Auth.php';
53
+ require_once 'cache/Google_Cache.php';
54
+ require_once 'io/Google_IO.php';
55
+ require_once('service/Google_MediaFileUpload.php');
56
+
57
+ /**
58
+ * The Google API Client
59
+ * http://code.google.com/p/google-api-php-client/
60
+ *
61
+ * @author Chris Chabot <chabotc@google.com>
62
+ * @author Chirag Shah <chirags@google.com>
63
+ */
64
+ class Googlefusiontables_Googleclient {
65
+ /**
66
+ * @static
67
+ * @var Google_Auth $auth
68
+ */
69
+ static $auth;
70
+
71
+ /**
72
+ * @static
73
+ * @var Google_IO $io
74
+ */
75
+ static $io;
76
+
77
+ /**
78
+ * @static
79
+ * @var Google_Cache $cache
80
+ */
81
+ static $cache;
82
+
83
+ /**
84
+ * @static
85
+ * @var boolean $useBatch
86
+ */
87
+ static $useBatch = false;
88
+
89
+ /** @var array $scopes */
90
+ protected $scopes = array();
91
+
92
+ /** @var bool $useObjects */
93
+ protected $useObjects = false;
94
+
95
+ // definitions of services that are discovered.
96
+ protected $services = array();
97
+
98
+ // Used to track authenticated state, can't discover services after doing authenticate()
99
+ private $authenticated = false;
100
+
101
+ public function __construct($config = array()) {
102
+ global $apiConfig;
103
+ $apiConfig = array_merge($apiConfig, $config);
104
+ self::$cache = new $apiConfig['cacheClass']();
105
+ self::$auth = new $apiConfig['authClass']();
106
+ self::$io = new $apiConfig['ioClass']();
107
+ }
108
+
109
+ /**
110
+ * Add a service
111
+ */
112
+ public function addService($service, $version = false) {
113
+ global $apiConfig;
114
+ if ($this->authenticated) {
115
+ throw new Google_Exception('Cant add services after having authenticated');
116
+ }
117
+ $this->services[$service] = array();
118
+ if (isset($apiConfig['services'][$service])) {
119
+ // Merge the service descriptor with the default values
120
+ $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]);
121
+ }
122
+ }
123
+
124
+ public function authenticate($code = null) {
125
+ $service = $this->prepareService();
126
+ $this->authenticated = true;
127
+ return self::$auth->authenticate($service, $code);
128
+ }
129
+
130
+ /**
131
+ * @return array
132
+ * @visible For Testing
133
+ */
134
+ public function prepareService() {
135
+ $service = array();
136
+ $scopes = array();
137
+ if ($this->scopes) {
138
+ $scopes = $this->scopes;
139
+ } else {
140
+ foreach ($this->services as $key => $val) {
141
+ if (isset($val['scope'])) {
142
+ if (is_array($val['scope'])) {
143
+ $scopes = array_merge($val['scope'], $scopes);
144
+ } else {
145
+ $scopes[] = $val['scope'];
146
+ }
147
+ } else {
148
+ $scopes[] = 'https://www.googleapis.com/auth/' . $key;
149
+ }
150
+ unset($val['discoveryURI']);
151
+ unset($val['scope']);
152
+ $service = array_merge($service, $val);
153
+ }
154
+ }
155
+ $service['scope'] = implode(' ', $scopes);
156
+ return $service;
157
+ }
158
+
159
+ /**
160
+ * Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
161
+ * or Google_Client#getAccessToken().
162
+ * @param string $accessToken JSON encoded string containing in the following format:
163
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
164
+ * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
165
+ */
166
+ public function setAccessToken($accessToken) {
167
+ if ($accessToken == null || 'null' == $accessToken) {
168
+ $accessToken = null;
169
+ }
170
+ self::$auth->setAccessToken($accessToken);
171
+ }
172
+
173
+ /**
174
+ * Set the type of Auth class the client should use.
175
+ * @param string $authClassName
176
+ */
177
+ public function setAuthClass($authClassName) {
178
+ self::$auth = new $authClassName();
179
+ }
180
+
181
+ /**
182
+ * Construct the OAuth 2.0 authorization request URI.
183
+ * @return string
184
+ */
185
+ public function createAuthUrl() {
186
+ $service = $this->prepareService();
187
+ return self::$auth->createAuthUrl($service['scope']);
188
+ }
189
+
190
+ /**
191
+ * Get the OAuth 2.0 access token.
192
+ * @return string $accessToken JSON encoded string in the following format:
193
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
194
+ * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
195
+ */
196
+ public function getAccessToken() {
197
+ $token = self::$auth->getAccessToken();
198
+ return (null == $token || 'null' == $token) ? null : $token;
199
+ }
200
+
201
+ /**
202
+ * Returns if the access_token is expired.
203
+ * @return bool Returns True if the access_token is expired.
204
+ */
205
+ public function isAccessTokenExpired() {
206
+ return self::$auth->isAccessTokenExpired();
207
+ }
208
+
209
+ /**
210
+ * Set the developer key to use, these are obtained through the API Console.
211
+ * @see http://code.google.com/apis/console-help/#generatingdevkeys
212
+ * @param string $developerKey
213
+ */
214
+ public function setDeveloperKey($developerKey) {
215
+ self::$auth->setDeveloperKey($developerKey);
216
+ }
217
+
218
+ /**
219
+ * Set OAuth 2.0 "state" parameter to achieve per-request customization.
220
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
221
+ * @param string $state
222
+ */
223
+ public function setState($state) {
224
+ self::$auth->setState($state);
225
+ }
226
+
227
+ /**
228
+ * @param string $accessType Possible values for access_type include:
229
+ * {@code "offline"} to request offline access from the user. (This is the default value)
230
+ * {@code "online"} to request online access from the user.
231
+ */
232
+ public function setAccessType($accessType) {
233
+ self::$auth->setAccessType($accessType);
234
+ }
235
+
236
+ /**
237
+ * @param string $approvalPrompt Possible values for approval_prompt include:
238
+ * {@code "force"} to force the approval UI to appear. (This is the default value)
239
+ * {@code "auto"} to request auto-approval when possible.
240
+ */
241
+ public function setApprovalPrompt($approvalPrompt) {
242
+ self::$auth->setApprovalPrompt($approvalPrompt);
243
+ }
244
+
245
+ /**
246
+ * Set the application name, this is included in the User-Agent HTTP header.
247
+ * @param string $applicationName
248
+ */
249
+ public function setApplicationName($applicationName) {
250
+ global $apiConfig;
251
+ $apiConfig['application_name'] = $applicationName;
252
+ }
253
+
254
+ /**
255
+ * Set the OAuth 2.0 Client ID.
256
+ * @param string $clientId
257
+ */
258
+ public function setClientId($clientId) {
259
+ global $apiConfig;
260
+ $apiConfig['oauth2_client_id'] = $clientId;
261
+ self::$auth->clientId = $clientId;
262
+ }
263
+
264
+ /**
265
+ * Get the OAuth 2.0 Client ID.
266
+ */
267
+ public function getClientId() {
268
+ return self::$auth->clientId;
269
+ }
270
+
271
+ /**
272
+ * Set the OAuth 2.0 Client Secret.
273
+ * @param string $clientSecret
274
+ */
275
+ public function setClientSecret($clientSecret) {
276
+ global $apiConfig;
277
+ $apiConfig['oauth2_client_secret'] = $clientSecret;
278
+ self::$auth->clientSecret = $clientSecret;
279
+ }
280
+
281
+ /**
282
+ * Get the OAuth 2.0 Client Secret.
283
+ */
284
+ public function getClientSecret() {
285
+ return self::$auth->clientSecret;
286
+ }
287
+
288
+ /**
289
+ * Set the OAuth 2.0 Redirect URI.
290
+ * @param string $redirectUri
291
+ */
292
+ public function setRedirectUri($redirectUri) {
293
+ global $apiConfig;
294
+ $apiConfig['oauth2_redirect_uri'] = $redirectUri;
295
+ self::$auth->redirectUri = $redirectUri;
296
+ }
297
+
298
+ /**
299
+ * Get the OAuth 2.0 Redirect URI.
300
+ */
301
+ public function getRedirectUri() {
302
+ return self::$auth->redirectUri;
303
+ }
304
+
305
+ /**
306
+ * Fetches a fresh OAuth 2.0 access token with the given refresh token.
307
+ * @param string $refreshToken
308
+ * @return void
309
+ */
310
+ public function refreshToken($refreshToken) {
311
+ self::$auth->refreshToken($refreshToken);
312
+ }
313
+
314
+ /**
315
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
316
+ * token, if a token isn't provided.
317
+ * @throws Google_AuthException
318
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
319
+ * @return boolean Returns True if the revocation was successful, otherwise False.
320
+ */
321
+ public function revokeToken($token = null) {
322
+ self::$auth->revokeToken($token);
323
+ }
324
+
325
+ /**
326
+ * Verify an id_token. This method will verify the current id_token, if one
327
+ * isn't provided.
328
+ * @throws Google_AuthException
329
+ * @param string|null $token The token (id_token) that should be verified.
330
+ * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
331
+ * successful.
332
+ */
333
+ public function verifyIdToken($token = null) {
334
+ return self::$auth->verifyIdToken($token);
335
+ }
336
+
337
+ /**
338
+ * @param Google_AssertionCredentials $creds
339
+ * @return void
340
+ */
341
+ public function setAssertionCredentials(Google_AssertionCredentials $creds) {
342
+ self::$auth->setAssertionCredentials($creds);
343
+ }
344
+
345
+ /**
346
+ * This function allows you to overrule the automatically generated scopes,
347
+ * so that you can ask for more or less permission in the auth flow
348
+ * Set this before you call authenticate() though!
349
+ * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator')
350
+ */
351
+ public function setScopes($scopes) {
352
+ $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes;
353
+ }
354
+
355
+ /**
356
+ * Returns the list of scopes set on the client
357
+ * @return array the list of scopes
358
+ *
359
+ */
360
+ public function getScopes() {
361
+ return $this->scopes;
362
+ }
363
+
364
+ /**
365
+ * If 'plus.login' is included in the list of requested scopes, you can use
366
+ * this method to define types of app activities that your app will write.
367
+ * You can find a list of available types here:
368
+ * @link https://developers.google.com/+/api/moment-types
369
+ *
370
+ * @param array $requestVisibleActions Array of app activity types
371
+ */
372
+ public function setRequestVisibleActions($requestVisibleActions) {
373
+ self::$auth->requestVisibleActions =
374
+ join(" ", $requestVisibleActions);
375
+ }
376
+
377
+ /**
378
+ * Declare if objects should be returned by the api service classes.
379
+ *
380
+ * @param boolean $useObjects True if objects should be returned by the service classes.
381
+ * False if associative arrays should be returned (default behavior).
382
+ * @experimental
383
+ */
384
+ public function setUseObjects($useObjects) {
385
+ global $apiConfig;
386
+ $apiConfig['use_objects'] = $useObjects;
387
+ }
388
+
389
+ /**
390
+ * Declare if objects should be returned by the api service classes.
391
+ *
392
+ * @param boolean $useBatch True if the experimental batch support should
393
+ * be enabled. Defaults to False.
394
+ * @experimental
395
+ */
396
+ public function setUseBatch($useBatch) {
397
+ self::$useBatch = $useBatch;
398
+ }
399
+
400
+ /**
401
+ * @static
402
+ * @return Google_Auth the implementation of apiAuth.
403
+ */
404
+ public static function getAuth() {
405
+ return Google_Client::$auth;
406
+ }
407
+
408
+ /**
409
+ * @static
410
+ * @return Google_IO the implementation of apiIo.
411
+ */
412
+ public static function getIo() {
413
+ return Google_Client::$io;
414
+ }
415
+
416
+ /**
417
+ * @return Google_Cache the implementation of apiCache.
418
+ */
419
+ public function getCache() {
420
+ return Google_Client::$cache;
421
+ }
422
+ }
423
+
424
+ // Exceptions that the Google PHP API Library can throw
425
+ class Google_Exception extends Exception {}
426
+ class Google_AuthException extends Google_Exception {}
427
+ class Google_CacheException extends Google_Exception {}
428
+ class Google_IOException extends Google_Exception {}
429
+ class Google_ServiceException extends Google_Exception {
430
+ /**
431
+ * Optional list of errors returned in a JSON body of an HTTP error response.
432
+ */
433
+ protected $errors = array();
434
+
435
+ /**
436
+ * Override default constructor to add ability to set $errors.
437
+ *
438
+ * @param string $message
439
+ * @param int $code
440
+ * @param Exception|null $previous
441
+ * @param [{string, string}] errors List of errors returned in an HTTP
442
+ * response. Defaults to [].
443
+ */
444
+ public function __construct($message, $code = 0, Exception $previous = null,
445
+ $errors = array()) {
446
+ if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
447
+ parent::__construct($message, $code, $previous);
448
+ } else {
449
+ parent::__construct($message, $code);
450
+ }
451
+
452
+ $this->errors = $errors;
453
+ }
454
+
455
+ /**
456
+ * An example of the possible errors returned.
457
+ *
458
+ * {
459
+ * "domain": "global",
460
+ * "reason": "authError",
461
+ * "message": "Invalid Credentials",
462
+ * "locationType": "header",
463
+ * "location": "Authorization",
464
+ * }
465
+ *
466
+ * @return [{string, string}] List of errors return in an HTTP response or [].
467
+ */
468
+ public function getErrors() {
469
+ return $this->errors;
470
+ }
471
+ }
lib/Googlefusiontables/auth/Google_AssertionCredentials.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
20
+ *
21
+ * @author Chirag Shah <chirags@google.com>
22
+ */
23
+ class Google_AssertionCredentials {
24
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
25
+
26
+ public $serviceAccountName;
27
+ public $scopes;
28
+ public $privateKey;
29
+ public $privateKeyPassword;
30
+ public $assertionType;
31
+ public $sub;
32
+ /**
33
+ * @deprecated
34
+ * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
35
+ */
36
+ public $prn;
37
+
38
+ /**
39
+ * @param $serviceAccountName
40
+ * @param $scopes array List of scopes
41
+ * @param $privateKey
42
+ * @param string $privateKeyPassword
43
+ * @param string $assertionType
44
+ * @param bool|string $sub The email address of the user for which the
45
+ * application is requesting delegated access.
46
+ */
47
+ public function __construct(
48
+ $serviceAccountName,
49
+ $scopes,
50
+ $privateKey,
51
+ $privateKeyPassword = 'notasecret',
52
+ $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
53
+ $sub = false) {
54
+ $this->serviceAccountName = $serviceAccountName;
55
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
56
+ $this->privateKey = $privateKey;
57
+ $this->privateKeyPassword = $privateKeyPassword;
58
+ $this->assertionType = $assertionType;
59
+ $this->sub = $sub;
60
+ $this->prn = $sub;
61
+ }
62
+
63
+ public function generateAssertion() {
64
+ $now = time();
65
+
66
+ $jwtParams = array(
67
+ 'aud' => Google_OAuth2::OAUTH2_TOKEN_URI,
68
+ 'scope' => $this->scopes,
69
+ 'iat' => $now,
70
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
71
+ 'iss' => $this->serviceAccountName,
72
+ );
73
+
74
+ if ($this->sub !== false) {
75
+ $jwtParams['sub'] = $this->sub;
76
+ } else if ($this->prn !== false) {
77
+ $jwtParams['prn'] = $this->prn;
78
+ }
79
+
80
+ return $this->makeSignedJwt($jwtParams);
81
+ }
82
+
83
+ /**
84
+ * Creates a signed JWT.
85
+ * @param array $payload
86
+ * @return string The signed JWT.
87
+ */
88
+ private function makeSignedJwt($payload) {
89
+ $header = array('typ' => 'JWT', 'alg' => 'RS256');
90
+
91
+ $segments = array(
92
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
93
+ Google_Utils::urlSafeB64Encode(json_encode($payload))
94
+ );
95
+
96
+ $signingInput = implode('.', $segments);
97
+ $signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword);
98
+ $signature = $signer->sign($signingInput);
99
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
100
+
101
+ return implode(".", $segments);
102
+ }
103
+ }
lib/Googlefusiontables/auth/Google_Auth.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google_AuthNone.php";
19
+ require_once "Google_OAuth2.php";
20
+
21
+ /**
22
+ * Abstract class for the Authentication in the API client
23
+ * @author Chris Chabot <chabotc@google.com>
24
+ *
25
+ */
26
+ abstract class Google_Auth {
27
+ abstract public function authenticate($service);
28
+ abstract public function sign(Google_HttpRequest $request);
29
+ abstract public function createAuthUrl($scope);
30
+
31
+ abstract public function getAccessToken();
32
+ abstract public function setAccessToken($accessToken);
33
+ abstract public function setDeveloperKey($developerKey);
34
+ abstract public function refreshToken($refreshToken);
35
+ abstract public function revokeToken();
36
+ }
lib/Googlefusiontables/auth/Google_AuthNone.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Do-nothing authentication implementation, use this if you want to make un-authenticated calls
20
+ * @author Chris Chabot <chabotc@google.com>
21
+ * @author Chirag Shah <chirags@google.com>
22
+ */
23
+ class Google_AuthNone extends Google_Auth {
24
+ public $key = null;
25
+
26
+ public function __construct() {
27
+ global $apiConfig;
28
+ if (!empty($apiConfig['developer_key'])) {
29
+ $this->setDeveloperKey($apiConfig['developer_key']);
30
+ }
31
+ }
32
+
33
+ public function setDeveloperKey($key) {$this->key = $key;}
34
+ public function authenticate($service) {/*noop*/}
35
+ public function setAccessToken($accessToken) {/* noop*/}
36
+ public function getAccessToken() {return null;}
37
+ public function createAuthUrl($scope) {return null;}
38
+ public function refreshToken($refreshToken) {/* noop*/}
39
+ public function revokeToken() {/* noop*/}
40
+
41
+ public function sign(Google_HttpRequest $request) {
42
+ if ($this->key) {
43
+ $request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&')
44
+ . 'key='.urlencode($this->key));
45
+ }
46
+ return $request;
47
+ }
48
+ }
lib/Googlefusiontables/auth/Google_LoginTicket.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Class to hold information about an authenticated login.
20
+ *
21
+ * @author Brian Eaton <beaton@google.com>
22
+ */
23
+ class Google_LoginTicket {
24
+ const USER_ATTR = "id";
25
+
26
+ // Information from id token envelope.
27
+ private $envelope;
28
+
29
+ // Information from id token payload.
30
+ private $payload;
31
+
32
+ /**
33
+ * Creates a user based on the supplied token.
34
+ *
35
+ * @param string $envelope Header from a verified authentication token.
36
+ * @param string $payload Information from a verified authentication token.
37
+ */
38
+ public function __construct($envelope, $payload) {
39
+ $this->envelope = $envelope;
40
+ $this->payload = $payload;
41
+ }
42
+
43
+ /**
44
+ * Returns the numeric identifier for the user.
45
+ * @throws Google_AuthException
46
+ * @return
47
+ */
48
+ public function getUserId() {
49
+ if (array_key_exists(self::USER_ATTR, $this->payload)) {
50
+ return $this->payload[self::USER_ATTR];
51
+ }
52
+ throw new Google_AuthException("No user_id in token");
53
+ }
54
+
55
+ /**
56
+ * Returns attributes from the login ticket. This can contain
57
+ * various information about the user session.
58
+ * @return array
59
+ */
60
+ public function getAttributes() {
61
+ return array("envelope" => $this->envelope, "payload" => $this->payload);
62
+ }
63
+ }
lib/Googlefusiontables/auth/Google_OAuth2.php ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google_Verifier.php";
19
+ require_once "Google_LoginTicket.php";
20
+ require_once "service/Google_Utils.php";
21
+
22
+ /**
23
+ * Authentication class that deals with the OAuth 2 web-server authentication flow
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ * @author Chirag Shah <chirags@google.com>
27
+ *
28
+ */
29
+ class Google_OAuth2 extends Google_Auth {
30
+ public $clientId;
31
+ public $clientSecret;
32
+ public $developerKey;
33
+ public $token;
34
+ public $redirectUri;
35
+ public $state;
36
+ public $accessType = 'offline';
37
+ public $approvalPrompt = 'force';
38
+ public $requestVisibleActions;
39
+
40
+ /** @var Google_AssertionCredentials $assertionCredentials */
41
+ public $assertionCredentials;
42
+
43
+ const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
44
+ const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
45
+ const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
46
+ const OAUTH2_FEDERATED_SIGNON_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs';
47
+ const CLOCK_SKEW_SECS = 300; // five minutes in seconds
48
+ const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
49
+ const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
50
+
51
+ /**
52
+ * Instantiates the class, but does not initiate the login flow, leaving it
53
+ * to the discretion of the caller (which is done by calling authenticate()).
54
+ */
55
+ public function __construct() {
56
+ global $apiConfig;
57
+
58
+ if (! empty($apiConfig['developer_key'])) {
59
+ $this->developerKey = $apiConfig['developer_key'];
60
+ }
61
+
62
+ if (! empty($apiConfig['oauth2_client_id'])) {
63
+ $this->clientId = $apiConfig['oauth2_client_id'];
64
+ }
65
+
66
+ if (! empty($apiConfig['oauth2_client_secret'])) {
67
+ $this->clientSecret = $apiConfig['oauth2_client_secret'];
68
+ }
69
+
70
+ if (! empty($apiConfig['oauth2_redirect_uri'])) {
71
+ $this->redirectUri = $apiConfig['oauth2_redirect_uri'];
72
+ }
73
+
74
+ if (! empty($apiConfig['oauth2_access_type'])) {
75
+ $this->accessType = $apiConfig['oauth2_access_type'];
76
+ }
77
+
78
+ if (! empty($apiConfig['oauth2_approval_prompt'])) {
79
+ $this->approvalPrompt = $apiConfig['oauth2_approval_prompt'];
80
+ }
81
+
82
+ }
83
+
84
+ /**
85
+ * @param $service
86
+ * @param string|null $code
87
+ * @throws Google_AuthException
88
+ * @return string
89
+ */
90
+ public function authenticate($service, $code = null) {
91
+ if (!$code && isset($_GET['code'])) {
92
+ $code = $_GET['code'];
93
+ }
94
+
95
+ if ($code) {
96
+ // We got here from the redirect from a successful authorization grant, fetch the access token
97
+ $request = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
98
+ 'code' => $code,
99
+ 'grant_type' => 'authorization_code',
100
+ 'redirect_uri' => $this->redirectUri,
101
+ 'client_id' => $this->clientId,
102
+ 'client_secret' => $this->clientSecret
103
+ )));
104
+
105
+ if ($request->getResponseHttpCode() == 200) {
106
+ $this->setAccessToken($request->getResponseBody());
107
+ $this->token['created'] = time();
108
+ return $this->getAccessToken();
109
+ } else {
110
+ $response = $request->getResponseBody();
111
+ $decodedResponse = json_decode($response, true);
112
+ if ($decodedResponse != null && $decodedResponse['error']) {
113
+ $response = $decodedResponse['error'];
114
+ }
115
+ throw new Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode());
116
+ }
117
+ }
118
+
119
+ $authUrl = $this->createAuthUrl($service['scope']);
120
+ header('Location: ' . $authUrl);
121
+ return true;
122
+ }
123
+
124
+ /**
125
+ * Create a URL to obtain user authorization.
126
+ * The authorization endpoint allows the user to first
127
+ * authenticate, and then grant/deny the access request.
128
+ * @param string $scope The scope is expressed as a list of space-delimited strings.
129
+ * @return string
130
+ */
131
+ public function createAuthUrl($scope) {
132
+ $params = array(
133
+ 'response_type=code',
134
+ 'redirect_uri=' . urlencode($this->redirectUri),
135
+ 'client_id=' . urlencode($this->clientId),
136
+ 'scope=' . urlencode($scope),
137
+ 'access_type=' . urlencode($this->accessType),
138
+ 'approval_prompt=' . urlencode($this->approvalPrompt),
139
+ );
140
+
141
+ // if the list of scopes contains plus.login, add request_visible_actions
142
+ // to auth URL
143
+ if(strpos($scope, 'plus.login') && count($this->requestVisibleActions) > 0) {
144
+ $params[] = 'request_visible_actions=' .
145
+ urlencode($this->requestVisibleActions);
146
+ }
147
+
148
+ if (isset($this->state)) {
149
+ $params[] = 'state=' . urlencode($this->state);
150
+ }
151
+ $params = implode('&', $params);
152
+ return self::OAUTH2_AUTH_URL . "?$params";
153
+ }
154
+
155
+ /**
156
+ * @param string $token
157
+ * @throws Google_AuthException
158
+ */
159
+ public function setAccessToken($token) {
160
+ $token = json_decode($token, true);
161
+ if ($token == null) {
162
+ throw new Google_AuthException('Could not json decode the token');
163
+ }
164
+ if (! isset($token['access_token'])) {
165
+ throw new Google_AuthException("Invalid token format");
166
+ }
167
+ $this->token = $token;
168
+ }
169
+
170
+ public function getAccessToken() {
171
+ return json_encode($this->token);
172
+ }
173
+
174
+ public function setDeveloperKey($developerKey) {
175
+ $this->developerKey = $developerKey;
176
+ }
177
+
178
+ public function setState($state) {
179
+ $this->state = $state;
180
+ }
181
+
182
+ public function setAccessType($accessType) {
183
+ $this->accessType = $accessType;
184
+ }
185
+
186
+ public function setApprovalPrompt($approvalPrompt) {
187
+ $this->approvalPrompt = $approvalPrompt;
188
+ }
189
+
190
+ public function setAssertionCredentials(Google_AssertionCredentials $creds) {
191
+ $this->assertionCredentials = $creds;
192
+ }
193
+
194
+ /**
195
+ * Include an accessToken in a given apiHttpRequest.
196
+ * @param Google_HttpRequest $request
197
+ * @return Google_HttpRequest
198
+ * @throws Google_AuthException
199
+ */
200
+ public function sign(Google_HttpRequest $request) {
201
+ // add the developer key to the request before signing it
202
+ if ($this->developerKey) {
203
+ $requestUrl = $request->getUrl();
204
+ $requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&';
205
+ $requestUrl .= 'key=' . urlencode($this->developerKey);
206
+ $request->setUrl($requestUrl);
207
+ }
208
+
209
+ // Cannot sign the request without an OAuth access token.
210
+ if (null == $this->token && null == $this->assertionCredentials) {
211
+ return $request;
212
+ }
213
+
214
+ // Check if the token is set to expire in the next 30 seconds
215
+ // (or has already expired).
216
+ if ($this->isAccessTokenExpired()) {
217
+ if ($this->assertionCredentials) {
218
+ $this->refreshTokenWithAssertion();
219
+ } else {
220
+ if (! array_key_exists('refresh_token', $this->token)) {
221
+ throw new Google_AuthException("The OAuth 2.0 access token has expired, "
222
+ . "and a refresh token is not available. Refresh tokens are not "
223
+ . "returned for responses that were auto-approved.");
224
+ }
225
+ $this->refreshToken($this->token['refresh_token']);
226
+ }
227
+ }
228
+
229
+ // Add the OAuth2 header to the request
230
+ $request->setRequestHeaders(
231
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
232
+ );
233
+
234
+ return $request;
235
+ }
236
+
237
+ /**
238
+ * Fetches a fresh access token with the given refresh token.
239
+ * @param string $refreshToken
240
+ * @return void
241
+ */
242
+ public function refreshToken($refreshToken) {
243
+ $this->refreshTokenRequest(array(
244
+ 'client_id' => $this->clientId,
245
+ 'client_secret' => $this->clientSecret,
246
+ 'refresh_token' => $refreshToken,
247
+ 'grant_type' => 'refresh_token'
248
+ ));
249
+ }
250
+
251
+ /**
252
+ * Fetches a fresh access token with a given assertion token.
253
+ * @param Google_AssertionCredentials $assertionCredentials optional.
254
+ * @return void
255
+ */
256
+ public function refreshTokenWithAssertion($assertionCredentials = null) {
257
+ if (!$assertionCredentials) {
258
+ $assertionCredentials = $this->assertionCredentials;
259
+ }
260
+
261
+ $this->refreshTokenRequest(array(
262
+ 'grant_type' => 'assertion',
263
+ 'assertion_type' => $assertionCredentials->assertionType,
264
+ 'assertion' => $assertionCredentials->generateAssertion(),
265
+ ));
266
+ }
267
+
268
+ private function refreshTokenRequest($params) {
269
+ $http = new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
270
+ $request = Google_Client::$io->makeRequest($http);
271
+
272
+ $code = $request->getResponseHttpCode();
273
+ $body = $request->getResponseBody();
274
+ if (200 == $code) {
275
+ $token = json_decode($body, true);
276
+ if ($token == null) {
277
+ throw new Google_AuthException("Could not json decode the access token");
278
+ }
279
+
280
+ if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
281
+ throw new Google_AuthException("Invalid token format");
282
+ }
283
+
284
+ $this->token['access_token'] = $token['access_token'];
285
+ $this->token['expires_in'] = $token['expires_in'];
286
+ $this->token['created'] = time();
287
+ } else {
288
+ throw new Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code);
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
294
+ * token, if a token isn't provided.
295
+ * @throws Google_AuthException
296
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
297
+ * @return boolean Returns True if the revocation was successful, otherwise False.
298
+ */
299
+ public function revokeToken($token = null) {
300
+ if (!$token) {
301
+ $token = $this->token['access_token'];
302
+ }
303
+ $request = new Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
304
+ $response = Google_Client::$io->makeRequest($request);
305
+ $code = $response->getResponseHttpCode();
306
+ if ($code == 200) {
307
+ $this->token = null;
308
+ return true;
309
+ }
310
+
311
+ return false;
312
+ }
313
+
314
+ /**
315
+ * Returns if the access_token is expired.
316
+ * @return bool Returns True if the access_token is expired.
317
+ */
318
+ public function isAccessTokenExpired() {
319
+ if (null == $this->token) {
320
+ return true;
321
+ }
322
+
323
+ // If the token is set to expire in the next 30 seconds.
324
+ $expired = ($this->token['created']
325
+ + ($this->token['expires_in'] - 30)) < time();
326
+
327
+ return $expired;
328
+ }
329
+
330
+ // Gets federated sign-on certificates to use for verifying identity tokens.
331
+ // Returns certs as array structure, where keys are key ids, and values
332
+ // are PEM encoded certificates.
333
+ private function getFederatedSignOnCerts() {
334
+ // This relies on makeRequest caching certificate responses.
335
+ $request = Google_Client::$io->makeRequest(new Google_HttpRequest(
336
+ self::OAUTH2_FEDERATED_SIGNON_CERTS_URL));
337
+ if ($request->getResponseHttpCode() == 200) {
338
+ $certs = json_decode($request->getResponseBody(), true);
339
+ if ($certs) {
340
+ return $certs;
341
+ }
342
+ }
343
+ throw new Google_AuthException(
344
+ "Failed to retrieve verification certificates: '" .
345
+ $request->getResponseBody() . "'.",
346
+ $request->getResponseHttpCode());
347
+ }
348
+
349
+ /**
350
+ * Verifies an id token and returns the authenticated apiLoginTicket.
351
+ * Throws an exception if the id token is not valid.
352
+ * The audience parameter can be used to control which id tokens are
353
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
354
+ *
355
+ * @param $id_token
356
+ * @param $audience
357
+ * @return Google_LoginTicket
358
+ */
359
+ public function verifyIdToken($id_token = null, $audience = null) {
360
+ if (!$id_token) {
361
+ $id_token = $this->token['id_token'];
362
+ }
363
+
364
+ $certs = $this->getFederatedSignonCerts();
365
+ if (!$audience) {
366
+ $audience = $this->clientId;
367
+ }
368
+ return $this->verifySignedJwtWithCerts($id_token, $certs, $audience);
369
+ }
370
+
371
+ // Verifies the id token, returns the verified token contents.
372
+ // Visible for testing.
373
+ function verifySignedJwtWithCerts($jwt, $certs, $required_audience) {
374
+ $segments = explode(".", $jwt);
375
+ if (count($segments) != 3) {
376
+ throw new Google_AuthException("Wrong number of segments in token: $jwt");
377
+ }
378
+ $signed = $segments[0] . "." . $segments[1];
379
+ $signature = Google_Utils::urlSafeB64Decode($segments[2]);
380
+
381
+ // Parse envelope.
382
+ $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
383
+ if (!$envelope) {
384
+ throw new Google_AuthException("Can't parse token envelope: " . $segments[0]);
385
+ }
386
+
387
+ // Parse token
388
+ $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
389
+ $payload = json_decode($json_body, true);
390
+ if (!$payload) {
391
+ throw new Google_AuthException("Can't parse token payload: " . $segments[1]);
392
+ }
393
+
394
+ // Check signature
395
+ $verified = false;
396
+ foreach ($certs as $keyName => $pem) {
397
+ $public_key = new Google_PemVerifier($pem);
398
+ if ($public_key->verify($signed, $signature)) {
399
+ $verified = true;
400
+ break;
401
+ }
402
+ }
403
+
404
+ if (!$verified) {
405
+ throw new Google_AuthException("Invalid token signature: $jwt");
406
+ }
407
+
408
+ // Check issued-at timestamp
409
+ $iat = 0;
410
+ if (array_key_exists("iat", $payload)) {
411
+ $iat = $payload["iat"];
412
+ }
413
+ if (!$iat) {
414
+ throw new Google_AuthException("No issue time in token: $json_body");
415
+ }
416
+ $earliest = $iat - self::CLOCK_SKEW_SECS;
417
+
418
+ // Check expiration timestamp
419
+ $now = time();
420
+ $exp = 0;
421
+ if (array_key_exists("exp", $payload)) {
422
+ $exp = $payload["exp"];
423
+ }
424
+ if (!$exp) {
425
+ throw new Google_AuthException("No expiration time in token: $json_body");
426
+ }
427
+ if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
428
+ throw new Google_AuthException(
429
+ "Expiration time too far in future: $json_body");
430
+ }
431
+
432
+ $latest = $exp + self::CLOCK_SKEW_SECS;
433
+ if ($now < $earliest) {
434
+ throw new Google_AuthException(
435
+ "Token used too early, $now < $earliest: $json_body");
436
+ }
437
+ if ($now > $latest) {
438
+ throw new Google_AuthException(
439
+ "Token used too late, $now > $latest: $json_body");
440
+ }
441
+
442
+ // TODO(beaton): check issuer field?
443
+
444
+ // Check audience
445
+ $aud = $payload["aud"];
446
+ if ($aud != $required_audience) {
447
+ throw new Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body");
448
+ }
449
+
450
+ // All good.
451
+ return new Google_LoginTicket($envelope, $payload);
452
+ }
453
+ }
lib/Googlefusiontables/auth/Google_P12Signer.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Signs data.
20
+ *
21
+ * Only used for testing.
22
+ *
23
+ * @author Brian Eaton <beaton@google.com>
24
+ */
25
+ class Google_P12Signer extends Google_Signer {
26
+ // OpenSSL private key resource
27
+ private $privateKey;
28
+
29
+ // Creates a new signer from a .p12 file.
30
+ function __construct($p12, $password) {
31
+ if (!function_exists('openssl_x509_read')) {
32
+ throw new Exception(
33
+ 'The Google PHP API library needs the openssl PHP extension');
34
+ }
35
+
36
+ // This throws on error
37
+ $certs = array();
38
+ if (!openssl_pkcs12_read($p12, $certs, $password)) {
39
+ throw new Google_AuthException("Unable to parse the p12 file. " .
40
+ "Is this a .p12 file? Is the password correct? OpenSSL error: " .
41
+ openssl_error_string());
42
+ }
43
+ // TODO(beaton): is this part of the contract for the openssl_pkcs12_read
44
+ // method? What happens if there are multiple private keys? Do we care?
45
+ if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
46
+ throw new Google_AuthException("No private key found in p12 file.");
47
+ }
48
+ $this->privateKey = openssl_pkey_get_private($certs["pkey"]);
49
+ if (!$this->privateKey) {
50
+ throw new Google_AuthException("Unable to load private key in ");
51
+ }
52
+ }
53
+
54
+ function __destruct() {
55
+ if ($this->privateKey) {
56
+ openssl_pkey_free($this->privateKey);
57
+ }
58
+ }
59
+
60
+ function sign($data) {
61
+ if(version_compare(PHP_VERSION, '5.3.0') < 0) {
62
+ throw new Google_AuthException(
63
+ "PHP 5.3.0 or higher is required to use service accounts.");
64
+ }
65
+ if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
66
+ throw new Google_AuthException("Unable to sign data");
67
+ }
68
+ return $signature;
69
+ }
70
+ }
lib/Googlefusiontables/auth/Google_PemVerifier.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Verifies signatures using PEM encoded certificates.
20
+ *
21
+ * @author Brian Eaton <beaton@google.com>
22
+ */
23
+ class Google_PemVerifier extends Google_Verifier {
24
+ private $publicKey;
25
+
26
+ /**
27
+ * Constructs a verifier from the supplied PEM-encoded certificate.
28
+ *
29
+ * $pem: a PEM encoded certificate (not a file).
30
+ * @param $pem
31
+ * @throws Google_AuthException
32
+ * @throws Google_Exception
33
+ */
34
+ function __construct($pem) {
35
+ if (!function_exists('openssl_x509_read')) {
36
+ throw new Google_Exception('Google API PHP client needs the openssl PHP extension');
37
+ }
38
+ $this->publicKey = openssl_x509_read($pem);
39
+ if (!$this->publicKey) {
40
+ throw new Google_AuthException("Unable to parse PEM: $pem");
41
+ }
42
+ }
43
+
44
+ function __destruct() {
45
+ if ($this->publicKey) {
46
+ openssl_x509_free($this->publicKey);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Verifies the signature on data.
52
+ *
53
+ * Returns true if the signature is valid, false otherwise.
54
+ * @param $data
55
+ * @param $signature
56
+ * @throws Google_AuthException
57
+ * @return bool
58
+ */
59
+ function verify($data, $signature) {
60
+ $status = openssl_verify($data, $signature, $this->publicKey, "sha256");
61
+ if ($status === -1) {
62
+ throw new Google_AuthException('Signature verification error: ' . openssl_error_string());
63
+ }
64
+ return $status === 1;
65
+ }
66
+ }
lib/Googlefusiontables/auth/Google_Signer.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google_P12Signer.php";
19
+
20
+ /**
21
+ * Signs data.
22
+ *
23
+ * @author Brian Eaton <beaton@google.com>
24
+ */
25
+ abstract class Google_Signer {
26
+ /**
27
+ * Signs data, returns the signature as binary data.
28
+ */
29
+ abstract public function sign($data);
30
+ }
lib/Googlefusiontables/auth/Google_Verifier.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google_PemVerifier.php";
19
+
20
+ /**
21
+ * Verifies signatures.
22
+ *
23
+ * @author Brian Eaton <beaton@google.com>
24
+ */
25
+ abstract class Google_Verifier {
26
+ /**
27
+ * Checks a signature, returns true if the signature is correct,
28
+ * false otherwise.
29
+ */
30
+ abstract public function verify($data, $signature);
31
+ }
lib/Googlefusiontables/cache/Google_ApcCache.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * A persistent storage class based on the APC cache, which is not
20
+ * really very persistent, as soon as you restart your web server
21
+ * the storage will be wiped, however for debugging and/or speed
22
+ * it can be useful, kinda, and cache is a lot cheaper then storage.
23
+ *
24
+ * @author Chris Chabot <chabotc@google.com>
25
+ */
26
+ class Google_APCCache extends Google_Cache {
27
+
28
+ public function __construct() {
29
+ if (! function_exists('apc_add')) {
30
+ throw new Google_CacheException("Apc functions not available");
31
+ }
32
+ }
33
+
34
+ private function isLocked($key) {
35
+ if ((@apc_fetch($key . '.lock')) === false) {
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+
41
+ private function createLock($key) {
42
+ // the interesting thing is that this could fail if the lock was created in the meantime..
43
+ // but we'll ignore that out of convenience
44
+ @apc_add($key . '.lock', '', 5);
45
+ }
46
+
47
+ private function removeLock($key) {
48
+ // suppress all warnings, if some other process removed it that's ok too
49
+ @apc_delete($key . '.lock');
50
+ }
51
+
52
+ private function waitForLock($key) {
53
+ // 20 x 250 = 5 seconds
54
+ $tries = 20;
55
+ $cnt = 0;
56
+ do {
57
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
58
+ usleep(250);
59
+ $cnt ++;
60
+ } while ($cnt <= $tries && $this->isLocked($key));
61
+ if ($this->isLocked($key)) {
62
+ // 5 seconds passed, assume the owning process died off and remove it
63
+ $this->removeLock($key);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @inheritDoc
69
+ */
70
+ public function get($key, $expiration = false) {
71
+
72
+ if (($ret = @apc_fetch($key)) === false) {
73
+ return false;
74
+ }
75
+ if (!$expiration || (time() - $ret['time'] > $expiration)) {
76
+ $this->delete($key);
77
+ return false;
78
+ }
79
+ return unserialize($ret['data']);
80
+ }
81
+
82
+ /**
83
+ * @inheritDoc
84
+ */
85
+ public function set($key, $value) {
86
+ if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) {
87
+ throw new Google_CacheException("Couldn't store data");
88
+ }
89
+ }
90
+
91
+ /**
92
+ * @inheritDoc
93
+ * @param String $key
94
+ */
95
+ public function delete($key) {
96
+ @apc_delete($key);
97
+ }
98
+ }
lib/Googlefusiontables/cache/Google_Cache.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google_FileCache.php";
19
+ require_once "Google_MemcacheCache.php";
20
+
21
+ /**
22
+ * Abstract storage class
23
+ *
24
+ * @author Chris Chabot <chabotc@google.com>
25
+ */
26
+ abstract class Google_Cache {
27
+
28
+ /**
29
+ * Retrieves the data for the given key, or false if they
30
+ * key is unknown or expired
31
+ *
32
+ * @param String $key The key who's data to retrieve
33
+ * @param boolean|int $expiration Expiration time in seconds
34
+ *
35
+ */
36
+ abstract function get($key, $expiration = false);
37
+
38
+ /**
39
+ * Store the key => $value set. The $value is serialized
40
+ * by this function so can be of any type
41
+ *
42
+ * @param string $key Key of the data
43
+ * @param string $value data
44
+ */
45
+ abstract function set($key, $value);
46
+
47
+ /**
48
+ * Removes the key/data pair for the given $key
49
+ *
50
+ * @param String $key
51
+ */
52
+ abstract function delete($key);
53
+ }
54
+
55
+
lib/Googlefusiontables/cache/Google_FileCache.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /*
19
+ * This class implements a basic on disk storage. While that does
20
+ * work quite well it's not the most elegant and scalable solution.
21
+ * It will also get you into a heap of trouble when you try to run
22
+ * this in a clustered environment. In those cases please use the
23
+ * MySql back-end
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ */
27
+ class Google_FileCache extends Google_Cache {
28
+ private $path;
29
+
30
+ public function __construct() {
31
+ global $apiConfig;
32
+ $this->path = $apiConfig['ioFileCache_directory'];
33
+ }
34
+
35
+ private function isLocked($storageFile) {
36
+ // our lock file convention is simple: /the/file/path.lock
37
+ return file_exists($storageFile . '.lock');
38
+ }
39
+
40
+ private function createLock($storageFile) {
41
+ $storageDir = dirname($storageFile);
42
+ if (! is_dir($storageDir)) {
43
+ // @codeCoverageIgnoreStart
44
+ if (! @mkdir($storageDir, 0755, true)) {
45
+ // make sure the failure isn't because of a concurrency issue
46
+ if (! is_dir($storageDir)) {
47
+ throw new Google_CacheException("Could not create storage directory: $storageDir");
48
+ }
49
+ }
50
+ // @codeCoverageIgnoreEnd
51
+ }
52
+ @touch($storageFile . '.lock');
53
+ }
54
+
55
+ private function removeLock($storageFile) {
56
+ // suppress all warnings, if some other process removed it that's ok too
57
+ @unlink($storageFile . '.lock');
58
+ }
59
+
60
+ private function waitForLock($storageFile) {
61
+ // 20 x 250 = 5 seconds
62
+ $tries = 20;
63
+ $cnt = 0;
64
+ do {
65
+ // make sure PHP picks up on file changes. This is an expensive action but really can't be avoided
66
+ clearstatcache();
67
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
68
+ usleep(250);
69
+ $cnt ++;
70
+ } while ($cnt <= $tries && $this->isLocked($storageFile));
71
+ if ($this->isLocked($storageFile)) {
72
+ // 5 seconds passed, assume the owning process died off and remove it
73
+ $this->removeLock($storageFile);
74
+ }
75
+ }
76
+
77
+ private function getCacheDir($hash) {
78
+ // use the first 2 characters of the hash as a directory prefix
79
+ // this should prevent slowdowns due to huge directory listings
80
+ // and thus give some basic amount of scalability
81
+ return $this->path . '/' . substr($hash, 0, 2);
82
+ }
83
+
84
+ private function getCacheFile($hash) {
85
+ return $this->getCacheDir($hash) . '/' . $hash;
86
+ }
87
+
88
+ public function get($key, $expiration = false) {
89
+ $storageFile = $this->getCacheFile(md5($key));
90
+ // See if this storage file is locked, if so we wait up to 5 seconds for the lock owning process to
91
+ // complete it's work. If the lock is not released within that time frame, it's cleaned up.
92
+ // This should give us a fair amount of 'Cache Stampeding' protection
93
+ if ($this->isLocked($storageFile)) {
94
+ $this->waitForLock($storageFile);
95
+ }
96
+ if (file_exists($storageFile) && is_readable($storageFile)) {
97
+ $now = time();
98
+ if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) {
99
+ if (($data = @file_get_contents($storageFile)) !== false) {
100
+ $data = unserialize($data);
101
+ return $data;
102
+ }
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+
108
+ public function set($key, $value) {
109
+ $storageDir = $this->getCacheDir(md5($key));
110
+ $storageFile = $this->getCacheFile(md5($key));
111
+ if ($this->isLocked($storageFile)) {
112
+ // some other process is writing to this file too, wait until it's done to prevent hiccups
113
+ $this->waitForLock($storageFile);
114
+ }
115
+ if (! is_dir($storageDir)) {
116
+ if (! @mkdir($storageDir, 0755, true)) {
117
+ throw new Google_CacheException("Could not create storage directory: $storageDir");
118
+ }
119
+ }
120
+ // we serialize the whole request object, since we don't only want the
121
+ // responseContent but also the postBody used, headers, size, etc
122
+ $data = serialize($value);
123
+ $this->createLock($storageFile);
124
+ if (! @file_put_contents($storageFile, $data)) {
125
+ $this->removeLock($storageFile);
126
+ throw new Google_CacheException("Could not store data in the file");
127
+ }
128
+ $this->removeLock($storageFile);
129
+ }
130
+
131
+ public function delete($key) {
132
+ $file = $this->getCacheFile(md5($key));
133
+ if (! @unlink($file)) {
134
+ throw new Google_CacheException("Cache file could not be deleted");
135
+ }
136
+ }
137
+ }
lib/Googlefusiontables/cache/Google_MemcacheCache.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * A persistent storage class based on the memcache, which is not
20
+ * really very persistent, as soon as you restart your memcache daemon
21
+ * the storage will be wiped, however for debugging and/or speed
22
+ * it can be useful, kinda, and cache is a lot cheaper then storage.
23
+ *
24
+ * @author Chris Chabot <chabotc@google.com>
25
+ */
26
+ class Google_MemcacheCache extends Google_Cache {
27
+ private $connection = false;
28
+
29
+ public function __construct() {
30
+ global $apiConfig;
31
+ if (! function_exists('memcache_connect')) {
32
+ throw new Google_CacheException("Memcache functions not available");
33
+ }
34
+ $this->host = $apiConfig['ioMemCacheCache_host'];
35
+ $this->port = $apiConfig['ioMemCacheCache_port'];
36
+ if (empty($this->host) || empty($this->port)) {
37
+ throw new Google_CacheException("You need to supply a valid memcache host and port");
38
+ }
39
+ }
40
+
41
+ private function isLocked($key) {
42
+ $this->check();
43
+ if ((@memcache_get($this->connection, $key . '.lock')) === false) {
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+
49
+ private function createLock($key) {
50
+ $this->check();
51
+ // the interesting thing is that this could fail if the lock was created in the meantime..
52
+ // but we'll ignore that out of convenience
53
+ @memcache_add($this->connection, $key . '.lock', '', 0, 5);
54
+ }
55
+
56
+ private function removeLock($key) {
57
+ $this->check();
58
+ // suppress all warnings, if some other process removed it that's ok too
59
+ @memcache_delete($this->connection, $key . '.lock');
60
+ }
61
+
62
+ private function waitForLock($key) {
63
+ $this->check();
64
+ // 20 x 250 = 5 seconds
65
+ $tries = 20;
66
+ $cnt = 0;
67
+ do {
68
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
69
+ usleep(250);
70
+ $cnt ++;
71
+ } while ($cnt <= $tries && $this->isLocked($key));
72
+ if ($this->isLocked($key)) {
73
+ // 5 seconds passed, assume the owning process died off and remove it
74
+ $this->removeLock($key);
75
+ }
76
+ }
77
+
78
+ // I prefer lazy initialization since the cache isn't used every request
79
+ // so this potentially saves a lot of overhead
80
+ private function connect() {
81
+ if (! $this->connection = @memcache_pconnect($this->host, $this->port)) {
82
+ throw new Google_CacheException("Couldn't connect to memcache server");
83
+ }
84
+ }
85
+
86
+ private function check() {
87
+ if (! $this->connection) {
88
+ $this->connect();
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @inheritDoc
94
+ */
95
+ public function get($key, $expiration = false) {
96
+ $this->check();
97
+ if (($ret = @memcache_get($this->connection, $key)) === false) {
98
+ return false;
99
+ }
100
+ if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
101
+ $this->delete($key);
102
+ return false;
103
+ }
104
+ return $ret['data'];
105
+ }
106
+
107
+ /**
108
+ * @inheritDoc
109
+ * @param string $key
110
+ * @param string $value
111
+ * @throws Google_CacheException
112
+ */
113
+ public function set($key, $value) {
114
+ $this->check();
115
+ // we store it with the cache_time default expiration so objects will at least get cleaned eventually.
116
+ if (@memcache_set($this->connection, $key, array('time' => time(),
117
+ 'data' => $value), false) == false) {
118
+ throw new Google_CacheException("Couldn't store data in cache");
119
+ }
120
+ }
121
+
122
+ /**
123
+ * @inheritDoc
124
+ * @param String $key
125
+ */
126
+ public function delete($key) {
127
+ $this->check();
128
+ @memcache_delete($this->connection, $key);
129
+ }
130
+ }
lib/Googlefusiontables/config.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ global $apiConfig;
19
+ $apiConfig = array(
20
+ // True if objects should be returned by the service classes.
21
+ // False if associative arrays should be returned (default behavior).
22
+ 'use_objects' => false,
23
+
24
+ // The application_name is included in the User-Agent HTTP header.
25
+ 'application_name' => '',
26
+
27
+ // OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
28
+ 'oauth2_client_id' => '',
29
+ 'oauth2_client_secret' => '',
30
+ 'oauth2_redirect_uri' => '',
31
+
32
+ // The developer key, you get this at https://code.google.com/apis/console
33
+ 'developer_key' => '',
34
+
35
+ // Site name to show in the Google's OAuth 1 authentication screen.
36
+ 'site_name' => 'www.example.org',
37
+
38
+ // Which Authentication, Storage and HTTP IO classes to use.
39
+ 'authClass' => 'Google_OAuth2',
40
+ 'ioClass' => 'Google_CurlIO',
41
+ 'cacheClass' => 'Google_FileCache',
42
+
43
+ // Don't change these unless you're working against a special development or testing environment.
44
+ 'basePath' => 'https://www.googleapis.com',
45
+
46
+ // IO Class dependent configuration, you only have to configure the values
47
+ // for the class that was configured as the ioClass above
48
+ 'ioFileCache_directory' =>
49
+ (function_exists('sys_get_temp_dir') ?
50
+ sys_get_temp_dir() . '/Google_Client' :
51
+ '/tmp/Google_Client'),
52
+
53
+ // Definition of service specific values like scopes, oauth token URLs, etc
54
+ 'services' => array(
55
+ 'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'),
56
+ 'calendar' => array(
57
+ 'scope' => array(
58
+ "https://www.googleapis.com/auth/calendar",
59
+ "https://www.googleapis.com/auth/calendar.readonly",
60
+ )
61
+ ),
62
+ 'books' => array('scope' => 'https://www.googleapis.com/auth/books'),
63
+ 'latitude' => array(
64
+ 'scope' => array(
65
+ 'https://www.googleapis.com/auth/latitude.all.best',
66
+ 'https://www.googleapis.com/auth/latitude.all.city',
67
+ )
68
+ ),
69
+ 'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'),
70
+ 'oauth2' => array(
71
+ 'scope' => array(
72
+ 'https://www.googleapis.com/auth/userinfo.profile',
73
+ 'https://www.googleapis.com/auth/userinfo.email',
74
+ )
75
+ ),
76
+ 'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.login'),
77
+ 'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'),
78
+ 'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'),
79
+ 'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener')
80
+ )
81
+ );
lib/Googlefusiontables/contrib/Google_FusiontablesService.php ADDED
@@ -0,0 +1,1391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/service/Google_Service.php');
3
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/service/Google_ServiceResource.php');
4
+ require_once(Mage::getBaseDir('lib') . '/Googlefusiontables/service/Google_Model.php');
5
+ /*
6
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
+ * use this file except in compliance with the License. You may obtain a copy of
8
+ * the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
+ * License for the specific language governing permissions and limitations under
16
+ * the License.
17
+ */
18
+
19
+
20
+ /**
21
+ * The "column" collection of methods.
22
+ * Typical usage is:
23
+ * <code>
24
+ * $fusiontablesService = new Google_FusiontablesService(...);
25
+ * $column = $fusiontablesService->column;
26
+ * </code>
27
+ */
28
+ class Google_ColumnServiceResource extends Google_ServiceResource {
29
+
30
+ /**
31
+ * Deletes the column. (column.delete)
32
+ *
33
+ * @param string $tableId Table from which the column is being deleted.
34
+ * @param string $columnId Name or identifier for the column being deleted.
35
+ * @param array $optParams Optional parameters.
36
+ */
37
+ public function delete($tableId, $columnId, $optParams = array()) {
38
+ $params = array('tableId' => $tableId, 'columnId' => $columnId);
39
+ $params = array_merge($params, $optParams);
40
+ $data = $this->__call('delete', array($params));
41
+ return $data;
42
+ }
43
+ /**
44
+ * Retrieves a specific column by its id. (column.get)
45
+ *
46
+ * @param string $tableId Table to which the column belongs.
47
+ * @param string $columnId Name or identifier for the column that is being requested.
48
+ * @param array $optParams Optional parameters.
49
+ * @return Google_Column
50
+ */
51
+ public function get($tableId, $columnId, $optParams = array()) {
52
+ $params = array('tableId' => $tableId, 'columnId' => $columnId);
53
+ $params = array_merge($params, $optParams);
54
+ $data = $this->__call('get', array($params));
55
+ if ($this->useObjects()) {
56
+ return new Google_Column($data);
57
+ } else {
58
+ return $data;
59
+ }
60
+ }
61
+ /**
62
+ * Adds a new column to the table. (column.insert)
63
+ *
64
+ * @param string $tableId Table for which a new column is being added.
65
+ * @param Google_Column $postBody
66
+ * @param array $optParams Optional parameters.
67
+ * @return Google_Column
68
+ */
69
+ public function insert($tableId, Google_Column $postBody, $optParams = array()) {
70
+ $params = array('tableId' => $tableId, 'postBody' => $postBody);
71
+ $params = array_merge($params, $optParams);
72
+ $data = $this->__call('insert', array($params));
73
+ if ($this->useObjects()) {
74
+ return new Google_Column($data);
75
+ } else {
76
+ return $data;
77
+ }
78
+ }
79
+ /**
80
+ * Retrieves a list of columns. (column.list)
81
+ *
82
+ * @param string $tableId Table whose columns are being listed.
83
+ * @param array $optParams Optional parameters.
84
+ *
85
+ * @opt_param string maxResults Maximum number of columns to return. Optional. Default is 5.
86
+ * @opt_param string pageToken Continuation token specifying which result page to return. Optional.
87
+ * @return Google_ColumnList
88
+ */
89
+ public function listColumn($tableId, $optParams = array()) {
90
+ $params = array('tableId' => $tableId);
91
+ $params = array_merge($params, $optParams);
92
+ $data = $this->__call('list', array($params));
93
+ if ($this->useObjects()) {
94
+ return new Google_ColumnList($data);
95
+ } else {
96
+ return $data;
97
+ }
98
+ }
99
+ /**
100
+ * Updates the name or type of an existing column. This method supports patch semantics.
101
+ * (column.patch)
102
+ *
103
+ * @param string $tableId Table for which the column is being updated.
104
+ * @param string $columnId Name or identifier for the column that is being updated.
105
+ * @param Google_Column $postBody
106
+ * @param array $optParams Optional parameters.
107
+ * @return Google_Column
108
+ */
109
+ public function patch($tableId, $columnId, Google_Column $postBody, $optParams = array()) {
110
+ $params = array('tableId' => $tableId, 'columnId' => $columnId, 'postBody' => $postBody);
111
+ $params = array_merge($params, $optParams);
112
+ $data = $this->__call('patch', array($params));
113
+ if ($this->useObjects()) {
114
+ return new Google_Column($data);
115
+ } else {
116
+ return $data;
117
+ }
118
+ }
119
+ /**
120
+ * Updates the name or type of an existing column. (column.update)
121
+ *
122
+ * @param string $tableId Table for which the column is being updated.
123
+ * @param string $columnId Name or identifier for the column that is being updated.
124
+ * @param Google_Column $postBody
125
+ * @param array $optParams Optional parameters.
126
+ * @return Google_Column
127
+ */
128
+ public function update($tableId, $columnId, Google_Column $postBody, $optParams = array()) {
129
+ $params = array('tableId' => $tableId, 'columnId' => $columnId, 'postBody' => $postBody);
130
+ $params = array_merge($params, $optParams);
131
+ $data = $this->__call('update', array($params));
132
+ if ($this->useObjects()) {
133
+ return new Google_Column($data);
134
+ } else {
135
+ return $data;
136
+ }
137
+ }
138
+ }
139
+
140
+ /**
141
+ * The "query" collection of methods.
142
+ * Typical usage is:
143
+ * <code>
144
+ * $fusiontablesService = new Google_FusiontablesService(...);
145
+ * $query = $fusiontablesService->query;
146
+ * </code>
147
+ */
148
+ class Google_QueryServiceResource extends Google_ServiceResource {
149
+
150
+ /**
151
+ * Executes an SQL SELECT/INSERT/UPDATE/DELETE/SHOW/DESCRIBE/CREATE statement. (query.sql)
152
+ *
153
+ * @param string $sql An SQL SELECT/SHOW/DESCRIBE/INSERT/UPDATE/DELETE/CREATE statement.
154
+ * @param array $optParams Optional parameters.
155
+ *
156
+ * @opt_param bool hdrs Should column names be included (in the first row)?. Default is true.
157
+ * @opt_param bool typed Should typed values be returned in the (JSON) response -- numbers for numeric values and parsed geometries for KML values? Default is true.
158
+ * @return Google_Sqlresponse
159
+ */
160
+ public function sql($sql, $optParams = array()) {
161
+ $params = array('sql' => $sql);
162
+ $params = array_merge($params, $optParams);
163
+ $data = $this->__call('sql', array($params));
164
+ if ($this->useObjects()) {
165
+ return new Google_Sqlresponse($data);
166
+ } else {
167
+ return $data;
168
+ }
169
+ }
170
+ /**
171
+ * Executes an SQL SELECT/SHOW/DESCRIBE statement. (query.sqlGet)
172
+ *
173
+ * @param string $sql An SQL SELECT/SHOW/DESCRIBE statement.
174
+ * @param array $optParams Optional parameters.
175
+ *
176
+ * @opt_param bool hdrs Should column names be included (in the first row)?. Default is true.
177
+ * @opt_param bool typed Should typed values be returned in the (JSON) response -- numbers for numeric values and parsed geometries for KML values? Default is true.
178
+ * @return Google_Sqlresponse
179
+ */
180
+ public function sqlGet($sql, $optParams = array()) {
181
+ $params = array('sql' => $sql);
182
+ $params = array_merge($params, $optParams);
183
+ $data = $this->__call('sqlGet', array($params));
184
+ if ($this->useObjects()) {
185
+ return new Google_Sqlresponse($data);
186
+ } else {
187
+ return $data;
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * The "style" collection of methods.
194
+ * Typical usage is:
195
+ * <code>
196
+ * $fusiontablesService = new Google_FusiontablesService(...);
197
+ * $style = $fusiontablesService->style;
198
+ * </code>
199
+ */
200
+ class Google_StyleServiceResource extends Google_ServiceResource {
201
+
202
+ /**
203
+ * Deletes a style. (style.delete)
204
+ *
205
+ * @param string $tableId Table from which the style is being deleted
206
+ * @param int $styleId Identifier (within a table) for the style being deleted
207
+ * @param array $optParams Optional parameters.
208
+ */
209
+ public function delete($tableId, $styleId, $optParams = array()) {
210
+ $params = array('tableId' => $tableId, 'styleId' => $styleId);
211
+ $params = array_merge($params, $optParams);
212
+ $data = $this->__call('delete', array($params));
213
+ return $data;
214
+ }
215
+ /**
216
+ * Gets a specific style. (style.get)
217
+ *
218
+ * @param string $tableId Table to which the requested style belongs
219
+ * @param int $styleId Identifier (integer) for a specific style in a table
220
+ * @param array $optParams Optional parameters.
221
+ * @return Google_StyleSetting
222
+ */
223
+ public function get($tableId, $styleId, $optParams = array()) {
224
+ $params = array('tableId' => $tableId, 'styleId' => $styleId);
225
+ $params = array_merge($params, $optParams);
226
+ $data = $this->__call('get', array($params));
227
+ if ($this->useObjects()) {
228
+ return new Google_StyleSetting($data);
229
+ } else {
230
+ return $data;
231
+ }
232
+ }
233
+ /**
234
+ * Adds a new style for the table. (style.insert)
235
+ *
236
+ * @param string $tableId Table for which a new style is being added
237
+ * @param Google_StyleSetting $postBody
238
+ * @param array $optParams Optional parameters.
239
+ * @return Google_StyleSetting
240
+ */
241
+ public function insert($tableId, Google_StyleSetting $postBody, $optParams = array()) {
242
+ $params = array('tableId' => $tableId, 'postBody' => $postBody);
243
+ $params = array_merge($params, $optParams);
244
+ $data = $this->__call('insert', array($params));
245
+ if ($this->useObjects()) {
246
+ return new Google_StyleSetting($data);
247
+ } else {
248
+ return $data;
249
+ }
250
+ }
251
+ /**
252
+ * Retrieves a list of styles. (style.list)
253
+ *
254
+ * @param string $tableId Table whose styles are being listed
255
+ * @param array $optParams Optional parameters.
256
+ *
257
+ * @opt_param string maxResults Maximum number of styles to return. Optional. Default is 5.
258
+ * @opt_param string pageToken Continuation token specifying which result page to return. Optional.
259
+ * @return Google_StyleSettingList
260
+ */
261
+ public function listStyle($tableId, $optParams = array()) {
262
+ $params = array('tableId' => $tableId);
263
+ $params = array_merge($params, $optParams);
264
+ $data = $this->__call('list', array($params));
265
+ if ($this->useObjects()) {
266
+ return new Google_StyleSettingList($data);
267
+ } else {
268
+ return $data;
269
+ }
270
+ }
271
+ /**
272
+ * Updates an existing style. This method supports patch semantics. (style.patch)
273
+ *
274
+ * @param string $tableId Table whose style is being updated.
275
+ * @param int $styleId Identifier (within a table) for the style being updated.
276
+ * @param Google_StyleSetting $postBody
277
+ * @param array $optParams Optional parameters.
278
+ * @return Google_StyleSetting
279
+ */
280
+ public function patch($tableId, $styleId, Google_StyleSetting $postBody, $optParams = array()) {
281
+ $params = array('tableId' => $tableId, 'styleId' => $styleId, 'postBody' => $postBody);
282
+ $params = array_merge($params, $optParams);
283
+ $data = $this->__call('patch', array($params));
284
+ if ($this->useObjects()) {
285
+ return new Google_StyleSetting($data);
286
+ } else {
287
+ return $data;
288
+ }
289
+ }
290
+ /**
291
+ * Updates an existing style. (style.update)
292
+ *
293
+ * @param string $tableId Table whose style is being updated.
294
+ * @param int $styleId Identifier (within a table) for the style being updated.
295
+ * @param Google_StyleSetting $postBody
296
+ * @param array $optParams Optional parameters.
297
+ * @return Google_StyleSetting
298
+ */
299
+ public function update($tableId, $styleId, Google_StyleSetting $postBody, $optParams = array()) {
300
+ $params = array('tableId' => $tableId, 'styleId' => $styleId, 'postBody' => $postBody);
301
+ $params = array_merge($params, $optParams);
302
+ $data = $this->__call('update', array($params));
303
+ if ($this->useObjects()) {
304
+ return new Google_StyleSetting($data);
305
+ } else {
306
+ return $data;
307
+ }
308
+ }
309
+ }
310
+
311
+ /**
312
+ * The "table" collection of methods.
313
+ * Typical usage is:
314
+ * <code>
315
+ * $fusiontablesService = new Google_FusiontablesService(...);
316
+ * $table = $fusiontablesService->table;
317
+ * </code>
318
+ */
319
+ class Google_TableServiceResource extends Google_ServiceResource {
320
+
321
+ /**
322
+ * Copies a table. (table.copy)
323
+ *
324
+ * @param string $tableId ID of the table that is being copied.
325
+ * @param array $optParams Optional parameters.
326
+ *
327
+ * @opt_param bool copyPresentation Whether to also copy tabs, styles, and templates. Default is false.
328
+ * @return Google_Table
329
+ */
330
+ public function copy($tableId, $optParams = array()) {
331
+ $params = array('tableId' => $tableId);
332
+ $params = array_merge($params, $optParams);
333
+ $data = $this->__call('copy', array($params));
334
+ if ($this->useObjects()) {
335
+ return new Google_Table($data);
336
+ } else {
337
+ return $data;
338
+ }
339
+ }
340
+ /**
341
+ * Deletes a table. (table.delete)
342
+ *
343
+ * @param string $tableId ID of the table that is being deleted.
344
+ * @param array $optParams Optional parameters.
345
+ */
346
+ public function delete($tableId, $optParams = array()) {
347
+ $params = array('tableId' => $tableId);
348
+ $params = array_merge($params, $optParams);
349
+ $data = $this->__call('delete', array($params));
350
+ return $data;
351
+ }
352
+ /**
353
+ * Retrieves a specific table by its id. (table.get)
354
+ *
355
+ * @param string $tableId Identifier(ID) for the table being requested.
356
+ * @param array $optParams Optional parameters.
357
+ * @return Google_Table
358
+ */
359
+ public function get($tableId, $optParams = array()) {
360
+ $params = array('tableId' => $tableId);
361
+ $params = array_merge($params, $optParams);
362
+ $data = $this->__call('get', array($params));
363
+ if ($this->useObjects()) {
364
+ return new Google_Table($data);
365
+ } else {
366
+ return $data;
367
+ }
368
+ }
369
+ /**
370
+ * Import more rows into a table. (table.importRows)
371
+ *
372
+ * @param string $tableId The table into which new rows are being imported.
373
+ * @param array $optParams Optional parameters.
374
+ *
375
+ * @opt_param string delimiter The delimiter used to separate cell values. This can only consist of a single character. Default is ','.
376
+ * @opt_param string encoding The encoding of the content. Default is UTF-8. Use 'auto-detect' if you are unsure of the encoding.
377
+ * @opt_param int endLine The index of the last line from which to start importing, exclusive. Thus, the number of imported lines is endLine - startLine. If this parameter is not provided, the file will be imported until the last line of the file. If endLine is negative, then the imported content will exclude the last endLine lines. That is, if endline is negative, no line will be imported whose index is greater than N + endLine where N is the number of lines in the file, and the number of imported lines will be N + endLine - startLine.
378
+ * @opt_param bool isStrict Whether the CSV must have the same number of values for each row. If false, rows with fewer values will be padded with empty values. Default is true.
379
+ * @opt_param int startLine The index of the first line from which to start importing, inclusive. Default is 0.
380
+ * @return Google_Import
381
+ */
382
+ public function importRows($tableId, $optParams = array()) {
383
+ $params = array('tableId' => $tableId);
384
+ $params = array_merge($params, $optParams);
385
+ $data = $this->__call('importRows', array($params));
386
+ if ($this->useObjects()) {
387
+ return new Google_Import($data);
388
+ } else {
389
+ return $data;
390
+ }
391
+ }
392
+ /**
393
+ * Import a new table. (table.importTable)
394
+ *
395
+ * @param string $name The name to be assigned to the new table.
396
+ * @param array $optParams Optional parameters.
397
+ *
398
+ * @opt_param string delimiter The delimiter used to separate cell values. This can only consist of a single character. Default is ','.
399
+ * @opt_param string encoding The encoding of the content. Default is UTF-8. Use 'auto-detect' if you are unsure of the encoding.
400
+ * @return Google_Table
401
+ */
402
+ public function importTable($name, $optParams = array()) {
403
+ $params = array('name' => $name);
404
+ $params = array_merge($params, $optParams);
405
+ $data = $this->__call('importTable', array($params));
406
+ if ($this->useObjects()) {
407
+ return new Google_Table($data);
408
+ } else {
409
+ return $data;
410
+ }
411
+ }
412
+ /**
413
+ * Creates a new table. (table.insert)
414
+ *
415
+ * @param Google_Table $postBody
416
+ * @param array $optParams Optional parameters.
417
+ * @return Google_Table
418
+ */
419
+ public function insert(Google_Table $postBody, $optParams = array()) {
420
+ $params = array('postBody' => $postBody);
421
+ $params = array_merge($params, $optParams);
422
+ $data = $this->__call('insert', array($params));
423
+ if ($this->useObjects()) {
424
+ return new Google_Table($data);
425
+ } else {
426
+ return $data;
427
+ }
428
+ }
429
+ /**
430
+ * Retrieves a list of tables a user owns. (table.list)
431
+ *
432
+ * @param array $optParams Optional parameters.
433
+ *
434
+ * @opt_param string maxResults Maximum number of styles to return. Optional. Default is 5.
435
+ * @opt_param string pageToken Continuation token specifying which result page to return. Optional.
436
+ * @return Google_TableList
437
+ */
438
+ public function listTable($optParams = array()) {
439
+ $params = array();
440
+ $params = array_merge($params, $optParams);
441
+ $data = $this->__call('list', array($params));
442
+ if ($this->useObjects()) {
443
+ return new Google_TableList($data);
444
+ } else {
445
+ return $data;
446
+ }
447
+ }
448
+ /**
449
+ * Updates an existing table. Unless explicitly requested, only the name, description, and
450
+ * attribution will be updated. This method supports patch semantics. (table.patch)
451
+ *
452
+ * @param string $tableId ID of the table that is being updated.
453
+ * @param Google_Table $postBody
454
+ * @param array $optParams Optional parameters.
455
+ *
456
+ * @opt_param bool replaceViewDefinition Should the view definition also be updated? The specified view definition replaces the existing one. Only a view can be updated with a new definition.
457
+ * @return Google_Table
458
+ */
459
+ public function patch($tableId, Google_Table $postBody, $optParams = array()) {
460
+ $params = array('tableId' => $tableId, 'postBody' => $postBody);
461
+ $params = array_merge($params, $optParams);
462
+ $data = $this->__call('patch', array($params));
463
+ if ($this->useObjects()) {
464
+ return new Google_Table($data);
465
+ } else {
466
+ return $data;
467
+ }
468
+ }
469
+ /**
470
+ * Updates an existing table. Unless explicitly requested, only the name, description, and
471
+ * attribution will be updated. (table.update)
472
+ *
473
+ * @param string $tableId ID of the table that is being updated.
474
+ * @param Google_Table $postBody
475
+ * @param array $optParams Optional parameters.
476
+ *
477
+ * @opt_param bool replaceViewDefinition Should the view definition also be updated? The specified view definition replaces the existing one. Only a view can be updated with a new definition.
478
+ * @return Google_Table
479
+ */
480
+ public function update($tableId, Google_Table $postBody, $optParams = array()) {
481
+ $params = array('tableId' => $tableId, 'postBody' => $postBody);
482
+ $params = array_merge($params, $optParams);
483
+ $data = $this->__call('update', array($params));
484
+ if ($this->useObjects()) {
485
+ return new Google_Table($data);
486
+ } else {
487
+ return $data;
488
+ }
489
+ }
490
+ }
491
+
492
+ /**
493
+ * The "template" collection of methods.
494
+ * Typical usage is:
495
+ * <code>
496
+ * $fusiontablesService = new Google_FusiontablesService(...);
497
+ * $template = $fusiontablesService->template;
498
+ * </code>
499
+ */
500
+ class Google_TemplateServiceResource extends Google_ServiceResource {
501
+
502
+ /**
503
+ * Deletes a template (template.delete)
504
+ *
505
+ * @param string $tableId Table from which the template is being deleted
506
+ * @param int $templateId Identifier for the template which is being deleted
507
+ * @param array $optParams Optional parameters.
508
+ */
509
+ public function delete($tableId, $templateId, $optParams = array()) {
510
+ $params = array('tableId' => $tableId, 'templateId' => $templateId);
511
+ $params = array_merge($params, $optParams);
512
+ $data = $this->__call('delete', array($params));
513
+ return $data;
514
+ }
515
+ /**
516
+ * Retrieves a specific template by its id (template.get)
517
+ *
518
+ * @param string $tableId Table to which the template belongs
519
+ * @param int $templateId Identifier for the template that is being requested
520
+ * @param array $optParams Optional parameters.
521
+ * @return Google_Template
522
+ */
523
+ public function get($tableId, $templateId, $optParams = array()) {
524
+ $params = array('tableId' => $tableId, 'templateId' => $templateId);
525
+ $params = array_merge($params, $optParams);
526
+ $data = $this->__call('get', array($params));
527
+ if ($this->useObjects()) {
528
+ return new Google_Template($data);
529
+ } else {
530
+ return $data;
531
+ }
532
+ }
533
+ /**
534
+ * Creates a new template for the table. (template.insert)
535
+ *
536
+ * @param string $tableId Table for which a new template is being created
537
+ * @param Google_Template $postBody
538
+ * @param array $optParams Optional parameters.
539
+ * @return Google_Template
540
+ */
541
+ public function insert($tableId, Google_Template $postBody, $optParams = array()) {
542
+ $params = array('tableId' => $tableId, 'postBody' => $postBody);
543
+ $params = array_merge($params, $optParams);
544
+ $data = $this->__call('insert', array($params));
545
+ if ($this->useObjects()) {
546
+ return new Google_Template($data);
547
+ } else {
548
+ return $data;
549
+ }
550
+ }
551
+ /**
552
+ * Retrieves a list of templates. (template.list)
553
+ *
554
+ * @param string $tableId Identifier for the table whose templates are being requested
555
+ * @param array $optParams Optional parameters.
556
+ *
557
+ * @opt_param string maxResults Maximum number of templates to return. Optional. Default is 5.
558
+ * @opt_param string pageToken Continuation token specifying which results page to return. Optional.
559
+ * @return Google_TemplateList
560
+ */
561
+ public function listTemplate($tableId, $optParams = array()) {
562
+ $params = array('tableId' => $tableId);
563
+ $params = array_merge($params, $optParams);
564
+ $data = $this->__call('list', array($params));
565
+ if ($this->useObjects()) {
566
+ return new Google_TemplateList($data);
567
+ } else {
568
+ return $data;
569
+ }
570
+ }
571
+ /**
572
+ * Updates an existing template. This method supports patch semantics. (template.patch)
573
+ *
574
+ * @param string $tableId Table to which the updated template belongs
575
+ * @param int $templateId Identifier for the template that is being updated
576
+ * @param Google_Template $postBody
577
+ * @param array $optParams Optional parameters.
578
+ * @return Google_Template
579
+ */
580
+ public function patch($tableId, $templateId, Google_Template $postBody, $optParams = array()) {
581
+ $params = array('tableId' => $tableId, 'templateId' => $templateId, 'postBody' => $postBody);
582
+ $params = array_merge($params, $optParams);
583
+ $data = $this->__call('patch', array($params));
584
+ if ($this->useObjects()) {
585
+ return new Google_Template($data);
586
+ } else {
587
+ return $data;
588
+ }
589
+ }
590
+ /**
591
+ * Updates an existing template (template.update)
592
+ *
593
+ * @param string $tableId Table to which the updated template belongs
594
+ * @param int $templateId Identifier for the template that is being updated
595
+ * @param Google_Template $postBody
596
+ * @param array $optParams Optional parameters.
597
+ * @return Google_Template
598
+ */
599
+ public function update($tableId, $templateId, Google_Template $postBody, $optParams = array()) {
600
+ $params = array('tableId' => $tableId, 'templateId' => $templateId, 'postBody' => $postBody);
601
+ $params = array_merge($params, $optParams);
602
+ $data = $this->__call('update', array($params));
603
+ if ($this->useObjects()) {
604
+ return new Google_Template($data);
605
+ } else {
606
+ return $data;
607
+ }
608
+ }
609
+ }
610
+
611
+ /**
612
+ * Service definition for Google_Fusiontables (v1).
613
+ *
614
+ * <p>
615
+ * API for working with Fusion Tables data.
616
+ * </p>
617
+ *
618
+ * <p>
619
+ * For more information about this service, see the
620
+ * <a href="https://developers.google.com/fusiontables" target="_blank">API Documentation</a>
621
+ * </p>
622
+ *
623
+ * @author Google, Inc.
624
+ */
625
+ class Google_FusiontablesService extends Google_Service {
626
+ public $column;
627
+ public $query;
628
+ public $style;
629
+ public $table;
630
+ public $template;
631
+ /**
632
+ * Constructs the internal representation of the Fusiontables service.
633
+ *
634
+ * @param Google_Client $client
635
+ */
636
+ public function __construct(Google_Client $client) {
637
+ $this->servicePath = 'fusiontables/v1/';
638
+ $this->version = 'v1';
639
+ $this->serviceName = 'fusiontables';
640
+
641
+ $client->addService($this->serviceName, $this->version);
642
+ $this->column = new Google_ColumnServiceResource($this, $this->serviceName, 'column', json_decode('{"methods": {"delete": {"id": "fusiontables.column.delete", "path": "tables/{tableId}/columns/{columnId}", "httpMethod": "DELETE", "parameters": {"columnId": {"type": "string", "required": true, "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "get": {"id": "fusiontables.column.get", "path": "tables/{tableId}/columns/{columnId}", "httpMethod": "GET", "parameters": {"columnId": {"type": "string", "required": true, "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "Column"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "insert": {"id": "fusiontables.column.insert", "path": "tables/{tableId}/columns", "httpMethod": "POST", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Column"}, "response": {"$ref": "Column"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "list": {"id": "fusiontables.column.list", "path": "tables/{tableId}/columns", "httpMethod": "GET", "parameters": {"maxResults": {"type": "integer", "format": "uint32", "minimum": "0", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "ColumnList"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "patch": {"id": "fusiontables.column.patch", "path": "tables/{tableId}/columns/{columnId}", "httpMethod": "PATCH", "parameters": {"columnId": {"type": "string", "required": true, "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Column"}, "response": {"$ref": "Column"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "update": {"id": "fusiontables.column.update", "path": "tables/{tableId}/columns/{columnId}", "httpMethod": "PUT", "parameters": {"columnId": {"type": "string", "required": true, "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Column"}, "response": {"$ref": "Column"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}}}', true));
643
+ $this->query = new Google_QueryServiceResource($this, $this->serviceName, 'query', json_decode('{"methods": {"sql": {"id": "fusiontables.query.sql", "path": "query", "httpMethod": "POST", "parameters": {"hdrs": {"type": "boolean", "location": "query"}, "sql": {"type": "string", "required": true, "location": "query"}, "typed": {"type": "boolean", "location": "query"}}, "response": {"$ref": "Sqlresponse"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "sqlGet": {"id": "fusiontables.query.sqlGet", "path": "query", "httpMethod": "GET", "parameters": {"hdrs": {"type": "boolean", "location": "query"}, "sql": {"type": "string", "required": true, "location": "query"}, "typed": {"type": "boolean", "location": "query"}}, "response": {"$ref": "Sqlresponse"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}}}', true));
644
+ $this->style = new Google_StyleServiceResource($this, $this->serviceName, 'style', json_decode('{"methods": {"delete": {"id": "fusiontables.style.delete", "path": "tables/{tableId}/styles/{styleId}", "httpMethod": "DELETE", "parameters": {"styleId": {"type": "integer", "required": true, "format": "int32", "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "get": {"id": "fusiontables.style.get", "path": "tables/{tableId}/styles/{styleId}", "httpMethod": "GET", "parameters": {"styleId": {"type": "integer", "required": true, "format": "int32", "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "StyleSetting"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "insert": {"id": "fusiontables.style.insert", "path": "tables/{tableId}/styles", "httpMethod": "POST", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "StyleSetting"}, "response": {"$ref": "StyleSetting"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "list": {"id": "fusiontables.style.list", "path": "tables/{tableId}/styles", "httpMethod": "GET", "parameters": {"maxResults": {"type": "integer", "format": "uint32", "minimum": "0", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "StyleSettingList"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "patch": {"id": "fusiontables.style.patch", "path": "tables/{tableId}/styles/{styleId}", "httpMethod": "PATCH", "parameters": {"styleId": {"type": "integer", "required": true, "format": "int32", "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "StyleSetting"}, "response": {"$ref": "StyleSetting"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "update": {"id": "fusiontables.style.update", "path": "tables/{tableId}/styles/{styleId}", "httpMethod": "PUT", "parameters": {"styleId": {"type": "integer", "required": true, "format": "int32", "location": "path"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "StyleSetting"}, "response": {"$ref": "StyleSetting"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}}}', true));
645
+ $this->table = new Google_TableServiceResource($this, $this->serviceName, 'table', json_decode('{"methods": {"copy": {"id": "fusiontables.table.copy", "path": "tables/{tableId}/copy", "httpMethod": "POST", "parameters": {"copyPresentation": {"type": "boolean", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "delete": {"id": "fusiontables.table.delete", "path": "tables/{tableId}", "httpMethod": "DELETE", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "get": {"id": "fusiontables.table.get", "path": "tables/{tableId}", "httpMethod": "GET", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "importRows": {"id": "fusiontables.table.importRows", "path": "tables/{tableId}/import", "httpMethod": "POST", "parameters": {"delimiter": {"type": "string", "location": "query"}, "encoding": {"type": "string", "location": "query"}, "endLine": {"type": "integer", "format": "int32", "location": "query"}, "isStrict": {"type": "boolean", "location": "query"}, "startLine": {"type": "integer", "format": "int32", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "Import"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"], "supportsMediaUpload": true, "mediaUpload": {"accept": ["application/octet-stream"], "maxSize": "100MB", "protocols": {"simple": {"multipart": true, "path": "/upload/fusiontables/v1/tables/{tableId}/import"}, "resumable": {"multipart": true, "path": "/resumable/upload/fusiontables/v1/tables/{tableId}/import"}}}}, "importTable": {"id": "fusiontables.table.importTable", "path": "tables/import", "httpMethod": "POST", "parameters": {"delimiter": {"type": "string", "location": "query"}, "encoding": {"type": "string", "location": "query"}, "name": {"type": "string", "required": true, "location": "query"}}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"], "supportsMediaUpload": true, "mediaUpload": {"accept": ["application/octet-stream"], "maxSize": "100MB", "protocols": {"simple": {"multipart": true, "path": "/upload/fusiontables/v1/tables/import"}, "resumable": {"multipart": true, "path": "/resumable/upload/fusiontables/v1/tables/import"}}}}, "insert": {"id": "fusiontables.table.insert", "path": "tables", "httpMethod": "POST", "request": {"$ref": "Table"}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "list": {"id": "fusiontables.table.list", "path": "tables", "httpMethod": "GET", "parameters": {"maxResults": {"type": "integer", "format": "uint32", "minimum": "0", "location": "query"}, "pageToken": {"type": "string", "location": "query"}}, "response": {"$ref": "TableList"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "patch": {"id": "fusiontables.table.patch", "path": "tables/{tableId}", "httpMethod": "PATCH", "parameters": {"replaceViewDefinition": {"type": "boolean", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Table"}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "update": {"id": "fusiontables.table.update", "path": "tables/{tableId}", "httpMethod": "PUT", "parameters": {"replaceViewDefinition": {"type": "boolean", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Table"}, "response": {"$ref": "Table"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}}}', true));
646
+ $this->template = new Google_TemplateServiceResource($this, $this->serviceName, 'template', json_decode('{"methods": {"delete": {"id": "fusiontables.template.delete", "path": "tables/{tableId}/templates/{templateId}", "httpMethod": "DELETE", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}, "templateId": {"type": "integer", "required": true, "format": "int32", "location": "path"}}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "get": {"id": "fusiontables.template.get", "path": "tables/{tableId}/templates/{templateId}", "httpMethod": "GET", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}, "templateId": {"type": "integer", "required": true, "format": "int32", "location": "path"}}, "response": {"$ref": "Template"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "insert": {"id": "fusiontables.template.insert", "path": "tables/{tableId}/templates", "httpMethod": "POST", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}}, "request": {"$ref": "Template"}, "response": {"$ref": "Template"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "list": {"id": "fusiontables.template.list", "path": "tables/{tableId}/templates", "httpMethod": "GET", "parameters": {"maxResults": {"type": "integer", "format": "uint32", "minimum": "0", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "tableId": {"type": "string", "required": true, "location": "path"}}, "response": {"$ref": "TemplateList"}, "scopes": ["https://www.googleapis.com/auth/fusiontables", "https://www.googleapis.com/auth/fusiontables.readonly"]}, "patch": {"id": "fusiontables.template.patch", "path": "tables/{tableId}/templates/{templateId}", "httpMethod": "PATCH", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}, "templateId": {"type": "integer", "required": true, "format": "int32", "location": "path"}}, "request": {"$ref": "Template"}, "response": {"$ref": "Template"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}, "update": {"id": "fusiontables.template.update", "path": "tables/{tableId}/templates/{templateId}", "httpMethod": "PUT", "parameters": {"tableId": {"type": "string", "required": true, "location": "path"}, "templateId": {"type": "integer", "required": true, "format": "int32", "location": "path"}}, "request": {"$ref": "Template"}, "response": {"$ref": "Template"}, "scopes": ["https://www.googleapis.com/auth/fusiontables"]}}}', true));
647
+
648
+ }
649
+ }
650
+
651
+
652
+
653
+ class Google_Bucket extends Google_Model {
654
+ public $color;
655
+ public $icon;
656
+ public $max;
657
+ public $min;
658
+ public $opacity;
659
+ public $weight;
660
+ public function setColor( $color) {
661
+ $this->color = $color;
662
+ }
663
+ public function getColor() {
664
+ return $this->color;
665
+ }
666
+ public function setIcon( $icon) {
667
+ $this->icon = $icon;
668
+ }
669
+ public function getIcon() {
670
+ return $this->icon;
671
+ }
672
+ public function setMax( $max) {
673
+ $this->max = $max;
674
+ }
675
+ public function getMax() {
676
+ return $this->max;
677
+ }
678
+ public function setMin( $min) {
679
+ $this->min = $min;
680
+ }
681
+ public function getMin() {
682
+ return $this->min;
683
+ }
684
+ public function setOpacity( $opacity) {
685
+ $this->opacity = $opacity;
686
+ }
687
+ public function getOpacity() {
688
+ return $this->opacity;
689
+ }
690
+ public function setWeight( $weight) {
691
+ $this->weight = $weight;
692
+ }
693
+ public function getWeight() {
694
+ return $this->weight;
695
+ }
696
+ }
697
+
698
+ class Google_Column extends Google_Model {
699
+ protected $__baseColumnType = 'Google_ColumnBaseColumn';
700
+ protected $__baseColumnDataType = '';
701
+ public $baseColumn;
702
+ public $columnId;
703
+ public $kind;
704
+ public $name;
705
+ public $type;
706
+ public function setBaseColumn(Google_ColumnBaseColumn $baseColumn) {
707
+ $this->baseColumn = $baseColumn;
708
+ }
709
+ public function getBaseColumn() {
710
+ return $this->baseColumn;
711
+ }
712
+ public function setColumnId( $columnId) {
713
+ $this->columnId = $columnId;
714
+ }
715
+ public function getColumnId() {
716
+ return $this->columnId;
717
+ }
718
+ public function setKind( $kind) {
719
+ $this->kind = $kind;
720
+ }
721
+ public function getKind() {
722
+ return $this->kind;
723
+ }
724
+ public function setName( $name) {
725
+ $this->name = $name;
726
+ }
727
+ public function getName() {
728
+ return $this->name;
729
+ }
730
+ public function setType( $type) {
731
+ $this->type = $type;
732
+ }
733
+ public function getType() {
734
+ return $this->type;
735
+ }
736
+ }
737
+
738
+ class Google_ColumnBaseColumn extends Google_Model {
739
+ public $columnId;
740
+ public $tableIndex;
741
+ public function setColumnId( $columnId) {
742
+ $this->columnId = $columnId;
743
+ }
744
+ public function getColumnId() {
745
+ return $this->columnId;
746
+ }
747
+ public function setTableIndex( $tableIndex) {
748
+ $this->tableIndex = $tableIndex;
749
+ }
750
+ public function getTableIndex() {
751
+ return $this->tableIndex;
752
+ }
753
+ }
754
+
755
+ class Google_ColumnList extends Google_Model {
756
+ protected $__itemsType = 'Google_Column';
757
+ protected $__itemsDataType = 'array';
758
+ public $items;
759
+ public $kind;
760
+ public $nextPageToken;
761
+ public $totalItems;
762
+ public function setItems(/* array(Google_Column) */ $items) {
763
+ $this->assertIsArray($items, 'Google_Column', __METHOD__);
764
+ $this->items = $items;
765
+ }
766
+ public function getItems() {
767
+ return $this->items;
768
+ }
769
+ public function setKind( $kind) {
770
+ $this->kind = $kind;
771
+ }
772
+ public function getKind() {
773
+ return $this->kind;
774
+ }
775
+ public function setNextPageToken( $nextPageToken) {
776
+ $this->nextPageToken = $nextPageToken;
777
+ }
778
+ public function getNextPageToken() {
779
+ return $this->nextPageToken;
780
+ }
781
+ public function setTotalItems( $totalItems) {
782
+ $this->totalItems = $totalItems;
783
+ }
784
+ public function getTotalItems() {
785
+ return $this->totalItems;
786
+ }
787
+ }
788
+
789
+ class Google_Geometry extends Google_Model {
790
+ public $geometries;
791
+ public $geometry;
792
+ public $type;
793
+ public function setGeometries(/* array(Google_object) */ $geometries) {
794
+ $this->assertIsArray($geometries, 'Google_object', __METHOD__);
795
+ $this->geometries = $geometries;
796
+ }
797
+ public function getGeometries() {
798
+ return $this->geometries;
799
+ }
800
+ public function setGeometry( $geometry) {
801
+ $this->geometry = $geometry;
802
+ }
803
+ public function getGeometry() {
804
+ return $this->geometry;
805
+ }
806
+ public function setType( $type) {
807
+ $this->type = $type;
808
+ }
809
+ public function getType() {
810
+ return $this->type;
811
+ }
812
+ }
813
+
814
+ class Google_Import extends Google_Model {
815
+ public $kind;
816
+ public $numRowsReceived;
817
+ public function setKind( $kind) {
818
+ $this->kind = $kind;
819
+ }
820
+ public function getKind() {
821
+ return $this->kind;
822
+ }
823
+ public function setNumRowsReceived( $numRowsReceived) {
824
+ $this->numRowsReceived = $numRowsReceived;
825
+ }
826
+ public function getNumRowsReceived() {
827
+ return $this->numRowsReceived;
828
+ }
829
+ }
830
+
831
+ class Google_Line extends Google_Model {
832
+ public $coordinates;
833
+ public $type;
834
+ public function setCoordinates(/* array(Google_double) */ $coordinates) {
835
+ $this->assertIsArray($coordinates, 'Google_double', __METHOD__);
836
+ $this->coordinates = $coordinates;
837
+ }
838
+ public function getCoordinates() {
839
+ return $this->coordinates;
840
+ }
841
+ public function setType( $type) {
842
+ $this->type = $type;
843
+ }
844
+ public function getType() {
845
+ return $this->type;
846
+ }
847
+ }
848
+
849
+ class Google_LineStyle extends Google_Model {
850
+ public $strokeColor;
851
+ protected $__strokeColorStylerType = 'Google_StyleFunction';
852
+ protected $__strokeColorStylerDataType = '';
853
+ public $strokeColorStyler;
854
+ public $strokeOpacity;
855
+ public $strokeWeight;
856
+ protected $__strokeWeightStylerType = 'Google_StyleFunction';
857
+ protected $__strokeWeightStylerDataType = '';
858
+ public $strokeWeightStyler;
859
+ public function setStrokeColor( $strokeColor) {
860
+ $this->strokeColor = $strokeColor;
861
+ }
862
+ public function getStrokeColor() {
863
+ return $this->strokeColor;
864
+ }
865
+ public function setStrokeColorStyler(Google_StyleFunction $strokeColorStyler) {
866
+ $this->strokeColorStyler = $strokeColorStyler;
867
+ }
868
+ public function getStrokeColorStyler() {
869
+ return $this->strokeColorStyler;
870
+ }
871
+ public function setStrokeOpacity( $strokeOpacity) {
872
+ $this->strokeOpacity = $strokeOpacity;
873
+ }
874
+ public function getStrokeOpacity() {
875
+ return $this->strokeOpacity;
876
+ }
877
+ public function setStrokeWeight( $strokeWeight) {
878
+ $this->strokeWeight = $strokeWeight;
879
+ }
880
+ public function getStrokeWeight() {
881
+ return $this->strokeWeight;
882
+ }
883
+ public function setStrokeWeightStyler(Google_StyleFunction $strokeWeightStyler) {
884
+ $this->strokeWeightStyler = $strokeWeightStyler;
885
+ }
886
+ public function getStrokeWeightStyler() {
887
+ return $this->strokeWeightStyler;
888
+ }
889
+ }
890
+
891
+ class Google_Point extends Google_Model {
892
+ public $coordinates;
893
+ public $type;
894
+ public function setCoordinates(/* array(Google_double) */ $coordinates) {
895
+ $this->assertIsArray($coordinates, 'Google_double', __METHOD__);
896
+ $this->coordinates = $coordinates;
897
+ }
898
+ public function getCoordinates() {
899
+ return $this->coordinates;
900
+ }
901
+ public function setType( $type) {
902
+ $this->type = $type;
903
+ }
904
+ public function getType() {
905
+ return $this->type;
906
+ }
907
+ }
908
+
909
+ class Google_PointStyle extends Google_Model {
910
+ public $iconName;
911
+ protected $__iconStylerType = 'Google_StyleFunction';
912
+ protected $__iconStylerDataType = '';
913
+ public $iconStyler;
914
+ public function setIconName( $iconName) {
915
+ $this->iconName = $iconName;
916
+ }
917
+ public function getIconName() {
918
+ return $this->iconName;
919
+ }
920
+ public function setIconStyler(Google_StyleFunction $iconStyler) {
921
+ $this->iconStyler = $iconStyler;
922
+ }
923
+ public function getIconStyler() {
924
+ return $this->iconStyler;
925
+ }
926
+ }
927
+
928
+ class Google_Polygon extends Google_Model {
929
+ public $coordinates;
930
+ public $type;
931
+ public function setCoordinates(/* array(Google_double) */ $coordinates) {
932
+ $this->assertIsArray($coordinates, 'Google_double', __METHOD__);
933
+ $this->coordinates = $coordinates;
934
+ }
935
+ public function getCoordinates() {
936
+ return $this->coordinates;
937
+ }
938
+ public function setType( $type) {
939
+ $this->type = $type;
940
+ }
941
+ public function getType() {
942
+ return $this->type;
943
+ }
944
+ }
945
+
946
+ class Google_PolygonStyle extends Google_Model {
947
+ public $fillColor;
948
+ protected $__fillColorStylerType = 'Google_StyleFunction';
949
+ protected $__fillColorStylerDataType = '';
950
+ public $fillColorStyler;
951
+ public $fillOpacity;
952
+ public $strokeColor;
953
+ protected $__strokeColorStylerType = 'Google_StyleFunction';
954
+ protected $__strokeColorStylerDataType = '';
955
+ public $strokeColorStyler;
956
+ public $strokeOpacity;
957
+ public $strokeWeight;
958
+ protected $__strokeWeightStylerType = 'Google_StyleFunction';
959
+ protected $__strokeWeightStylerDataType = '';
960
+ public $strokeWeightStyler;
961
+ public function setFillColor( $fillColor) {
962
+ $this->fillColor = $fillColor;
963
+ }
964
+ public function getFillColor() {
965
+ return $this->fillColor;
966
+ }
967
+ public function setFillColorStyler(Google_StyleFunction $fillColorStyler) {
968
+ $this->fillColorStyler = $fillColorStyler;
969
+ }
970
+ public function getFillColorStyler() {
971
+ return $this->fillColorStyler;
972
+ }
973
+ public function setFillOpacity( $fillOpacity) {
974
+ $this->fillOpacity = $fillOpacity;
975
+ }
976
+ public function getFillOpacity() {
977
+ return $this->fillOpacity;
978
+ }
979
+ public function setStrokeColor( $strokeColor) {
980
+ $this->strokeColor = $strokeColor;
981
+ }
982
+ public function getStrokeColor() {
983
+ return $this->strokeColor;
984
+ }
985
+ public function setStrokeColorStyler(Google_StyleFunction $strokeColorStyler) {
986
+ $this->strokeColorStyler = $strokeColorStyler;
987
+ }
988
+ public function getStrokeColorStyler() {
989
+ return $this->strokeColorStyler;
990
+ }
991
+ public function setStrokeOpacity( $strokeOpacity) {
992
+ $this->strokeOpacity = $strokeOpacity;
993
+ }
994
+ public function getStrokeOpacity() {
995
+ return $this->strokeOpacity;
996
+ }
997
+ public function setStrokeWeight( $strokeWeight) {
998
+ $this->strokeWeight = $strokeWeight;
999
+ }
1000
+ public function getStrokeWeight() {
1001
+ return $this->strokeWeight;
1002
+ }
1003
+ public function setStrokeWeightStyler(Google_StyleFunction $strokeWeightStyler) {
1004
+ $this->strokeWeightStyler = $strokeWeightStyler;
1005
+ }
1006
+ public function getStrokeWeightStyler() {
1007
+ return $this->strokeWeightStyler;
1008
+ }
1009
+ }
1010
+
1011
+ class Google_Sqlresponse extends Google_Model {
1012
+ public $columns;
1013
+ public $kind;
1014
+ public $rows;
1015
+ public function setColumns(/* array(Google_string) */ $columns) {
1016
+ $this->assertIsArray($columns, 'Google_string', __METHOD__);
1017
+ $this->columns = $columns;
1018
+ }
1019
+ public function getColumns() {
1020
+ return $this->columns;
1021
+ }
1022
+ public function setKind( $kind) {
1023
+ $this->kind = $kind;
1024
+ }
1025
+ public function getKind() {
1026
+ return $this->kind;
1027
+ }
1028
+ public function setRows(/* array(Google_object) */ $rows) {
1029
+ $this->assertIsArray($rows, 'Google_object', __METHOD__);
1030
+ $this->rows = $rows;
1031
+ }
1032
+ public function getRows() {
1033
+ return $this->rows;
1034
+ }
1035
+ }
1036
+
1037
+ class Google_StyleFunction extends Google_Model {
1038
+ protected $__bucketsType = 'Google_Bucket';
1039
+ protected $__bucketsDataType = 'array';
1040
+ public $buckets;
1041
+ public $columnName;
1042
+ protected $__gradientType = 'Google_StyleFunctionGradient';
1043
+ protected $__gradientDataType = '';
1044
+ public $gradient;
1045
+ public $kind;
1046
+ public function setBuckets(/* array(Google_Bucket) */ $buckets) {
1047
+ $this->assertIsArray($buckets, 'Google_Bucket', __METHOD__);
1048
+ $this->buckets = $buckets;
1049
+ }
1050
+ public function getBuckets() {
1051
+ return $this->buckets;
1052
+ }
1053
+ public function setColumnName( $columnName) {
1054
+ $this->columnName = $columnName;
1055
+ }
1056
+ public function getColumnName() {
1057
+ return $this->columnName;
1058
+ }
1059
+ public function setGradient(Google_StyleFunctionGradient $gradient) {
1060
+ $this->gradient = $gradient;
1061
+ }
1062
+ public function getGradient() {
1063
+ return $this->gradient;
1064
+ }
1065
+ public function setKind( $kind) {
1066
+ $this->kind = $kind;
1067
+ }
1068
+ public function getKind() {
1069
+ return $this->kind;
1070
+ }
1071
+ }
1072
+
1073
+ class Google_StyleFunctionGradient extends Google_Model {
1074
+ protected $__colorsType = 'Google_StyleFunctionGradientColors';
1075
+ protected $__colorsDataType = 'array';
1076
+ public $colors;
1077
+ public $max;
1078
+ public $min;
1079
+ public function setColors(/* array(Google_StyleFunctionGradientColors) */ $colors) {
1080
+ $this->assertIsArray($colors, 'Google_StyleFunctionGradientColors', __METHOD__);
1081
+ $this->colors = $colors;
1082
+ }
1083
+ public function getColors() {
1084
+ return $this->colors;
1085
+ }
1086
+ public function setMax( $max) {
1087
+ $this->max = $max;
1088
+ }
1089
+ public function getMax() {
1090
+ return $this->max;
1091
+ }
1092
+ public function setMin( $min) {
1093
+ $this->min = $min;
1094
+ }
1095
+ public function getMin() {
1096
+ return $this->min;
1097
+ }
1098
+ }
1099
+
1100
+ class Google_StyleFunctionGradientColors extends Google_Model {
1101
+ public $color;
1102
+ public $opacity;
1103
+ public function setColor( $color) {
1104
+ $this->color = $color;
1105
+ }
1106
+ public function getColor() {
1107
+ return $this->color;
1108
+ }
1109
+ public function setOpacity( $opacity) {
1110
+ $this->opacity = $opacity;
1111
+ }
1112
+ public function getOpacity() {
1113
+ return $this->opacity;
1114
+ }
1115
+ }
1116
+
1117
+ class Google_StyleSetting extends Google_Model {
1118
+ public $kind;
1119
+ protected $__markerOptionsType = 'Google_PointStyle';
1120
+ protected $__markerOptionsDataType = '';
1121
+ public $markerOptions;
1122
+ public $name;
1123
+ protected $__polygonOptionsType = 'Google_PolygonStyle';
1124
+ protected $__polygonOptionsDataType = '';
1125
+ public $polygonOptions;
1126
+ protected $__polylineOptionsType = 'Google_LineStyle';
1127
+ protected $__polylineOptionsDataType = '';
1128
+ public $polylineOptions;
1129
+ public $styleId;
1130
+ public $tableId;
1131
+ public function setKind( $kind) {
1132
+ $this->kind = $kind;
1133
+ }
1134
+ public function getKind() {
1135
+ return $this->kind;
1136
+ }
1137
+ public function setMarkerOptions(Google_PointStyle $markerOptions) {
1138
+ $this->markerOptions = $markerOptions;
1139
+ }
1140
+ public function getMarkerOptions() {
1141
+ return $this->markerOptions;
1142
+ }
1143
+ public function setName( $name) {
1144
+ $this->name = $name;
1145
+ }
1146
+ public function getName() {
1147
+ return $this->name;
1148
+ }
1149
+ public function setPolygonOptions(Google_PolygonStyle $polygonOptions) {
1150
+ $this->polygonOptions = $polygonOptions;
1151
+ }
1152
+ public function getPolygonOptions() {
1153
+ return $this->polygonOptions;
1154
+ }
1155
+ public function setPolylineOptions(Google_LineStyle $polylineOptions) {
1156
+ $this->polylineOptions = $polylineOptions;
1157
+ }
1158
+ public function getPolylineOptions() {
1159
+ return $this->polylineOptions;
1160
+ }
1161
+ public function setStyleId( $styleId) {
1162
+ $this->styleId = $styleId;
1163
+ }
1164
+ public function getStyleId() {
1165
+ return $this->styleId;
1166
+ }
1167
+ public function setTableId( $tableId) {
1168
+ $this->tableId = $tableId;
1169
+ }
1170
+ public function getTableId() {
1171
+ return $this->tableId;
1172
+ }
1173
+ }
1174
+
1175
+ class Google_StyleSettingList extends Google_Model {
1176
+ protected $__itemsType = 'Google_StyleSetting';
1177
+ protected $__itemsDataType = 'array';
1178
+ public $items;
1179
+ public $kind;
1180
+ public $nextPageToken;
1181
+ public $totalItems;
1182
+ public function setItems(/* array(Google_StyleSetting) */ $items) {
1183
+ $this->assertIsArray($items, 'Google_StyleSetting', __METHOD__);
1184
+ $this->items = $items;
1185
+ }
1186
+ public function getItems() {
1187
+ return $this->items;
1188
+ }
1189
+ public function setKind( $kind) {
1190
+ $this->kind = $kind;
1191
+ }
1192
+ public function getKind() {
1193
+ return $this->kind;
1194
+ }
1195
+ public function setNextPageToken( $nextPageToken) {
1196
+ $this->nextPageToken = $nextPageToken;
1197
+ }
1198
+ public function getNextPageToken() {
1199
+ return $this->nextPageToken;
1200
+ }
1201
+ public function setTotalItems( $totalItems) {
1202
+ $this->totalItems = $totalItems;
1203
+ }
1204
+ public function getTotalItems() {
1205
+ return $this->totalItems;
1206
+ }
1207
+ }
1208
+
1209
+ class Google_Table extends Google_Model {
1210
+ public $attribution;
1211
+ public $attributionLink;
1212
+ public $baseTableIds;
1213
+ protected $__columnsType = 'Google_Column';
1214
+ protected $__columnsDataType = 'array';
1215
+ public $columns;
1216
+ public $description;
1217
+ public $isExportable;
1218
+ public $kind;
1219
+ public $name;
1220
+ public $sql;
1221
+ public $tableId;
1222
+ public function setAttribution( $attribution) {
1223
+ $this->attribution = $attribution;
1224
+ }
1225
+ public function getAttribution() {
1226
+ return $this->attribution;
1227
+ }
1228
+ public function setAttributionLink( $attributionLink) {
1229
+ $this->attributionLink = $attributionLink;
1230
+ }
1231
+ public function getAttributionLink() {
1232
+ return $this->attributionLink;
1233
+ }
1234
+ public function setBaseTableIds(/* array(Google_string) */ $baseTableIds) {
1235
+ $this->assertIsArray($baseTableIds, 'Google_string', __METHOD__);
1236
+ $this->baseTableIds = $baseTableIds;
1237
+ }
1238
+ public function getBaseTableIds() {
1239
+ return $this->baseTableIds;
1240
+ }
1241
+ public function setColumns(/* array(Google_Column) */ $columns) {
1242
+ $this->assertIsArray($columns, 'Google_Column', __METHOD__);
1243
+ $this->columns = $columns;
1244
+ }
1245
+ public function getColumns() {
1246
+ return $this->columns;
1247
+ }
1248
+ public function setDescription( $description) {
1249
+ $this->description = $description;
1250
+ }
1251
+ public function getDescription() {
1252
+ return $this->description;
1253
+ }
1254
+ public function setIsExportable( $isExportable) {
1255
+ $this->isExportable = $isExportable;
1256
+ }
1257
+ public function getIsExportable() {
1258
+ return $this->isExportable;
1259
+ }
1260
+ public function setKind( $kind) {
1261
+ $this->kind = $kind;
1262
+ }
1263
+ public function getKind() {
1264
+ return $this->kind;
1265
+ }
1266
+ public function setName( $name) {
1267
+ $this->name = $name;
1268
+ }
1269
+ public function getName() {
1270
+ return $this->name;
1271
+ }
1272
+ public function setSql( $sql) {
1273
+ $this->sql = $sql;
1274
+ }
1275
+ public function getSql() {
1276
+ return $this->sql;
1277
+ }
1278
+ public function setTableId( $tableId) {
1279
+ $this->tableId = $tableId;
1280
+ }
1281
+ public function getTableId() {
1282
+ return $this->tableId;
1283
+ }
1284
+ }
1285
+
1286
+ class Google_TableList extends Google_Model {
1287
+ protected $__itemsType = 'Google_Table';
1288
+ protected $__itemsDataType = 'array';
1289
+ public $items;
1290
+ public $kind;
1291
+ public $nextPageToken;
1292
+ public function setItems(/* array(Google_Table) */ $items) {
1293
+ $this->assertIsArray($items, 'Google_Table', __METHOD__);
1294
+ $this->items = $items;
1295
+ }
1296
+ public function getItems() {
1297
+ return $this->items;
1298
+ }
1299
+ public function setKind( $kind) {
1300
+ $this->kind = $kind;
1301
+ }
1302
+ public function getKind() {
1303
+ return $this->kind;
1304
+ }
1305
+ public function setNextPageToken( $nextPageToken) {
1306
+ $this->nextPageToken = $nextPageToken;
1307
+ }
1308
+ public function getNextPageToken() {
1309
+ return $this->nextPageToken;
1310
+ }
1311
+ }
1312
+
1313
+ class Google_Template extends Google_Model {
1314
+ public $automaticColumnNames;
1315
+ public $body;
1316
+ public $kind;
1317
+ public $name;
1318
+ public $tableId;
1319
+ public $templateId;
1320
+ public function setAutomaticColumnNames(/* array(Google_string) */ $automaticColumnNames) {
1321
+ $this->assertIsArray($automaticColumnNames, 'Google_string', __METHOD__);
1322
+ $this->automaticColumnNames = $automaticColumnNames;
1323
+ }
1324
+ public function getAutomaticColumnNames() {
1325
+ return $this->automaticColumnNames;
1326
+ }
1327
+ public function setBody( $body) {
1328
+ $this->body = $body;
1329
+ }
1330
+ public function getBody() {
1331
+ return $this->body;
1332
+ }
1333
+ public function setKind( $kind) {
1334
+ $this->kind = $kind;
1335
+ }
1336
+ public function getKind() {
1337
+ return $this->kind;
1338
+ }
1339
+ public function setName( $name) {
1340
+ $this->name = $name;
1341
+ }
1342
+ public function getName() {
1343
+ return $this->name;
1344
+ }
1345
+ public function setTableId( $tableId) {
1346
+ $this->tableId = $tableId;
1347
+ }
1348
+ public function getTableId() {
1349
+ return $this->tableId;
1350
+ }
1351
+ public function setTemplateId( $templateId) {
1352
+ $this->templateId = $templateId;
1353
+ }
1354
+ public function getTemplateId() {
1355
+ return $this->templateId;
1356
+ }
1357
+ }
1358
+
1359
+ class Google_TemplateList extends Google_Model {
1360
+ protected $__itemsType = 'Google_Template';
1361
+ protected $__itemsDataType = 'array';
1362
+ public $items;
1363
+ public $kind;
1364
+ public $nextPageToken;
1365
+ public $totalItems;
1366
+ public function setItems(/* array(Google_Template) */ $items) {
1367
+ $this->assertIsArray($items, 'Google_Template', __METHOD__);
1368
+ $this->items = $items;
1369
+ }
1370
+ public function getItems() {
1371
+ return $this->items;
1372
+ }
1373
+ public function setKind( $kind) {
1374
+ $this->kind = $kind;
1375
+ }
1376
+ public function getKind() {
1377
+ return $this->kind;
1378
+ }
1379
+ public function setNextPageToken( $nextPageToken) {
1380
+ $this->nextPageToken = $nextPageToken;
1381
+ }
1382
+ public function getNextPageToken() {
1383
+ return $this->nextPageToken;
1384
+ }
1385
+ public function setTotalItems( $totalItems) {
1386
+ $this->totalItems = $totalItems;
1387
+ }
1388
+ public function getTotalItems() {
1389
+ return $this->totalItems;
1390
+ }
1391
+ }
lib/Googlefusiontables/external/URITemplateParser.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright (c) 2010 Kevin M Burns Jr, http://kevburnsjr.com/
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+ /**
26
+ * A URI Template Parser which is used by the apiREST class to resolve the REST requests
27
+ * Blogpost: http://lab.kevburnsjr.com/php-uri-template-parser
28
+ * Source: http://github.com/KevBurnsJr/php-uri-template-parser
29
+ */
30
+ class URI_Template_Parser {
31
+
32
+ public static $operators = array('+', ';', '?', '/', '.');
33
+ public static $reserved_operators = array('|', '!', '@');
34
+ public static $explode_modifiers = array('+', '*');
35
+ public static $partial_modifiers = array(':', '^');
36
+
37
+ public static $gen_delims = array(':', '/', '?', '#', '[', ']', '@');
38
+ public static $gen_delims_pct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40');
39
+ public static $sub_delims = array('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=');
40
+ public static $sub_delims_pct = array('%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D');
41
+ public static $reserved;
42
+ public static $reserved_pct;
43
+
44
+ public function __construct($template) {
45
+ self::$reserved = array_merge(self::$gen_delims, self::$sub_delims);
46
+ self::$reserved_pct = array_merge(self::$gen_delims_pct, self::$sub_delims_pct);
47
+ $this->template = $template;
48
+ }
49
+
50
+ public function expand($data) {
51
+ // Modification to make this a bit more performant (since gettype is very slow)
52
+ if (! is_array($data)) {
53
+ $data = (array)$data;
54
+ }
55
+ /*
56
+ // Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect
57
+ switch (gettype($data)) {
58
+ case "boolean":
59
+ case "integer":
60
+ case "double":
61
+ case "string":
62
+ case "object":
63
+ $data = (array)$data;
64
+ break;
65
+ }
66
+ */
67
+
68
+ // Resolve template vars
69
+ preg_match_all('/\{([^\}]*)\}/', $this->template, $em);
70
+
71
+ foreach ($em[1] as $i => $bare_expression) {
72
+ preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm);
73
+ $exp = new StdClass();
74
+ $exp->expression = $em[0][$i];
75
+ $exp->operator = $lm[1];
76
+ $exp->variable_list = $lm[2];
77
+ $exp->varspecs = explode(',', $exp->variable_list);
78
+ $exp->vars = array();
79
+ foreach ($exp->varspecs as $varspec) {
80
+ preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm);
81
+ $var = new StdClass();
82
+ $var->name = $vm[1];
83
+ $var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null;
84
+ $var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier;
85
+ $var->default = isset($vm[4]) ? substr($vm[4], 1) : null;
86
+ $exp->vars[] = $var;
87
+ }
88
+
89
+ // Add processing flags
90
+ $exp->reserved = false;
91
+ $exp->prefix = '';
92
+ $exp->delimiter = ',';
93
+ switch ($exp->operator) {
94
+ case '+':
95
+ $exp->reserved = 'true';
96
+ break;
97
+ case ';':
98
+ $exp->prefix = ';';
99
+ $exp->delimiter = ';';
100
+ break;
101
+ case '?':
102
+ $exp->prefix = '?';
103
+ $exp->delimiter = '&';
104
+ break;
105
+ case '/':
106
+ $exp->prefix = '/';
107
+ $exp->delimiter = '/';
108
+ break;
109
+ case '.':
110
+ $exp->prefix = '.';
111
+ $exp->delimiter = '.';
112
+ break;
113
+ }
114
+ $expressions[] = $exp;
115
+ }
116
+
117
+ // Expansion
118
+ $this->expansion = $this->template;
119
+
120
+ foreach ($expressions as $exp) {
121
+ $part = $exp->prefix;
122
+ $exp->one_var_defined = false;
123
+ foreach ($exp->vars as $var) {
124
+ $val = '';
125
+ if ($exp->one_var_defined && isset($data[$var->name])) {
126
+ $part .= $exp->delimiter;
127
+ }
128
+ // Variable present
129
+ if (isset($data[$var->name])) {
130
+ $exp->one_var_defined = true;
131
+ $var->data = $data[$var->name];
132
+
133
+ $val = self::val_from_var($var, $exp);
134
+
135
+ // Variable missing
136
+ } else {
137
+ if ($var->default) {
138
+ $exp->one_var_defined = true;
139
+ $val = $var->default;
140
+ }
141
+ }
142
+ $part .= $val;
143
+ }
144
+ if (! $exp->one_var_defined) $part = '';
145
+ $this->expansion = str_replace($exp->expression, $part, $this->expansion);
146
+ }
147
+
148
+ return $this->expansion;
149
+ }
150
+
151
+ private function val_from_var($var, $exp) {
152
+ $val = '';
153
+ if (is_array($var->data)) {
154
+ $i = 0;
155
+ if ($exp->operator == '?' && ! $var->modifier) {
156
+ $val .= $var->name . '=';
157
+ }
158
+ foreach ($var->data as $k => $v) {
159
+ $del = $var->modifier ? $exp->delimiter : ',';
160
+ $ek = rawurlencode($k);
161
+ $ev = rawurlencode($v);
162
+
163
+ // Array
164
+ if ($k !== $i) {
165
+ if ($var->modifier == '+') {
166
+ $val .= $var->name . '.';
167
+ }
168
+ if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') {
169
+ $val .= $ek . '=';
170
+ } else {
171
+ $val .= $ek . $del;
172
+ }
173
+
174
+ // List
175
+ } else {
176
+ if ($var->modifier == '+') {
177
+ if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') {
178
+ $val .= $var->name . '=';
179
+ } else {
180
+ $val .= $var->name . '.';
181
+ }
182
+ }
183
+ }
184
+ $val .= $ev . $del;
185
+ $i ++;
186
+ }
187
+ $val = trim($val, $del);
188
+
189
+ // Strings, numbers, etc.
190
+ } else {
191
+ if ($exp->operator == '?') {
192
+ $val = $var->name . (isset($var->data) ? '=' : '');
193
+ } else if ($exp->operator == ';') {
194
+ $val = $var->name . ($var->data ? '=' : '');
195
+ }
196
+ $val .= rawurlencode($var->data);
197
+ if ($exp->operator == '+') {
198
+ $val = str_replace(self::$reserved_pct, self::$reserved, $val);
199
+ }
200
+ }
201
+ return $val;
202
+ }
203
+
204
+ public function match($uri) {}
205
+
206
+ public function __toString() {
207
+ return $this->template;
208
+ }
209
+ }
lib/Googlefusiontables/io/Google_CacheParser.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Implement the caching directives specified in rfc2616. This
19
+ * implementation is guided by the guidance offered in rfc2616-sec13.
20
+ * @author Chirag Shah <chirags@google.com>
21
+ */
22
+ class Google_CacheParser {
23
+ public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
24
+ public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
25
+
26
+ private function __construct() {}
27
+
28
+ /**
29
+ * Check if an HTTP request can be cached by a private local cache.
30
+ *
31
+ * @static
32
+ * @param Google_HttpRequest $resp
33
+ * @return bool True if the request is cacheable.
34
+ * False if the request is uncacheable.
35
+ */
36
+ public static function isRequestCacheable (Google_HttpRequest $resp) {
37
+ $method = $resp->getRequestMethod();
38
+ if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
39
+ return false;
40
+ }
41
+
42
+ // Don't cache authorized requests/responses.
43
+ // [rfc2616-14.8] When a shared cache receives a request containing an
44
+ // Authorization field, it MUST NOT return the corresponding response
45
+ // as a reply to any other request...
46
+ if ($resp->getRequestHeader("authorization")) {
47
+ return false;
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ /**
54
+ * Check if an HTTP response can be cached by a private local cache.
55
+ *
56
+ * @static
57
+ * @param Google_HttpRequest $resp
58
+ * @return bool True if the response is cacheable.
59
+ * False if the response is un-cacheable.
60
+ */
61
+ public static function isResponseCacheable (Google_HttpRequest $resp) {
62
+ // First, check if the HTTP request was cacheable before inspecting the
63
+ // HTTP response.
64
+ if (false == self::isRequestCacheable($resp)) {
65
+ return false;
66
+ }
67
+
68
+ $code = $resp->getResponseHttpCode();
69
+ if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) {
70
+ return false;
71
+ }
72
+
73
+ // The resource is uncacheable if the resource is already expired and
74
+ // the resource doesn't have an ETag for revalidation.
75
+ $etag = $resp->getResponseHeader("etag");
76
+ if (self::isExpired($resp) && $etag == false) {
77
+ return false;
78
+ }
79
+
80
+ // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
81
+ // store any part of either this response or the request that elicited it.
82
+ $cacheControl = $resp->getParsedCacheControl();
83
+ if (isset($cacheControl['no-store'])) {
84
+ return false;
85
+ }
86
+
87
+ // Pragma: no-cache is an http request directive, but is occasionally
88
+ // used as a response header incorrectly.
89
+ $pragma = $resp->getResponseHeader('pragma');
90
+ if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
91
+ return false;
92
+ }
93
+
94
+ // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
95
+ // a cache cannot determine from the request headers of a subsequent request
96
+ // whether this response is the appropriate representation."
97
+ // Given this, we deem responses with the Vary header as uncacheable.
98
+ $vary = $resp->getResponseHeader('vary');
99
+ if ($vary) {
100
+ return false;
101
+ }
102
+
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * @static
108
+ * @param Google_HttpRequest $resp
109
+ * @return bool True if the HTTP response is considered to be expired.
110
+ * False if it is considered to be fresh.
111
+ */
112
+ public static function isExpired(Google_HttpRequest $resp) {
113
+ // HTTP/1.1 clients and caches MUST treat other invalid date formats,
114
+ // especially including the value “0”, as in the past.
115
+ $parsedExpires = false;
116
+ $responseHeaders = $resp->getResponseHeaders();
117
+ if (isset($responseHeaders['expires'])) {
118
+ $rawExpires = $responseHeaders['expires'];
119
+ // Check for a malformed expires header first.
120
+ if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
121
+ return true;
122
+ }
123
+
124
+ // See if we can parse the expires header.
125
+ $parsedExpires = strtotime($rawExpires);
126
+ if (false == $parsedExpires || $parsedExpires <= 0) {
127
+ return true;
128
+ }
129
+ }
130
+
131
+ // Calculate the freshness of an http response.
132
+ $freshnessLifetime = false;
133
+ $cacheControl = $resp->getParsedCacheControl();
134
+ if (isset($cacheControl['max-age'])) {
135
+ $freshnessLifetime = $cacheControl['max-age'];
136
+ }
137
+
138
+ $rawDate = $resp->getResponseHeader('date');
139
+ $parsedDate = strtotime($rawDate);
140
+
141
+ if (empty($rawDate) || false == $parsedDate) {
142
+ $parsedDate = time();
143
+ }
144
+ if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
145
+ $freshnessLifetime = $parsedExpires - $parsedDate;
146
+ }
147
+
148
+ if (false == $freshnessLifetime) {
149
+ return true;
150
+ }
151
+
152
+ // Calculate the age of an http response.
153
+ $age = max(0, time() - $parsedDate);
154
+ if (isset($responseHeaders['age'])) {
155
+ $age = max($age, strtotime($responseHeaders['age']));
156
+ }
157
+
158
+ return $freshnessLifetime <= $age;
159
+ }
160
+
161
+ /**
162
+ * Determine if a cache entry should be revalidated with by the origin.
163
+ *
164
+ * @param Google_HttpRequest $response
165
+ * @return bool True if the entry is expired, else return false.
166
+ */
167
+ public static function mustRevalidate(Google_HttpRequest $response) {
168
+ // [13.3] When a cache has a stale entry that it would like to use as a
169
+ // response to a client's request, it first has to check with the origin
170
+ // server to see if its cached entry is still usable.
171
+ return self::isExpired($response);
172
+ }
173
+ }
lib/Googlefusiontables/io/Google_CurlIO.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Curl based implementation of apiIO.
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ * @author Chirag Shah <chirags@google.com>
23
+ */
24
+
25
+ require_once 'Google_CacheParser.php';
26
+
27
+ class Google_CurlIO extends Google_IO {
28
+ private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
29
+ private static $HOP_BY_HOP = array(
30
+ 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
31
+ 'te', 'trailers', 'transfer-encoding', 'upgrade');
32
+
33
+ private $curlParams = array (
34
+ CURLOPT_RETURNTRANSFER => true,
35
+ CURLOPT_FOLLOWLOCATION => 0,
36
+ CURLOPT_FAILONERROR => false,
37
+ CURLOPT_SSL_VERIFYPEER => true,
38
+ CURLOPT_HEADER => true,
39
+ CURLOPT_VERBOSE => false,
40
+ );
41
+
42
+ /**
43
+ * Check for cURL availability.
44
+ */
45
+ public function __construct() {
46
+ if (! function_exists('curl_init')) {
47
+ throw new Exception(
48
+ 'Google CurlIO client requires the CURL PHP extension');
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Perform an authenticated / signed apiHttpRequest.
54
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
55
+ * (which can modify the request in what ever way fits the auth mechanism)
56
+ * and then calls apiCurlIO::makeRequest on the signed request
57
+ *
58
+ * @param Google_HttpRequest $request
59
+ * @return Google_HttpRequest The resulting HTTP response including the
60
+ * responseHttpCode, responseHeaders and responseBody.
61
+ */
62
+ public function authenticatedRequest(Google_HttpRequest $request) {
63
+ $request = Google_Client::$auth->sign($request);
64
+ return $this->makeRequest($request);
65
+ }
66
+
67
+ /**
68
+ * Execute a apiHttpRequest
69
+ *
70
+ * @param Google_HttpRequest $request the http request to be executed
71
+ * @return Google_HttpRequest http request with the response http code, response
72
+ * headers and response body filled in
73
+ * @throws Google_IOException on curl or IO error
74
+ */
75
+ public function makeRequest(Google_HttpRequest $request) {
76
+ // First, check to see if we have a valid cached version.
77
+ $cached = $this->getCachedRequest($request);
78
+ if ($cached !== false) {
79
+ if (!$this->checkMustRevaliadateCachedRequest($cached, $request)) {
80
+ return $cached;
81
+ }
82
+ }
83
+
84
+ if (array_key_exists($request->getRequestMethod(),
85
+ self::$ENTITY_HTTP_METHODS)) {
86
+ $request = $this->processEntityRequest($request);
87
+ }
88
+
89
+ $ch = curl_init();
90
+ curl_setopt_array($ch, $this->curlParams);
91
+ curl_setopt($ch, CURLOPT_URL, $request->getUrl());
92
+ if ($request->getPostBody()) {
93
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody());
94
+ }
95
+
96
+ $requestHeaders = $request->getRequestHeaders();
97
+ if ($requestHeaders && is_array($requestHeaders)) {
98
+ $parsed = array();
99
+ foreach ($requestHeaders as $k => $v) {
100
+ $parsed[] = "$k: $v";
101
+ }
102
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed);
103
+ }
104
+
105
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
106
+ curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent());
107
+ $respData = curl_exec($ch);
108
+
109
+ // Retry if certificates are missing.
110
+ if (curl_errno($ch) == CURLE_SSL_CACERT) {
111
+ error_log('SSL certificate problem, verify that the CA cert is OK.'
112
+ . ' Retrying with the CA cert bundle from google-api-php-client.');
113
+ curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
114
+ $respData = curl_exec($ch);
115
+ }
116
+
117
+ $respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
118
+ $respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
119
+ $curlErrorNum = curl_errno($ch);
120
+ $curlError = curl_error($ch);
121
+ curl_close($ch);
122
+ if ($curlErrorNum != CURLE_OK) {
123
+ throw new Google_IOException("HTTP Error: ($respHttpCode) $curlError");
124
+ }
125
+
126
+ // Parse out the raw response into usable bits
127
+ list($responseHeaders, $responseBody) =
128
+ self::parseHttpResponse($respData, $respHeaderSize);
129
+
130
+ if ($respHttpCode == 304 && $cached) {
131
+ // If the server responded NOT_MODIFIED, return the cached request.
132
+ $this->updateCachedRequest($cached, $responseHeaders);
133
+ return $cached;
134
+ }
135
+
136
+ // Fill in the apiHttpRequest with the response values
137
+ $request->setResponseHttpCode($respHttpCode);
138
+ $request->setResponseHeaders($responseHeaders);
139
+ $request->setResponseBody($responseBody);
140
+ // Store the request in cache (the function checks to see if the request
141
+ // can actually be cached)
142
+ $this->setCachedRequest($request);
143
+ // And finally return it
144
+ return $request;
145
+ }
146
+
147
+ /**
148
+ * Set options that update cURL's default behavior.
149
+ * The list of accepted options are:
150
+ * {@link http://php.net/manual/en/function.curl-setopt.php]
151
+ *
152
+ * @param array $optCurlParams Multiple options used by a cURL session.
153
+ */
154
+ public function setOptions($optCurlParams) {
155
+ foreach ($optCurlParams as $key => $val) {
156
+ $this->curlParams[$key] = $val;
157
+ }
158
+ }
159
+
160
+ /**
161
+ * @param $respData
162
+ * @param $headerSize
163
+ * @return array
164
+ */
165
+ private static function parseHttpResponse($respData, $headerSize) {
166
+ if (stripos($respData, parent::CONNECTION_ESTABLISHED) !== false) {
167
+ $respData = str_ireplace(parent::CONNECTION_ESTABLISHED, '', $respData);
168
+ }
169
+
170
+ if ($headerSize) {
171
+ $responseBody = substr($respData, $headerSize);
172
+ $responseHeaders = substr($respData, 0, $headerSize);
173
+ } else {
174
+ list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
175
+ }
176
+
177
+ $responseHeaders = self::parseResponseHeaders($responseHeaders);
178
+ return array($responseHeaders, $responseBody);
179
+ }
180
+
181
+ private static function parseResponseHeaders($rawHeaders) {
182
+ $responseHeaders = array();
183
+
184
+ $responseHeaderLines = explode("\r\n", $rawHeaders);
185
+ foreach ($responseHeaderLines as $headerLine) {
186
+ if ($headerLine && strpos($headerLine, ':') !== false) {
187
+ list($header, $value) = explode(': ', $headerLine, 2);
188
+ $header = strtolower($header);
189
+ if (isset($responseHeaders[$header])) {
190
+ $responseHeaders[$header] .= "\n" . $value;
191
+ } else {
192
+ $responseHeaders[$header] = $value;
193
+ }
194
+ }
195
+ }
196
+ return $responseHeaders;
197
+ }
198
+ }
lib/Googlefusiontables/io/Google_HttpRequest.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * HTTP Request to be executed by apiIO classes. Upon execution, the
20
+ * responseHttpCode, responseHeaders and responseBody will be filled in.
21
+ *
22
+ * @author Chris Chabot <chabotc@google.com>
23
+ * @author Chirag Shah <chirags@google.com>
24
+ *
25
+ */
26
+ class Google_HttpRequest {
27
+ const USER_AGENT_SUFFIX = "google-api-php-client/0.6.5";
28
+ private $batchHeaders = array(
29
+ 'Content-Type' => 'application/http',
30
+ 'Content-Transfer-Encoding' => 'binary',
31
+ 'MIME-Version' => '1.0',
32
+ 'Content-Length' => ''
33
+ );
34
+
35
+ protected $url;
36
+ protected $requestMethod;
37
+ protected $requestHeaders;
38
+ protected $postBody;
39
+ protected $userAgent;
40
+
41
+ protected $responseHttpCode;
42
+ protected $responseHeaders;
43
+ protected $responseBody;
44
+
45
+ public $accessKey;
46
+
47
+ public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) {
48
+ $this->setUrl($url);
49
+ $this->setRequestMethod($method);
50
+ $this->setRequestHeaders($headers);
51
+ $this->setPostBody($postBody);
52
+
53
+ global $apiConfig;
54
+ if (empty($apiConfig['application_name'])) {
55
+ $this->userAgent = self::USER_AGENT_SUFFIX;
56
+ } else {
57
+ $this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Misc function that returns the base url component of the $url
63
+ * used by the OAuth signing class to calculate the base string
64
+ * @return string The base url component of the $url.
65
+ * @see http://oauth.net/core/1.0a/#anchor13
66
+ */
67
+ public function getBaseUrl() {
68
+ if ($pos = strpos($this->url, '?')) {
69
+ return substr($this->url, 0, $pos);
70
+ }
71
+ return $this->url;
72
+ }
73
+
74
+ /**
75
+ * Misc function that returns an array of the query parameters of the current
76
+ * url used by the OAuth signing class to calculate the signature
77
+ * @return array Query parameters in the query string.
78
+ */
79
+ public function getQueryParams() {
80
+ if ($pos = strpos($this->url, '?')) {
81
+ $queryStr = substr($this->url, $pos + 1);
82
+ $params = array();
83
+ parse_str($queryStr, $params);
84
+ return $params;
85
+ }
86
+ return array();
87
+ }
88
+
89
+ /**
90
+ * @return string HTTP Response Code.
91
+ */
92
+ public function getResponseHttpCode() {
93
+ return (int) $this->responseHttpCode;
94
+ }
95
+
96
+ /**
97
+ * @param int $responseHttpCode HTTP Response Code.
98
+ */
99
+ public function setResponseHttpCode($responseHttpCode) {
100
+ $this->responseHttpCode = $responseHttpCode;
101
+ }
102
+
103
+ /**
104
+ * @return $responseHeaders (array) HTTP Response Headers.
105
+ */
106
+ public function getResponseHeaders() {
107
+ return $this->responseHeaders;
108
+ }
109
+
110
+ /**
111
+ * @return string HTTP Response Body
112
+ */
113
+ public function getResponseBody() {
114
+ return $this->responseBody;
115
+ }
116
+
117
+ /**
118
+ * @param array $headers The HTTP response headers
119
+ * to be normalized.
120
+ */
121
+ public function setResponseHeaders($headers) {
122
+ $headers = Google_Utils::normalize($headers);
123
+ if ($this->responseHeaders) {
124
+ $headers = array_merge($this->responseHeaders, $headers);
125
+ }
126
+
127
+ $this->responseHeaders = $headers;
128
+ }
129
+
130
+ /**
131
+ * @param string $key
132
+ * @return array|boolean Returns the requested HTTP header or
133
+ * false if unavailable.
134
+ */
135
+ public function getResponseHeader($key) {
136
+ return isset($this->responseHeaders[$key])
137
+ ? $this->responseHeaders[$key]
138
+ : false;
139
+ }
140
+
141
+ /**
142
+ * @param string $responseBody The HTTP response body.
143
+ */
144
+ public function setResponseBody($responseBody) {
145
+ $this->responseBody = $responseBody;
146
+ }
147
+
148
+ /**
149
+ * @return string $url The request URL.
150
+ */
151
+
152
+ public function getUrl() {
153
+ return $this->url;
154
+ }
155
+
156
+ /**
157
+ * @return string $method HTTP Request Method.
158
+ */
159
+ public function getRequestMethod() {
160
+ return $this->requestMethod;
161
+ }
162
+
163
+ /**
164
+ * @return array $headers HTTP Request Headers.
165
+ */
166
+ public function getRequestHeaders() {
167
+ return $this->requestHeaders;
168
+ }
169
+
170
+ /**
171
+ * @param string $key
172
+ * @return array|boolean Returns the requested HTTP header or
173
+ * false if unavailable.
174
+ */
175
+ public function getRequestHeader($key) {
176
+ return isset($this->requestHeaders[$key])
177
+ ? $this->requestHeaders[$key]
178
+ : false;
179
+ }
180
+
181
+ /**
182
+ * @return string $postBody HTTP Request Body.
183
+ */
184
+ public function getPostBody() {
185
+ return $this->postBody;
186
+ }
187
+
188
+ /**
189
+ * @param string $url the url to set
190
+ */
191
+ public function setUrl($url) {
192
+ if (substr($url, 0, 4) == 'http') {
193
+ $this->url = $url;
194
+ } else {
195
+ // Force the path become relative.
196
+ if (substr($url, 0, 1) !== '/') {
197
+ $url = '/' . $url;
198
+ }
199
+ global $apiConfig;
200
+ $this->url = $apiConfig['basePath'] . $url;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * @param string $method Set he HTTP Method and normalize
206
+ * it to upper-case, as required by HTTP.
207
+ *
208
+ */
209
+ public function setRequestMethod($method) {
210
+ $this->requestMethod = strtoupper($method);
211
+ }
212
+
213
+ /**
214
+ * @param array $headers The HTTP request headers
215
+ * to be set and normalized.
216
+ */
217
+ public function setRequestHeaders($headers) {
218
+ $headers = Google_Utils::normalize($headers);
219
+ if ($this->requestHeaders) {
220
+ $headers = array_merge($this->requestHeaders, $headers);
221
+ }
222
+ $this->requestHeaders = $headers;
223
+ }
224
+
225
+ /**
226
+ * @param string $postBody the postBody to set
227
+ */
228
+ public function setPostBody($postBody) {
229
+ $this->postBody = $postBody;
230
+ }
231
+
232
+ /**
233
+ * Set the User-Agent Header.
234
+ * @param string $userAgent The User-Agent.
235
+ */
236
+ public function setUserAgent($userAgent) {
237
+ $this->userAgent = $userAgent;
238
+ }
239
+
240
+ /**
241
+ * @return string The User-Agent.
242
+ */
243
+ public function getUserAgent() {
244
+ return $this->userAgent;
245
+ }
246
+
247
+ /**
248
+ * Returns a cache key depending on if this was an OAuth signed request
249
+ * in which case it will use the non-signed url and access key to make this
250
+ * cache key unique per authenticated user, else use the plain request url
251
+ * @return string The md5 hash of the request cache key.
252
+ */
253
+ public function getCacheKey() {
254
+ $key = $this->getUrl();
255
+
256
+ if (isset($this->accessKey)) {
257
+ $key .= $this->accessKey;
258
+ }
259
+
260
+ if (isset($this->requestHeaders['authorization'])) {
261
+ $key .= $this->requestHeaders['authorization'];
262
+ }
263
+
264
+ return md5($key);
265
+ }
266
+
267
+ public function getParsedCacheControl() {
268
+ $parsed = array();
269
+ $rawCacheControl = $this->getResponseHeader('cache-control');
270
+ if ($rawCacheControl) {
271
+ $rawCacheControl = str_replace(', ', '&', $rawCacheControl);
272
+ parse_str($rawCacheControl, $parsed);
273
+ }
274
+
275
+ return $parsed;
276
+ }
277
+
278
+ /**
279
+ * @param string $id
280
+ * @return string A string representation of the HTTP Request.
281
+ */
282
+ public function toBatchString($id) {
283
+ $str = '';
284
+ foreach($this->batchHeaders as $key => $val) {
285
+ $str .= $key . ': ' . $val . "\n";
286
+ }
287
+
288
+ $str .= "Content-ID: $id\n";
289
+ $str .= "\n";
290
+
291
+ $path = parse_url($this->getUrl(), PHP_URL_PATH);
292
+ $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n";
293
+ foreach($this->getRequestHeaders() as $key => $val) {
294
+ $str .= $key . ': ' . $val . "\n";
295
+ }
296
+
297
+ if ($this->getPostBody()) {
298
+ $str .= "\n";
299
+ $str .= $this->getPostBody();
300
+ }
301
+
302
+ return $str;
303
+ }
304
+ }
lib/Googlefusiontables/io/Google_HttpStreamIO.php ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Http Streams based implementation of Google_IO.
20
+ *
21
+ * @author Stuart Langley <slangley@google.com>
22
+ */
23
+
24
+ require_once 'Google_CacheParser.php';
25
+
26
+ class Google_HttpStreamIO extends Google_IO {
27
+
28
+ private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
29
+
30
+ private static $DEFAULT_HTTP_CONTEXT = array(
31
+ "follow_location" => 0,
32
+ "ignore_errors" => 1,
33
+ );
34
+
35
+ private static $DEFAULT_SSL_CONTEXT = array(
36
+ "verify_peer" => true,
37
+ );
38
+
39
+ /**
40
+ * Perform an authenticated / signed apiHttpRequest.
41
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
42
+ * (which can modify the request in what ever way fits the auth mechanism)
43
+ * and then calls Google_HttpStreamIO::makeRequest on the signed request
44
+ *
45
+ * @param Google_HttpRequest $request
46
+ * @return Google_HttpRequest The resulting HTTP response including the
47
+ * responseHttpCode, responseHeaders and responseBody.
48
+ */
49
+ public function authenticatedRequest(Google_HttpRequest $request) {
50
+ $request = Google_Client::$auth->sign($request);
51
+ return $this->makeRequest($request);
52
+ }
53
+
54
+ /**
55
+ * Execute a apiHttpRequest
56
+ *
57
+ * @param Google_HttpRequest $request the http request to be executed
58
+ * @return Google_HttpRequest http request with the response http code,
59
+ * response headers and response body filled in
60
+ * @throws Google_IOException on curl or IO error
61
+ */
62
+ public function makeRequest(Google_HttpRequest $request) {
63
+ // First, check to see if we have a valid cached version.
64
+ $cached = $this->getCachedRequest($request);
65
+ if ($cached !== false) {
66
+ if (!$this->checkMustRevaliadateCachedRequest($cached, $request)) {
67
+ return $cached;
68
+ }
69
+ }
70
+
71
+ $default_options = stream_context_get_options(stream_context_get_default());
72
+
73
+ $requestHttpContext = array_key_exists('http', $default_options) ?
74
+ $default_options['http'] : array();
75
+ if (array_key_exists($request->getRequestMethod(),
76
+ self::$ENTITY_HTTP_METHODS)) {
77
+ $request = $this->processEntityRequest($request);
78
+ }
79
+
80
+ if ($request->getPostBody()) {
81
+ $requestHttpContext["content"] = $request->getPostBody();
82
+ }
83
+
84
+ $requestHeaders = $request->getRequestHeaders();
85
+ if ($requestHeaders && is_array($requestHeaders)) {
86
+ $headers = "";
87
+ foreach($requestHeaders as $k => $v) {
88
+ $headers .= "$k: $v\n";
89
+ }
90
+ $requestHttpContext["header"] = $headers;
91
+ }
92
+
93
+ $requestHttpContext["method"] = $request->getRequestMethod();
94
+ $requestHttpContext["user_agent"] = $request->getUserAgent();
95
+
96
+ $requestSslContext = array_key_exists('ssl', $default_options) ?
97
+ $default_options['ssl'] : array();
98
+
99
+ if (!array_key_exists("cafile", $requestSslContext)) {
100
+ $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem';
101
+ }
102
+
103
+ $options = array("http" => array_merge(self::$DEFAULT_HTTP_CONTEXT,
104
+ $requestHttpContext),
105
+ "ssl" => array_merge(self::$DEFAULT_SSL_CONTEXT,
106
+ $requestSslContext));
107
+
108
+ $context = stream_context_create($options);
109
+
110
+ $response_data = file_get_contents($request->getUrl(),
111
+ false,
112
+ $context);
113
+
114
+ if (false === $response_data) {
115
+ throw new Google_IOException("HTTP Error: Unable to connect");
116
+ }
117
+
118
+ $respHttpCode = $this->getHttpResponseCode($http_response_header);
119
+ $responseHeaders = $this->getHttpResponseHeaders($http_response_header);
120
+
121
+ if ($respHttpCode == 304 && $cached) {
122
+ // If the server responded NOT_MODIFIED, return the cached request.
123
+ $this->updateCachedRequest($cached, $responseHeaders);
124
+ return $cached;
125
+ }
126
+
127
+ $request->setResponseHttpCode($respHttpCode);
128
+ $request->setResponseHeaders($responseHeaders);
129
+ $request->setResponseBody($response_data);
130
+ // Store the request in cache (the function checks to see if the request
131
+ // can actually be cached)
132
+ $this->setCachedRequest($request);
133
+ return $request;
134
+ }
135
+
136
+ /**
137
+ * Set options that update the transport implementation's behavior.
138
+ * @param $options
139
+ */
140
+ public function setOptions($options) {
141
+ }
142
+
143
+ private function getHttpResponseCode($response_headers) {
144
+ $header_count = count($response_headers);
145
+
146
+ for ($i = 0; $i < $header_count; $i++) {
147
+ $header = $response_headers[$i];
148
+ if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) {
149
+ $response = explode(' ', $header);
150
+ return $response[1];
151
+ }
152
+ }
153
+ return 'UNKNOWN';
154
+ }
155
+
156
+ private function getHttpResponseHeaders($response_headers) {
157
+ $header_count = count($response_headers);
158
+ $headers = array();
159
+
160
+ for ($i = 0; $i < $header_count; $i++) {
161
+ $header = $response_headers[$i];
162
+ $header_parts = explode(':', $header);
163
+ if (count($header_parts) == 2) {
164
+ $headers[$header_parts[0]] = $header_parts[1];
165
+ }
166
+ }
167
+
168
+ return $headers;
169
+ }
170
+ }
lib/Googlefusiontables/io/Google_IO.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once 'io/Google_HttpRequest.php';
19
+ require_once 'io/Google_HttpStreamIO.php';
20
+ require_once 'io/Google_CurlIO.php';
21
+ require_once 'io/Google_REST.php';
22
+
23
+ /**
24
+ * Abstract IO class
25
+ *
26
+ * @author Chris Chabot <chabotc@google.com>
27
+ */
28
+ abstract class Google_IO {
29
+ const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
30
+ const FORM_URLENCODED = 'application/x-www-form-urlencoded';
31
+ /**
32
+ * An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
33
+ * on that signed request. Used for when a request should be authenticated
34
+ * @param Google_HttpRequest $request
35
+ * @return Google_HttpRequest $request
36
+ */
37
+ abstract function authenticatedRequest(Google_HttpRequest $request);
38
+
39
+ /**
40
+ * Executes a apIHttpRequest and returns the resulting populated httpRequest
41
+ * @param Google_HttpRequest $request
42
+ * @return Google_HttpRequest $request
43
+ */
44
+ abstract function makeRequest(Google_HttpRequest $request);
45
+
46
+ /**
47
+ * Set options that update the transport implementation's behavior.
48
+ * @param $options
49
+ */
50
+ abstract function setOptions($options);
51
+
52
+ /**
53
+ * @visible for testing.
54
+ * Cache the response to an HTTP request if it is cacheable.
55
+ * @param Google_HttpRequest $request
56
+ * @return bool Returns true if the insertion was successful.
57
+ * Otherwise, return false.
58
+ */
59
+ protected function setCachedRequest(Google_HttpRequest $request) {
60
+ // Determine if the request is cacheable.
61
+ if (Google_CacheParser::isResponseCacheable($request)) {
62
+ Google_Client::$cache->set($request->getCacheKey(), $request);
63
+ return true;
64
+ }
65
+
66
+ return false;
67
+ }
68
+
69
+ /**
70
+ * @visible for testing.
71
+ * @param Google_HttpRequest $request
72
+ * @return Google_HttpRequest|bool Returns the cached object or
73
+ * false if the operation was unsuccessful.
74
+ */
75
+ protected function getCachedRequest(Google_HttpRequest $request) {
76
+ if (false == Google_CacheParser::isRequestCacheable($request)) {
77
+ false;
78
+ }
79
+
80
+ return Google_Client::$cache->get($request->getCacheKey());
81
+ }
82
+
83
+ /**
84
+ * @visible for testing
85
+ * Process an http request that contains an enclosed entity.
86
+ * @param Google_HttpRequest $request
87
+ * @return Google_HttpRequest Processed request with the enclosed entity.
88
+ */
89
+ protected function processEntityRequest(Google_HttpRequest $request) {
90
+ $postBody = $request->getPostBody();
91
+ $contentType = $request->getRequestHeader("content-type");
92
+
93
+ // Set the default content-type as application/x-www-form-urlencoded.
94
+ if (false == $contentType) {
95
+ $contentType = self::FORM_URLENCODED;
96
+ $request->setRequestHeaders(array('content-type' => $contentType));
97
+ }
98
+
99
+ // Force the payload to match the content-type asserted in the header.
100
+ if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
101
+ $postBody = http_build_query($postBody, '', '&');
102
+ $request->setPostBody($postBody);
103
+ }
104
+
105
+ // Make sure the content-length header is set.
106
+ if (!$postBody || is_string($postBody)) {
107
+ $postsLength = strlen($postBody);
108
+ $request->setRequestHeaders(array('content-length' => $postsLength));
109
+ }
110
+
111
+ return $request;
112
+ }
113
+
114
+ /**
115
+ * Check if an already cached request must be revalidated, and if so update
116
+ * the request with the correct ETag headers.
117
+ * @param Google_HttpRequest $cached A previously cached response.
118
+ * @param Google_HttpRequest $request The outbound request.
119
+ * return bool If the cached object needs to be revalidated, false if it is
120
+ * still current and can be re-used.
121
+ */
122
+ protected function checkMustRevaliadateCachedRequest($cached, $request) {
123
+ if (Google_CacheParser::mustRevalidate($cached)) {
124
+ $addHeaders = array();
125
+ if ($cached->getResponseHeader('etag')) {
126
+ // [13.3.4] If an entity tag has been provided by the origin server,
127
+ // we must use that entity tag in any cache-conditional request.
128
+ $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
129
+ } elseif ($cached->getResponseHeader('date')) {
130
+ $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
131
+ }
132
+
133
+ $request->setRequestHeaders($addHeaders);
134
+ return true;
135
+ } else {
136
+ return false;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Update a cached request, using the headers from the last response.
142
+ * @param Google_HttpRequest $cached A previously cached response.
143
+ * @param mixed Associative array of response headers from the last request.
144
+ */
145
+ protected function updateCachedRequest($cached, $responseHeaders) {
146
+ if (isset($responseHeaders['connection'])) {
147
+ $hopByHop = array_merge(
148
+ self::$HOP_BY_HOP,
149
+ explode(',', $responseHeaders['connection'])
150
+ );
151
+
152
+ $endToEnd = array();
153
+ foreach($hopByHop as $key) {
154
+ if (isset($responseHeaders[$key])) {
155
+ $endToEnd[$key] = $responseHeaders[$key];
156
+ }
157
+ }
158
+ $cached->setResponseHeaders($endToEnd);
159
+ }
160
+ }
161
+ }
lib/Googlefusiontables/io/Google_REST.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * This class implements the RESTful transport of apiServiceRequest()'s
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ * @author Chirag Shah <chirags@google.com>
23
+ */
24
+ class Google_REST {
25
+ /**
26
+ * Executes a apiServiceRequest using a RESTful call by transforming it into
27
+ * an apiHttpRequest, and executed via apiIO::authenticatedRequest().
28
+ *
29
+ * @param Google_HttpRequest $req
30
+ * @return array decoded result
31
+ * @throws Google_ServiceException on server side error (ie: not authenticated,
32
+ * invalid or malformed post body, invalid url)
33
+ */
34
+ static public function execute(Google_HttpRequest $req) {
35
+ $httpRequest = Google_Client::$io->makeRequest($req);
36
+ $decodedResponse = self::decodeHttpResponse($httpRequest);
37
+ $ret = isset($decodedResponse['data'])
38
+ ? $decodedResponse['data'] : $decodedResponse;
39
+ return $ret;
40
+ }
41
+
42
+
43
+ /**
44
+ * Decode an HTTP Response.
45
+ * @static
46
+ * @throws Google_ServiceException
47
+ * @param Google_HttpRequest $response The http response to be decoded.
48
+ * @return mixed|null
49
+ */
50
+ public static function decodeHttpResponse($response) {
51
+ $code = $response->getResponseHttpCode();
52
+ $body = $response->getResponseBody();
53
+ $decoded = null;
54
+
55
+ if ((intVal($code)) >= 300) {
56
+ $decoded = json_decode($body, true);
57
+ $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
58
+ if ($decoded != null && isset($decoded['error']['message']) && isset($decoded['error']['code'])) {
59
+ // if we're getting a json encoded error definition, use that instead of the raw response
60
+ // body for improved readability
61
+ $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
62
+ } else {
63
+ $err .= ": ($code) $body";
64
+ }
65
+
66
+ throw new Google_ServiceException($err, $code, null, $decoded['error']['errors']);
67
+ }
68
+
69
+ // Only attempt to decode the response, if the response code wasn't (204) 'no content'
70
+ if ($code != '204') {
71
+ $decoded = json_decode($body, true);
72
+ if ($decoded === null || $decoded === "") {
73
+ throw new Google_ServiceException("Invalid json in service response: $body");
74
+ }
75
+ }
76
+ return $decoded;
77
+ }
78
+
79
+ /**
80
+ * Parse/expand request parameters and create a fully qualified
81
+ * request uri.
82
+ * @static
83
+ * @param string $servicePath
84
+ * @param string $restPath
85
+ * @param array $params
86
+ * @return string $requestUrl
87
+ */
88
+ static function createRequestUri($servicePath, $restPath, $params) {
89
+ $requestUrl = $servicePath . $restPath;
90
+ $uriTemplateVars = array();
91
+ $queryVars = array();
92
+ foreach ($params as $paramName => $paramSpec) {
93
+ // Discovery v1.0 puts the canonical location under the 'location' field.
94
+ if (! isset($paramSpec['location'])) {
95
+ $paramSpec['location'] = $paramSpec['restParameterType'];
96
+ }
97
+
98
+ if ($paramSpec['type'] == 'boolean') {
99
+ $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
100
+ }
101
+ if ($paramSpec['location'] == 'path') {
102
+ $uriTemplateVars[$paramName] = $paramSpec['value'];
103
+ } else {
104
+ if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
105
+ foreach ($paramSpec['value'] as $value) {
106
+ $queryVars[] = $paramName . '=' . rawurlencode($value);
107
+ }
108
+ } else {
109
+ $queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']);
110
+ }
111
+ }
112
+ }
113
+
114
+ if (count($uriTemplateVars)) {
115
+ $uriTemplateParser = new URI_Template_Parser($requestUrl);
116
+ $requestUrl = $uriTemplateParser->expand($uriTemplateVars);
117
+ }
118
+ //FIXME work around for the the uri template lib which url encodes
119
+ // the @'s & confuses our servers.
120
+ $requestUrl = str_replace('%40', '@', $requestUrl);
121
+
122
+ if (count($queryVars)) {
123
+ $requestUrl .= '?' . implode($queryVars, '&');
124
+ }
125
+
126
+ return $requestUrl;
127
+ }
128
+ }
lib/Googlefusiontables/io/cacerts.pem ADDED
@@ -0,0 +1,738 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Certifcate Authority certificates for validating SSL connections.
2
+ #
3
+ # This file contains PEM format certificates generated from
4
+ # http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt
5
+ #
6
+ # ***** BEGIN LICENSE BLOCK *****
7
+ # Version: MPL 1.1/GPL 2.0/LGPL 2.1
8
+ #
9
+ # The contents of this file are subject to the Mozilla Public License Version
10
+ # 1.1 (the "License"); you may not use this file except in compliance with
11
+ # the License. You may obtain a copy of the License at
12
+ # http://www.mozilla.org/MPL/
13
+ #
14
+ # Software distributed under the License is distributed on an "AS IS" basis,
15
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16
+ # for the specific language governing rights and limitations under the
17
+ # License.
18
+ #
19
+ # The Original Code is the Netscape security libraries.
20
+ #
21
+ # The Initial Developer of the Original Code is
22
+ # Netscape Communications Corporation.
23
+ # Portions created by the Initial Developer are Copyright (C) 1994-2000
24
+ # the Initial Developer. All Rights Reserved.
25
+ #
26
+ # Contributor(s):
27
+ #
28
+ # Alternatively, the contents of this file may be used under the terms of
29
+ # either the GNU General Public License Version 2 or later (the "GPL"), or
30
+ # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
+ # in which case the provisions of the GPL or the LGPL are applicable instead
32
+ # of those above. If you wish to allow use of your version of this file only
33
+ # under the terms of either the GPL or the LGPL, and not to allow others to
34
+ # use your version of this file under the terms of the MPL, indicate your
35
+ # decision by deleting the provisions above and replace them with the notice
36
+ # and other provisions required by the GPL or the LGPL. If you do not delete
37
+ # the provisions above, a recipient may use your version of this file under
38
+ # the terms of any one of the MPL, the GPL or the LGPL.
39
+ #
40
+ # ***** END LICENSE BLOCK *****
41
+
42
+ Verisign/RSA Secure Server CA
43
+ =============================
44
+
45
+ -----BEGIN CERTIFICATE-----
46
+ MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
47
+ A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
48
+ VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
49
+ MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
50
+ BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
51
+ dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
52
+ ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
53
+ 0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
54
+ uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
55
+ hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
56
+ YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
57
+ 1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
58
+ -----END CERTIFICATE-----
59
+
60
+ Thawte Personal Basic CA
61
+ ========================
62
+
63
+ -----BEGIN CERTIFICATE-----
64
+ MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx
65
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
66
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
67
+ ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj
68
+ IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X
69
+ DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw
70
+ EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
71
+ ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
72
+ dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD
73
+ QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN
74
+ BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53
75
+ dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK
76
+ wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7
77
+ G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF
78
+ AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
79
+ c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P
80
+ 9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
81
+ -----END CERTIFICATE-----
82
+
83
+ Thawte Personal Premium CA
84
+ ==========================
85
+
86
+ -----BEGIN CERTIFICATE-----
87
+ MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx
88
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
89
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
90
+ ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p
91
+ dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv
92
+ bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa
93
+ QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY
94
+ BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u
95
+ IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl
96
+ bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu
97
+ Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs
98
+ Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI
99
+ Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD
100
+ ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
101
+ SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
102
+ b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh
103
+ KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ
104
+ -----END CERTIFICATE-----
105
+
106
+ Thawte Personal Freemail CA
107
+ ===========================
108
+
109
+ -----BEGIN CERTIFICATE-----
110
+ MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx
111
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
112
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
113
+ ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt
114
+ YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu
115
+ Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT
116
+ AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa
117
+ MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp
118
+ b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG
119
+ cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh
120
+ d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY
121
+ DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E
122
+ rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq
123
+ uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
124
+ BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
125
+ MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa
126
+ /RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei
127
+ gQ==
128
+ -----END CERTIFICATE-----
129
+
130
+ Thawte Server CA
131
+ ================
132
+
133
+ -----BEGIN CERTIFICATE-----
134
+ MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
135
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
136
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
137
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
138
+ MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
139
+ MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
140
+ DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
141
+ dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
142
+ cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
143
+ DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
144
+ gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
145
+ yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
146
+ L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
147
+ EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
148
+ 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
149
+ QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
150
+ qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
151
+ -----END CERTIFICATE-----
152
+
153
+ Thawte Premium Server CA
154
+ ========================
155
+
156
+ -----BEGIN CERTIFICATE-----
157
+ MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
158
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
159
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
160
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
161
+ dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
162
+ MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
163
+ MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
164
+ A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
165
+ b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
166
+ cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
167
+ bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
168
+ VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
169
+ ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
170
+ uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
171
+ 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
172
+ hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
173
+ pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
174
+ -----END CERTIFICATE-----
175
+
176
+ Equifax Secure CA
177
+ =================
178
+
179
+ -----BEGIN CERTIFICATE-----
180
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
181
+ UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
182
+ dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
183
+ MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
184
+ dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
185
+ AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
186
+ BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
187
+ cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
188
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
189
+ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
190
+ aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
191
+ ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
192
+ IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
193
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
194
+ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
195
+ 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
196
+ 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
197
+ -----END CERTIFICATE-----
198
+
199
+ Verisign Class 1 Public Primary Certification Authority
200
+ =======================================================
201
+
202
+ -----BEGIN CERTIFICATE-----
203
+ MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
204
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
205
+ c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
206
+ NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
207
+ VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp
208
+ bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
209
+ jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N
210
+ H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR
211
+ 4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN
212
+ BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo
213
+ EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5
214
+ FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx
215
+ lA==
216
+ -----END CERTIFICATE-----
217
+
218
+ Verisign Class 2 Public Primary Certification Authority
219
+ =======================================================
220
+
221
+ -----BEGIN CERTIFICATE-----
222
+ MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG
223
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
224
+ cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
225
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
226
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
227
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
228
+ ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
229
+ YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
230
+ FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
231
+ CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg
232
+ J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc
233
+ r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
234
+ -----END CERTIFICATE-----
235
+
236
+ Verisign Class 3 Public Primary Certification Authority
237
+ =======================================================
238
+
239
+ -----BEGIN CERTIFICATE-----
240
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
241
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
242
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
243
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
244
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
245
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
246
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
247
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
248
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
249
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
250
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
251
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
252
+ -----END CERTIFICATE-----
253
+
254
+ Verisign Class 1 Public Primary Certification Authority - G2
255
+ ============================================================
256
+
257
+ -----BEGIN CERTIFICATE-----
258
+ MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
259
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
260
+ c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
261
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
262
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
263
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
264
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
265
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
266
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
267
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
268
+ AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
269
+ VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
270
+ Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
271
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
272
+ h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
273
+ uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
274
+ DzFc6PLZ
275
+ -----END CERTIFICATE-----
276
+
277
+ Verisign Class 2 Public Primary Certification Authority - G2
278
+ ============================================================
279
+
280
+ -----BEGIN CERTIFICATE-----
281
+ MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
282
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
283
+ YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
284
+ MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
285
+ aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
286
+ Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
287
+ MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
288
+ IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
289
+ KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
290
+ eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
291
+ AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
292
+ HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
293
+ DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
294
+ AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
295
+ nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
296
+ rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
297
+ jBJ7xUS0rg==
298
+ -----END CERTIFICATE-----
299
+
300
+ Verisign Class 3 Public Primary Certification Authority - G2
301
+ ============================================================
302
+
303
+ -----BEGIN CERTIFICATE-----
304
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
305
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
306
+ c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
307
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
308
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
309
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
310
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
311
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
312
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
313
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
314
+ AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
315
+ pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
316
+ 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
317
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
318
+ U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
319
+ F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
320
+ oJ2daZH9
321
+ -----END CERTIFICATE-----
322
+
323
+ Verisign Class 4 Public Primary Certification Authority - G2
324
+ ============================================================
325
+
326
+ -----BEGIN CERTIFICATE-----
327
+ MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
328
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
329
+ c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
330
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
331
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
332
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
333
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg
334
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
335
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
336
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
337
+ AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM
338
+ HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK
339
+ qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID
340
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj
341
+ cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
342
+ cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP
343
+ T8qAkbYp
344
+ -----END CERTIFICATE-----
345
+
346
+ Verisign Class 1 Public Primary Certification Authority - G3
347
+ ============================================================
348
+
349
+ -----BEGIN CERTIFICATE-----
350
+ MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
351
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
352
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
353
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
354
+ aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
355
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
356
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
357
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
358
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
359
+ IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
360
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
361
+ nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
362
+ 8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
363
+ ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
364
+ PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
365
+ 6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
366
+ n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
367
+ qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
368
+ wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
369
+ ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
370
+ pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
371
+ E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
372
+ -----END CERTIFICATE-----
373
+
374
+ Verisign Class 2 Public Primary Certification Authority - G3
375
+ ============================================================
376
+
377
+ -----BEGIN CERTIFICATE-----
378
+ MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
379
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
380
+ aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
381
+ IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
382
+ Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
383
+ eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
384
+ BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
385
+ Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
386
+ Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
387
+ Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
388
+ IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
389
+ J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
390
+ JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
391
+ wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
392
+ koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
393
+ qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
394
+ Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
395
+ xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
396
+ 7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
397
+ sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
398
+ sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
399
+ cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
400
+ -----END CERTIFICATE-----
401
+
402
+ Verisign Class 3 Public Primary Certification Authority - G3
403
+ ============================================================
404
+
405
+ -----BEGIN CERTIFICATE-----
406
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
407
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
408
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
409
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
410
+ aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
411
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
412
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
413
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
414
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
415
+ IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
416
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
417
+ N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
418
+ KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
419
+ kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
420
+ CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
421
+ Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
422
+ imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
423
+ 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
424
+ DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
425
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
426
+ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
427
+ TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
428
+ -----END CERTIFICATE-----
429
+
430
+ Verisign Class 4 Public Primary Certification Authority - G3
431
+ ============================================================
432
+
433
+ -----BEGIN CERTIFICATE-----
434
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
435
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
436
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
437
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
438
+ aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
439
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
440
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
441
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
442
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
443
+ IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
444
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
445
+ GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
446
+ +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
447
+ U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
448
+ NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
449
+ ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
450
+ ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
451
+ CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
452
+ g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
453
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
454
+ 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
455
+ bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
456
+ -----END CERTIFICATE-----
457
+
458
+ Equifax Secure Global eBusiness CA
459
+ ==================================
460
+
461
+ -----BEGIN CERTIFICATE-----
462
+ MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
463
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
464
+ ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
465
+ MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
466
+ dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
467
+ c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
468
+ UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
469
+ 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
470
+ o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
471
+ MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
472
+ aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
473
+ A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
474
+ Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
475
+ 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
476
+ -----END CERTIFICATE-----
477
+
478
+ Equifax Secure eBusiness CA 1
479
+ =============================
480
+
481
+ -----BEGIN CERTIFICATE-----
482
+ MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
483
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
484
+ ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
485
+ MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
486
+ LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
487
+ KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
488
+ RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
489
+ WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
490
+ Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
491
+ AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
492
+ eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
493
+ zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
494
+ WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
495
+ /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
496
+ -----END CERTIFICATE-----
497
+
498
+ Equifax Secure eBusiness CA 2
499
+ =============================
500
+
501
+ -----BEGIN CERTIFICATE-----
502
+ MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
503
+ UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj
504
+ dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0
505
+ NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD
506
+ VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B
507
+ AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G
508
+ vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/
509
+ BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C
510
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX
511
+ MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl
512
+ IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw
513
+ NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq
514
+ y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF
515
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
516
+ A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
517
+ 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1
518
+ E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
519
+ -----END CERTIFICATE-----
520
+
521
+ Thawte Time Stamping CA
522
+ =======================
523
+
524
+ -----BEGIN CERTIFICATE-----
525
+ MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx
526
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
527
+ BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd
528
+ BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN
529
+ MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g
530
+ Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG
531
+ A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l
532
+ c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT
533
+ 6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa
534
+ Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL
535
+ 8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB
536
+ Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC
537
+ 9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ
538
+ pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ
539
+ CayJSdM=
540
+ -----END CERTIFICATE-----
541
+
542
+ thawte Primary Root CA
543
+ ======================
544
+
545
+ -----BEGIN CERTIFICATE-----
546
+ MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
547
+ qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
548
+ Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
549
+ MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
550
+ BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
551
+ NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
552
+ LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
553
+ A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
554
+ IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
555
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
556
+ W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
557
+ 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
558
+ 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
559
+ Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
560
+ NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
561
+ MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
562
+ r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
563
+ DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
564
+ YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
565
+ xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
566
+ /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
567
+ LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
568
+ jVaMaA==
569
+ -----END CERTIFICATE-----
570
+
571
+ VeriSign Class 3 Public Primary Certification Authority - G5
572
+ ============================================================
573
+
574
+ -----BEGIN CERTIFICATE-----
575
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
576
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
577
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
578
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
579
+ ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
580
+ aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
581
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
582
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
583
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
584
+ U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
585
+ aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
586
+ nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
587
+ t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
588
+ SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
589
+ BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
590
+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
591
+ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
592
+ BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
593
+ BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
594
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
595
+ MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
596
+ p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
597
+ 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
598
+ WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
599
+ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
600
+ hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
601
+ -----END CERTIFICATE-----
602
+
603
+ Entrust.net Secure Server Certification Authority
604
+ =================================================
605
+
606
+ -----BEGIN CERTIFICATE-----
607
+ MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
608
+ VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
609
+ ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
610
+ KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
611
+ ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
612
+ MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
613
+ ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
614
+ b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
615
+ bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
616
+ U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
617
+ A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
618
+ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
619
+ wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
620
+ AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
621
+ oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
622
+ BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
623
+ dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
624
+ MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
625
+ b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
626
+ dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
627
+ MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
628
+ E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
629
+ MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
630
+ hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
631
+ 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
632
+ 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
633
+ -----END CERTIFICATE-----
634
+
635
+ Go Daddy Certification Authority Root Certificate Bundle
636
+ ========================================================
637
+
638
+ -----BEGIN CERTIFICATE-----
639
+ MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
640
+ ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
641
+ RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
642
+ MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
643
+ QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
644
+ b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
645
+ b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
646
+ YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
647
+ AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
648
+ KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
649
+ VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
650
+ SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
651
+ cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
652
+ 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
653
+ MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
654
+ kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
655
+ BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
656
+ BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
657
+ c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
658
+ AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
659
+ BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
660
+ OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
661
+ A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
662
+ 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
663
+ RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
664
+ qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
665
+ U+4=
666
+ -----END CERTIFICATE-----
667
+ -----BEGIN CERTIFICATE-----
668
+ MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
669
+ bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
670
+ Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
671
+ QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
672
+ BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
673
+ DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
674
+ YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
675
+ aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
676
+ ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
677
+ 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
678
+ N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
679
+ r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
680
+ f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
681
+ U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
682
+ TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
683
+ VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
684
+ SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
685
+ biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
686
+ MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
687
+ AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
688
+ ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
689
+ Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
690
+ IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
691
+ bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
692
+ QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
693
+ WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
694
+ SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
695
+ -----END CERTIFICATE-----
696
+ -----BEGIN CERTIFICATE-----
697
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
698
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
699
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
700
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
701
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
702
+ NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
703
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
704
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
705
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
706
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
707
+ dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
708
+ WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
709
+ v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
710
+ UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
711
+ IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
712
+ W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
713
+ -----END CERTIFICATE-----
714
+
715
+ GeoTrust Global CA
716
+ ==================
717
+
718
+ -----BEGIN CERTIFICATE-----
719
+ MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
720
+ MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
721
+ aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
722
+ WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
723
+ AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
724
+ CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
725
+ OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
726
+ T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
727
+ JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
728
+ Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
729
+ PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
730
+ aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
731
+ TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
732
+ LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
733
+ BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
734
+ dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
735
+ AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
736
+ NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
737
+ b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
738
+ -----END CERTIFICATE-----
lib/Googlefusiontables/key/fusionmaps-681f7b1ccf74.p12 ADDED
Binary file
lib/Googlefusiontables/key/fusionmaps-7915addd10af.p12 ADDED
Binary file
lib/Googlefusiontables/service/Google_BatchRequest.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * @author Chirag Shah <chirags@google.com>
20
+ */
21
+ class Google_BatchRequest {
22
+ /** @var string Multipart Boundary. */
23
+ private $boundary;
24
+
25
+ /** @var array service requests to be executed. */
26
+ private $requests = array();
27
+
28
+ public function __construct($boundary = false) {
29
+ $boundary = (false == $boundary) ? mt_rand() : $boundary;
30
+ $this->boundary = str_replace('"', '', $boundary);
31
+ }
32
+
33
+ public function add(Google_HttpRequest $request, $key = false) {
34
+ if (false == $key) {
35
+ $key = mt_rand();
36
+ }
37
+
38
+ $this->requests[$key] = $request;
39
+ }
40
+
41
+ public function execute() {
42
+ $body = '';
43
+
44
+ /** @var Google_HttpRequest $req */
45
+ foreach($this->requests as $key => $req) {
46
+ $body .= "--{$this->boundary}\n";
47
+ $body .= $req->toBatchString($key) . "\n";
48
+ }
49
+
50
+ $body = rtrim($body);
51
+ $body .= "\n--{$this->boundary}--";
52
+
53
+ global $apiConfig;
54
+ $url = $apiConfig['basePath'] . '/batch';
55
+ $httpRequest = new Google_HttpRequest($url, 'POST');
56
+ $httpRequest->setRequestHeaders(array(
57
+ 'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
58
+
59
+ $httpRequest->setPostBody($body);
60
+ $response = Google_Client::$io->makeRequest($httpRequest);
61
+
62
+ $response = $this->parseResponse($response);
63
+ return $response;
64
+ }
65
+
66
+ public function parseResponse(Google_HttpRequest $response) {
67
+ $contentType = $response->getResponseHeader('content-type');
68
+ $contentType = explode(';', $contentType);
69
+ $boundary = false;
70
+ foreach($contentType as $part) {
71
+ $part = (explode('=', $part, 2));
72
+ if (isset($part[0]) && 'boundary' == trim($part[0])) {
73
+ $boundary = $part[1];
74
+ }
75
+ }
76
+
77
+ $body = $response->getResponseBody();
78
+ if ($body) {
79
+ $body = str_replace("--$boundary--", "--$boundary", $body);
80
+ $parts = explode("--$boundary", $body);
81
+ $responses = array();
82
+
83
+ foreach($parts as $part) {
84
+ $part = trim($part);
85
+ if (!empty($part)) {
86
+ list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
87
+ $metaHeaders = Google_CurlIO::parseResponseHeaders($metaHeaders);
88
+
89
+ $status = substr($part, 0, strpos($part, "\n"));
90
+ $status = explode(" ", $status);
91
+ $status = $status[1];
92
+
93
+ list($partHeaders, $partBody) = Google_CurlIO::parseHttpResponse($part, false);
94
+ $response = new Google_HttpRequest("");
95
+ $response->setResponseHttpCode($status);
96
+ $response->setResponseHeaders($partHeaders);
97
+ $response->setResponseBody($partBody);
98
+ $response = Google_REST::decodeHttpResponse($response);
99
+
100
+ // Need content id.
101
+ $responses[$metaHeaders['content-id']] = $response;
102
+ }
103
+ }
104
+
105
+ return $responses;
106
+ }
107
+
108
+ return null;
109
+ }
110
+ }
lib/Googlefusiontables/service/Google_MediaFileUpload.php ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * @author Chirag Shah <chirags@google.com>
20
+ *
21
+ */
22
+ class Google_MediaFileUpload {
23
+ const UPLOAD_MEDIA_TYPE = 'media';
24
+ const UPLOAD_MULTIPART_TYPE = 'multipart';
25
+ const UPLOAD_RESUMABLE_TYPE = 'resumable';
26
+
27
+ /** @var string $mimeType */
28
+ public $mimeType;
29
+
30
+ /** @var string $data */
31
+ public $data;
32
+
33
+ /** @var bool $resumable */
34
+ public $resumable;
35
+
36
+ /** @var int $chunkSize */
37
+ public $chunkSize;
38
+
39
+ /** @var int $size */
40
+ public $size;
41
+
42
+ /** @var string $resumeUri */
43
+ public $resumeUri;
44
+
45
+ /** @var int $progress */
46
+ public $progress;
47
+
48
+ /**
49
+ * @param $mimeType string
50
+ * @param $data string The bytes you want to upload.
51
+ * @param $resumable bool
52
+ * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
53
+ * only used if resumable=True
54
+ */
55
+ public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
56
+ $this->mimeType = $mimeType;
57
+ $this->data = $data;
58
+ $this->size = strlen($this->data);
59
+ $this->resumable = $resumable;
60
+ if(!$chunkSize) {
61
+ $chunkSize = 256 * 1024;
62
+ }
63
+ $this->chunkSize = $chunkSize;
64
+ $this->progress = 0;
65
+ }
66
+
67
+ public function setFileSize($size) {
68
+ $this->size = $size;
69
+ }
70
+
71
+ /**
72
+ * @static
73
+ * @param $meta
74
+ * @param $params
75
+ * @return array|bool
76
+ */
77
+ public static function process($meta, &$params) {
78
+ $payload = array();
79
+ $meta = is_string($meta) ? json_decode($meta, true) : $meta;
80
+ $uploadType = self::getUploadType($meta, $payload, $params);
81
+ if (!$uploadType) {
82
+ // Process as a normal API request.
83
+ return false;
84
+ }
85
+
86
+ // Process as a media upload request.
87
+ $params['uploadType'] = array(
88
+ 'type' => 'string',
89
+ 'location' => 'query',
90
+ 'value' => $uploadType,
91
+ );
92
+
93
+ $mimeType = isset($params['mimeType'])
94
+ ? $params['mimeType']['value']
95
+ : false;
96
+ unset($params['mimeType']);
97
+
98
+ if (!$mimeType) {
99
+ $mimeType = $payload['content-type'];
100
+ }
101
+
102
+ if (isset($params['file'])) {
103
+ // This is a standard file upload with curl.
104
+ $file = $params['file']['value'];
105
+ unset($params['file']);
106
+ return self::processFileUpload($file, $mimeType);
107
+ }
108
+
109
+ $data = isset($params['data'])
110
+ ? $params['data']['value']
111
+ : false;
112
+ unset($params['data']);
113
+
114
+ if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
115
+ $payload['content-type'] = $mimeType;
116
+ $payload['postBody'] = is_string($meta) ? $meta : json_encode($meta);
117
+
118
+ } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
119
+ // This is a simple media upload.
120
+ $payload['content-type'] = $mimeType;
121
+ $payload['postBody'] = $data;
122
+ }
123
+
124
+ elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
125
+ // This is a multipart/related upload.
126
+ $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
127
+ $boundary = str_replace('"', '', $boundary);
128
+ $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
129
+ $related = "--$boundary\r\n";
130
+ $related .= "Content-Type: application/json; charset=UTF-8\r\n";
131
+ $related .= "\r\n" . json_encode($meta) . "\r\n";
132
+ $related .= "--$boundary\r\n";
133
+ $related .= "Content-Type: $mimeType\r\n";
134
+ $related .= "Content-Transfer-Encoding: base64\r\n";
135
+ $related .= "\r\n" . base64_encode($data) . "\r\n";
136
+ $related .= "--$boundary--";
137
+ $payload['postBody'] = $related;
138
+ }
139
+
140
+ return $payload;
141
+ }
142
+
143
+ /**
144
+ * Prepares a standard file upload via cURL.
145
+ * @param $file
146
+ * @param $mime
147
+ * @return array Includes the processed file name.
148
+ * @visible For testing.
149
+ */
150
+ public static function processFileUpload($file, $mime) {
151
+ if (!$file) return array();
152
+ if (substr($file, 0, 1) != '@') {
153
+ $file = '@' . $file;
154
+ }
155
+
156
+ // This is a standard file upload with curl.
157
+ $params = array('postBody' => array('file' => $file));
158
+ if ($mime) {
159
+ $params['content-type'] = $mime;
160
+ }
161
+
162
+ return $params;
163
+ }
164
+
165
+ /**
166
+ * Valid upload types:
167
+ * - resumable (UPLOAD_RESUMABLE_TYPE)
168
+ * - media (UPLOAD_MEDIA_TYPE)
169
+ * - multipart (UPLOAD_MULTIPART_TYPE)
170
+ * - none (false)
171
+ * @param $meta
172
+ * @param $payload
173
+ * @param $params
174
+ * @return bool|string
175
+ */
176
+ public static function getUploadType($meta, &$payload, &$params) {
177
+ if (isset($params['mediaUpload'])
178
+ && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
179
+ $upload = $params['mediaUpload']['value'];
180
+ unset($params['mediaUpload']);
181
+ $payload['content-type'] = $upload->mimeType;
182
+ if (isset($upload->resumable) && $upload->resumable) {
183
+ return self::UPLOAD_RESUMABLE_TYPE;
184
+ }
185
+ }
186
+
187
+ // Allow the developer to override the upload type.
188
+ if (isset($params['uploadType'])) {
189
+ return $params['uploadType']['value'];
190
+ }
191
+
192
+ $data = isset($params['data']['value'])
193
+ ? $params['data']['value'] : false;
194
+
195
+ if (false == $data && false == isset($params['file'])) {
196
+ // No upload data available.
197
+ return false;
198
+ }
199
+
200
+ if (isset($params['file'])) {
201
+ return self::UPLOAD_MEDIA_TYPE;
202
+ }
203
+
204
+ if (false == $meta) {
205
+ return self::UPLOAD_MEDIA_TYPE;
206
+ }
207
+
208
+ return self::UPLOAD_MULTIPART_TYPE;
209
+ }
210
+
211
+
212
+ public function nextChunk(Google_HttpRequest $req, $chunk=false) {
213
+ if (false == $this->resumeUri) {
214
+ $this->resumeUri = $this->getResumeUri($req);
215
+ }
216
+
217
+ if (false == $chunk) {
218
+ $chunk = substr($this->data, $this->progress, $this->chunkSize);
219
+ }
220
+
221
+ $lastBytePos = $this->progress + strlen($chunk) - 1;
222
+ $headers = array(
223
+ 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
224
+ 'content-type' => $req->getRequestHeader('content-type'),
225
+ 'content-length' => $this->chunkSize,
226
+ 'expect' => '',
227
+ );
228
+
229
+ $httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
230
+ $response = Google_Client::$io->authenticatedRequest($httpRequest);
231
+ $code = $response->getResponseHttpCode();
232
+ if (308 == $code) {
233
+ $range = explode('-', $response->getResponseHeader('range'));
234
+ $this->progress = $range[1] + 1;
235
+ return false;
236
+ } else {
237
+ return Google_REST::decodeHttpResponse($response);
238
+ }
239
+ }
240
+
241
+ private function getResumeUri(Google_HttpRequest $httpRequest) {
242
+ $result = null;
243
+ $body = $httpRequest->getPostBody();
244
+ if ($body) {
245
+ $httpRequest->setRequestHeaders(array(
246
+ 'content-type' => 'application/json; charset=UTF-8',
247
+ 'content-length' => Google_Utils::getStrLen($body),
248
+ 'x-upload-content-type' => $this->mimeType,
249
+ 'x-upload-content-length' => $this->size,
250
+ 'expect' => '',
251
+ ));
252
+ }
253
+
254
+ $response = Google_Client::$io->makeRequest($httpRequest);
255
+ $location = $response->getResponseHeader('location');
256
+ $code = $response->getResponseHttpCode();
257
+ if (200 == $code && true == $location) {
258
+ return $location;
259
+ }
260
+ throw new Google_Exception("Failed to start the resumable upload");
261
+ }
262
+ }
lib/Googlefusiontables/service/Google_Model.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * This class defines attributes, valid values, and usage which is generated from
20
+ * a given json schema. http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
21
+ *
22
+ * @author Chirag Shah <chirags@google.com>
23
+ *
24
+ */
25
+ class Google_Model {
26
+ public function __construct( /* polymorphic */ ) {
27
+ if (func_num_args() == 1 && is_array(func_get_arg(0))) {
28
+ // Initialize the model with the array's contents.
29
+ $array = func_get_arg(0);
30
+ $this->mapTypes($array);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Initialize this object's properties from an array.
36
+ *
37
+ * @param array $array Used to seed this object's properties.
38
+ * @return void
39
+ */
40
+ protected function mapTypes($array) {
41
+ foreach ($array as $key => $val) {
42
+ $this->$key = $val;
43
+
44
+ $keyTypeName = "__$key" . 'Type';
45
+ $keyDataType = "__$key" . 'DataType';
46
+ if ($this->useObjects() && property_exists($this, $keyTypeName)) {
47
+ if ($this->isAssociativeArray($val)) {
48
+ if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
49
+ foreach($val as $arrayKey => $arrayItem) {
50
+ $val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem);
51
+ }
52
+ $this->$key = $val;
53
+ } else {
54
+ $this->$key = $this->createObjectFromName($keyTypeName, $val);
55
+ }
56
+ } else if (is_array($val)) {
57
+ $arrayObject = array();
58
+ foreach ($val as $arrayIndex => $arrayItem) {
59
+ $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem);
60
+ }
61
+ $this->$key = $arrayObject;
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Returns true only if the array is associative.
69
+ * @param array $array
70
+ * @return bool True if the array is associative.
71
+ */
72
+ protected function isAssociativeArray($array) {
73
+ if (!is_array($array)) {
74
+ return false;
75
+ }
76
+ $keys = array_keys($array);
77
+ foreach($keys as $key) {
78
+ if (is_string($key)) {
79
+ return true;
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
85
+ /**
86
+ * Given a variable name, discover its type.
87
+ *
88
+ * @param $name
89
+ * @param $item
90
+ * @return object The object from the item.
91
+ */
92
+ private function createObjectFromName($name, $item) {
93
+ $type = $this->$name;
94
+ return new $type($item);
95
+ }
96
+
97
+ protected function useObjects() {
98
+ global $apiConfig;
99
+ return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
100
+ }
101
+
102
+ /**
103
+ * Verify if $obj is an array.
104
+ * @throws Google_Exception Thrown if $obj isn't an array.
105
+ * @param array $obj Items that should be validated.
106
+ * @param string $type Array items should be of this type.
107
+ * @param string $method Method expecting an array as an argument.
108
+ */
109
+ public function assertIsArray($obj, $type, $method) {
110
+ if ($obj && !is_array($obj)) {
111
+ throw new Google_Exception("Incorrect parameter type passed to $method(), expected an"
112
+ . " array containing items of type $type.");
113
+ }
114
+ }
115
+ }
lib/Googlefusiontables/service/Google_Service.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ class Google_Service {
19
+ public $version;
20
+ public $servicePath;
21
+ public $resource;
22
+ }
lib/Googlefusiontables/service/Google_ServiceResource.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Implements the actual methods/resources of the discovered Google API using magic function
20
+ * calling overloading (__call()), which on call will see if the method name (plus.activities.list)
21
+ * is available in this service, and if so construct an apiHttpRequest representing it.
22
+ *
23
+ * @author Chris Chabot <chabotc@google.com>
24
+ * @author Chirag Shah <chirags@google.com>
25
+ *
26
+ */
27
+ class Google_ServiceResource {
28
+ // Valid query parameters that work, but don't appear in discovery.
29
+ private $stackParameters = array(
30
+ 'alt' => array('type' => 'string', 'location' => 'query'),
31
+ 'boundary' => array('type' => 'string', 'location' => 'query'),
32
+ 'fields' => array('type' => 'string', 'location' => 'query'),
33
+ 'trace' => array('type' => 'string', 'location' => 'query'),
34
+ 'userIp' => array('type' => 'string', 'location' => 'query'),
35
+ 'userip' => array('type' => 'string', 'location' => 'query'),
36
+ 'quotaUser' => array('type' => 'string', 'location' => 'query'),
37
+ 'file' => array('type' => 'complex', 'location' => 'body'),
38
+ 'data' => array('type' => 'string', 'location' => 'body'),
39
+ 'mimeType' => array('type' => 'string', 'location' => 'header'),
40
+ 'uploadType' => array('type' => 'string', 'location' => 'query'),
41
+ 'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
42
+ );
43
+
44
+ /** @var Google_Service $service */
45
+ private $service;
46
+
47
+ /** @var string $serviceName */
48
+ private $serviceName;
49
+
50
+ /** @var string $resourceName */
51
+ private $resourceName;
52
+
53
+ /** @var array $methods */
54
+ private $methods;
55
+
56
+ public function __construct($service, $serviceName, $resourceName, $resource) {
57
+ $this->service = $service;
58
+ $this->serviceName = $serviceName;
59
+ $this->resourceName = $resourceName;
60
+ $this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource);
61
+ }
62
+
63
+ /**
64
+ * @param $name
65
+ * @param $arguments
66
+ * @return Google_HttpRequest|array
67
+ * @throws Google_Exception
68
+ */
69
+ public function __call($name, $arguments) {
70
+ if (! isset($this->methods[$name])) {
71
+ throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
72
+ }
73
+ $method = $this->methods[$name];
74
+ $parameters = $arguments[0];
75
+
76
+ // postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it
77
+ $postBody = null;
78
+ if (isset($parameters['postBody'])) {
79
+ if (is_object($parameters['postBody'])) {
80
+ $this->stripNull($parameters['postBody']);
81
+ }
82
+
83
+ // Some APIs require the postBody to be set under the data key.
84
+ if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) {
85
+ if (!isset($parameters['postBody']['data'])) {
86
+ $rawBody = $parameters['postBody'];
87
+ unset($parameters['postBody']);
88
+ $parameters['postBody']['data'] = $rawBody;
89
+ }
90
+ }
91
+
92
+ $postBody = is_array($parameters['postBody']) || is_object($parameters['postBody'])
93
+ ? json_encode($parameters['postBody'])
94
+ : $parameters['postBody'];
95
+ unset($parameters['postBody']);
96
+
97
+ if (isset($parameters['optParams'])) {
98
+ $optParams = $parameters['optParams'];
99
+ unset($parameters['optParams']);
100
+ $parameters = array_merge($parameters, $optParams);
101
+ }
102
+ }
103
+
104
+ if (!isset($method['parameters'])) {
105
+ $method['parameters'] = array();
106
+ }
107
+
108
+ $method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
109
+ foreach ($parameters as $key => $val) {
110
+ if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
111
+ throw new Google_Exception("($name) unknown parameter: '$key'");
112
+ }
113
+ }
114
+ if (isset($method['parameters'])) {
115
+ foreach ($method['parameters'] as $paramName => $paramSpec) {
116
+ if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
117
+ throw new Google_Exception("($name) missing required param: '$paramName'");
118
+ }
119
+ if (isset($parameters[$paramName])) {
120
+ $value = $parameters[$paramName];
121
+ $parameters[$paramName] = $paramSpec;
122
+ $parameters[$paramName]['value'] = $value;
123
+ unset($parameters[$paramName]['required']);
124
+ } else {
125
+ unset($parameters[$paramName]);
126
+ }
127
+ }
128
+ }
129
+
130
+ // Discovery v1.0 puts the canonical method id under the 'id' field.
131
+ if (! isset($method['id'])) {
132
+ $method['id'] = $method['rpcMethod'];
133
+ }
134
+
135
+ // Discovery v1.0 puts the canonical path under the 'path' field.
136
+ if (! isset($method['path'])) {
137
+ $method['path'] = $method['restPath'];
138
+ }
139
+
140
+ $servicePath = $this->service->servicePath;
141
+
142
+ // Process Media Request
143
+ $contentType = false;
144
+ if (isset($method['mediaUpload'])) {
145
+ $media = Google_MediaFileUpload::process($postBody, $parameters);
146
+ if ($media) {
147
+ $contentType = isset($media['content-type']) ? $media['content-type']: null;
148
+ $postBody = isset($media['postBody']) ? $media['postBody'] : null;
149
+ $servicePath = $method['mediaUpload']['protocols']['simple']['path'];
150
+ $method['path'] = '';
151
+ }
152
+ }
153
+
154
+ $url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
155
+ $httpRequest = new Google_HttpRequest($url, $method['httpMethod'], null, $postBody);
156
+ if ($postBody) {
157
+ $contentTypeHeader = array();
158
+ if (isset($contentType) && $contentType) {
159
+ $contentTypeHeader['content-type'] = $contentType;
160
+ } else {
161
+ $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
162
+ $contentTypeHeader['content-length'] = Google_Utils::getStrLen($postBody);
163
+ }
164
+ $httpRequest->setRequestHeaders($contentTypeHeader);
165
+ }
166
+
167
+ $httpRequest = Google_Client::$auth->sign($httpRequest);
168
+ if (Google_Client::$useBatch) {
169
+ return $httpRequest;
170
+ }
171
+
172
+ // Terminate immediately if this is a resumable request.
173
+ if (isset($parameters['uploadType']['value'])
174
+ && Google_MediaFileUpload::UPLOAD_RESUMABLE_TYPE == $parameters['uploadType']['value']) {
175
+ $contentTypeHeader = array();
176
+ if (isset($contentType) && $contentType) {
177
+ $contentTypeHeader['content-type'] = $contentType;
178
+ }
179
+ $httpRequest->setRequestHeaders($contentTypeHeader);
180
+ if ($postBody) {
181
+ $httpRequest->setPostBody($postBody);
182
+ }
183
+ return $httpRequest;
184
+ }
185
+
186
+ return Google_REST::execute($httpRequest);
187
+ }
188
+
189
+ public function useObjects() {
190
+ global $apiConfig;
191
+ return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
192
+ }
193
+
194
+ protected function stripNull(&$o) {
195
+ $o = (array) $o;
196
+ foreach ($o as $k => $v) {
197
+ if ($v === null || strstr($k, "\0*\0__")) {
198
+ unset($o[$k]);
199
+ }
200
+ elseif (is_object($v) || is_array($v)) {
201
+ $this->stripNull($o[$k]);
202
+ }
203
+ }
204
+ }
205
+ }
lib/Googlefusiontables/service/Google_Utils.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Collection of static utility methods used for convenience across
20
+ * the client library.
21
+ *
22
+ * @author Chirag Shah <chirags@google.com>
23
+ */
24
+ class Google_Utils {
25
+ public static function urlSafeB64Encode($data) {
26
+ $b64 = base64_encode($data);
27
+ $b64 = str_replace(array('+', '/', '\r', '\n', '='),
28
+ array('-', '_'),
29
+ $b64);
30
+ return $b64;
31
+ }
32
+
33
+ public static function urlSafeB64Decode($b64) {
34
+ $b64 = str_replace(array('-', '_'),
35
+ array('+', '/'),
36
+ $b64);
37
+ return base64_decode($b64);
38
+ }
39
+
40
+ /**
41
+ * Misc function used to count the number of bytes in a post body, in the world of multi-byte chars
42
+ * and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane
43
+ * manner at the moment.
44
+ *
45
+ * This algorithm was originally developed for the
46
+ * Solar Framework by Paul M. Jones
47
+ *
48
+ * @link http://solarphp.com/
49
+ * @link http://svn.solarphp.com/core/trunk/Solar/Json.php
50
+ * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
51
+ * @param string $str
52
+ * @return int The number of bytes in a string.
53
+ */
54
+ static public function getStrLen($str) {
55
+ $strlenVar = strlen($str);
56
+ $d = $ret = 0;
57
+ for ($count = 0; $count < $strlenVar; ++ $count) {
58
+ $ordinalValue = ord($str{$ret});
59
+ switch (true) {
60
+ case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
61
+ // characters U-00000000 - U-0000007F (same as ASCII)
62
+ $ret ++;
63
+ break;
64
+
65
+ case (($ordinalValue & 0xE0) == 0xC0):
66
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
67
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
68
+ $ret += 2;
69
+ break;
70
+
71
+ case (($ordinalValue & 0xF0) == 0xE0):
72
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
73
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
74
+ $ret += 3;
75
+ break;
76
+
77
+ case (($ordinalValue & 0xF8) == 0xF0):
78
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
79
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
80
+ $ret += 4;
81
+ break;
82
+
83
+ case (($ordinalValue & 0xFC) == 0xF8):
84
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
85
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
86
+ $ret += 5;
87
+ break;
88
+
89
+ case (($ordinalValue & 0xFE) == 0xFC):
90
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
91
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
92
+ $ret += 6;
93
+ break;
94
+ default:
95
+ $ret ++;
96
+ }
97
+ }
98
+ return $ret;
99
+ }
100
+
101
+ /**
102
+ * Normalize all keys in an array to lower-case.
103
+ * @param array $arr
104
+ * @return array Normalized array.
105
+ */
106
+ public static function normalize($arr) {
107
+ if (!is_array($arr)) {
108
+ return array();
109
+ }
110
+
111
+ $normalized = array();
112
+ foreach ($arr as $key => $val) {
113
+ $normalized[strtolower($key)] = $val;
114
+ }
115
+ return $normalized;
116
+ }
117
+ }
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>CP_Ordermapmarker</name>
4
+ <version>1.0.1</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>This module shows Order Shipping Address as a Marker in Maps using Google Fusion Table Application.</summary>
10
+ <description>This module shows Order Shipping Address as a Marker in Maps using Google Fusion Table Application. Generally we have to store our order data to Fusion Tables . Our Orders so far have to be entered manually with co-ordinates data into fusion table. We need to have Google Developer Web Application(Project) created having Oauth Permission. We also need to create Service key for Authentication.(in .p12 Extension format)</description>
11
+ <notes>Stable Version</notes>
12
+ <authors><author><name>Digisha</name><user>Digisha_patel</user><email>digishappatel@gmail.com</email></author></authors>
13
+ <date>2016-05-19</date>
14
+ <time>07:07:41</time>
15
+ <contents><target name="magelocal"><dir name="CP"><dir name="Ordermapmarker"><dir name="Block"><file name="Index.php" hash="b31658ba80941f09c6d2fe576f36d63a"/></dir><dir name="Helper"><file name="Data.php" hash="909208e5a1e77c2d5c54f852d3c28b48"/><file name="Ordermapmarker.php" hash="ab6f5855c5cb33c280c57fa9a1404daa"/></dir><dir name="Model"><file name="Observer.php" hash="db036e98ff1a0dbbd7ce67b32d4bfb30"/></dir><dir name="controllers"><file name="IndexController.php" hash="25bdd0fff0639857f7e65b0638f032b0"/></dir><dir name="etc"><file name="adminhtml.xml" hash="095fb005457d56c8291753afbb7d3f10"/><file name="config.xml" hash="7e5ac833c09f44e35def2235c2adce52"/><file name="system.xml" hash="cfe119803ee33bbb9bf030b5695e501f"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="CP_Ordermapmarker.xml" hash="518109326fa5f488ec567668b6e80164"/></dir></target><target name="magelib"><dir name="Googlefusiontables"><file name="Google_Client.php" hash="a788bb8bd2f4e5b204a69be3e150411e"/><file name="Googleclient.php" hash="a5a73c8581a4cb4bdbd145898ecf2386"/><dir name="auth"><file name="Google_AssertionCredentials.php" hash="de9e46c822cefc04b8a596df355659ee"/><file name="Google_Auth.php" hash="15873dc9c390eadbd5da2c0297062d7c"/><file name="Google_AuthNone.php" hash="093b237c59e2e085a97e664c0ce88ebe"/><file name="Google_LoginTicket.php" hash="4397ba773564c0c73f32ae118c24b5d2"/><file name="Google_OAuth2.php" hash="acb231b360ef09762189f89776789982"/><file name="Google_P12Signer.php" hash="e33e570503ed42cf7d25dd6c32d67263"/><file name="Google_PemVerifier.php" hash="e9fb745bc98981953a270e0374e77e58"/><file name="Google_Signer.php" hash="b89eb963b836860aa622c2111915e5ac"/><file name="Google_Verifier.php" hash="08c9de305f4824c6d94d7c40bfe7be58"/></dir><dir name="cache"><file name="Google_ApcCache.php" hash="69f000c3254d148bc775c6555e275ee0"/><file name="Google_Cache.php" hash="98c92b5d919c9143e68230e612298a9b"/><file name="Google_FileCache.php" hash="5aea15f8d2d1e00c2b021c18dd04f1e4"/><file name="Google_MemcacheCache.php" hash="6a19d2af53375dbfa5e7362127a22bff"/></dir><file name="config.php" hash="a26b007bba5cd5ca2a48bb13f8e7b663"/><dir name="contrib"><file name="Google_FusiontablesService.php" hash="d562f5a06bb381c85716ffb74fd6abaf"/></dir><dir name="external"><file name="URITemplateParser.php" hash="dc829ddd424801e2bc4bf83bfb5e698c"/></dir><dir name="io"><file name="Google_CacheParser.php" hash="a8524de4f95bc1d237a7bf22dd3dfb8a"/><file name="Google_CurlIO.php" hash="b497f8b2421548bde3aa5e87eb864c19"/><file name="Google_HttpRequest.php" hash="c641ca370e3a9610408bb7285ada0b89"/><file name="Google_HttpStreamIO.php" hash="9b61279ea37fc99571d1a03c729b0a67"/><file name="Google_IO.php" hash="5a358c599f39443e821d16e1e8d2470f"/><file name="Google_REST.php" hash="61d31688aa7d280b1e7a7ba4d2fcacb3"/><file name="cacerts.pem" hash="0d806fdc81ab8ec35c05b7dc869dd208"/></dir><dir name="key"><file name="fusionmaps-681f7b1ccf74.p12" hash="e358a81d1c01864f23b55224533cb863"/><file name="fusionmaps-7915addd10af.p12" hash="71f0a8e8b6373e7427d0d9ce5d38ecc3"/></dir><dir name="service"><file name="Google_BatchRequest.php" hash="3c5f95b98e16d1a4a3fe2cc5cf48e9b6"/><file name="Google_MediaFileUpload.php" hash="90cc23d99dd18df03372a02a67de1cce"/><file name="Google_Model.php" hash="2c2d018441c8e8971d6b0528f3f34d85"/><file name="Google_Service.php" hash="213627cf943f19478ecd263b1f253195"/><file name="Google_ServiceResource.php" hash="6aa5fb58563b8c00f5210a9b3db67def"/><file name="Google_Utils.php" hash="612e0e3add05f9cf52d64065b7ccca0a"/></dir></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.1.0.0</min><max>5.5.12</max></php></required></dependencies>
18
+ </package>