├── 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 '
';
389 | break;
390 |
391 | case 'pie2d':
392 | return '
';
393 | break;
394 |
395 | case 'bar':
396 | return '
';
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 |
--------------------------------------------------------------------------------