Parent Directory
|
Revision Log
|
Revision Graph
Use gmdate instead fo date
| 1 | <?php |
| 2 | // $Id: legislature.module,v 1.70 2009/10/21 03:09:35 drumm Exp $ |
| 3 | |
| 4 | /** |
| 5 | * @file |
| 6 | * |
| 7 | * To build a jurisdiction's import: |
| 8 | * - Fill out the @link /api/group/metadata metadata @endlink functions. |
| 9 | * - For each data source or type, create a PHP file, |
| 10 | * imports/{jusrisdiction}/{name}.inc. Define all functions as |
| 11 | * legislature_{jurisdiction}_{...}(). |
| 12 | * - Import functions which should be visible in the UI for importing need an |
| 13 | * entry in legislature_imports(). |
| 14 | * - Long imports can be queued to run later with job_queue_add(). |
| 15 | * - Call @link /api/group/import import @endlink functions for saving data. |
| 16 | * - Call @link /api/group/info info @endlink functions for getting information about the |
| 17 | * database. |
| 18 | */ |
| 19 | |
| 20 | define('LEGISLATURE_SPONSOR', 1); |
| 21 | define('LEGISLATURE_COSPONSOR', 2); |
| 22 | |
| 23 | define('LEGISLATURE_LAST_FIRST', 1); |
| 24 | define('LEGISLATURE_FIRST_LAST', 2); |
| 25 | |
| 26 | function legislature_perm() { |
| 27 | return array('run legislature imports', 'configure legislatures'); |
| 28 | } |
| 29 | |
| 30 | function legislature_menu() { |
| 31 | return array( |
| 32 | 'admin/settings/legislature' => array( |
| 33 | 'title' => 'Legislatures', |
| 34 | 'page callback' => 'drupal_get_form', |
| 35 | 'page arguments' => array('legislature_configure_form'), |
| 36 | 'access arguments' => array('configure legislatures'), |
| 37 | ), |
| 38 | 'legislature-ids.csv' => array( |
| 39 | 'title' => 'Legislature IDs', |
| 40 | 'page callback' => 'legislature_ids_csv', |
| 41 | 'access arguments' => array('access content'), |
| 42 | 'type' => MENU_CALLBACK, |
| 43 | ), |
| 44 | ); |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * @defgroup import Importing data |
| 49 | * Import functions will either update existing records or save new data. |
| 50 | * |
| 51 | * Most data structures should be saved via the API instead of directly |
| 52 | * accessing the database. Execptions which have not been implemented in the |
| 53 | * API yet include the following tables: |
| 54 | * - {legislature_action_politician}, individual politician votes on a action. |
| 55 | * - {legislature_bill_committee}, committees which have worked on a bill. |
| 56 | * - {legislature_bill_sponsor}, politicians which have sponsored or |
| 57 | * co-sponsored a bill. |
| 58 | * - {legislature_bill_title}, alternate titles for bills. |
| 59 | * - {legislature_committee_membership}, politician membership to committees. |
| 60 | * |
| 61 | * The full database structure is described in legislature_install(). |
| 62 | */ |
| 63 | |
| 64 | /** |
| 65 | * @defgroup info Information retrieval |
| 66 | * Retrieve information from the legislature database, such as ID numbers. |
| 67 | */ |
| 68 | |
| 69 | /** |
| 70 | * @defgroup metadata Jurisdiction metadata |
| 71 | * |
| 72 | * Information about each jurisdiction. |
| 73 | * |
| 74 | * @{ |
| 75 | */ |
| 76 | |
| 77 | /** |
| 78 | * A list of supported sessions. |
| 79 | */ |
| 80 | function legislature_sessions() { |
| 81 | return array( |
| 82 | 'us' => array( // Top-level key is jusisdiction. |
| 83 | '108' => t('108th U.S. Congress'), // Number => Title |
| 84 | '109' => t('109th U.S. Congress'), |
| 85 | '110' => t('110th U.S. Congress'), |
| 86 | '111' => t('111th U.S. Congress'), |
| 87 | ), |
| 88 | 'ca' => array( |
| 89 | '2003' => t('2003-2004 California State Legislature'), |
| 90 | '2009' => t('2009-2010 California State Legislature'), |
| 91 | ), |
| 92 | 'ia' => array( |
| 93 | '82' => t('82nd Iowa General Assembly'), |
| 94 | ), |
| 95 | 'lax' => array( |
| 96 | '2009' => t('2009 City of Los Angeles'), |
| 97 | ), |
| 98 | ); |
| 99 | } |
| 100 | |
| 101 | /** |
| 102 | * A list of start and end years for each session. |
| 103 | */ |
| 104 | function legislature_session_years() { |
| 105 | return array( |
| 106 | 'us' => array( |
| 107 | '108' => array('start' => 2003, 'end' => 2004), |
| 108 | '109' => array('start' => 2005, 'end' => 2006), |
| 109 | '110' => array('start' => 2007, 'end' => 2008), |
| 110 | '111' => array('start' => 2009, 'end' => 2010), |
| 111 | ), |
| 112 | 'ca' => array( |
| 113 | '2003' => array('start' => 2003, 'end' => 2004), |
| 114 | '2009' => array('start' => 2009, 'end' => 2010), |
| 115 | ), |
| 116 | 'ia' => array( |
| 117 | '82' => array('start' => 2007, 'end' => 2008), |
| 118 | ), |
| 119 | 'lax' => array( |
| 120 | '2009' => array('start' => 2009, 'end' => 2009), |
| 121 | ), |
| 122 | ); |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * A list of offices. |
| 127 | */ |
| 128 | function legislature_offices() { |
| 129 | return array( |
| 130 | 'us' => array( |
| 131 | t('Senate') => array( // Office title |
| 132 | 'length' => 6, // Years |
| 133 | 'count_limit' => 0, // Sessions, 0 is unlimited |
| 134 | ), |
| 135 | t('House') => array( |
| 136 | 'length' => 2, |
| 137 | 'count_limit' => 0, |
| 138 | ), |
| 139 | ), |
| 140 | 'ca' => array( |
| 141 | t('Assembly') => array( |
| 142 | 'length' => 2, |
| 143 | 'count_limit' => 3, |
| 144 | ), |
| 145 | t('Senate') => array( |
| 146 | 'length' => 4, |
| 147 | 'count_limit' => 2, |
| 148 | ), |
| 149 | t('Governor') => array( |
| 150 | 'length' => 4, |
| 151 | 'count_limit' => 2, |
| 152 | ), |
| 153 | ), |
| 154 | 'ia' => array( |
| 155 | t('Senate') => array( |
| 156 | 'length' => 4, |
| 157 | 'count_limit' => 0, |
| 158 | ), |
| 159 | t('House') => array( |
| 160 | 'length' => 2, |
| 161 | 'count_limit' => 0, |
| 162 | ), |
| 163 | ), |
| 164 | 'lax' => array( |
| 165 | t('Mayor') => array( |
| 166 | 'length' => 4, |
| 167 | 'count_limit' => 2, |
| 168 | ), |
| 169 | t('Controller') => array( |
| 170 | 'length' => 4, |
| 171 | 'count_limit' => 0, |
| 172 | ), |
| 173 | t('Attorney') => array( |
| 174 | 'length' => 4, |
| 175 | 'count_limit' => 0, |
| 176 | ), |
| 177 | t('Council') => array( |
| 178 | 'length' => 4, |
| 179 | 'count_limit' => 0, |
| 180 | ), |
| 181 | ), |
| 182 | ); |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * A list of bill prefixes. |
| 187 | * |
| 188 | * @return an array of system prefix => display prefix. |
| 189 | */ |
| 190 | function legislature_prefixes($jurisdiction) { |
| 191 | switch ($jurisdiction) { |
| 192 | case 'us': |
| 193 | // Put short prefixes last. |
| 194 | return array( |
| 195 | 'HR' => 'H.Res.', |
| 196 | 'HJ' => 'H.J.Res.', |
| 197 | 'HC' => 'H.Con.Res.', |
| 198 | 'H' => 'H.R.', |
| 199 | 'SR' => 'S.Res.', |
| 200 | 'SJ' => 'S.J.Res.', |
| 201 | 'SC' => 'S.Con.Res.', |
| 202 | 'S' => 'S.', |
| 203 | ); |
| 204 | |
| 205 | case 'ca': |
| 206 | return array( |
| 207 | 'AB' => 'AB', |
| 208 | 'SB' => 'SB', |
| 209 | ); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | /** |
| 214 | * A list of full chamber names corresponding to the first letter of the bill |
| 215 | * prefix. |
| 216 | * |
| 217 | * @return An array of prefix{0} => house name. |
| 218 | */ |
| 219 | function legislature_prefix_chamber($jurisdiction) { |
| 220 | switch ($jurisdiction) { |
| 221 | case 'us': |
| 222 | return array( |
| 223 | 'H' => t('House'), |
| 224 | 'S' => t('Senate'), |
| 225 | ); |
| 226 | |
| 227 | case 'ca': |
| 228 | return array( |
| 229 | 'A' => t('Assembly'), |
| 230 | 'S' => t('Senate'), |
| 231 | ); |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | /** |
| 236 | * @} |
| 237 | */ |
| 238 | |
| 239 | /** |
| 240 | * Parses measures into valid prefixes and numbers. If the prefix is not valid, |
| 241 | * the returned prefix is NULL. |
| 242 | */ |
| 243 | function legislature_parse_measure($measure, $jurisdiction) { |
| 244 | $measure = str_replace(' ', '', str_replace('.', '', drupal_strtoupper($measure))); |
| 245 | |
| 246 | foreach (legislature_prefixes($jurisdiction) as $system => $prefix) { |
| 247 | $prefix = str_replace('.', '', drupal_strtoupper($prefix)); |
| 248 | if (strpos($measure, $prefix) === 0) { |
| 249 | return array($system, intval(trim(drupal_substr($measure, strlen($prefix))))); |
| 250 | } |
| 251 | } |
| 252 | return array(NULL, intval($measure)); |
| 253 | } |
| 254 | |
| 255 | /** |
| 256 | * Define import functions which will be visible in the UI. |
| 257 | */ |
| 258 | function legislature_imports() { |
| 259 | $imports = array(); |
| 260 | |
| 261 | if (count(legislature_get_enabled_sessions('us')) > 0) { // Only show imports if the jurisdiction is enabled |
| 262 | $imports[t('GovTrack')] = array( // Section |
| 263 | 'legislature_govtrack_politicians' => array( // Function name |
| 264 | 'title' => t('Politicians'), |
| 265 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 266 | 'access' => user_access('run legislature imports'), |
| 267 | ), |
| 268 | 'legislature_govtrack_committees' => array( |
| 269 | 'title' => t('Committees'), |
| 270 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 271 | 'access' => user_access('run legislature imports'), |
| 272 | ), |
| 273 | 'legislature_govtrack_bills' => array( |
| 274 | 'title' => t('Bills'), |
| 275 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 276 | 'access' => user_access('run legislature imports'), |
| 277 | ), |
| 278 | 'legislature_govtrack_update_bill' => array( |
| 279 | 'title' => t('Specific bill'), |
| 280 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 281 | 'access' => user_access('run legislature imports'), |
| 282 | ), |
| 283 | 'legislature_govtrack_roll' => array( |
| 284 | 'title' => t('Specific roll'), |
| 285 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 286 | 'access' => user_access('run legislature imports'), |
| 287 | ), |
| 288 | 'legislature_govtrack_recent_votes' => array( |
| 289 | 'title' => t('Recent votes'), |
| 290 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 291 | 'access' => user_access('run legislature imports'), |
| 292 | ), |
| 293 | 'legislature_govtrack_undervotes' => array( |
| 294 | 'title' => t('Schedule updates for under or over-voted bills'), |
| 295 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/govtrack.inc', |
| 296 | 'access' => user_access('run legislature imports'), |
| 297 | ), |
| 298 | ); |
| 299 | |
| 300 | $imports[t('Sunlight')] = array( |
| 301 | 'legislature_sunlight_politicians' => array( |
| 302 | 'title' => t('Politician contact information'), |
| 303 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/sunlight.inc', |
| 304 | 'access' => user_access('run legislature imports') && (variable_get('legislature_sunlight_api_key', '') !== ''), |
| 305 | ), |
| 306 | ); |
| 307 | |
| 308 | $imports[t('Thomas')] = array( |
| 309 | 'legislature_us_thomas_committees' => array( |
| 310 | 'title' => t('Committees'), |
| 311 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/us/thomas.inc', |
| 312 | 'access' => user_access('run legislature imports'), |
| 313 | ), |
| 314 | ); |
| 315 | } |
| 316 | |
| 317 | if (count(legislature_get_enabled_sessions('ia')) > 0) { |
| 318 | $imports[t('Iowa')] = array( |
| 319 | 'legislature_ia_politicians' => array( |
| 320 | 'title' => t('Politicians'), |
| 321 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ia/legis_politicians.inc', |
| 322 | 'access' => user_access('run legislature imports') && legislature_html_parser_installed(), |
| 323 | ), |
| 324 | 'legislature_ia_bills' => array( |
| 325 | 'title' => t('Bills'), |
| 326 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ia/legis_bills.inc', |
| 327 | 'access' => user_access('run legislature imports') && legislature_html_parser_installed(), |
| 328 | ), |
| 329 | ); |
| 330 | } |
| 331 | |
| 332 | if (count(legislature_get_enabled_sessions('ca')) > 0) { |
| 333 | $imports[t('California')] = array( |
| 334 | 'legislature_ca_load_state_data' => array( |
| 335 | 'title' => t('Load State Data (load files and move records)'), |
| 336 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 337 | 'access' => user_access('run legislature imports'), |
| 338 | ), |
| 339 | 'legislature_ca_load_files' => array( |
| 340 | 'title' => t('Load State Files'), |
| 341 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 342 | 'access' => user_access('run legislature imports'), |
| 343 | ), |
| 344 | 'legislature_ca_move_legislators' => array( |
| 345 | 'title' => t('Move State Legislators'), |
| 346 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 347 | 'access' => user_access('run legislature imports'), |
| 348 | ), |
| 349 | 'legislature_ca_move_committees' => array( |
| 350 | 'title' => t('Move State Committees'), |
| 351 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 352 | 'access' => user_access('run legislature imports'), |
| 353 | ), |
| 354 | 'legislature_ca_move_bills' => array( |
| 355 | 'title' => t('Move State Bills'), |
| 356 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 357 | 'access' => user_access('run legislature imports'), |
| 358 | ), |
| 359 | 'legislature_ca_move_actions' => array( |
| 360 | 'title' => t('Move State Actions'), |
| 361 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/leginfo.inc', |
| 362 | 'access' => user_access('run legislature imports'), |
| 363 | ), |
| 364 | 'legislature_ca_move_nimsp' => array( |
| 365 | 'title' => t('Move NIMSP Data'), |
| 366 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/ca/nimsp.inc', |
| 367 | 'access' => user_access('run legislature imports'), |
| 368 | ), |
| 369 | ); |
| 370 | } |
| 371 | |
| 372 | $imports[t('CSV')] = array( |
| 373 | 'legislature_import_politicians' => array( |
| 374 | 'title' => t('Politicians'), |
| 375 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/politicians.inc', |
| 376 | 'access' => user_access('run legislature imports'), |
| 377 | ), |
| 378 | 'legislature_import_districts' => array( |
| 379 | 'title' => t('Districts'), |
| 380 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/districts.inc', |
| 381 | 'access' => user_access('run legislature imports'), |
| 382 | ), |
| 383 | 'legislature_import_jobs' => array( |
| 384 | 'title' => t('Jobs'), |
| 385 | 'file path' => drupal_get_path('module', 'legislature') .'/imports/jobs.inc', |
| 386 | 'access' => user_access('run legislature imports'), |
| 387 | ), |
| 388 | ); |
| 389 | |
| 390 | return $imports; |
| 391 | } |
| 392 | |
| 393 | function legislature_help($page = NULL) { |
| 394 | switch ($page) { |
| 395 | case 'admin/content/import_manager/legislature/GovTrack': |
| 396 | case 'admin/content/import_manager/legislature/Sunlight': |
| 397 | return '<p>'. t('These can take awhile. Let the browser load and check the <a href="!logs">logs</a>. Some actions add <a href="!queue">queued jobs</a> to be executed later.', array('!logs' => url('admin/logs/watchdog'), '!queue' => url('admin/logs/job_queue'))) .'</p>'; |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | function legislature_form_alter(&$form, &$form_state, $form_id) { |
| 402 | switch ($form_id) { |
| 403 | case 'legislature_govtrack_bills': |
| 404 | foreach (legislature_get_enabled_sessions('us') as $session) { |
| 405 | $form['data']['clear'][$session] = array( |
| 406 | '#type' => 'checkbox', |
| 407 | '#title' => t('Reload all %session bills', array('%session' => $session)), |
| 408 | ); |
| 409 | } |
| 410 | break; |
| 411 | |
| 412 | case 'legislature_govtrack_update_bill': |
| 413 | $form['data']['bill_id'] = array( |
| 414 | '#type' => 'textfield', |
| 415 | '#title' => t('Bill ID'), |
| 416 | ); |
| 417 | break; |
| 418 | |
| 419 | case 'legislature_govtrack_roll': |
| 420 | $form['data']['action_id'] = array( |
| 421 | '#type' => 'textfield', |
| 422 | '#title' => t('Action ID'), |
| 423 | ); |
| 424 | break; |
| 425 | |
| 426 | case 'legislature_ia_politicians': |
| 427 | if (!legislature_html_parser_installed()) { |
| 428 | $form['data'][] = array( |
| 429 | '#value' => '<p>'. t('Requires <a href="@url">htmlparser.inc</a>', array('@url' => 'http://php-html.cvs.sourceforge.net/php-html/phphtmlparser/src/htmlparser.inc?view=log')) .'</p>', |
| 430 | ); |
| 431 | } |
| 432 | break; |
| 433 | |
| 434 | case 'legislature_import_politicians': |
| 435 | $form['#attributes']['enctype'] = 'multipart/form-data'; |
| 436 | $form['data']['file'] = array( |
| 437 | '#type' => 'file', |
| 438 | '#value' => t('CSV file'), |
| 439 | '#description' => t('With columns politician_id, last_name, full_name, roster_name, phone, fax, email, party, gender, middle_name, nick_name, first_name, name_modifier.'), |
| 440 | ); |
| 441 | break; |
| 442 | |
| 443 | case 'legislature_import_districts': |
| 444 | $form['#attributes']['enctype'] = 'multipart/form-data'; |
| 445 | $form['data']['file'] = array( |
| 446 | '#type' => 'file', |
| 447 | '#value' => t('CSV file'), |
| 448 | '#description' => t('With columns jurisdiction, office, number, state, name_display.'), |
| 449 | ); |
| 450 | break; |
| 451 | |
| 452 | case 'legislature_import_jobs': |
| 453 | $form['#attributes']['enctype'] = 'multipart/form-data'; |
| 454 | $form['data']['file'] = array( |
| 455 | '#type' => 'file', |
| 456 | '#value' => t('CSV file'), |
| 457 | '#description' => t('With columns politician_id, jurisdiction, state, office, number, start, end, is_candidate.'), |
| 458 | ); |
| 459 | break; |
| 460 | |
| 461 | case 'legislature_ca_load_state_data': |
| 462 | $sessions = legislature_sessions(); |
| 463 | // Session menu |
| 464 | $form['data']['session'] = array( |
| 465 | '#type' => 'select', |
| 466 | '#title' => t('Session'), |
| 467 | '#options' => $sessions['ca'], |
| 468 | ); |
| 469 | // Day menu |
| 470 | $form['data']['day'] = array( |
| 471 | '#type' => 'select', |
| 472 | '#title' => t('Day'), |
| 473 | '#options' => array( |
| 474 | 'Sun' => 'Sun', |
| 475 | 'Mon' => 'Mon', |
| 476 | 'Tue' => 'Tue', |
| 477 | 'Wed' => 'Wed', |
| 478 | 'Thu' => 'Thu', |
| 479 | 'Fri' => 'Fri', |
| 480 | 'Sat' => 'Sat', |
| 481 | ), |
| 482 | ); |
| 483 | break; |
| 484 | |
| 485 | case 'legislature_ca_load_files': |
| 486 | $sessions = legislature_sessions(); |
| 487 | // Session menu |
| 488 | $form['data']['session'] = array( |
| 489 | '#type' => 'select', |
| 490 | '#title' => t('Session'), |
| 491 | '#options' => $sessions['ca'], |
| 492 | ); |
| 493 | // Day menu |
| 494 | $form['data']['day'] = array( |
| 495 | '#type' => 'select', |
| 496 | '#title' => t('Day'), |
| 497 | '#options' => array( |
| 498 | 'Sun' => 'Sun', |
| 499 | 'Mon' => 'Mon', |
| 500 | 'Tue' => 'Tue', |
| 501 | 'Wed' => 'Wed', |
| 502 | 'Thu' => 'Thu', |
| 503 | 'Fri' => 'Fri', |
| 504 | 'Sat' => 'Sat', |
| 505 | ), |
| 506 | ); |
| 507 | // Table menu |
| 508 | $tables['all'] = 'All'; |
| 509 | include_once './' . drupal_get_path('module', 'legislature') .'/imports/ca/leginfo_mapping.inc'; |
| 510 | foreach(legislature_ca_table_file_mapping() as $key => $value) { |
| 511 | $tables[$key] = $key; |
| 512 | } |
| 513 | $form['data']['table'] = array( |
| 514 | '#type' => 'select', |
| 515 | '#title' => t('Table(s)'), |
| 516 | '#options' => $tables, |
| 517 | ); |
| 518 | break; |
| 519 | |
| 520 | case 'legislature_ca_move_legislators': |
| 521 | $sessions = legislature_sessions(); |
| 522 | // Session menu |
| 523 | $form['data']['session'] = array( |
| 524 | '#type' => 'select', |
| 525 | '#title' => t('Session'), |
| 526 | '#options' => $sessions['ca'], |
| 527 | ); |
| 528 | break; |
| 529 | |
| 530 | case 'legislature_ca_move_committees': |
| 531 | $sessions = legislature_sessions(); |
| 532 | // Session menu |
| 533 | $form['data']['session'] = array( |
| 534 | '#type' => 'select', |
| 535 | '#title' => t('Session'), |
| 536 | '#options' => $sessions['ca'], |
| 537 | ); |
| 538 | break; |
| 539 | |
| 540 | case 'legislature_ca_move_bills': |
| 541 | $sessions = legislature_sessions(); |
| 542 | // Session menu |
| 543 | $form['data']['session'] = array( |
| 544 | '#type' => 'select', |
| 545 | '#title' => t('Session'), |
| 546 | '#options' => $sessions['ca'], |
| 547 | ); |
| 548 | break; |
| 549 | case 'legislature_ca_move_actions': |
| 550 | $sessions = legislature_sessions(); |
| 551 | // Session menu |
| 552 | $form['data']['session'] = array( |
| 553 | '#type' => 'select', |
| 554 | '#title' => t('Session'), |
| 555 | '#options' => $sessions['ca'], |
| 556 | ); |
| 557 | break; |
| 558 | |
| 559 | } |
| 560 | } |
| 561 | |
| 562 | function legislature_configure_form() { |
| 563 | $session_options = array(); |
| 564 | $session_value = array(); |
| 565 | foreach (legislature_sessions() as $jurisdiction => $sessions) { |
| 566 | foreach ($sessions as $session => $name) { |
| 567 | $session_options[$jurisdiction .'-'. $session] = $name; |
| 568 | $session = legislature_get_session($jurisdiction, $session); |
| 569 | if (!is_null($session) && $session->enabled) { |
| 570 | $session_value[] = $jurisdiction .'-'. $session->name; |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | $form = array(); |
| 575 | |
| 576 | $form['legislature_sessions'] = array( |
| 577 | '#title' => t('Enabled sessions'), |
| 578 | '#type' => 'checkboxes', |
| 579 | '#options' => $session_options, |
| 580 | '#default_value' => $session_value, |
| 581 | ); |
| 582 | |
| 583 | $form['legislature_ca_data_directory'] = array( |
| 584 | '#type' => 'textfield', |
| 585 | '#title' => t('California Legislature data directory'), |
| 586 | '#default_value' => variable_get('legislature_ca_data_directory', ''), |
| 587 | ); |
| 588 | $form['legislature_ca_antiword'] = array( |
| 589 | '#type' => 'textfield', |
| 590 | '#title' => t('Location of Antiword application (converts Word documents to plain text)'), |
| 591 | '#default_value' => variable_get('legislature_ca_antiword', ''), |
| 592 | ); |
| 593 | |
| 594 | $form['legislature_sunlight_api_key'] = array( |
| 595 | '#type' => 'textfield', |
| 596 | '#title' => t('Sunlight API key'), |
| 597 | '#default_value' => variable_get('legislature_sunlight_api_key', ''), |
| 598 | '#description' => l(t('Register for a key'), 'http://services.sunlightlabs.com/api/register/'), |
| 599 | ); |
| 600 | |
| 601 | $form['submit'] = array( |
| 602 | '#type' => 'submit', |
| 603 | '#default_value' => t('Save'), |
| 604 | ); |
| 605 | |
| 606 | return $form; |
| 607 | } |
| 608 | |
| 609 | function legislature_configure_form_submit($form, &$form_state) { |
| 610 | foreach ($form_state['values']['legislature_sessions'] as $key => $value) { |
| 611 | list($jurisdiction, $name) = explode('-', $key); |
| 612 | $session = legislature_get_session($jurisdiction, $name); |
| 613 | if (is_null($session)) { |
| 614 | db_query("INSERT INTO {legislature_session} (session_jurisdiction, session_name, enabled) VALUES ('%s', '%s', %d)", $jurisdiction, $name, ($key === $value)); |
| 615 | |
| 616 | // If this is the first of a jurisdiction, we need to add offices. |
| 617 | if (db_result(db_query("SELECT count(*) FROM {legislature_office} WHERE jurisdiction = '%s'", drupal_strtoupper($jurisdiction))) == 0) { |
| 618 | $offices = legislature_offices(); |
| 619 | foreach ($offices[$jurisdiction] as $title => $office) { |
| 620 | db_query("INSERT INTO {legislature_office} (jurisdiction, title, length, count_limit) VALUES ('%s', '%s', %d, %d)", drupal_strtoupper($jurisdiction), $title, $office['length'], $office['count_limit']); |
| 621 | } |
| 622 | } |
| 623 | } |
| 624 | else { |
| 625 | db_query('UPDATE {legislature_session} SET enabled = %d WHERE session_id = %d', ($key === $value), $session->session_id); |
| 626 | } |
| 627 | } |
| 628 | |
| 629 | variable_set('legislature_ca_data_directory', $form_state['values']['legislature_ca_data_directory']); |
| 630 | variable_set('legislature_ca_antiword', $form_state['values']['legislature_ca_antiword']); |
| 631 | |
| 632 | variable_set('legislature_sunlight_api_key', $form_state['values']['legislature_sunlight_api_key']); |
| 633 | |
| 634 | drupal_set_message(t('Saved configuration.')); |
| 635 | } |
| 636 | |
| 637 | function legislature_ids_csv() { |
| 638 | $output = "politician_id,govtrack_id,crp_id,legis_id,fec_id,name\n"; |
| 639 | $result = db_query('SELECT politician_id, govtrack_id, crp_id, legis_id, fec_id, full_name FROM {legislature_politician}'); |
| 640 | while ($row = db_fetch_array($result)) { |
| 641 | $row['name'] = '"'. $row['name'] .'"'; |
| 642 | $output .= implode(',', $row) ."\n"; |
| 643 | } |
| 644 | drupal_set_header('Content-type: text/csv'); |
| 645 | print $output; |
| 646 | } |
| 647 | |
| 648 | /** |
| 649 | * Get the session object for a given jurisdiction and name. |
| 650 | * |
| 651 | * @ingroup info |
| 652 | * |
| 653 | * @param $jurisdiction |
| 654 | * A jurisdiction name |
| 655 | * @param $name |
| 656 | * A session name |
| 657 | * @return |
| 658 | * A session object. If the session does not exist, NULL. |
| 659 | */ |
| 660 | function legislature_get_session($jurisdiction, $name) { |
| 661 | static $sessions; |
| 662 | |
| 663 | if (is_null($sessions)) { |
| 664 | $sessions = array(); |
| 665 | $result = db_query('SELECT session_id, session_jurisdiction, session_name, enabled FROM {legislature_session}'); |
| 666 | while ($session = db_fetch_object($result)) { |
| 667 | $sessions[$session->session_jurisdiction][$session->session_name] = (object) array( |
| 668 | 'session_id' => $session->session_id, |
| 669 | 'jurisdiction' => $session->session_jurisdiction, |
| 670 | 'name' => $session->session_name, |
| 671 | 'enabled' => $session->enabled, |
| 672 | ); |
| 673 | } |
| 674 | } |
| 675 | |
| 676 | if (isset($sessions[$jurisdiction][$name])) { |
| 677 | return $sessions[$jurisdiction][$name]; |
| 678 | } |
| 679 | return NULL; |
| 680 | } |
| 681 | |
| 682 | /** |
| 683 | * Find enabled sessions within a jurisdiction. |
| 684 | * |
| 685 | * @ingroup info |
| 686 | * |
| 687 | * @param $jurisdiction |
| 688 | * A jurisdiction string. |
| 689 | * @return |
| 690 | * An array of enabled session name strings. |
| 691 | */ |
| 692 | function legislature_get_enabled_sessions($jurisdiction) { |
| 693 | $enabled_sessions = array(); |
| 694 | |
| 695 | $sessions = legislature_sessions(); |
| 696 | foreach (array_keys($sessions[$jurisdiction]) as $name) { |
| 697 | $session = legislature_get_session($jurisdiction, $name); |
| 698 | if (!is_null($session) && $session->enabled) { |
| 699 | $enabled_sessions[] = $name; |
| 700 | } |
| 701 | } |
| 702 | |
| 703 | return $enabled_sessions; |
| 704 | } |
| 705 | |
| 706 | function legislature_html_parser_installed() { |
| 707 | return is_readable(drupal_get_path('module', 'legislature') .'/htmlparser.inc'); |
| 708 | } |
| 709 | |
| 710 | /** |
| 711 | * Import a politician. |
| 712 | * |
| 713 | * @ingroup import |
| 714 | * |
| 715 | * @param $politician |
| 716 | * An associative array of the politician's data. A key matching |
| 717 | * $id_key .'_id' must exist. Not all possible keys need to exist. |
| 718 | * @param $id_key |
| 719 | * The key to de-dupe on. Do not include '_id' suffix. |
| 720 | * |
| 721 | * @return |
| 722 | * The $politician array with the 'politician_id' filled in. |
| 723 | */ |
| 724 | function legislature_politician($politician, $id_key = 'politician') { |
| 725 | if ($id_key != 'politician') { |
| 726 | $politician['politician_id'] = legislature_get_politician_id($id_key, $politician[$id_key .'_id']); |
| 727 | } |
| 728 | |
| 729 | if ($politician['politician_id'] == 0) { |
| 730 | drupal_write_record('legislature_politician', $politician); |
| 731 | $politician['politician_id'] = db_last_insert_id('legislature_politician', 'politician_id'); |
| 732 | } |
| 733 | else { |
| 734 | drupal_write_record('legislature_politician', $politician, 'politician_id'); |
| 735 | } |
| 736 | |
| 737 | return $politician['politician_id']; |
| 738 | } |
| 739 | |
| 740 | /** |
| 741 | * Import a district and retrieve the district_id. |
| 742 | * |
| 743 | * @ingroup import |
| 744 | * |
| 745 | * @param $jurisdiction |
| 746 | * The jusrisdiction string, such as 'ca' or 'us'. |
| 747 | * @param $office |
| 748 | * The office string, such as 'Senate' or 'House'. |
| 749 | * @param $state |
| 750 | * Two-letter state abbreviation, such as 'CA' or 'IA'. |
| 751 | * @param $number |
| 752 | * District number, or 0 if the district is not numbered. |
| 753 | * @param $name_display |
| 754 | * The human-readable name for the district. |
| 755 | * |
| 756 | * @return |
| 757 | * The district_id for the district. |
| 758 | */ |
| 759 | function legislature_district($jurisdiction, $office, $state, $number, $name_display) { |
| 760 | $name = drupal_strtoupper($jurisdiction) .'-'. $office .'-'. $state .'-'. $number; |
| 761 | $return = db_result(db_query("SELECT district_id FROM {legislature_district} WHERE name = '%s'", $name)); |
| 762 | if ($return !== FALSE) { |
| 763 | return $return; |
| 764 | } |
| 765 | else { |
| 766 | db_query("INSERT INTO {legislature_district} (jurisdiction, name, office, number, city, state, name_display) VALUES ('%s', '%s', '%s', %d, '', '%s', '%s')", $jurisdiction, $name, $office, $number, $state, $name_display); |
| 767 | return db_last_insert_id('legislature_district', 'district_id');; |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | /** |
| 772 | * Get a district's district_id. |
| 773 | * |
| 774 | * @ingroup info |
| 775 | * |
| 776 | * @param $jurisdiction |
| 777 | * The jusrisdiction string, such as 'ca' or 'us'. |
| 778 | * @param $office |
| 779 | * The office string, such as 'Senate' or 'House'. |
| 780 | * @param $state |
| 781 | * Two-letter state abbreviation, such as 'CA' or 'IA'. |
| 782 | * @param $number |
| 783 | * District number, or 0 if the district is not numbered. |
| 784 | * |
| 785 | * @return |
| 786 | * The district_id for the district. |
| 787 | */ |
| 788 | function legislature_get_district_id($jurisdiction, $state, $office, $number) { |
| 789 | static $districts = array(); |
| 790 | |
| 791 | $name = drupal_strtoupper($jurisdiction) .'-'. $office .'-'. drupal_strtoupper($state) .'-'. $number; |
| 792 | |
| 793 | if (!isset($districts[$name])) { |
| 794 | $districts[$name] = db_result(db_query("SELECT district_id FROM {legislature_district} WHERE name = '%s'", $name)); |
| 795 | } |
| 796 | |
| 797 | return $districts[$name]; |
| 798 | } |
| 799 | |
| 800 | /** |
| 801 | * Returns all districts in a jurisdiction. |
| 802 | */ |
| 803 | function legislature_get_districts($jurisdiction) { |
| 804 | $districts = array(); |
| 805 | $result = db_query("SELECT district_id, name, office, number, city, state, name_display FROM {legislature_district} WHERE jurisdiction = '%s'", $jurisdiction); |
| 806 | while ($district = db_fetch_object($result)) { |
| 807 | $districts[$district->district_id] = $district; |
| 808 | } |
| 809 | return $districts; |
| 810 | } |
| 811 | |
| 812 | /** |
| 813 | * Get an office's office_id. |
| 814 | * |
| 815 | * @ingroup info |
| 816 | * |
| 817 | * @param $jurisdiction |
| 818 | * The jusrisdiction string, such as 'ca' or 'us'. |
| 819 | * @param $title |
| 820 | * The office's title. |
| 821 | * @return |
| 822 | * The office_id for the office. |
| 823 | */ |
| 824 | function legislature_get_office_id($jurisdiction, $title) { |
| 825 | return db_result(db_query("SELECT office_id FROM {legislature_office} WHERE jurisdiction = '%s' AND title = '%s'", $jurisdiction, $title)); |
| 826 | } |
| 827 | |
| 828 | /** |
| 829 | * Save elected jobs for a politician. All the elected jobs for a politician |
| 830 | * need to be saved in one call to this function. Include elected_jobs from all |
| 831 | * sessions. |
| 832 | * |
| 833 | * Keys in a elected_job associative array are: |
| 834 | * - office_id |
| 835 | * - district_id |
| 836 | * - start, a UNIX timestamp for the start of the politician's term. |
| 837 | * - end, a UNIX timestamp for the end of the politician's term. |
| 838 | * - is_candidate, TRUE if the job is a candidacy. |
| 839 | * |
| 840 | * @ingroup import |
| 841 | * |
| 842 | * @param $jurisdiction |
| 843 | * The jusrisdiction string, such as 'ca' or 'us'. |
| 844 | * @param $politician_id |
| 845 | * The politician_id for the elected job. |
| 846 | * @param $elected_jobs |
| 847 | * An array of elected_job associative arrays. |
| 848 | */ |
| 849 | function legislature_save_elected_jobs($jurisdiction, $politician_id, $elected_jobs, $session = NULL) { |
| 850 | //todo this thrashes the elected job id, but we don't really use that anywhere. |
| 851 | // Clear old jobs |
| 852 | if (isset($session)) { |
| 853 | $result = db_query("SELECT ej.elected_job_id FROM {legislature_elected_job} ej INNER JOIN {legislature_elected_job_session} ejs ON ejs.elected_job_id = ej.elected_job_id INNER JOIN {legislature_session} s ON s.session_id = ejs.session_id WHERE ej.politician_id = %d AND s.session_name = '%s' AND s.session_jurisdiction = '%s'", $politician_id, $session, $jurisdiction); |
| 854 | } |
| 855 | else { |
| 856 | $result = db_query('SELECT elected_job_id FROM {legislature_elected_job} WHERE politician_id = %d', $politician_id); |
| 857 | } |
| 858 | $old_elected_job_ids = array(); |
| 859 | while ($row = db_fetch_object($result)) { |
| 860 | $old_elected_job_ids[] = $row->elected_job_id; |
| 861 | } |
| 862 | db_query("DELETE FROM {legislature_elected_job_session} WHERE elected_job_id IN (" . db_placeholders($old_elected_job_ids) . ")", $old_elected_job_ids); |
| 863 | db_query("DELETE FROM {legislature_elected_job} WHERE elected_job_id IN (" . db_placeholders($old_elected_job_ids) . ")", $old_elected_job_ids); |
| 864 | |
| 865 | // Save the jobs |
| 866 | foreach ($elected_jobs as $job) { |
| 867 | db_query('INSERT INTO {legislature_elected_job} (politician_id, office_id, district_id, start, end, is_candidate) VALUES (%d, %d, %d, %d, %d, %d)', $politician_id, $job['office_id'], $job['district_id'], $job['start'], $job['end'], $job['is_candidate']); |
| 868 | $job['elected_job_id'] = db_last_insert_id('legislature_elected_job', 'elected_job_id'); |
| 869 | foreach (legislature_get_sessions_by_date($jurisdiction, $job['start'], $job['end']) as $session) { |
| 870 | db_query('INSERT INTO {legislature_elected_job_session} (elected_job_id, session_id) VALUES (%d, %d)', $job['elected_job_id'], $session->session_id); |
| 871 | } |
| 872 | } |
| 873 | |
| 874 | // Mark is_most_recent for all elected job rows as 0 |
| 875 | db_query("UPDATE {legislature_elected_job} SET is_most_recent = 0 WHERE politician_id = %d", $politician_id); |
| 876 | // Mark record with most recent start value as 1 |
| 877 | $max_start = db_result(db_query("SELECT MAX(start) FROM {legislature_elected_job} WHERE politician_id = %d", $politician_id)); |
| 878 | db_query("UPDATE {legislature_elected_job} SET is_most_recent = 1 WHERE politician_id = %d AND start = %d", $politician_id, $max_start); |
| 879 | } |
| 880 | |
| 881 | /** |
| 882 | * Get an array of sessions intersecting with a time period. |
| 883 | * |
| 884 | * @ingroup info |
| 885 | * |
| 886 | * @param $jurisdiction |
| 887 | * The jusrisdiction string, such as 'ca' or 'us'. |
| 888 | * @param $start |
| 889 | * A UNIX timestamp for the time period start. |
| 890 | * @param $end |
| 891 | * A UNIX timestamp for the time period end. |
| 892 | * |
| 893 | * @return |
| 894 | * An array of session objects. |
| 895 | */ |
| 896 | function legislature_get_sessions_by_date($jurisdiction, $start, $end) { |
| 897 | $session_years = legislature_session_years(); |
| 898 | $years = range(gmdate('Y', $start), gmdate('Y', $end)); |
| 899 | |
| 900 | $sessions = array(); |
| 901 | foreach (legislature_get_enabled_sessions($jurisdiction) as $session) { |
| 902 | if (array_intersect(range($session_years[$jurisdiction][$session]['start'], $session_years[$jurisdiction][$session]['end']), $years)) { |
| 903 | $sessions[] = legislature_get_session($jurisdiction, $session); |
| 904 | } |
| 905 | } |
| 906 | return $sessions; |
| 907 | } |
| 908 | |
| 909 | /** |
| 910 | * Import a bill's metadata. |
| 911 | * |
| 912 | * Keys for bill data include: |
| 913 | * - session_id |
| 914 | * - measure, {machine-readable prefix} .' '. {bill number} |
| 915 | * - last_version, any string which changes when a full bill update is needed. |
| 916 | * - status, a short machine-readble string describing the bill's status. |
| 917 | * - topic, the bill's main title. |
| 918 | * - description, a string descriibng the bill. |
| 919 | * all are required. |
| 920 | * |
| 921 | * @ingroup import |
| 922 | * |
| 923 | * @param $data |
| 924 | * An object of bill data. |
| 925 | * |
| 926 | * @return |
| 927 | * TRUE if a full bill update needs to be run, otherwise FALSE. The bill_id |
| 928 | * is filled into $data, which is passed by-reference. |
| 929 | */ |
| 930 | function legislature_save_bill(&$data) { |
| 931 | $update = FALSE; |
| 932 | |
| 933 | $bill = db_fetch_object(db_query("SELECT bill_id, last_version FROM {legislature_bill} WHERE session_id = %d AND measure = '%s'", $data['session_id'], $data['measure'])); |
| 934 | if ($bill !== FALSE) { |
| 935 | $data['bill_id'] = $bill->bill_id; |
| 936 | if ($data['last_version'] != $bill->last_version) { |
| 937 | $update = TRUE; |
| 938 | $data['queued'] = TRUE; |
| 939 | } |
| 940 | db_query("UPDATE {legislature_bill} SET status = '%s', last_version = '%s', topic = '%s', description = '%s' WHERE bill_id = %d", $data['status'], $data['last_version'], $data['topic'], $data['description'], $data['bill_id']); |
| 941 | module_invoke_all('legislature', 'bill', 'update', $data); |
| 942 | } |
| 943 | else { |
| 944 | db_query("INSERT INTO {legislature_bill} (measure, prefix, session_id, topic, description, status, last_version) VALUES ('%s', '%s', %d, '%s', '%s', '%s', '%s')", $data['measure'], $data['prefix'], $data['session_id'], $data['topic'], $data['description'], $data['status'], $data['last_version']); |
| 945 | $data['bill_id'] = db_last_insert_id('legislature_bill', 'bill_id'); |
| 946 | $update = TRUE; |
| 947 | module_invoke_all('legislature', 'bill', 'insert', $data); |
| 948 | } |
| 949 | |
| 950 | return $update; |
| 951 | } |
| 952 | |
| 953 | /** |
| 954 | * Get the standardized politician ID using a 3rd party ID. |
| 955 | * |
| 956 | * @ingroup info |
| 957 | * |
| 958 | * @param $type |
| 959 | * Either 'govtrack', 'crp', or 'legis' for US, CA, and IA. |
| 960 | * @param $id |
| 961 | * An ID number of $type. |
| 962 | * |
| 963 | * @return |
| 964 | * The corresponding standardized politician ID. |
| 965 | */ |
| 966 | function legislature_get_politician_id($type, $id) { |
| 967 | static $politician_ids = array( |
| 968 | 'govtrack' => array(), |
| 969 | 'crp' => array(), |
| 970 | 'legis' => array(), |
| 971 | 'fec' => array(), |
| 972 | ); |
| 973 | |
| 974 | if (!in_array($type, array_keys($politician_ids))) { |
| 975 | return NULL; // We don't support this $type. |
| 976 | } |
| 977 | |
| 978 | if (!isset($politician_ids[$type][$id])) { |
| 979 | $politician_ids[$type][$id] = db_result(db_query('SELECT politician_id FROM {legislature_politician} WHERE '. $type ."_id = '%s'", $id)); |
| 980 | } |
| 981 | |
| 982 | return $politician_ids[$type][$id]; |
| 983 | } |
| 984 | |
| 985 | /** |
| 986 | * |
| 987 | */ |
| 988 | function legislature_search_politician_id($conditions = array()) { |
| 989 | $where = array(); |
| 990 | $args = array(); |
| 991 | |
| 992 | foreach ($conditions as $key => $value) { |
| 993 | switch ($key) { |
| 994 | case 'session id': |
| 995 | $where[] = 'ejs.session_id = %d'; |
| 996 | $args[] = $value; |
| 997 | break; |
| 998 | |
| 999 | case 'office id': |
| 1000 | $where[] = 'ej.office_id = %d'; |
| 1001 | $args[] = $value; |
| 1002 | break; |
| 1003 | |
| 1004 | case 'district id': |
| 1005 | $where[] = 'ej.district_id = %d'; |
| 1006 | $args[] = $value; |
| 1007 | break; |
| 1008 | |
| 1009 | case 'name': |
| 1010 | $politician_ids = legislature_normalize_politician_name($value); |
| 1011 | if (count($politician_ids) == 0) { |
| 1012 | return NULL; |
| 1013 | } |
| 1014 | $where[] = 'p.politician_id IN ('. implode(',', array_fill(0, count($politician_ids), '%d')) .') '; |
| 1015 | $args = array_merge($args, $politician_ids); |
| 1016 | break; |
| 1017 | |
| 1018 | case 'first last name': |
| 1019 | $politician_ids = legislature_normalize_politician_name($value, LEGISLATURE_FIRST_LAST); |
| 1020 | if (count($politician_ids) == 0) { |
| 1021 | return NULL; |
| 1022 | } |
| 1023 | $where[] = 'p.politician_id IN ('. implode(',', array_fill(0, count($politician_ids), '%d')) .') '; |
| 1024 | $args = array_merge($args, $politician_ids); |
| 1025 | break; |
| 1026 | } |
| 1027 | } |
| 1028 | |
| 1029 | $return = db_result(db_query_range('SELECT DISTINCT p.politician_id FROM {legislature_politician} p INNER JOIN {legislature_elected_job} ej ON ej.politician_id = p.politician_id INNER JOIN {legislature_elected_job_session} ejs ON ejs.elected_job_id = ej.elected_job_id WHERE '. implode(' AND ', $where), $args, 0, 1)); |
| 1030 | if ($return === FALSE) { |
| 1031 | return NULL; |
| 1032 | } |
| 1033 | else { |
| 1034 | return $return; |
| 1035 | } |
| 1036 | } |
| 1037 | |
| 1038 | /** |
| 1039 | * Normalize a poltician's name and look for matches. |
| 1040 | * |
| 1041 | * Based on work by GovTrack.us. http://www.govtrack.us/source.xpd |
| 1042 | * |
| 1043 | * @param $name |
| 1044 | * The politician's name. Either as 'Last, First' or 'First Last'. |
| 1045 | * @param $format |
| 1046 | * Either LEGISLATURE_LAST_FIRST or LEGISLATURE_FIRST_LAST. |
| 1047 | * @return |
| 1048 | * An array of possible politician_ids. |
| 1049 | */ |
| 1050 | function legislature_normalize_politician_name($name, $format = LEGISLATURE_LAST_FIRST) { |
| 1051 | // Split last name, first name |
| 1052 | $name = str_replace(array('``', "''"), array('"', '"'), $name); // ``Hank'' |
| 1053 | $name = str_replace(array('é', 'ú'), array('e', 'u'), $name); // MySQL has little respect for proper accents |
| 1054 | $name = str_replace(',"', '",', $name); // Henry C. "Hank," Jr. |
| 1055 | $name = preg_replace('/(\.)(\S)/', '$1 $2', $name); // 'C.A.' => 'C. A.' |
| 1056 | |
| 1057 | if ($format == LEGISLATURE_FIRST_LAST) { |
| 1058 | list($name, $namemod) = legislature_parse_suffix($name, $namemod); |
| 1059 | |
| 1060 | $fnames = preg_split('/\s+/', $name); |
| 1061 | $lastname = array_pop($fnames); |
| 1062 | if ($namemod != '') { |
| 1063 | array_push($fnames, $namemod); |
| 1064 | } |
| 1065 | |
| 1066 | if (preg_match('/^(du|de|La|Van)$/i', $fnames[count($fnames) - 1])) { |
| 1067 | $lastname = array_pop($fnames) .' '. $lastname; |
| 1068 | } |
| 1069 | } |
| 1070 | else { // Either just last name, or 'last, first' format. |
| 1071 | $lastname = $name; |
| 1072 | $fnames = array(); |
| 1073 | if (preg_match('/^([^,]+),\s+([\w\W]+)/', $name, $matches)) { |
| 1074 | $lastname = $matches[1]; |
| 1075 | $fnames = preg_split('/[\s,]+/', $matches[2]); |
| 1076 | |
| 1077 | // Test $namemod |
| 1078 | $m = $fnames[count($fnames) - 1]; |
| 1079 | if (preg_match('/^(Jr\.?|Sr\.?|I|II|III|IV)$/', $m)) { |
| 1080 | $namemod = $m; |
| 1081 | array_pop($fnames); |
| 1082 | } |
| 1083 | } |
| 1084 | |
| 1085 | if ($lastname == drupal_strtoupper($lastname)) { |
| 1086 | $lastname = drupal_strtolower($lastname); |
| 1087 | $lastname = drupal_ucfirst($lastname); |
| 1088 | } |
| 1089 | |
| 1090 | list($lastname, $namemod) = legislature_parse_suffix($lastname, $namemod); |
| 1091 | if ($namemod != '') { |
| 1092 | array_push($fnames, $namemod); |
| 1093 | } |
| 1094 | } |
| 1095 | |
| 1096 | // Single letter first name entries need a period. |
| 1097 | foreach ($fnames as $key => $f) { |
| 1098 | if (strlen($f) == 1) { |
| 1099 | $fnames[$key] .= '.'; |
| 1100 | } |
| 1101 | } |
| 1102 | |
| 1103 | // Get list of matching records by last name. |
| 1104 | |
| 1105 | $lastsplit = explode(' ', $lastname); |
| 1106 | |
| 1107 | // For women we better search the middle name field for maiden names, but |
| 1108 | // then if it matches the last name we have to undef the middle name field |
| 1109 | // because then it's not to be understood as a middle name. |
| 1110 | $lastname = strtr($lastname, ' ', '-'); |
| 1111 | $lastname2 = strtr($lastname, '-', ' '); |
| 1112 | $where = array(); |
| 1113 | $args = array(); |
| 1114 | $where[] = "last_name = '%s'"; |
| 1115 | $args[] = $lastname; |
| 1116 | $where[] = "last_name = '%s'"; |
| 1117 | $args[] = $lastname2; |
| 1118 | $where[] = "middle_name = '%s'"; |
| 1119 | $args[] = $lastname2; |
| 1120 | if (count($lastsplit) == 2) { |
| 1121 | $where[] = "(middle_name = '%s' AND last_name = '%s')"; |
| 1122 | $args[] = $lastsplit[0]; |
| 1123 | $args[] = $lastsplit[1]; |
| 1124 | } |
| 1125 | $where[] = "last_name LIKE '%s'"; |
| 1126 | $args[] = $lastname .'-'; |
| 1127 | $where[] = "last_name LIKE '%s'"; |
| 1128 | $args[] = $lastname .' '; |
| 1129 | if (count($fnames) >= 2) { |
| 1130 | $where[] = "last_name = '%s'"; |
| 1131 | $args[] = $fnames[count($fnames) - 1] .' '. $lastname; |
| 1132 | $where[] = "last_name = '%s'"; |
| 1133 | $args[] = $fnames[count($fnames) - 1] .'-'. $lastname; |
| 1134 | } |
| 1135 | $count = db_result(db_query('SELECT count(*) FROM {legislature_politician} WHERE ('. implode(' OR ', $where) .') AND govtrack_id <> 0', $args)); |
| 1136 | if ($count == 1) { |
| 1137 | return array(db_result(db_query('SELECT politician_id FROM {legislature_politician} WHERE ('. implode(' OR ', $where) .') AND govtrack_id <> 0', $args))); |
| 1138 | } |
| 1139 | $result = db_query('SELECT politician_id, middle_name, nick_name, last_name, name_modifier, first_name FROM {legislature_politician} WHERE ('. implode(' OR ', $where) .') AND govtrack_id <> 0', $args); |
| 1140 | while ($match = db_fetch_object($result)) { |
| 1141 | if ($lastname != $match->lastname && $lastname == $match->middle_name) { |
| 1142 | $match->middle_name = ''; |
| 1143 | } |
| 1144 | |
| 1145 | foreach (array('first_name', 'nick_name', 'name_modifier', 'middle_name') as $n) { |
| 1146 | $match->$n = str_replace(array('é', 'ú'), array('e', 'u'), $match->$n); // MySQL has little respect for proper accents |
| 1147 | } |
| 1148 | |
| 1149 | // Make list of possible first name strings |
| 1150 | $fntests = array(); |
| 1151 | $fntests[] = array($match->first_name, $match->nick_name, $match->name_modifier); |
| 1152 | if ($match->nick_name != '') { |
| 1153 | $fntests[] = array($match->first_name, $match->middle_name, $match->name_modifier); |
| 1154 | $fntests[] = array($match->first_name, '('. $match->nick_name .')', $match->name_modifier); |
| 1155 | $fntests[] = array($match->first_name, '"'. $match->nick_name .'"', $match->name_modifier); |
| 1156 | $fntests[] = array($match->first_name, $match->middle_name, '('. $match->nick_name .')', $match->name_modifier); |
| 1157 | $fntests[] = |