1 Mint =& $Mint;
39 $this->plugin_id = $plugin_id;
40
41 // Used to display info about this plug-in
42 $this->info['developer'] = "Marc A. Garrett";
43 $this->info['plugin'] = "Parsel";
44 $this->info['description'] = "
Version 0.6.1
45 Find out which languages your visitors use. If you have any problems please email me. Parsel should be stable but you install at your own risk.
46 IMPORTANT: Parsel requires that you have Mint 1.1 or higher. Parsel will not install on older versions of Mint.
47 For more information on the Accept-Language Header see w3.org.
";
48 $this->info['developer_url'] = "http://since1968.com/";
49 $this->info['documentation'] = "http://since1968.com/article/128/parsel";
50
51 // Used internally
52 $this->info['src'] = "since1968/parsel/";
53 $this->info['class'] = "since1968_Parsel";
54
55 // Panes used to keep track of the data displayed by this plug-in and
56 // for ordering preferences
57 $this->panes['Languages'] = array('Most Common','Most Recent');
58 }
59
60 /**************************************************************************
61 install()
62 This function will be called by the Mint plug-in installer
63
64 It may add columns to the Mint table but the onRecord/onJavaScript event
65 handlers must provide and validate the necessary data
66
67 **************************************************************************/
68 function install() {
69 $up_to_date = true; // assume they have current version of mint
70 $query = " ALTER TABLE {$this->Mint->db['tblprefix']}visit
71 ADD since1968_language VARCHAR( 100 ) NOT NULL default ''";
72
73 // check to ensure Mint 110 is installed as new function calls are used.
74 // source: Colby's install checker from Sparks
75 if ($this->Mint->version < 110) {
76 // the following function call is to output a failed installation message.
77 // currently, in mint 1.1, even if we fill in the error array (errors[]),
78 // the resulting html screen still has a successful installation message.
79
80 $errMsgs = Array();
81 $errMsgs[] = 'Parsel did not install properly.';
82 $errMsgs[] = '';
83 $errMsgs[] = 'Parsel requires Mint version 1.1 or higher.';
84 $errMsgs[] = '';
85 $errMsgs[] = 'Please upgrade your Mint, then try installing Parsel again.';
86
87 echo $this->getHTML_PermissionErrors($errMsgs);
88 $up_to_date = false;
89 exit;
90
91 // todo, once shaun enhances the install routine, the follow may be used instead of above
92 // $this->Mint->errors[] = 'Sparks! did not install properly.';
93 // $this->Mint->errors[] = '';
94 // $this->Mint->errors[] = 'Sparks! requires Mint version 1.1 or higher.';
95 // $this->Mint->errors[] = '';
96 // $this->Mint->errors[] = 'Please upgrade your Mint, then try installing Sparks! again.';
97 }
98
99 if (mysql_query($query)&&$up_to_date==true) {
100 $prefs['show_as_percent'] = 1; // by default show aggregated values as percentages
101 $prefs['show_raw_string'] = 1; // by default show raw output string
102 $this->Mint->savePluginPreferences($this->plugin_id,$prefs);
103 // Do not change this line
104 $this->Mint->registerPlugIn($this->info['src'],$this->info['class'],$this->panes);
105 }
106 }
107
108 /**************************************************************************
109 uninstall()
110 This function will be called by the Mint plug-in remover
111
112 Should delete any columns or additional tables added by $this->install().
113 Mint will take care of deleting any associated preferences or data
114
115 Need to:
116 - Reconsider this as other plug-ins may form dependancies on these
117 non-standard columns
118
119 **************************************************************************/
120 function uninstall() {
121 $query = "ALTER TABLE {$this->Mint->db['tblprefix']}visit
122 DROP since1968_language";
123 mysql_query($query);
124 }
125
126 /**************************************************************************
127 onRecord()
128 Operates on existing $_GET values, values generated as a result of the
129 JavaScript output below or existing $_SERVER variables and returns an
130 associative array with a column name as the index and the value to be
131 stored in that column as the value.
132 **************************************************************************/
133
134 function onRecord() {
135 if (empty($_GET)) {
136 return array();
137 }
138
139 $language = '';
140
141 // get the user's language
142 $language = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
143
144
145 // trim to 100 characters so string isn't too long for database
146 // (this is probably overkill)
147 $language = substr($language, 0, 100);
148
149 // put field name and value in array for insert into table
150 return array('since1968_language'=>$language);
151 }
152
153 /**************************************************************************
154 onJavaScript()
155 Returns a JavaScript string responsible for extracting the necessary values
156 (if any) necessary for this plug-in.
157
158 Should follow format of the new SI Object()
159 **************************************************************************/
160 function onJavaScript() { }
161
162 /**************************************************************************
163 onDisplay()
164 Produces what the user sees when they are browsing their Mint install
165
166 Returns an associative array of associative arrays that contain an HTML
167 string for each display unit this plug-in is responsible for, plus a formal
168 display name and the containing element's id (for ordering in preferences
169 and anchor linking)
170
171 **************************************************************************/
172 function onDisplay($pane,$tab,$column='',$sort='') {
173 $html = '';
174
175 $languages = $this->get_Languages();
176
177 switch($pane) {
178 /* Languages ********************************************************/
179 case 'Languages':
180 switch($tab) {
181 /* Most Common ************************************************/
182 case 'Most Common':
183 $html .= $this->getHTML_LanguagesCommon($languages);
184 break;
185 /* Most Recent ************************************************/
186 case 'Most Recent':
187 $html .= $this->getHTML_LanguagesRecent($languages);
188 break;
189 }
190 break;
191 }
192 return $html;
193 }
194
195 /**************************************************************************
196 onWidget()
197
198 **************************************************************************/
199 function onWidget() { }
200
201 /**************************************************************************
202 onDisplayPreferences()
203
204 Should return an assoicative array (indexed by pane name) that contains the
205 HTML contents of that pane's preference. Preferences used by all panes in
206 this plug-in should be indexed as 'global'. Any pane that isn't represeneted
207 by an index in the return array will simply display the string "This pane
208 does not have any preferences" (or similar).
209
210 **************************************************************************/
211 function onDisplayPreferences() {
212
213 $prefs = $this->Mint->getPluginPreferences($this->plugin_id);
214 $show_as_percent = ( $prefs['show_as_percent'] ? ' checked="checked"' : '' );
215 $show_raw_string = ( $prefs['show_raw_string'] ? ' checked="checked"' : '' );
216
217 $preferences['Global'] = '';
235
236 return $preferences;
237
238 }
239
240 /**************************************************************************
241 onSavePreferences()
242
243 **************************************************************************/
244 function onSavePreferences() {
245 $prefs['show_as_percent'] = ( isset($_POST['show_as_percent']) ? $_POST['show_as_percent'] : 0 );
246 $prefs['show_raw_string'] = ( isset($_POST['show_raw_string']) ? $_POST['show_raw_string'] : 0 );
247 $this->Mint->savePluginPreferences($this->plugin_id,$prefs);
248 }
249
250 /**************************************************************************
251 onCustom()
252
253 **************************************************************************/
254 function onCustom() {
255 if (isset($_POST['action']) && $_POST['action']=='getranges' && isset($_POST['lang']) && isset($_POST['total'])) {
256 $lang = $this->Mint->escapeSQL($_POST['lang']);
257 $total = $_POST['total'];
258 echo $this->getHTML_Ranges($lang, $total);
259 }
260 }
261
262
263 /**************************************************************************
264 getHTML_LanguagesRecent()
This function expects an array of language abbreviations (key) and language
names (value).
265
266 **************************************************************************/
267 function getHTML_LanguagesRecent($since1968_languages) {
268 $html = '';
269
270 // get rows from preferences
271 $gPrefs = $this->Mint->getCfgValue('preferences');
272 $rows = $gPrefs['rows'];
273
274 // get prefs for this plug-in
275 $prefs = $this->Mint->getPluginPreferences($this->plugin_id);
276 $show_raw_string = $prefs['show_raw_string'];
277
278 $tableData['table'] = array('id'=>'','class'=>'');
279 $tableData['thead'] = array(
280 // display name, CSS class(es) for each column
281 array('value'=>'Language Combinations','class'=>'stacked-rows'),
282 array('value'=>'When','class'=>'')
283 );
284
285 $query = "SELECT SUBSTRING_INDEX(since1968_language, ',', 1) AS str_language, since1968_language AS str_abbrevs, `dt`
286 FROM `{$this->Mint->db['tblprefix']}visit`
287 WHERE
288 `since1968_language`!=''
289 ORDER BY `dt` DESC
290 LIMIT 0,{$rows}";
291
292 if ($result = mysql_query($query)) {
293 while ($r = mysql_fetch_array($result)) {
294 $dt = $this->Mint->formatDateTimeRelative($r['dt']);
295 $language_row = $this->Mint->abbr(stripslashes($r['str_language']));
296 $sub_row = '';
297
298 // here are some sample strings:
299 // en-us,th;q
300 // es-uy
301 // de;q=1.0,e
302 // en,ja;q=0.
303
304 // replace semi-colons with commas
305 $language_row = str_replace(';', ',', $language_row);
306 if ($show_raw_string == 1) {
307 $sub_row = "
" . $this->Mint->abbr(stripslashes($r['str_abbrevs'])) . "";
308 }
309 // explode list of abbreviations into an array
310 $language_row_exploded = explode(',', $language_row);
311
312 // create a new, empty array to hold readable language names
313 $language_row_readable = array();
314 // loop through language abbreviations. For each abbreviation, look up in $a_languages
315 // If found, add human readable name to array. If not found, add original abbreviation to array
316 // Implode and print when done.
317 foreach ($language_row_exploded as $lang) {
318 if(array_key_exists($lang, $since1968_languages)) {
319 $language_row_readable[] = $since1968_languages[$lang];
320 } else {
321 $language_row_readable[] = $lang;
322 }
323 }
324
325 $language_row_final = implode(', ', $language_row_readable) . $sub_row;
326
327 $tableData['tbody'][] = array(
328 $language_row_final,
329 $dt
330 );
331 }
332 }
333
334 $html = $this->Mint->generateTable($tableData);
335 return $html;
336 }
337
338 /**************************************************************************
339 getHTML_LangugesCommon()
340 This function expects an array of language abbreviations (key) and language
names (value).
341 **************************************************************************/
342 function getHTML_LanguagesCommon($since1968_languages) {
343 $html = '';
344 $thead_label = 'Count';
345
346 // get rows from preferences
347 $gPrefs = $this->Mint->getCfgValue('preferences');
348 $rows = $gPrefs['rows'];
349 // get prefs for this plug-in
350 $prefs = $this->Mint->getPluginPreferences($this->plugin_id);
351 $show_as_percent = $prefs['show_as_percent'];
352 if ($show_as_percent == 1) {
353 $thead_label = '% of Total';
354 }
355
356 $tableData['hasFolders'] = true;
357
358 $tableData['table'] = array('id'=>'','class'=>'folder');
359 $tableData['thead'] = array(
360 // display name, CSS class(es) for each column
361 array('value'=>'Languages','class'=>'stacked-rows'),
362 array('value'=>$thead_label,'class'=>'')
363 );
364
365 $query = "SELECT LEFT(since1968_language, 2) AS str_language, COUNT(LEFT(since1968_language, 2)) AS `count`, `dt`
366 FROM `{$this->Mint->db['tblprefix']}visit`
367 WHERE
368 `since1968_language`!=''
369 GROUP BY `str_language`
370 ORDER BY `count` DESC, `dt` DESC
371 LIMIT 0,{$rows}";
372
373 $result = mysql_query($query);
374 $total = mysql_num_rows($result);
375
376 if ($result) {
377 while ($r = mysql_fetch_array($result)) {
378 $language_row = $this->Mint->abbr(stripslashes($r['str_language']));
379
380 if(array_key_exists($language_row, $since1968_languages)) {
381 $language_row_readable = $since1968_languages[$language_row];
382 } else {
383 $language_row_readable = $language_row;
384 }
385
386 $num_output = 0;
387 if ($show_as_percent==1) {
388 $num_output = $this->Mint->formatPercents($r['count']/$total);
389 } else {
390 $num_output = $r['count'];
391 }
392
393 $tableData['tbody'][] = array(
394 $language_row_readable,
395 $num_output,
396 'folderargs'=>array(
397 'action'=>'getranges',
398 'lang'=>$r['str_language'],
399 'total'=>$total
400 )
401 );
402 }
403 }
404
405 $html = $this->Mint->generateTable($tableData);
406 return $html;
407 }
408
409 /**************************************************************************
410 getHTML_Ranges()
This function takes a language (en) and returns a set of ranges such as English (US), English (UK) along with their counts (value).
411
412 **************************************************************************/
413 function getHTML_Ranges($lang, $total) {
414 $html = '';
415
416 // get rows from global preferences
417 $gPrefs = $this->Mint->getCfgValue('preferences');
418 $rows = $gPrefs['rows'];
419
420 // get prefs for this plug-in
421 $prefs = $this->Mint->getPluginPreferences($this->plugin_id);
422 $show_as_percent = $prefs['show_as_percent'];
423
424 // load array of languages
425 /* Normally we do this only once onDisplay() and then pass the array
426 around to different functions as needed, but getHTML_Ranges() is
427 called via POST. Including each time is probably not optimal, so
428 revisit in future version. I don't want to put the array in global
429 scope in a multiple-developer plug-in environment, and serializing
430 the array to pass via POST makes the page too heavy.
431 */
432
433 $languages = $this->get_Languages();
434
435 $query = "SELECT SUBSTRING_INDEX(since1968_language, ',', 1) AS str_language,
436 COUNT(SUBSTRING_INDEX(since1968_language, ',', 1)) AS count,
437 'dt'
438 FROM `{$this->Mint->db['tblprefix']}visit`
439 WHERE
440 LEFT(since1968_language, 2) ='$lang'
441 GROUP BY str_language
442 ORDER BY count DESC
443 LIMIT 0,{$rows}";
444
445 if ($result = mysql_query($query)) {
446 while ($r = mysql_fetch_array($result)) {
447 // $language_row = $r['str_language'];
448 if(array_key_exists($r['str_language'], $languages)) {
449 $language_row = $languages[$r{'str_language'}];
450 } else {
451 $language_row = $r['str_language'];
452 }
453
454
455 $num_output = 0;
456 if ($show_as_percent==1) {
457 $num_output = $this->Mint->formatPercents($r['count']/$total);
458 } else {
459 $num_output = $r['count'];
460 }
461
462
463 $tableData['tbody'][] = array(
464 $language_row,
465 $num_output
466 );
467 } // end while fetch
468
469 } // end if result
470
471 $html = $this->Mint->generateTableRows($tableData);
472 return $html;
473
474 } // end function
475
476 /**************************************************************************
477 getHTML_PermissionErrors()
478
479 **************************************************************************/
480
481 function getHTML_PermissionErrors($errMsgs) {
482 $html = '
484
485
486
487 Mint
488
493
494
495
496
497 ';
498
499 if (!empty($errMsgs)) {
500 $errMsgs[] = '

';
501 $tableData['list']['class'] = 'errors';
502 $tableData['items'] = $errMsgs;
503 $html .= $this->Mint->generateUnorderedList($tableData);
504 }
505
506 $html .= '
';
507 $html .= $this->Mint->getFormattedVersion() . ' © 2004-'.date("Y");
508 $html .= '
Shaun Inman. All rights reserved. Available at
haveamint.com.
509
510
511 ';
512
513 return $html;
514 }
515
516 /**************************************************************************
517 get_Languages()
518
519 return array of languages, with abbreviation as key and language as value
520
521 **************************************************************************/
522
523 function get_Languages() {
524 $languages = array(
525 'af' => 'Afrikaans',
526 'sq' => 'Albanian',
527 'ar-dz' => 'Arabic (Algeria)',
528 'ar-bh' => 'Arabic (Bahrain)',
529 'ar-eg' => 'Arabic (Egypt)',
530 'ar-iq' => 'Arabic (Iraq)',
531 'ar-jo' => 'Arabic (Jordan)',
532 'ar-kw' => 'Arabic (Kuwait)',
533 'ar-lb' => 'Arabic (Lebanon)',
534 'ar-ly' => 'Arabic (libya)',
535 'ar-ma' => 'Arabic (Morocco)',
536 'ar-om' => 'Arabic (Oman)',
537 'ar-qa' => 'Arabic (Qatar)',
538 'ar-sa' => 'Arabic (Saudi Arabia)',
539 'ar-sy' => 'Arabic (Syria)',
540 'ar-tn' => 'Arabic (Tunisia)',
541 'ar-ae' => 'Arabic (U.A.E.)',
542 'ar-ye' => 'Arabic (Yemen)',
543 'ar' => 'Arabic',
544 'hy' => 'Armenian',
545 'as' => 'Assamese',
546 'ast' => 'Asturian',
547 'az' => 'Azeri',
548 'eu' => 'Basque',
549 'be' => 'Belarusian',
550 'bn' => 'Bengali',
551 'bg' => 'Bulgarian',
552 'ca' => 'Catalan',
553 'zh-cn' => 'Chinese (China)',
554 'zh-hk' => 'Chinese (Hong Kong SAR)',
555 'zh-mo' => 'Chinese (Macau SAR)',
556 'zh-sg' => 'Chinese (Singapore)',
557 'zh-tw' => 'Chinese (Taiwan)',
558 'zh' => 'Chinese',
559 'hr' => 'Croatian',
560 'hr-hr' => 'Croatian',
561 'cs' => 'Czech',
562 'da' => 'Danish',
563 'div' => 'Divehi',
564 'nl-be' => 'Dutch (Belgium)',
565 'nl-nl' => 'Dutch (Netherlands)',
566 'nl' => 'Dutch',
567 'en-au' => 'English (Australia)',
568 'en-bz' => 'English (Belize)',
569 'en-ca' => 'English (Canada)',
570 'en-ie' => 'English (Ireland)',
571 'en-jm' => 'English (Jamaica)',
572 'en-nz' => 'English (New Zealand)',
573 'en-ph' => 'English (Philippines)',
574 'en-za' => 'English (South Africa)',
575 'en-tt' => 'English (Trinidad)',
576 'en-gb' => 'English (United Kingdom)',
577 'en-us' => 'English (United States)',
578 'en-zw' => 'English (Zimbabwe)',
579 'en' => 'English',
580 'us' => 'English (United States)',
581 'et' => 'Estonian',
582 'fo' => 'Faeroese',
583 'fa' => 'Farsi',
584 'fi' => 'Finnish',
585 'fr-be' => 'French (Belgium)',
586 'fr-ca' => 'French (Canada)',
587 'fr-lu' => 'French (Luxembourg)',
588 'fr-mc' => 'French (Monaco)',
589 'fr-ch' => 'French (Switzerland)',
590 'fr-fr' => 'French (France)',
591 'fr' => 'French',
592 'mk' => 'FYRO Macedonian',
593 'gd' => 'Gaelic',
594 'ka' => 'Georgian',
595 'de-at' => 'German (Austria)',
596 'de-li' => 'German (Liechtenstein)',
597 'de-lu' => 'German (lexumbourg)',
598 'de-ch' => 'German (Switzerland)',
599 'de-de' => 'German (Germany)',
600 'de' => 'German',
601 'el' => 'Greek',
602 'gu' => 'Gujarati',
603 'he' => 'Hebrew',
604 'hi' => 'Hindi',
605 'hu' => 'Hungarian',
606 'is-is' => 'Icelandic (Iceland)',
607 'is' => 'Icelandic',
608 'id' => 'Indonesian',
609 'it-ch' => 'Italian (Switzerland)',
610 'it' => 'Italian',
611 'ja-jp' => 'Japanese (Japan)',
612 'ja' => 'Japanese',
613 'kn' => 'Kannada',
614 'kk' => 'Kazakh',
615 'kok' => 'Konkani',
616 'ko' => 'Korean',
617 'kz' => 'Kyrgyz',
618 'lv' => 'Latvian',
619 'lt' => 'Lithuanian',
620 'ms' => 'Malay',
621 'ml' => 'Malayalam',
622 'mt' => 'Maltese',
623 'mr' => 'Marathi',
624 'mn' => 'Mongolian (Cyrillic)',
625 'ne' => 'Nepali (India)',
626 'nb-no' => 'Norwegian (Bokmal)',
627 'nb' => 'Norwegian (Bokmal)',
628 'nn-no' => 'Norwegian (Nynorsk)',
629 'no' => 'Norwegian',
630 'or' => 'Oriya',
631 'pl' => 'Polish',
632 'pt-br' => 'Portuguese (Brazil)',
633 'pt-pt' => 'Portuguese (Portugal)',
634 'pt' => 'Portuguese',
635 'pa' => 'Punjabi',
636 'rm' => 'Rhaeto-Romanic',
637 'ro-md' => 'Romanian (Moldova)',
638 'ro' => 'Romanian',
639 'ru-md' => 'Russian (Moldova)',
640 'ru-ru' => 'Russian (Russia)',
641 'ru' => 'Russian',
642 'sa' => 'Sanskrit',
643 'sr' => 'Serbian',
644 'sk' => 'Slovak',
645 'sl' => 'Slovenian',
646 'sb' => 'Sorbian',
647 'es-ar' => 'Spanish (Argentina)',
648 'es-bo' => 'Spanish (Bolivia)',
649 'es-cl' => 'Spanish (Chile)',
650 'es-co' => 'Spanish (Colombia)',
651 'es-cr' => 'Spanish (Costa Rica)',
652 'es-do' => 'Spanish (Dominican Republic)',
653 'es-ec' => 'Spanish (Ecuador)',
654 'es-sv' => 'Spanish (El Salvador)',
655 'es-gt' => 'Spanish (Guatemala)',
656 'es-hn' => 'Spanish (Honduras)',
657 'es-mx' => 'Spanish (Mexico)',
658 'es-ni' => 'Spanish (Nicaragua)',
659 'es-pa' => 'Spanish (Panama)',
660 'es-py' => 'Spanish (Paraguay)',
661 'es-pe' => 'Spanish (Peru)',
662 'es-pr' => 'Spanish (Puerto Rico)',
663 'es-us' => 'Spanish (United States)',
664 'es-uy' => 'Spanish (Uruguay)',
665 'es-ve' => 'Spanish (Venezuela)',
666 'es-es' => 'Spanish (Spain)',
667 'es' => 'Spanish',
668 'sx' => 'Sutu',
669 'sw' => 'Swahili',
670 'sv-fi' => 'Swedish (Finland)',
671 'sv-se' => 'Swedish (Sweden)',
672 'sv' => 'Swedish',
673 'syr' => 'Syriac',
674 'ta' => 'Tamil',
675 'tt' => 'Tatar',
676 'te' => 'Telugu',
677 'th' => 'Thai',
678 'ts' => 'Tsonga',
679 'tn' => 'Tswana',
680 'tr' => 'Turkish',
681 'uk' => 'Ukrainian',
682 'ur' => 'Urdu',
683 'uz' => 'Uzbek',
684 'vi' => 'Vietnamese',
685 'xh' => 'Xhosa',
686 'yi' => 'Yiddish',
687 'zu' => 'Zulu' );
688
689 return $languages;
690
691 } //end get_Languages() function
692
693 }
694
695 ?>