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'] = ' 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
Show as Percent
 Show the aggregated language data as counts or percentages.
Show Raw Data
 Show the raw language string (such as en-us,en;q=0.5) in addition to the user-friendly language listing.
'; 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[] = '
Okay'; 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 ?>