├── README.mdown ├── config └── setup.php ├── controllers ├── components │ └── empty └── google_contacts_controller.php ├── google plugin.PHPEditProject ├── google_app_controller.php ├── libs ├── google_api_base.php └── google_api_contacts.php ├── models ├── datasources │ ├── ad_sense.php │ ├── ad_words.php │ ├── analytics.php │ ├── blogger.php │ ├── calendar.php │ ├── checkout.php │ ├── finance.php │ └── google_contacts_source.php └── google_contacts.php ├── vendors └── img │ └── chart_cache │ └── empty └── views ├── google_contacts └── index.ctp └── helpers ├── analytics.php ├── chart.php └── map.php /README.mdown: -------------------------------------------------------------------------------- 1 | ## CakePHP Google Api (CakePHP GApi) 2 | 3 | This is a set of datasources, models, libs and helpers that will eventually allow you to use all of Google's api's in CakePhp. 4 | 5 | ### Structure definition of CakePHP GApi (So far) 6 | 7 | #### General Google API methods like auth and sendRequest 8 | 9 | ##### app/libs/ 10 | google_api_base.php 11 | 12 | #### Specific API interaction classes that extend google_api_base (to be used by datasources) 13 | 14 | ##### app/libs/ 15 | google_api_adsense.php 16 | google_api_adwords.php 17 | google_api_analytics.php 18 | google_api_blogger.php 19 | google_api_calendar.php 20 | google_api_checkout.php 21 | google_api_contacts.php 22 | google_api_finance.php 23 | 24 | #### Models 25 | 26 | ##### app/models/ 27 | google_contacts.php 28 | google_adwords.php 29 | google_analytics.php 30 | google_blogger.php 31 | google_calendar.php 32 | google_checkout.php 33 | google_contacts.php 34 | google_finance.php 35 | 36 | #### Datasources 37 | 38 | ##### app/models/datasources/ 39 | google_contacts_source.php 40 | google_adwords_source.php 41 | google_analytics_source.php 42 | google_blogger_source.php 43 | google_calendar_source.php 44 | google_checkout_source.php 45 | google_contacts_source.php 46 | google_finance_source.php 47 | 48 | #### Helpers (dogmatic should define this) 49 | 50 | ##### app/views/helpers/ 51 | chart.php 52 | map.php 53 | 54 | ## Contributing to CakePHP GApi 55 | 56 | If you want to help to contribute in any way, please fork the project on github. 57 | Once you have forked the project you can commit your code. 58 | Once you have pushed your changes back to github send a pull request, and your changes will be reviewed and merged in or feedback will be given. 59 | 60 | Order in branches new code should have is the following: 61 | 62 | Dev -> Testing -> Master 63 | 64 | We should keep master branch free of bugs as they are filtered by dev and testing branches. 65 | 66 | ## Issues with CakePHP GApi 67 | 68 | For a list of known issues have a look at the issue tracker. 69 | If you have issues with CakePHP GApi, you can report them at the issue tracker. 70 | 71 | You can look at the wiki for more information on how to use CakePHP GApi, they will all be self containing so that you are able to use them independent form each other. 72 | 73 | ## License 74 | 75 | The MIT License (http://www.opensource.org/licenses/mit-license.php) 76 | Redistributions of files must retain the above copyright notice. 77 | 78 | ## Contact Collaborators (dogmatic, imekinox) 79 | 80 | Look for us on irc.freenode.net #cakephp or send a message on github to us. 81 | -------------------------------------------------------------------------------- /config/setup.php: -------------------------------------------------------------------------------- 1 | 'xxxxxxxx-x' 54 | ); 55 | Configure::write( 'Google.Analytics', $analytics ); 56 | } 57 | } -------------------------------------------------------------------------------- /controllers/components/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/controllers/components/empty -------------------------------------------------------------------------------- /controllers/google_contacts_controller.php: -------------------------------------------------------------------------------- 1 | 'google_contacts', 26 | * 'accounttype' => 'GOOGLE', 27 | * 'email' => 'YOUR GOOGLE EMAIL', 28 | * 'passwd' => 'YOUR PASSWORD', 29 | * 'source' => 'companyName-applicationName-versionID', 30 | * 'database' => '' 31 | * ); 32 | * 33 | * Find methods: 34 | * - all 35 | * - count 36 | * - first 37 | * 38 | * Default limit is 25 use limit for override. 39 | * 40 | * Available conditions: 41 | * - start-index -> For paging 42 | * - updated-min -> The lower bound on entry update dates. 43 | * - orderby -> Sorting criterion. The only supported value is lastmodified. 44 | * - showdeleted -> Include deleted contacts in the returned contacts feed. 45 | * - group -> Value of this parameter specifies group ID 46 | * 47 | * Restult array keys: 48 | * 49 | * Use debug($this->GoogleContacts->_schema); to get structured array 50 | * 51 | */ 52 | 53 | class GoogleContactsController extends AppController 54 | { 55 | var $name = 'GoogleContacts'; 56 | var $uses = array( 'GoogleContacts' , 'Users' ); 57 | 58 | function testFindById(){ 59 | $contact = $this->GoogleContacts->find('first'); 60 | $res = $this->GoogleContacts->findById($contact['id']); 61 | debug($res); 62 | die(); 63 | } 64 | 65 | function testFindAllLimit5(){ 66 | $contact = $this->GoogleContacts->find('all', array('limit'=>5)); 67 | debug($contact); 68 | die(); 69 | } 70 | 71 | function testFindAll(){ 72 | $contact = $this->GoogleContacts->find('all'); 73 | debug($contact); 74 | die(); 75 | } 76 | 77 | function testCount(){ 78 | $contact = $this->GoogleContacts->find('count'); 79 | debug($contact); 80 | die(); 81 | } 82 | 83 | function testFindFirst(){ 84 | $contact = $this->GoogleContacts->find('first'); 85 | debug($contact); 86 | die(); 87 | } 88 | 89 | function testUpdate() { 90 | $contact = $this->GoogleContacts->find('first'); 91 | $contact['Name']['fullName'] = "Contact Changed From Cake"; 92 | $this->GoogleContacts->create($contact); 93 | $r = $this->GoogleContacts->save(); 94 | debug($r); 95 | die(); 96 | } 97 | 98 | function index() 99 | { 100 | $contact['title'] = "NEW CONTACT"; 101 | $res = $this->GoogleContacts->create('Juanito'); 102 | debug($res); 103 | $this->GoogleContacts->save($contact); 104 | //debug($r); 105 | } 106 | } -------------------------------------------------------------------------------- /google plugin.PHPEditProject: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /google_app_controller.php: -------------------------------------------------------------------------------- 1 | 'File', 5 | 'name' => 'Google.GoogleConfig', 6 | 'file' => 'config'. DS .'setup.php' 7 | ) 8 | ); 9 | 10 | /** 11 | * Google App Controller class file. 12 | * 13 | * the google_appcontroller file, extends AppController 14 | * 15 | * Copyright (c) 2009 Carl Sutton ( dogmatic69 ) 16 | * 17 | * Licensed under The MIT License 18 | * Redistributions of files must retain the above copyright notice. 19 | * 20 | * @filesource 21 | * @copyright Copyright (c) 2009 Carl Sutton ( dogmatic69 ) 22 | * @link http://www.dogmatic.co.za 23 | * @package google 24 | * @subpackage google.controllers.google_app_controller 25 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License 26 | */ 27 | class GoogleAppController extends AppController 28 | { 29 | function beforeFilter() 30 | { 31 | parent::beforeFilter(); 32 | 33 | $GoogleConfig = new GoogleConfig(); 34 | } 35 | } 36 | ?> -------------------------------------------------------------------------------- /libs/google_api_base.php: -------------------------------------------------------------------------------- 1 | HttpSocket = new HttpSocket(); 85 | 86 | // Initializing Cake Session 87 | $session = new CakeSession(); 88 | $session->start(); 89 | 90 | // Validating if curl is available 91 | if (function_exists('curl_init')) { 92 | $this->_method = 'curl'; 93 | } else { 94 | $this->_method = 'fopen'; 95 | } 96 | 97 | //Looking for auth key in cookie of google api client login 98 | $cookie_key = $session->read('GoogleClientLogin'.$_toPost['service'].'._auth_key'); 99 | if ($cookie_key == NULL || $cookie_key == "") { 100 | //Geting auth key via HttpSocket 101 | $results = $this->HttpSocket->post($this->_login_uri, $_toPost); 102 | $first_split = split("\n",$results); 103 | foreach($first_split as $string) { 104 | $arr = split("=",$string); 105 | if ($arr[0] == "Auth") $this->_auth_key = $arr[1]; 106 | } 107 | $session->write('GoogleClientLogin'.$_toPost['service'].'._auth_key', $this->_auth_key); 108 | } else { 109 | $this->_auth_key = $cookie_key; 110 | } 111 | } 112 | 113 | /** 114 | * Send Request 115 | * 116 | * @param string $url URL to do the request 117 | * @param string $method GET or POST 118 | * @return xml object 119 | * @access public 120 | */ 121 | public function sendRequest($url, $action, $content = NULL) { 122 | /* 123 | Could'nt find a way to do it via HttpSocket i got empty result 124 | 125 | $auth['header'] = "Authorization: GoogleLogin auth=" . $this->_auth_key; 126 | $result = $HttpSocket->get("http://www.google.com/m8/feeds/contacts/jc.ekinox@gmail.com/full", array(), $auth); 127 | */ 128 | $header[] = "Authorization: GoogleLogin auth=" . $this->_auth_key; 129 | $header[] = "GData-Version: 3.0"; 130 | switch ($action) { 131 | case "CREATE": 132 | $method = "POST"; 133 | $header[] = "Content-type: application/atom+xml"; 134 | //$header[] = "Content-length: 1"; 135 | $header[] = "If-Match: *"; 136 | break; 137 | case "READ": 138 | $method = "GET"; 139 | break; 140 | case "UPDATE": 141 | $header[] = "Content-type: application/atom+xml"; 142 | $header[] = "X-HTTP-Method-Override: PUT"; 143 | $header[] = "If-Match: *"; 144 | $method = "POST"; 145 | break; 146 | case "DELETE": 147 | break; 148 | } 149 | if ($this->_method == 'curl') { 150 | $ch = curl_init(); 151 | curl_setopt($ch, CURLOPT_URL, $url); 152 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 153 | curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 154 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 155 | if ($action == "UPDATE") { 156 | curl_setopt($ch, CURLOPT_POSTFIELDS,$content); 157 | } 158 | $atom = curl_exec($ch); 159 | curl_close($ch); 160 | } else { 161 | $opts = array( 162 | 'http'=>array( 163 | 'method'=>$method, 164 | 'header'=>implode("\r\n",$header) 165 | ) 166 | ); 167 | $context = stream_context_create($opts); 168 | if ($action == "UPDATE") { 169 | $atom = file_put_contents($url, $content, NULL, $context); 170 | } else { 171 | $atom = file_get_contents($url, false, $context); 172 | } 173 | } 174 | debug("GOOGLE RESPONSE: " . $atom); 175 | $xml_result =& new XML($atom); 176 | return Set::reverse($xml_result); 177 | } 178 | 179 | } -------------------------------------------------------------------------------- /libs/google_api_contacts.php: -------------------------------------------------------------------------------- 1 | array( 45 | 'gd:etag' => array( 46 | 'type' => 'string', 47 | 'null' => true 48 | ), 49 | 'id' => array( 50 | 'type' => 'string', 51 | 'null' => true, 52 | 'length' => 255 53 | ), 54 | 'updated' => array( 55 | 'type' => 'string', 56 | 'null' => true 57 | ), 58 | 'edited' => array( 59 | 'type' => 'string', 60 | 'null' => true 61 | ), 62 | 'category' => array( 63 | 'type' => 'string', 64 | 'null' => true 65 | ), 66 | 'title' => array( 67 | 'type' => 'string', 68 | 'null' => false 69 | ), 70 | 'name' => array( 71 | 'type' => 'string', 72 | 'null' => true 73 | ), 74 | 'nickname' => array( 75 | 'type' => 'string', 76 | 'null' => true 77 | ), 78 | 'birthday' => array( 79 | 'type' => 'string', 80 | 'null' => true 81 | ), 82 | 'organization' => array( 83 | 'title' => array( 84 | 'type' => 'string', 85 | 'null' => true 86 | ), 87 | 'company' => array( 88 | 'type' => 'string', 89 | 'null' => true 90 | ) 91 | ), 92 | 'email' => array( 93 | 'primary' => array( 94 | 'type' => 'boolean', 95 | 'null' => true 96 | ), 97 | 'address' => array( 98 | 'type' => 'string', 99 | 'null' => true 100 | ), 101 | 'category' => array( 102 | 'type' => 'string', 103 | 'null' => true 104 | ) 105 | ), 106 | 'im' => array( 107 | 'address' => array( 108 | 'type' => 'string', 109 | 'null' => true 110 | ), 111 | 'category' => array( 112 | 'type' => 'string', 113 | 'null' => true 114 | ) 115 | ), 116 | 'phones' => array( 117 | 'phone' => array( 118 | 'type' => 'integer', 119 | 'null' => true 120 | ), 121 | 'category' => array( 122 | 'type' => 'string', 123 | 'null' => true 124 | ) 125 | ), 126 | 'address' => array( 127 | 'address' => array( 128 | 'type' => 'string', 129 | 'null' => true 130 | ), 131 | 'category' => array( 132 | 'type' => 'string', 133 | 'null' => true 134 | ) 135 | ), 136 | 'events' => array( 137 | 'date' => array( 138 | 'type' => 'string', 139 | 'null' => true 140 | ), 141 | 'category' => array( 142 | 'type' => 'string', 143 | 'null' => true 144 | ) 145 | ), 146 | 'relations' => array( 147 | 'name' => array( 148 | 'type' => 'string', 149 | 'null' => true 150 | ), 151 | 'category' => array( 152 | 'type' => 'string', 153 | 'null' => true 154 | ) 155 | ), 156 | 'custom' => array( 157 | 'key' => array( 158 | 'type' => 'string', 159 | 'null' => true 160 | ), 161 | 'value' => array( 162 | 'type' => 'string', 163 | 'null' => true 164 | ) 165 | ), 166 | 'websites' => array( 167 | 'address' => array( 168 | 'type' => 'string', 169 | 'null' => true 170 | ), 171 | 'category' => array( 172 | 'type' => 'string', 173 | 'null' => true 174 | ) 175 | ), 176 | 'groups' => array( 177 | 'group_id' => array( 178 | 'type' => 'string', 179 | 'null' => true 180 | ), 181 | 'deleted' => array( 182 | 'type' => 'boolean', 183 | 'null' => true 184 | ) 185 | ) 186 | ) 187 | ); 188 | return $schema; 189 | } 190 | 191 | /** 192 | * Convert Google Contacts schema-based Object into Atom text 193 | * 194 | * @return string $atom 195 | * @access public 196 | */ 197 | public function toAtom($object) { 198 | $atom = ""; 199 | if (isset($object['id'])) { 200 | $atom .= "".$object['id'].""; 201 | } 202 | if (isset($object['updated'])) { 203 | $atom .= "".$object['updated'].""; 204 | } 205 | if (isset($object['edited'])) { 206 | $atom .= "".$object['edited'].""; 207 | } 208 | if (isset($object['Category'])) { 209 | $atom .= ""; 210 | } 211 | if (isset($object['title'])) { 212 | $atom .= "".$object['title'].""; 213 | } 214 | if (isset($object['content'])) { 215 | $atom .= "".$object['content'].""; 216 | } 217 | if (isset($object['Link'])) { 218 | foreach ($object['Link'] as $Link) { 219 | $atom .= ""; 220 | } 221 | } 222 | if (isset($object['Name'])) { 223 | $atom .= ""; 224 | $atom .= "".$object['Name']['fullName'].""; 225 | $atom .= ""; 226 | } 227 | if (isset($object['nickname'])) { 228 | $atom .= "".$object['nickname'].""; 229 | } 230 | if (isset($object['Birthday'])) { 231 | $atom .= ""; 232 | } 233 | if (isset($object['Organization'])) { 234 | $atom .= ""; 235 | $atom .= "".$object['Organization']['orgName'].""; 236 | $atom .= "".$object['Organization']['orgTitle'].""; 237 | $atom .= ""; 238 | } 239 | if (isset($object['Email'])) { 240 | foreach ($object['Email'] as $Email) { 241 | $primary = isset($Email['primary'])?"true":"false"; 242 | $atom .= ""; 243 | } 244 | } 245 | if (isset($object['Im'])) { 246 | foreach ($object['Im'] as $Im) { 247 | $atom .= ""; 248 | } 249 | } 250 | if (isset($object['PhoneNumber'])) { 251 | foreach ($object['PhoneNumber'] as $PhoneNumber) { 252 | $atom .= "".$PhoneNumber['value'].""; 253 | } 254 | } 255 | if (isset($object['StructuredPostalAddress'])) { 256 | foreach ($object['StructuredPostalAddress'] as $StructuredPostalAddress) { 257 | $atom .= ""; 258 | $atom .= "".$StructuredPostalAddress['formattedAddress'].""; 259 | $atom .= ""; 260 | } 261 | } 262 | if (isset($object['Event'])) { 263 | foreach ($object['Event'] as $Event) { 264 | $atom .= ""; 265 | $atom .= ""; 266 | $atom .= ""; 267 | } 268 | } 269 | if (isset($object['Relation'])) { 270 | foreach ($object['Relation'] as $Relation) { 271 | $atom .= "".$Relation['value'].""; 272 | } 273 | } 274 | if (isset($object['UserDefinedField'])) { 275 | foreach ($object['UserDefinedField'] as $UserDefinedField) { 276 | $atom .= ""; 277 | } 278 | } 279 | if (isset($object['Website'])) { 280 | foreach ($object['Website'] as $Website) { 281 | $atom .= ""; 282 | } 283 | } 284 | if (isset($object['GroupMembershipInfo'])) { 285 | foreach ($object['GroupMembershipInfo'] as $GroupMembershipInfo) { 286 | $atom .= ""; 287 | } 288 | } 289 | $atom .= ""; 290 | return $atom; 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /models/datasources/ad_sense.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/ad_sense.php -------------------------------------------------------------------------------- /models/datasources/ad_words.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/ad_words.php -------------------------------------------------------------------------------- /models/datasources/analytics.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/analytics.php -------------------------------------------------------------------------------- /models/datasources/blogger.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/blogger.php -------------------------------------------------------------------------------- /models/datasources/calendar.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/calendar.php -------------------------------------------------------------------------------- /models/datasources/checkout.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/checkout.php -------------------------------------------------------------------------------- /models/datasources/finance.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/models/datasources/finance.php -------------------------------------------------------------------------------- /models/datasources/google_contacts_source.php: -------------------------------------------------------------------------------- 1 | GoogleApiContacts = new GoogleApiContacts($config); 78 | $this->_schema = $this->GoogleApiContacts->getSchema(); 79 | parent::__construct($config); 80 | } 81 | 82 | /** 83 | * Read method for find calls 84 | * 85 | * @param object $model 86 | * @param array $queryData 87 | * @access public 88 | */ 89 | public function read($model, $queryData = array()) { 90 | if (isset($queryData['conditions']['id'])) { 91 | return $this->findById($queryData['conditions']['id']); 92 | } else { 93 | $args['max-results'] = ($queryData['limit'] != null)?$queryData['limit']:'25'; 94 | 95 | //Sorting order direction. Can be either ascending or descending. 96 | if (isset($queryData['order'][0]) && $queryData['order'][0] != NULL) { 97 | //If no order is specified (ascending || descending) google will set default ordering criteria 98 | $args['sortorder'] = $queryData['order'][0]; 99 | } 100 | 101 | if (isset($queryData['conditions'])) { 102 | foreach($queryData['conditions'] AS $key => $value) { 103 | $args[$key] = $value; 104 | } 105 | } 106 | if (isset($queryData['conditions']['query'])) { 107 | $args['q'] = $queryData['conditions']['query']; 108 | } 109 | $query = $this->read_uri . "?" . http_build_query($args, "", "&"); 110 | $result = $this->GoogleApiContacts->sendRequest($query, "READ"); 111 | if (isset($queryData['fields']['COUNT']) && $queryData['fields']['COUNT'] == 1) { 112 | $count[0][0] = array('count'=>count($result['Feed']['Entry'])); 113 | return $count; 114 | } else { 115 | if($queryData['limit'] == 1) { 116 | $tmp[0] = $result['Feed']['Entry']; 117 | } else { 118 | $tmp = $result['Feed']['Entry']; 119 | } 120 | return $tmp; 121 | } 122 | } 123 | } 124 | 125 | /** 126 | * Create method for model 127 | * 128 | * @param object $model 129 | * @param array $fields 130 | * @param array $values 131 | * @access public 132 | */ 133 | public function create($model, $fields = array(), $values = array()) { 134 | $baseObject = $model->data['GoogleContacts']; 135 | debug($baseObject); 136 | // $atom = $this->GoogleApiContacts->toAtom($baseObject); 137 | // return $this->GoogleApiContacts->sendRequest($this->read_uri, "CREATE", $atom); 138 | } 139 | 140 | /** 141 | * Update method for model 142 | * 143 | * @param object $model 144 | * @param array $fields 145 | * @param array $values 146 | * @access public 147 | */ 148 | public function update($model, $fields = array(), $values = array()) { 149 | $baseObject = $model->data['GoogleContacts']; 150 | $atom = $this->GoogleApiContacts->toAtom($baseObject); 151 | $query = $baseObject['Link'][1]['href']; 152 | return $this->GoogleApiContacts->sendRequest($query, "UPDATE", $atom); 153 | } 154 | 155 | /** 156 | * Delete method for model 157 | * 158 | * @param object $model 159 | * @param string $id 160 | * @access public 161 | */ 162 | public function delete($model, $id = null) { 163 | debug("delete"); 164 | } 165 | 166 | /** 167 | * Calculate some specific prameters to find like count before calling read 168 | * 169 | * @param object $model 170 | * @param string $func 171 | * @param array $params 172 | * @access public 173 | */ 174 | public function calculate(&$model, $func, $params = array()) { 175 | $params = (array)$params; 176 | switch (strtolower($func)) { 177 | case 'count': 178 | return array('COUNT' => true); 179 | break; 180 | case 'max': 181 | break; 182 | case 'min': 183 | break; 184 | } 185 | } 186 | 187 | /** 188 | * Handle specific query's 189 | * 190 | * @param array $query 191 | * @param array $params 192 | * @param object $model 193 | * @access public 194 | */ 195 | public function query($query, $params, $model) { 196 | switch ($query) { 197 | case "findById": 198 | $result = $this->GoogleApiContacts->sendRequest($params[0], "READ"); 199 | return $result['Entry']; 200 | break; 201 | } 202 | } 203 | 204 | public function listSources() { 205 | return array('google_contacts'); 206 | } 207 | 208 | public function describe($model) { 209 | return $this->_schema['google_contacts']; 210 | } 211 | 212 | /** 213 | * @todo public function insertQueryData($query, $data, $association, $assocData, $model, $linkModel, $stack) { debug("iq"); } 214 | * @todo public function resolveKey( $model, $key ) { debug("key"); } 215 | * @todo public function rollback( $model ) { debug("rollback"); } 216 | * @todo public function sources( $reset = false ) {} 217 | * @todo public function column( $real ) {} 218 | * @todo public function commit( $model ) { debug("commit"); } 219 | * @todo public function begin( $model ) { debug("begin"); } 220 | * @todo public function __cacheDescription( $object, $data = NULL ){} 221 | * @todo public function __destruct(){} 222 | * @todo public function isInterfaceSupported( $interface ){ debug("interface"); } 223 | * @todo public function lastAffected( $source = NULL ){} 224 | * @todo public function lastInsertId( $source = NULL ){} 225 | * @todo public function lastNumRows( $source = NULL ){} 226 | * @todo public function cakeError( $method, $messages = array ( ) ){ debug("Error"); } 227 | * @todo public function dispatchMethod( $method, $params = array ( ) ){ debug("method" . $method); } 228 | */ 229 | 230 | } -------------------------------------------------------------------------------- /models/google_contacts.php: -------------------------------------------------------------------------------- 1 | data[$this->name]['updated'] = ""; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /vendors/img/chart_cache/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/vendors/img/chart_cache/empty -------------------------------------------------------------------------------- /views/google_contacts/index.ctp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dogmatic69/cakephp_google_plugin/e03f71b713ffa108adb3dce79fad94c6a2cfab35/views/google_contacts/index.ctp -------------------------------------------------------------------------------- /views/helpers/analytics.php: -------------------------------------------------------------------------------- 1 | 'File', 5 | 'name' => 'Google.GoogleConfig', 6 | 'file' => 'config'. DS .'setup.php' 7 | ) 8 | ); 9 | 10 | /** 11 | * Google Analytics Helper class file. 12 | * 13 | * A helper for Analytics. 14 | * 15 | * atm it is just used for the tracking code, but when the code for 16 | * getting stats from analytics is done there will be more here. 17 | * 18 | * Copyright (c) 2009 Carl Sutton ( dogmatic69 ) 19 | * 20 | * Licensed under The MIT License 21 | * Redistributions of files must retain the above copyright notice. 22 | * 23 | * @filesource 24 | * @copyright Copyright (c) 2009 Carl Sutton ( dogmatic69 ) 25 | * @link http://www.dogmatic.co.za 26 | * @package google 27 | * @subpackage google.views.helpers.analytics 28 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License 29 | */ 30 | class AnalyticsHelper extends AppHelper 31 | { 32 | private $__trackingInstalled = false; 33 | 34 | /** 35 | * get the settings for analytics. 36 | */ 37 | function __construct() 38 | { 39 | if ( !Configure::read( 'Google' ) ) 40 | { 41 | $GoogleConfig = new GoogleConfig(); 42 | } 43 | 44 | return true; 45 | } 46 | 47 | /** 48 | * generate tracking code. 49 | * 50 | * generates the tracking code for your site based on the config in 51 | * Configure::read( 'Google.Analytics' ); this will load automaticaly from 52 | * the config file in /google/config/setup.php 53 | * 54 | * @param string $params stuff you would normaly put in pageTracker._trackPageview() 55 | * @return the script generated. 56 | */ 57 | public function tracker( $params = '' ) 58 | { 59 | //already run. 60 | if ( $this->__trackingInstalled ) 61 | { 62 | return true; 63 | } 64 | 65 | $out = ''."\n"; 73 | 74 | $this->__trackingInstalled = true; 75 | 76 | return $out; 77 | } 78 | } 79 | ?> -------------------------------------------------------------------------------- /views/helpers/chart.php: -------------------------------------------------------------------------------- 1 | array( 33 | 'KM', 'GW', 'KE', 'NA', 'LS', 'LR', 'LY', 'MG', 'MW', 'ML', 34 | 'GN', 'GH', 'CG', 'CI', 'DJ', 'EG', 'GQ', 'ER', 'ET', 'GA', 35 | 'GM', 'MR', 'MU', 'YT', 'SO', 'ZA', 'SD', 'SZ', 'TZ', 'TG', 36 | 'TN', 'UG', 'EH', 'SL', 'SC', 'MA', 'MZ', 'NE', 'NG', 'RE', 37 | 'RW', 'SH', 'ST', 'SN', 'ZM', 'BF', 'BI', 'BJ', 'AO', 'CM', 38 | 'CV', 'ZW', 'DZ', 'BW', 'TD', 'CF' 39 | ), 40 | 'Antarctica' => array( 41 | 'GS', 'HM', 'AQ', 'TF', 'BV' 42 | ), 43 | 'Asia' => array( 44 | 'IO', 'AM', 'ID', 'SG', 'KP', 'MM', 'JO', 'JP', 'IN', 'IL', 45 | 'BD', 'PK', 'PH', 'NP', 'BN', 'MN', 'LB', 'HK', 'GE', 'TL', 46 | 'KR', 'CY', 'UZ', 'VN', 'MO', 'TH', 'MY', 'LA', 'KH', 'CC', 47 | 'TW', 'KG', 'LK', 'CX', 'MV', 'CN', 'BT' 48 | ), 49 | 'Europe' => array( 50 | 'MK', 'MC', 'AL', 'BE', 'MT', 'MD', 'ME', 'BY', 'ES', 'SJ', 51 | 'SE', 'CH', 'AD', 'FO', 'TR', 'UA', 'GB', 'SI', 'SK', 'NL', 52 | 'NO', 'PL', 'PT', 'RO', 'RU', 'AT', 'SM', 'RS', 'AX', 'LU', 53 | 'LT', 'FI', 'IT', 'IM', 'IE', 'FR', 'HR', 'GR', 'IS', 'VA', 54 | 'HU', 'GI', 'DE', 'BG', 'LV', 'JE', 'BA', 'EE', 'GG', 'LI', 55 | 'DK', 'CZ' 56 | ), 57 | 'ME' => array( 58 | 'PS', 'OM', 'QA', 'AZ', 'AE', 'TM', 'SA', 'AF', 'KZ', 'SY', 59 | 'TJ', 'YE', 'IQ', 'IR', 'KW', 'BH' 60 | ), 61 | 'North America' => array( 62 | 'GD', 'GP', 'KN', 'DM', 'PM', 'VC', 'AG', 'DO', 'AW', 'AI', 63 | 'SV', 'GL', 'CA', 'TT', 'KY', 'BS', 'US', 'HN', 'AN', 'BB', 64 | 'MS', 'JM', 'MX', 'BZ', 'MQ', 'BM', 'NI', 'CR', 'TC', 'LC', 65 | 'VG', 'PA', 'GT', 'VI', 'CU', 'HT', 'PR' 66 | ), 67 | 'Oceania' => array( 68 | 'WF', 'TK', 'VU', 'TV', 'CK', 'AS', 'UM', 'TO', 'NR', 'PN', 69 | 'PG', 'PW', 'FM', 'MP', 'NF', 'NU', 'NZ', 'NC', 'GU', 'SB', 70 | 'FJ', 'KI', 'MH', 'PF', 'AU', 'WS' 71 | ), 72 | 'South America' => array( 73 | 'CL', 'CO', 'VE', 'BO', 'FK', 'UY', 'GY', 'PE', 'AR', 'BR', 74 | 'PY', 'GF', 'SR', 'EC' 75 | ) 76 | ); 77 | 78 | /** 79 | * Setting up charts. 80 | * 81 | * This setup decides what values can and cant be drawn with the helper. It stops you from 82 | * submitting params for graphs that are not ment to be there. If there is something that is 83 | * not showing in your graph check Chart::debug as it alert you if you added something that is 84 | * not supported. 85 | * 86 | * @var array 87 | * @access public 88 | */ 89 | var $setup = array( 90 | 'pie3d' => array( 91 | //required 92 | 'data' => true, 'labels' => true, 'size' => true, 93 | //optional 94 | 'colors' => true, 95 | 'fill' => array( 'type' => true, 'color' => true, 'angle' => true, 'offset' => true, ), 96 | 'scale' => array( 0 => array( 'min' => true, 'max' => true ) ), 97 | 'title' =>array( 'text' => true, 'color' => true, 'size' => true ), 98 | 'legend' => array( 99 | 'labels' => true, 100 | 'position' => array( 'horizontal' => true, 'vertical' => true ) 101 | ), 102 | 'orientation' => true 103 | ), 104 | 'pie2d' => array( 105 | //required 106 | 'data' => true, 'labels' => true, 'size' => true, 107 | //optional 108 | 'colors' => true, 109 | 'fill' => array( 'type' => true, 'color' => true, 'angle' => true, 'offset' => true, ), 110 | 'scale' => array( 0 => array( 'min' => true, 'max' => true ) ), 111 | 'title' =>array( 'text' => true, 'color' => true, 'size' => true ), 112 | 'legend' => array( 113 | 'labels' => true, 114 | 'position' => array( 'horizontal' => true, 'vertical' => true ) 115 | ), 116 | 'orientation' => true 117 | ), 118 | 'bar' => array( 119 | //required 120 | 'data' => array( 0 => true ), 'labels' => true, 'size' => true, 121 | //optional 122 | 'colors' => true, 123 | 'fill' => array( 'type' => true, 'color' => true, 'angle' => true, 'offset' => true, ), 124 | 'scale' => array( 0 => array( 'min' => true, 'max' => true ) ), 125 | 'title' => array( 'text' => true, 'color' => true, 'size' => true ), 126 | 'legend' => array( 127 | 'labels' => true, 128 | 'position' => array( 'horizontal' => true, 'vertical' => true ) 129 | ), 130 | 'orientation' => true, 131 | 'grid' => true, 132 | 'marker' => array( 133 | 0 => array( 134 | 'shape' => true, 135 | 'color' => true, 136 | 'index' => true, // the key of the data set 137 | 'size' => true, 138 | 'z-index' => true 139 | ) 140 | ), 141 | 'axis_type' => true, 142 | 'axis_labels' => true, 143 | 'axis_label_positions' => true, 144 | 'axis_range' => array(0 => array('start' => true, 'end' => true, 'interval' => false)), 145 | 'axis_styles' => array(0 => array('color' => true, 'font-size' => false, 'alignment' => false, 'drawing_control' => false, 'tick_color' => false)) 146 | 147 | ), 148 | 149 | 150 | 151 | 'line' => array( 152 | //required 153 | 'data' => true, 'labels' => true, 'size' => true, 154 | 155 | 'axis_type' => true, 156 | 'axis_labels' => true, 157 | ) 158 | ); 159 | 160 | /** 161 | * the query that is sent to the api to generate the chart. 162 | * 163 | * @var string 164 | * @access public 165 | */ 166 | var $return = null; 167 | 168 | /** 169 | * turn debug on or off. 170 | * 171 | * @var bool 172 | * @access public 173 | */ 174 | var $debug = false; 175 | 176 | /** 177 | * turn cache on or off. 178 | * 179 | * @var bool 180 | * @access public 181 | */ 182 | var $cache = true; 183 | 184 | /** 185 | * Path to store cached images 186 | * 187 | * @var string 188 | * @access public 189 | */ 190 | var $cachePath = ''; 191 | 192 | /** 193 | * Path to use when displaying cached images 194 | * 195 | * @var string 196 | * @access public 197 | */ 198 | var $cacheImagePath = ''; 199 | 200 | /** 201 | * Do not modify these 202 | */ 203 | /** 204 | * the seperator between params in the url. 205 | * 206 | * @var string 207 | * @access public 208 | */ 209 | var $paramSeperator = '&'; 210 | 211 | /** 212 | * the max size of the graph (height x width). 213 | * 214 | * @var int 215 | * @access private 216 | */ 217 | var $__maxSize = 300000; 218 | 219 | /** 220 | * the api address. 221 | * 222 | * @var string 223 | * @access private 224 | */ 225 | var $__apiUrl = 'http://chart.apis.google.com/chart?'; 226 | 227 | /** 228 | * array of errors. 229 | * 230 | * holds a list of errors / warnings that were generated while trying 231 | * generate the query string for the api 232 | * 233 | * @var array 234 | * @access private 235 | */ 236 | var $__errors = array(); 237 | 238 | /** 239 | * internal to hold origional data for caching. 240 | */ 241 | var $input = array(); 242 | 243 | /** 244 | * Map names to code. 245 | * 246 | * this is used to conver the english names used in the helper to 247 | * the codes needed by google to create the graph. 248 | * 249 | * @var array 250 | * @access public 251 | */ 252 | var $map = array( 253 | 'data' => array( //done 254 | 'code' => 'chd=t:', 255 | 'seperator' => ',' 256 | ), 257 | 'labels' => array( //done 258 | 'code' => 'chl=', 259 | 'seperator' => '|' 260 | ), 261 | 'size' => array( //done 262 | 'code' => 'chs=', 263 | 'seperator' => 'x' 264 | ), 265 | 'colors' => array( 266 | 'code' => 'chco=', 267 | 'seperator' => ',', 268 | 'slice_separator' => '|' 269 | ), 270 | 'solid_fill' => array( //done 271 | 'code' => 'chf=', 272 | 'format' => '%s,%s,%s', //type,style,color 273 | 'seperator' => '|' 274 | ), 275 | 'gradient_file' => array( //gradient and lines ... offset == width 276 | 'code' => 'chf=', 277 | 'format' => '%s,%s,%d,%s,%f', //type,style,angle,color,offset 278 | 'seperator' => '|' 279 | ), 280 | 'special_fill' => array( 281 | 'code' => '', 282 | 'format' => '' 283 | ), 284 | 'scale' => array( 285 | 'code' => 'chds=', 286 | 'seperator' => ',' 287 | ), 288 | 'title' => array( //done 289 | 'code' => 'chtt=', 290 | 'seperator' => '+' 291 | ), 292 | 'title_color' => array( //done 293 | 'code' => 'chts=', 294 | 'seperator' => ',' 295 | ), 296 | 'legend' => array( 297 | 'code' => '', 298 | 'seperator' => '' 299 | ), 300 | 'orientation' => array( 301 | 'code' => 'chp=' 302 | ), 303 | 'axis_type' => array( 304 | 'code' => 'chxt=', 305 | 'seperator' => ',', 306 | 'valid_values' => array('x', 't', 'y', 'r') 307 | ), 308 | 'axis_labels' => array( 309 | 'code' => 'chxl=', 310 | 'seperator' => '|', 311 | 'index_title_seperator' => ':' 312 | ), 313 | 'axis_label_positions' => array( 314 | 'code' => 'chxp', 315 | 'seperator' => ',', 316 | 'index_seperator' => '|' 317 | ), 318 | 'axis_range' => array( 319 | 'code' => 'chxr=', 320 | 'seperator' => ',', 321 | 'index_seperator' => '|' 322 | ), 323 | 'axis_styles' => array( 324 | 'code' => 'chxs=', 325 | 'seperator' => ',', 326 | 'index_seperator' => '|' 327 | ) 328 | ); 329 | 330 | /** 331 | * Map from names to codes. 332 | * 333 | * This is used to generat the maps based on a friendly name. 334 | * 335 | * @var array 336 | * @access public 337 | */ 338 | var $chartTypes = array( 339 | //pie charts 340 | 'pie2d' => 'cht=p', 341 | 'pie3d' => 'cht=p3', 342 | 'concentric' => 'cht=pc', 343 | //bar charts 344 | 'bar' => array( 345 | 'horizontal' => 'cht=bhs', 346 | 'vertical' => 'cht=bvs', 347 | 'horizontal_grouped' => 'cht=bhg', 348 | 'vertical_grouped' => 'cht=bvg' 349 | ), 350 | 351 | //line charts 352 | 'line' => 'cht=lc', 353 | 'spark' => 'cht=ls', 354 | 'compare' => 'cht=lxy', 355 | 356 | // radar 357 | 'radar' => 'cht=r', 358 | //'radar_fill' => 'cht=rs', 359 | 360 | // other 361 | 'scatter' => 'cht=s', 362 | 'venn' => 'cht=v', 363 | 364 | // special 365 | 'meter' => 'cht=gom', 366 | 'map' => 'cht=t', 367 | 'qr_code' => 'cht=qr' 368 | ); 369 | 370 | public function __construct($options = array()) 371 | { 372 | $default = array( 373 | 'cachePath' => APP.'plugins'.DS.'google'.DS.'vendors'.DS.'img'.DS.'chart_cache'.DS, 374 | 'cacheImagePath' => '/google/img/chart_cache/' 375 | ); 376 | 377 | $options = array_merge($default, $options); 378 | 379 | $this->cachePath = $options['cachePath']; 380 | $this->cacheImagePath = $options['cacheImagePath']; 381 | } 382 | 383 | public function test( $name = 'pie3d' ) 384 | { 385 | switch( $name ) 386 | { 387 | case 'pie3d': 388 | return 'Yellow pie chart'; 389 | break; 390 | 391 | case 'pie2d': 392 | return 'Yellow pie chart'; 393 | break; 394 | 395 | case 'bar': 396 | return 'Yellow pie chart'; 397 | break; 398 | 399 | default: 400 | ; 401 | } // switch 402 | } 403 | 404 | function display( $name = null, $data = array(), $absolute = false ) 405 | { 406 | // used for cache 407 | $this->originalData = array( 'name' => $name, 'data' => $data ); 408 | 409 | if ( !$name ) 410 | { 411 | $this->__errors[] = __( 'Please specify what graph you need', true ); 412 | return false; 413 | } 414 | 415 | if ( empty( $data ) ) 416 | { 417 | $this->__errors[] = __( 'No data was given', true ); 418 | return false; 419 | } 420 | 421 | if ( $this->cache && $this->__checkCache($absolute) ) 422 | { 423 | return $this->__checkCache($absolute); 424 | } 425 | 426 | $this->__reset(); 427 | 428 | $this->__setChartType( $name ); 429 | 430 | foreach( $data as $key => $value ) 431 | { 432 | if ( is_array( $name ) ) 433 | { 434 | if ( !isset( $this->setup[$name['name']][$key] ) ) 435 | { 436 | $this->__errors = __( 'Param "'.$key.'" is not supported in chart type "'.$name.'"', true ); 437 | continue; 438 | } 439 | } 440 | else if ( !isset( $this->setup[$name][$key] ) ) 441 | { 442 | $this->__errors = __( 'Param "'.$key.'" is not supported in chart type "'.$name.'"', true ); 443 | continue; 444 | } 445 | 446 | switch( $key ) 447 | { 448 | case 'data': 449 | case 'labels': 450 | $this->__setData( $key, $value ); 451 | break; 452 | 453 | case 'orientation': 454 | $this->__setOrientaion( $value ); 455 | break; 456 | 457 | case 'size': 458 | $this->__setSize( $value ); 459 | break; 460 | 461 | case 'title': 462 | $this->__setTitle( $value ); 463 | break; 464 | 465 | case 'fill': 466 | $this->__setFill( $key, $value ); 467 | break; 468 | 469 | case 'scale': 470 | $this->__setScale( $value ); 471 | break; 472 | 473 | case 'colors': 474 | $this->__setColors($value); 475 | break; 476 | 477 | case 'axis_type': 478 | case 'axis_labels': 479 | case 'axis_label_positions': 480 | case 'axis_range': 481 | case 'axis_style': 482 | $this->__setAxis($key, $value); 483 | break; 484 | 485 | } // switch 486 | } 487 | 488 | return $this->__render( $data ); 489 | } 490 | 491 | function __checkCache() 492 | { 493 | $file = sha1( $this->originalData['name'].serialize( $this->originalData['data'] ) ).'.png'; 494 | 495 | if ( is_file( $this->cachePath.$file ) ) 496 | { 497 | return $this->Html->image($this->cacheImagePath.$file ); 498 | } 499 | else 500 | { 501 | $this->__errors[] = 'File '.$this->cachePath.$file.' does not exist'; 502 | } 503 | } 504 | 505 | function __writeCache( $url ) 506 | { 507 | $file = sha1( $this->originalData['name'].serialize( $this->originalData['data'] ) ).'.png'; 508 | 509 | if(is_writable($this->cachePath)) 510 | { 511 | $contents = file_get_contents( $url ); 512 | 513 | $fp = fopen( $this->cachePath.$file, 'w' ); 514 | fwrite( $fp, $contents ); 515 | fclose( $fp ); 516 | 517 | if ( !is_file( $this->cachePath.$file ) ) 518 | { 519 | $this->__errors[] = __( 'Could not create the cache file', true ); 520 | } 521 | } 522 | } 523 | 524 | function __reset() 525 | { 526 | $this->output = null; 527 | $this->__errors = null; 528 | $this->__debug = null; 529 | $this->return = null; 530 | } 531 | 532 | function __setFill( $key, $data ) 533 | { 534 | if ( !isset( $data[0] ) ) 535 | { 536 | $data = array( $data ); 537 | } 538 | 539 | foreach( $data as $k => $fill ) 540 | { 541 | switch( $fill['position'] ) 542 | { 543 | case 'background': 544 | $param[$k][] = 'bg'; 545 | break; 546 | 547 | case 'chart': 548 | $param[$k][] = 'c'; 549 | break; 550 | 551 | case 'transparency': 552 | $param[$k][] = 'a'; 553 | break; 554 | } // switch 555 | 556 | switch( $fill['type'] ) 557 | { 558 | case 'solid': 559 | $param[$k][] = 's'; 560 | break; 561 | } // switch 562 | 563 | if ( !isset( $fill['color'] ) ) 564 | { 565 | unset( $param[$k] ); 566 | } 567 | else 568 | { 569 | $param[$k][] = $fill['color']; 570 | } 571 | 572 | if ( isset( $param[$k] ) ) 573 | { 574 | if ( count( $param[$k] == 3 ) ) 575 | { 576 | $key = 'solid_fill'; 577 | $param[$k] = array_values( $param[$k] ); 578 | $param[$k] = sprintf( $this->map['solid_fill']['format'], $param[$k][0], $param[$k][1], $param[$k][2] ); 579 | } 580 | } 581 | } 582 | 583 | $this->__setReturn( $key, $param ); 584 | 585 | } 586 | 587 | function __setOrientaion( $value ) 588 | { 589 | $this->__setData( 'orientation', round( ( ( (float)$value * pi() ) / 180 ), 3 ) ); 590 | } 591 | 592 | function __setTitle( $title ) 593 | { 594 | if ( is_array( $title ) && isset( $title['text'] ) ) 595 | { 596 | $params = array(); 597 | if ( isset( $title['color'] ) ) 598 | { 599 | $params[] = $title['color']; 600 | } 601 | 602 | if ( isset( $title['size'] ) ) 603 | { 604 | if ( empty( $params ) ) 605 | { 606 | $params[] = '4F4F4F'; 607 | $this->__errors[] = __( 'No color was set, adding a default', true ); 608 | } 609 | $params[] = (int)$title['size']; 610 | } 611 | 612 | $title = str_replace( '
', '|', $title['text'] ); 613 | $this->__setData( 'title_color', $params ); 614 | } 615 | 616 | else 617 | { 618 | $title = str_replace( '
', '|', $title ); 619 | } 620 | $this->__setData( 'title', explode( ' ', $title ) ); 621 | } 622 | 623 | function __setScale($value) 624 | { 625 | $this->__setData('scale', implode($this->map['scale']['seperator'], Set::flatten($value))); 626 | } 627 | 628 | function __setAxis($type, $value) 629 | { 630 | $data = ''; 631 | 632 | $isMultiDim = false; 633 | foreach($value as $values) 634 | { 635 | if(is_array($values)) 636 | { 637 | $isMultiDim = true; 638 | break; 639 | } 640 | } 641 | 642 | if($isMultiDim) 643 | { 644 | foreach($value as $index => $values) 645 | { 646 | if(isset($this->map[$type]['index_title_seperator'])) 647 | { 648 | $data .= $index . $this->map[$type]['index_title_seperator']; 649 | } 650 | elseif(isset($this->map[$type]['index_seperator'])) 651 | { 652 | $data .= $index . $this->map[$type]['seperator']; 653 | } 654 | 655 | $data .= implode($this->map[$type]['seperator'], $values); 656 | 657 | if(isset($this->map[$type]['index_seperator']) && $index < max(array_keys($value))) 658 | $data .= $this->map[$type]['index_seperator']; 659 | } 660 | } 661 | else 662 | { 663 | $data = implode($this->map[$type]['seperator'], $value); 664 | } 665 | 666 | $this->__setData($type, $data); 667 | } 668 | 669 | function __render( $data ) 670 | { 671 | $data['html'] = array(); 672 | if ( !isset( $data['html']['title'] ) && isset( $data['title'] ) ) 673 | { 674 | if ( !is_array( $data['title'] ) ) 675 | { 676 | $data['html']['title'] = $data['title']; 677 | } 678 | else if ( is_array( $data['title']['text'] ) ) 679 | { 680 | $data['html']['title'] = $data['title']['text']; 681 | } 682 | } 683 | 684 | $this->output = $this->__apiUrl.implode( $this->paramSeperator, $this->return ); 685 | 686 | $graph = $this->Html->image( 687 | $this->output, 688 | $data['html'], 689 | array('escape' => false) 690 | ); 691 | 692 | if ( $this->cache ) 693 | { 694 | $this->__writeCache( $this->output ); 695 | } 696 | 697 | if ( $this->debug ) 698 | { 699 | $graph .= '
'; 700 | $graph .= '

Query String

'; 701 | $graph .= '

'.$this->output.'

'; 702 | if ( is_array( $this->__errors ) && !empty( $this->__errors ) ) 703 | { 704 | $graph .= '

Errors

'; 705 | foreach( $this->__errors as $error ) 706 | { 707 | $graph .= '

'.$error.'

'; 708 | } 709 | } 710 | $graph .= '
'; 711 | } 712 | 713 | return $graph; 714 | } 715 | 716 | function __setSize( $data ) 717 | { 718 | if ( !is_array( $data ) ) 719 | { 720 | $data = explode( ',', $data, 3 ); 721 | } 722 | 723 | if ( $data[0] > 1000 ) 724 | { 725 | $data[0] = 1000; 726 | $this->erros[] = __( 'Width to big, reset to 1000px', true ); 727 | } 728 | 729 | if ( $data[1] > 1000 ) 730 | { 731 | $data[1] = 1000; 732 | $this->erros[] = __( 'Height to big, reset to 1000px', true ); 733 | } 734 | 735 | if ( $data[0] * $data[1] > $this->__maxSize ) 736 | { 737 | $this->erros[] = __( 'Sizes exceed the maximum for google charts api', true ); 738 | $data = array( 100, 100 ); 739 | } 740 | 741 | return $this->__setReturn( 'size', $data ); 742 | } 743 | 744 | function __setData( $key, $data ) 745 | { 746 | if ( !is_array( $data ) ) 747 | { 748 | $data = explode( ',', $data ); 749 | } 750 | 751 | return $this->__setReturn( $key, $data ); 752 | } 753 | 754 | function __setReturn( $key, $data ) 755 | { 756 | 757 | $return = $this->map[$key]['code']; 758 | 759 | if ( isset( $this->map[$key]['seperator'] ) ) 760 | { 761 | $return .= implode( $this->map[$key]['seperator'], $data ); 762 | } 763 | else 764 | { 765 | $return .= implode( '', $data ); 766 | } 767 | 768 | $this->return[] = $return; 769 | return true; 770 | 771 | } 772 | 773 | /** 774 | * ChartHelper::__setChart() 775 | * 776 | * checks that the name passed in is part of the valid charts that can be drawn. 777 | * saves the data to the $this->return 778 | * 779 | * @param string $name 780 | * @retrun bool 781 | */ 782 | function __setChartType( $name ) 783 | { 784 | $nameArray = array(); 785 | if ( is_array( $name ) ) 786 | { 787 | $nameArray = $name; 788 | if ( !isset( $name['name'] ) ) 789 | { 790 | $this->__errors[] = __( 'Please specify the type of chart with array( \'name\' => \'some_name\' ); or just \'some_name\'.', true ); 791 | return false; 792 | } 793 | 794 | if ( isset( $name['type'] ) ) 795 | { 796 | $name = $name['name'].'_'.$name['type']; 797 | } 798 | else 799 | { 800 | $name = $name['name']; 801 | } 802 | } 803 | if ( !empty( $nameArray ) ) 804 | { 805 | if ( !in_array( str_replace( $nameArray['name'].'_', '', $name ), array_flip( $this->chartTypes[$nameArray['name']] ) ) ) 806 | { 807 | $this->__errors[] = __( 'Incorect chart type', true ); 808 | return false; 809 | } 810 | } 811 | else if ( !isset( $this->chartTypes[$name] ) ) 812 | { 813 | $this->__errors[] = __( 'Incorect chart type', true ); 814 | return false; 815 | } 816 | 817 | if ( !empty( $nameArray ) ) 818 | { 819 | $this->return[] = $this->chartTypes[$nameArray['name']][str_replace( $nameArray['name'].'_', '', $name )]; 820 | } 821 | else 822 | { 823 | $this->return[] = $this->chartTypes[$name]; 824 | } 825 | 826 | return true; 827 | } 828 | 829 | /** 830 | * Sets the colors for the chart 831 | * 832 | * Colors can be set by individual slice/piece, or by series. If array item is 833 | * an array, it is seen as a series, otherwise a slice. 834 | * 835 | * {{{ 836 | * // two colors, one red and one blue 837 | * array('FF0000', '0000FF'); 838 | * 839 | * // two series, one red and one blue 840 | * array( 841 | * array( 842 | * 'FF0000' 843 | * ), 844 | * array( 845 | * '0000FF' 846 | * ) 847 | * ); 848 | * }}} 849 | * 850 | * @param array $data The data passed in the `colors` key 851 | * @see http://code.google.com/apis/chart/docs/gallery/pie_charts.html#chart_colors 852 | */ 853 | function __setColors($data = array()) { 854 | $series = false; 855 | foreach ($data as &$color) { 856 | if (is_array($color)) { 857 | $color = implode($this->map['colors']['slice_separator'], $color); 858 | $series = true; 859 | } 860 | } 861 | $reset = $this->map['colors']['seperator']; 862 | if (!$series) { 863 | $this->map['colors']['seperator'] = $this->map['colors']['slice_separator']; 864 | } 865 | $this->__setData('colors', $data); 866 | $this->map['colors']['seperator'] = $reset; 867 | } 868 | 869 | function __autoColor() 870 | { 871 | 872 | } 873 | 874 | function __autoScale() 875 | { 876 | 877 | } 878 | 879 | function encode( $data = array(), $type = 't' ) 880 | { 881 | if ( !is_array( $data ) ) 882 | { 883 | $data = array( $data ); 884 | } 885 | } 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | /** 899 | * legacy code below 900 | */ 901 | var $settings = array( 902 | 'api_address' => 'http://chart.apis.google.com/chart?', 903 | 'size' => array( 904 | 'width' => 300, 905 | 'height' => 300, 906 | 'name' => 'chs=' 907 | ), 908 | 'charts' => array( 909 | 'meter' => array( 910 | 'name' => 'cht=gom', 911 | 'data' => 'chd=t:', 912 | 'label' => 'chl=' 913 | ), 914 | 'sparkline' => array( 915 | 'name' => 'cht=ls', 916 | 'color' => 'chco=', 917 | 'data' => 'chd=t:', 918 | 'labels' => array( 919 | 'axis' => array( 920 | 'name' => 'chxt=', 921 | 'where' => array( 'x', 'y' ) 922 | ), 923 | 'label' => array( 924 | 'name' => 'chxl=', 925 | 'data' => array() 926 | ), 927 | ), 928 | ), 929 | 'pie' => array( 930 | 'name' => 'cht=p3', 931 | 'data' => 'chd=t:', 932 | 'label' => 'chl=' 933 | ), 934 | 'map' => array( 935 | 'type' => array( 936 | 'name' => 'chtm=', 937 | 'type' => 'world' 938 | ), 939 | 'colors' => array( 940 | 'name' => 'chco=', 941 | 'seperator' => ',' 942 | ), 943 | 'places' => array( 944 | 'name' => 'chld=', 945 | 'seperator' => '' 946 | ), 947 | 'data' => array( 948 | 'name' => 'chd=t:', 949 | 'seperator' => ',' 950 | ), 951 | 'size' => array( 952 | 'name' => 'chs=' 953 | ) 954 | ) 955 | ) 956 | ); 957 | 958 | function map( $type = 'world', $size = 'large', $data = null ) 959 | { 960 | $chart = $this->settings['charts']['map']; 961 | 962 | if ( !$data ) 963 | { 964 | return false; 965 | } 966 | if ( !$type ) 967 | { 968 | $type = $chart['type']['type']; 969 | } 970 | 971 | switch( $size ) 972 | { 973 | case 'small': 974 | $width = 220; 975 | $height = 110; 976 | break; 977 | 978 | case'medium' : 979 | $width = 330; 980 | $height = 165; 981 | break; 982 | 983 | case'large' : 984 | $width = 440; 985 | $height = 220; 986 | break; 987 | } // switch 988 | $size = $width.'x'.$height; 989 | 990 | $render = $this->settings['api_address'].'cht=t&'. 991 | $this->settings['size']['name'].$size.'&'. 992 | $chart['data']['name'].implode( $chart['data']['seperator'], $data['amount'] ).'&'. 993 | $chart['colors']['name'].implode( $chart['colors']['seperator'], $data['colors'] ).'&'. 994 | $chart['places']['name'].implode( $chart['places']['seperator'], $data['countries'] ).'&'. 995 | $chart['type']['name'].$type.'&'. 996 | 'chf=bg,s,EAF7FE'; 997 | 998 | 999 | 1000 | return $this->Html->image( 1001 | $render, 1002 | array( 1003 | 'title' => $chart['type']['type'], 1004 | 'alt' => $chart['type']['type'] 1005 | ) 1006 | ); 1007 | 1008 | } 1009 | 1010 | function pie3D( $data = array(), $labels = array(), $size = array() ) 1011 | { 1012 | $chart = $this->settings['charts']['pie']; 1013 | 1014 | if ( empty( $data ) ) 1015 | { 1016 | return false; 1017 | } 1018 | 1019 | if ( empty( $size ) ) 1020 | { 1021 | $size = $this->settings['size']; 1022 | } 1023 | 1024 | if ( $check = $this->checkSize( $size ) != true ) 1025 | { 1026 | return $check; 1027 | } 1028 | 1029 | $render = $this->settings['api_address']. 1030 | $this->settings['size']['name']. 1031 | $size['width'].'x'.$size['height'].'&'. 1032 | $chart['name'].'&'. 1033 | $chart['data'].implode( ',', $data ).'&'. 1034 | $chart['label'].implode( '|', $labels ); 1035 | 1036 | return $this->Html->image( 1037 | $render, 1038 | array( 1039 | 'title' => implode( ' vs. ', $labels ), 1040 | 'alt' => implode( ' vs. ', $labels ), 1041 | 'width' => $size['width'], 1042 | 'height' => $size['height'] 1043 | ) 1044 | ); 1045 | } 1046 | 1047 | function sparkline( $data = array(), $axis_label = array(), $size = array() ) 1048 | { 1049 | $chart = $this->settings['charts']['sparkline']; 1050 | 1051 | if ( empty( $data ) ) 1052 | { 1053 | return false; 1054 | } 1055 | 1056 | if ( empty( $size ) ) 1057 | { 1058 | $size = $this->settings['size']; 1059 | } 1060 | 1061 | if ( $check = $this->checkSize( $size ) != true ) 1062 | { 1063 | return $check; 1064 | } 1065 | 1066 | $max = 0; 1067 | foreach( $data as $k => $v ) 1068 | { 1069 | $data[$k] = (int)$v + 0; 1070 | $bottom_label[] = $k; 1071 | 1072 | if ( $v > $max ) 1073 | { 1074 | $max = $v; 1075 | } 1076 | } 1077 | $i = 0; 1078 | while( $i <= $max ) 1079 | { 1080 | $x_inc[$i] = $i; 1081 | $i++; 1082 | } // while 1083 | 1084 | $render = $this->settings['api_address']. 1085 | $this->settings['size']['name']. 1086 | $size['width'].'x'.$size['height'].'&'. 1087 | $chart['name'].'&'. 1088 | $chart['data'].implode( ',', $data ).'&'. 1089 | $chart['labels']['axis']['name'].implode( ',', $chart['labels']['axis']['where'] ).'&'. 1090 | $chart['labels']['label']['name']. 1091 | '0:|'.implode( '|', $bottom_label ).'|'. 1092 | '1:|'.implode( '|', $x_inc ). 1093 | '&chds=0,'.$max; 1094 | 1095 | return $this->Html->image( 1096 | $render, 1097 | array( 1098 | 'title' => '', 1099 | 'alt' => '', 1100 | 'width' => $size['width'], 1101 | 'height' => $size['height'] 1102 | ) 1103 | ); 1104 | } 1105 | 1106 | function meter( $data = null, $label = '', $size = array() ) 1107 | { 1108 | $chart = $this->settings['charts']['meter']; 1109 | 1110 | if ( $data == null || is_array( $data ) ) 1111 | { 1112 | return false; 1113 | } 1114 | 1115 | if ( empty( $size ) ) 1116 | { 1117 | $size = $this->settings['size']; 1118 | } 1119 | 1120 | $size['height'] = $size['width'] / 2; 1121 | 1122 | if ( $check = $this->checkSize( $size ) != true ) 1123 | { 1124 | return $check; 1125 | } 1126 | 1127 | if ( $data <= 0 ) 1128 | { 1129 | $data = 1; 1130 | } 1131 | 1132 | elseif ( $data >= 100 ) 1133 | { 1134 | $data = 100; 1135 | } 1136 | 1137 | $render = $this->settings['api_address']. 1138 | $this->settings['size']['name']. 1139 | $size['width'].'x'.$size['height'].'&'. 1140 | $chart['name'].'&'. 1141 | $chart['data'].$this->Number->precision( $data, 0 ).'&'. 1142 | $chart['label'].$label; 1143 | 1144 | return $this->Html->image( 1145 | $render, 1146 | array( 1147 | 'title' => __( 'Health: ', true ).$this->Number->toPercentage( $data, 0 ), 1148 | 'alt' => __( 'Health: ', true ).$this->Number->toPercentage( $data, 0 ), 1149 | 'width' => $size['width'], 1150 | 'height' => $size['height'] 1151 | ) 1152 | ); 1153 | } 1154 | 1155 | function checkSize( $size = array() ) 1156 | { 1157 | if ( empty( $size ) ) 1158 | { 1159 | return false; 1160 | } 1161 | 1162 | $total = $size['width'] * $size['height']; 1163 | 1164 | if ( $total >= 300000 ) 1165 | { 1166 | return false; 1167 | } 1168 | 1169 | return true; 1170 | } 1171 | } -------------------------------------------------------------------------------- /views/helpers/map.php: -------------------------------------------------------------------------------- 1 | dirname(dirname(dirname(__FILE__))).DS.'webroot'.DS.'img'.DS.get_class($this).DS, 6 | 'cacheImagePath' => '/google/img/'.get_class($this).'/' 7 | ); 8 | 9 | $options = array_merge($default, $options); 10 | 11 | $this->cachePath = $options['cachePath']; 12 | $this->cacheImagePath = $options['cacheImagePath']; 13 | } 14 | 15 | protected function _checkCache($data){ 16 | $file = sha1(serialize($data)).'.png'; 17 | if (is_file($this->cachePath.$file)){ 18 | return $this->Html->image($this->cacheImagePath.$file ); 19 | } 20 | return false; 21 | } 22 | 23 | protected function _writeCache($data, $url){ 24 | $file = sha1(serialize($data)).'.png'; 25 | 26 | if(is_writable($this->cachePath)){ 27 | $contents = file_get_contents($url); 28 | 29 | $fp = fopen($this->cachePath.$file, 'w'); 30 | fwrite($fp, $contents); 31 | fclose($fp); 32 | 33 | if (!is_file($this->cachePath.$file)){ 34 | $this->__errors[] = __('Could not create the cache file', true); 35 | } 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * http://code.google.com/apis/maps/documentation/staticmaps/#Usage 42 | * @author dogmatic69 43 | * 44 | * @todo custom icons 45 | * @todo 46 | */ 47 | class StaticMapHelper extends GoogleAppHelper{ 48 | /** 49 | * Set some defaults 50 | * @var array 51 | */ 52 | protected $_default = array( 53 | 'location' => array(), 54 | 'sensor' => 'false', // true, false or both 55 | 'zoom' => 10, 56 | 'visible' => null, 57 | 'size' => array( 58 | 'width' => 640, 59 | 'height' => 640 60 | ), 61 | 'image_type' => 'png32', // png, png8, png32, jpg 62 | 'map_type' => 'roadmap', // roadmap, satellite, hybrid, terrain 63 | 'markers' => array( //nested array 64 | array( 65 | 'size' => '', // tiny, mid, small or normal 66 | 'color' => '', // like css with no # 67 | 'label' => '', // {A-Z, 0-9} 68 | 'location' => array( 69 | // like above 70 | ) 71 | ) 72 | ) 73 | ); 74 | 75 | public function draw($data = array(), $imageProperties = array()){ 76 | $cache = $this->_checkCache(array($data, $imageProperties)); 77 | if($cache !== false){ 78 | return $cache; 79 | } 80 | 81 | $this->query = $data; 82 | 83 | if(!isset($this->query['location']) || !$this->__getValidLocation($this->query['location'])){ 84 | if(!isset($this->query['markers']) || count($this->query['markers']) < 2){ 85 | $this->errors[] = 'Invalid location'; 86 | return false; 87 | } 88 | } 89 | 90 | if(isset($this->query['visible']) && empty($this->query['visable'])){ 91 | $this->query['visible'] = $this->__getValidLocation($this->query['visible']); 92 | } 93 | else{ 94 | $this->query['visible'] = null; 95 | } 96 | 97 | if(!$this->query['visible'] && !(isset($this->query['zoom']) || !$this->__validZoom($this->query['zoom']))){ 98 | $this->query['zoom'] = $this->_default['zoom']; 99 | } 100 | 101 | if(!isset($this->query['size']) || !$this->__validSize($this->query['size'])){ 102 | $this->errors[] = 'Invalid size'; 103 | return false; 104 | } 105 | 106 | if(!isset($this->query['image_type']) || !$this->__validImageType($this->query['image_type'])){ 107 | $this->query['image_type'] = $this->_default['image_type']; 108 | } 109 | 110 | if(!isset($this->query['map_type']) || !$this->__validMapType($this->query['map_type'])){ 111 | $this->query['map_type'] = $this->_default['map_type']; 112 | } 113 | 114 | $this->query['sensor'] = $this->__SensorType(isset($this->query['sensor']) ? $this->query['sensor'] : false); 115 | $this->query['markers'] = $this->__markersValid(isset($this->query['markers']) ? $this->query['markers'] : array()); 116 | 117 | $url = $this->__buildQuery(); 118 | $this->_writeCache(array($data, $imageProperties), $url); 119 | return $this->Html->image( 120 | $url, 121 | $imageProperties 122 | ); 123 | 124 | } 125 | 126 | private function __buildQuery(){ 127 | if($this->query['visible']){ 128 | $return[] = 'visible='.$this->query['visible']; 129 | } 130 | else{ 131 | $return[] = 'center='.implode(',', (array)$this->query['location']); 132 | $return[] = 'zoom='.$this->query['zoom']; 133 | } 134 | $return[] = 'size='.$this->query['size']['width'].'x'.$this->query['size']['height']; 135 | $return[] = 'sensor='.$this->query['sensor']; 136 | 137 | foreach($this->query['markers'] as $marker){ 138 | $return[] = $this->__formatMarker($marker); 139 | } 140 | 141 | $return = $this->__url.'?'.implode('&', array_filter($return)); 142 | 143 | return $return; 144 | } 145 | 146 | /** 147 | * points on the map 148 | * 149 | * The set of marker style descriptors is a series of value assignments 150 | * separated by the pipe (|) character. This style descriptor defines the 151 | * visual attributes to use when displaying the markers within this marker 152 | * descriptor. 153 | * 154 | * @param unknown_type $marker 155 | */ 156 | private function __formatMarker($marker){ 157 | if(empty($marker['location'])){ 158 | return null; 159 | } 160 | $return = array(); 161 | $return[] = $marker['location']; 162 | 163 | if(!empty($marker['color'])){ 164 | $return[] = 'color:'.$marker['color']; 165 | } 166 | 167 | if(!empty($marker['label'])){ 168 | $return[] = 'label:'.$marker['label']; 169 | } 170 | 171 | if(!empty($marker['size'])){ 172 | $return[] = 'size:'.$marker['size']; 173 | } 174 | 175 | return 'markers='.implode('|', $return); 176 | } 177 | 178 | /** 179 | * There is no need to modyfy this class. 180 | * @author dogmatic69 181 | */ 182 | /** 183 | * The map api url 184 | * @var string 185 | */ 186 | protected $__url = 'http://maps.google.com/maps/api/staticmap'; 187 | 188 | /** 189 | * Max height allowed 190 | * @var int 191 | */ 192 | protected $__maxHeight = 640; 193 | 194 | /** 195 | * max width allowed 196 | * @var int 197 | */ 198 | protected $__maxWidth = 640; 199 | 200 | /** 201 | * Allowed image types 202 | * @var array 203 | */ 204 | protected $__imageTypes = array( 205 | 'png', 206 | 'png8', 207 | 'png32', 208 | 'gif', 209 | 'jpg', 210 | 'jpg-baseline' 211 | ); 212 | 213 | /** 214 | * Allowed map types 215 | * @var array 216 | */ 217 | protected $__mapTypes = array( 218 | 'roadmap', 219 | 'satellite', 220 | 'terrain', 221 | 'hybrid' 222 | ); 223 | 224 | protected $__markerSizes = array( 225 | 'normal', 226 | 'tiny', 227 | 'small', 228 | 'med' 229 | ); 230 | 231 | /** 232 | * by address could return wrong maps. 233 | * 234 | * @param array $data 235 | */ 236 | protected function __getValidLocation($location){ 237 | if(isset($location) && !empty($location) && !is_array($location)){ 238 | return urlencode($location); 239 | } 240 | 241 | if(isset($location['latitude']) && isset($location['longitude'])){ 242 | $valid = $this->__validLatitude($location['latitude']) && $this->__validLongitude($location['longitude']); 243 | if($valid){ 244 | return urlencode(implode(',', $location)); 245 | } 246 | } 247 | 248 | return null; 249 | } 250 | 251 | /** 252 | * valid latitude. 253 | * 254 | * Latitudes can take any value between -90 and 90 while 255 | * 256 | * @param float $latitude 257 | */ 258 | protected function __validLatitude($latitude){ 259 | return -90 <= (float)$latitude && (float)$latitude <= 90; 260 | } 261 | 262 | /** 263 | * valid longitude. 264 | * 265 | * longitude values can take any value between -180 and 180. 266 | * 267 | * @param float $longitude 268 | */ 269 | protected function __validLongitude($longitude){ 270 | return -180 <= (float)$longitude && (float)$longitude <= 180; 271 | } 272 | 273 | /** 274 | * valid zoom 275 | * 276 | * Zoom levels between 0 (the lowest zoom level, in which the entire 277 | * world can be seen on one map) to 21+ (down to individual buildings) 278 | * 279 | * NOTE: not all zoom levels appear at all locations on the earth 280 | * 281 | * @param unknown_type $zoom 282 | */ 283 | protected function __validZoom($zoom){ 284 | return 0 <= $zoom && $zoom <= 21; 285 | } 286 | 287 | /** 288 | * valid image size 289 | * 290 | * Images may be retrieved in sizes up to 640 by 640 pixels. 291 | * @param array $sizes 292 | */ 293 | protected function __validSize($sizes){ 294 | return $sizes['width'] <= $this->__maxWidth && $sizes['height'] <= $this->__maxHeight; 295 | } 296 | 297 | /** 298 | * valid image format 299 | * 300 | * Images may be returned in several common web graphics formats: GIF, JPEG and PNG. 301 | * 302 | * @param string $imageType 303 | */ 304 | protected function __validImageType($imageType){ 305 | return in_array($imageType, $this->__imageTypes); 306 | } 307 | 308 | /** 309 | * valid map type 310 | * 311 | * roadmap (default) specifies a standard roadmap image, as is normally shown on the Google Maps website. If no maptype value is specified, the Static Maps API serves roadmap tiles by default. 312 | * satellite specifies a satellite image. 313 | * terrain specifies a physical relief map image, showing terrain and vegetation. 314 | * hybrid specifies a hybrid of the satellite and roadmap image, showing a transparent layer of major streets and place names on the satellite image. 315 | * 316 | * @param string $mapType 317 | */ 318 | protected function __validMapType($mapType){ 319 | return in_array($mapType, $this->__mapTypes); 320 | } 321 | 322 | /** 323 | * maps for gps device 324 | * 325 | * specifies whether the application requesting the static map is using a sensor to determine the user's location. 326 | * 327 | * @param string $mapType 328 | */ 329 | protected function __SensorType($sensor){ 330 | switch(true){ 331 | case $sensor === true: 332 | case strtolower($sensor) === 'true': 333 | return 'true'; 334 | break; 335 | 336 | default: 337 | return 'false'; 338 | break; 339 | } 340 | } 341 | 342 | /** 343 | * validate and remove unneded params for markers 344 | * @param array $markers 345 | */ 346 | protected function __markersValid($markers){ 347 | if(empty($markers) || !is_array($markers)){ 348 | return array(); 349 | } 350 | 351 | $return = array(); 352 | $i = 0; 353 | foreach($markers as $marker){ 354 | $return[$i]['size'] = $this->__validMarkerSize(isset($marker['size']) ? $marker['size'] : ''); 355 | $return[$i]['color'] = $this->__validMarkerColor(isset($marker['color']) ? $marker['color'] : ''); 356 | $return[$i]['label'] = $this->__validMarkerLabel(isset($marker['label']) ? $marker['label'] : ''); 357 | $return[$i]['location'] = $this->__getValidLocation(isset($marker['location']) ? $marker['location'] : ''); 358 | ++$i; 359 | } 360 | 361 | unset($markers); 362 | return $return; 363 | } 364 | 365 | /** 366 | * check the size param 367 | * 368 | * if its the default dont add it, waste of url chars :) 369 | * @param unknown_type $size 370 | */ 371 | protected function __validMarkerSize($size){ 372 | if(empty($size) || !in_array(strtolower($size), $this->__markerSizes) && strtolower($size) !== $this->__markerSizes[0]){ 373 | return null; 374 | } 375 | return $size; 376 | } 377 | 378 | /** 379 | * check colors are valid. 380 | * @param unknown_type $color 381 | */ 382 | protected function __validMarkerColor($color){ 383 | if(empty($color) || !preg_match('/^([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$/', 'fff111')){ 384 | return null; 385 | } 386 | 387 | return '0x'.$color; 388 | } 389 | 390 | /** 391 | * a single uppercase alphanumeric character from the set {A-Z, 0-9} 392 | * @param $label 393 | */ 394 | protected function __validMarkerLabel($label){ 395 | if(!empty($label) && preg_match('/^[A-Z0-9]$/', '1')){ 396 | return $label; 397 | } 398 | return ''; 399 | } 400 | } 401 | --------------------------------------------------------------------------------