[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package VC 5 * @version $Id$ 6 * @copyright (c) 2006, 2008 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * @ignore 13 */ 14 if (!defined('IN_PHPBB')) 15 { 16 exit; 17 } 18 19 global $table_prefix; 20 21 define('CAPTCHA_QUESTIONS_TABLE', $table_prefix . 'captcha_questions'); 22 define('CAPTCHA_ANSWERS_TABLE', $table_prefix . 'captcha_answers'); 23 define('CAPTCHA_QA_CONFIRM_TABLE', $table_prefix . 'qa_confirm'); 24 25 /** 26 * And now to something completely different. Let's make a captcha without extending the abstract class. 27 * QA CAPTCHA sample implementation 28 * 29 * @package VC 30 */ 31 class phpbb_captcha_qa 32 { 33 var $confirm_id; 34 var $answer; 35 var $question_ids; 36 var $question_text; 37 var $question_lang; 38 var $question_strict; 39 var $attempts = 0; 40 var $type; 41 // dirty trick: 0 is false, but can still encode that the captcha is not yet validated 42 var $solved = 0; 43 44 /** 45 * @param int $type as per the CAPTCHA API docs, the type 46 */ 47 function init($type) 48 { 49 global $config, $db, $user; 50 51 // load our language file 52 $user->add_lang('captcha_qa'); 53 54 // read input 55 $this->confirm_id = request_var('qa_confirm_id', ''); 56 $this->answer = utf8_normalize_nfc(request_var('qa_answer', '', true)); 57 58 $this->type = (int) $type; 59 $this->question_lang = $user->lang_name; 60 61 // we need all defined questions - shouldn't be too many, so we can just grab them 62 // try the user's lang first 63 $sql = 'SELECT question_id 64 FROM ' . CAPTCHA_QUESTIONS_TABLE . " 65 WHERE lang_iso = '" . $db->sql_escape($user->lang_name) . "'"; 66 $result = $db->sql_query($sql, 3600); 67 68 while ($row = $db->sql_fetchrow($result)) 69 { 70 $this->question_ids[$row['question_id']] = $row['question_id']; 71 } 72 $db->sql_freeresult($result); 73 74 // fallback to the board default lang 75 if (!sizeof($this->question_ids)) 76 { 77 $this->question_lang = $config['default_lang']; 78 79 $sql = 'SELECT question_id 80 FROM ' . CAPTCHA_QUESTIONS_TABLE . " 81 WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; 82 $result = $db->sql_query($sql, 7200); 83 84 while ($row = $db->sql_fetchrow($result)) 85 { 86 $this->question_ids[$row['question_id']] = $row['question_id']; 87 } 88 $db->sql_freeresult($result); 89 } 90 91 // okay, if there is a confirm_id, we try to load that confirm's state. If not, we try to find one 92 if (!$this->load_answer() && (!$this->load_confirm_id() || !$this->load_answer())) 93 { 94 // we have no valid confirm ID, better get ready to ask something 95 $this->select_question(); 96 } 97 } 98 99 /** 100 * API function 101 */ 102 function &get_instance() 103 { 104 $instance =& new phpbb_captcha_qa(); 105 106 return $instance; 107 } 108 109 /** 110 * See if the captcha has created its tables. 111 */ 112 function is_installed() 113 { 114 global $db, $phpbb_root_path, $phpEx; 115 116 if (!class_exists('phpbb_db_tools')) 117 { 118 include("$phpbb_root_path/includes/db/db_tools.$phpEx"); 119 } 120 $db_tool = new phpbb_db_tools($db); 121 122 return $db_tool->sql_table_exists(CAPTCHA_QUESTIONS_TABLE); 123 } 124 125 /** 126 * API function - for the captcha to be available, it must have installed itself and there has to be at least one question in the board's default lang 127 */ 128 function is_available() 129 { 130 global $config, $db, $phpbb_root_path, $phpEx, $user; 131 132 // load language file for pretty display in the ACP dropdown 133 $user->add_lang('captcha_qa'); 134 135 if (!phpbb_captcha_qa::is_installed()) 136 { 137 return false; 138 } 139 140 $sql = 'SELECT COUNT(question_id) AS question_count 141 FROM ' . CAPTCHA_QUESTIONS_TABLE . " 142 WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; 143 $result = $db->sql_query($sql); 144 $row = $db->sql_fetchrow($result); 145 $db->sql_freeresult($result); 146 147 return ((bool) $row['question_count']); 148 } 149 150 /** 151 * API function 152 */ 153 function has_config() 154 { 155 return true; 156 } 157 158 /** 159 * API function 160 */ 161 function get_name() 162 { 163 return 'CAPTCHA_QA'; 164 } 165 166 /** 167 * API function 168 */ 169 function get_class_name() 170 { 171 return 'phpbb_captcha_qa'; 172 } 173 174 /** 175 * API function - not needed as we don't display an image 176 */ 177 function execute_demo() 178 { 179 } 180 181 /** 182 * API function - not needed as we don't display an image 183 */ 184 function execute() 185 { 186 } 187 188 /** 189 * API function - send the question to the template 190 */ 191 function get_template() 192 { 193 global $template; 194 195 if ($this->is_solved()) 196 { 197 return false; 198 } 199 else 200 { 201 $template->assign_vars(array( 202 'QA_CONFIRM_QUESTION' => $this->question_text, 203 'QA_CONFIRM_ID' => $this->confirm_id, 204 'S_CONFIRM_CODE' => true, 205 'S_TYPE' => $this->type, 206 )); 207 208 return 'captcha_qa.html'; 209 } 210 } 211 212 /** 213 * API function - we just display a mockup so that the captcha doesn't need to be installed 214 */ 215 function get_demo_template() 216 { 217 global $config, $db, $template; 218 219 if ($this->is_available()) 220 { 221 $sql = 'SELECT question_text 222 FROM ' . CAPTCHA_QUESTIONS_TABLE . " 223 WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; 224 $result = $db->sql_query_limit($sql, 1); 225 if ($row = $db->sql_fetchrow($result)) 226 { 227 $template->assign_vars(array( 228 'QA_CONFIRM_QUESTION' => $row['question_text'], 229 )); 230 } 231 $db->sql_freeresult($result); 232 } 233 return 'captcha_qa_acp_demo.html'; 234 } 235 236 /** 237 * API function 238 */ 239 function get_hidden_fields() 240 { 241 $hidden_fields = array(); 242 243 // this is required - otherwise we would forget about the captcha being already solved 244 if ($this->solved) 245 { 246 $hidden_fields['qa_answer'] = $this->answer; 247 } 248 $hidden_fields['qa_confirm_id'] = $this->confirm_id; 249 250 return $hidden_fields; 251 } 252 253 /** 254 * API function 255 */ 256 function garbage_collect($type = 0) 257 { 258 global $db, $config; 259 260 $sql = 'SELECT c.confirm_id 261 FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' c 262 LEFT JOIN ' . SESSIONS_TABLE . ' s 263 ON (c.session_id = s.session_id) 264 WHERE s.session_id IS NULL' . 265 ((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type); 266 $result = $db->sql_query($sql); 267 268 if ($row = $db->sql_fetchrow($result)) 269 { 270 $sql_in = array(); 271 272 do 273 { 274 $sql_in[] = (string) $row['confirm_id']; 275 } 276 while ($row = $db->sql_fetchrow($result)); 277 278 if (sizeof($sql_in)) 279 { 280 $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' 281 WHERE ' . $db->sql_in_set('confirm_id', $sql_in); 282 $db->sql_query($sql); 283 } 284 } 285 $db->sql_freeresult($result); 286 } 287 288 /** 289 * API function - we don't drop the tables here, as that would cause the loss of all entered questions. 290 */ 291 function uninstall() 292 { 293 $this->garbage_collect(0); 294 } 295 296 /** 297 * API function - set up shop 298 */ 299 function install() 300 { 301 global $db, $phpbb_root_path, $phpEx; 302 303 if (!class_exists('phpbb_db_tools')) 304 { 305 include("$phpbb_root_path/includes/db/db_tools.$phpEx"); 306 } 307 $db_tool = new phpbb_db_tools($db); 308 309 $tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE, CAPTCHA_QA_CONFIRM_TABLE); 310 311 $schemas = array( 312 CAPTCHA_QUESTIONS_TABLE => array ( 313 'COLUMNS' => array( 314 'question_id' => array('UINT', Null, 'auto_increment'), 315 'strict' => array('BOOL', 0), 316 'lang_id' => array('UINT', 0), 317 'lang_iso' => array('VCHAR:30', ''), 318 'question_text' => array('TEXT_UNI', ''), 319 ), 320 'PRIMARY_KEY' => 'question_id', 321 'KEYS' => array( 322 'lang' => array('INDEX', 'lang_iso'), 323 ), 324 ), 325 CAPTCHA_ANSWERS_TABLE => array ( 326 'COLUMNS' => array( 327 'question_id' => array('UINT', 0), 328 'answer_text' => array('STEXT_UNI', ''), 329 ), 330 'KEYS' => array( 331 'qid' => array('INDEX', 'question_id'), 332 ), 333 ), 334 CAPTCHA_QA_CONFIRM_TABLE => array ( 335 'COLUMNS' => array( 336 'session_id' => array('CHAR:32', ''), 337 'confirm_id' => array('CHAR:32', ''), 338 'lang_iso' => array('VCHAR:30', ''), 339 'question_id' => array('UINT', 0), 340 'attempts' => array('UINT', 0), 341 'confirm_type' => array('USINT', 0), 342 ), 343 'KEYS' => array( 344 'session_id' => array('INDEX', 'session_id'), 345 'lookup' => array('INDEX', array('confirm_id', 'session_id', 'lang_iso')), 346 ), 347 'PRIMARY_KEY' => 'confirm_id', 348 ), 349 ); 350 351 foreach($schemas as $table => $schema) 352 { 353 if (!$db_tool->sql_table_exists($table)) 354 { 355 $db_tool->sql_create_table($table, $schema); 356 } 357 } 358 } 359 360 /** 361 * API function - see what has to be done to validate 362 */ 363 function validate() 364 { 365 global $config, $db, $user; 366 367 $error = ''; 368 369 if (!sizeof($this->question_ids)) 370 { 371 return false; 372 } 373 374 if (!$this->confirm_id) 375 { 376 $error = $user->lang['CONFIRM_QUESTION_WRONG']; 377 } 378 else 379 { 380 if ($this->check_answer()) 381 { 382 // $this->delete_code(); commented out to allow posting.php to repeat the question 383 $this->solved = true; 384 } 385 else 386 { 387 $error = $user->lang['CONFIRM_QUESTION_WRONG']; 388 } 389 } 390 391 if (strlen($error)) 392 { 393 // okay, incorrect answer. Let's ask a new question. 394 $this->new_attempt(); 395 $this->solved = false; 396 397 return $error; 398 } 399 else 400 { 401 return false; 402 } 403 } 404 405 /** 406 * Select a question 407 */ 408 function select_question() 409 { 410 global $db, $user; 411 412 if (!sizeof($this->question_ids)) 413 { 414 return false; 415 } 416 $this->confirm_id = md5(unique_id($user->ip)); 417 $this->question = (int) array_rand($this->question_ids); 418 419 $sql = 'INSERT INTO ' . CAPTCHA_QA_CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array( 420 'confirm_id' => (string) $this->confirm_id, 421 'session_id' => (string) $user->session_id, 422 'lang_iso' => (string) $this->question_lang, 423 'confirm_type' => (int) $this->type, 424 'question_id' => (int) $this->question, 425 )); 426 $db->sql_query($sql); 427 428 $this->load_answer(); 429 } 430 431 /** 432 * New Question, if desired. 433 */ 434 function reselect_question() 435 { 436 global $db, $user; 437 438 if (!sizeof($this->question_ids)) 439 { 440 return false; 441 } 442 443 $this->question = (int) array_rand($this->question_ids); 444 $this->solved = 0; 445 446 $sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . ' 447 SET question_id = ' . (int) $this->question . " 448 WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "' 449 AND session_id = '" . $db->sql_escape($user->session_id) . "'"; 450 $db->sql_query($sql); 451 452 $this->load_answer(); 453 } 454 455 /** 456 * Wrong answer, so we increase the attempts and use a different question. 457 */ 458 function new_attempt() 459 { 460 global $db, $user; 461 462 // yah, I would prefer a stronger rand, but this should work 463 $this->question = (int) array_rand($this->question_ids); 464 $this->solved = 0; 465 466 $sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . ' 467 SET question_id = ' . (int) $this->question . ", 468 attempts = attempts + 1 469 WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "' 470 AND session_id = '" . $db->sql_escape($user->session_id) . "'"; 471 $db->sql_query($sql); 472 473 $this->load_answer(); 474 } 475 476 477 /** 478 * See if there is already an entry for the current session. 479 */ 480 function load_confirm_id() 481 { 482 global $db, $user; 483 484 $sql = 'SELECT confirm_id 485 FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " 486 WHERE 487 session_id = '" . $db->sql_escape($user->session_id) . "' 488 AND lang_iso = '" . $db->sql_escape($this->question_lang) . "' 489 AND confirm_type = " . $this->type; 490 $result = $db->sql_query_limit($sql, 1); 491 $row = $db->sql_fetchrow($result); 492 $db->sql_freeresult($result); 493 494 if ($row) 495 { 496 $this->confirm_id = $row['confirm_id']; 497 return true; 498 } 499 return false; 500 } 501 502 /** 503 * Look up everything we need and populate the instance variables. 504 */ 505 function load_answer() 506 { 507 global $db, $user; 508 509 if (!strlen($this->confirm_id) || !sizeof($this->question_ids)) 510 { 511 return false; 512 } 513 514 $sql = 'SELECT con.question_id, attempts, question_text, strict 515 FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' con, ' . CAPTCHA_QUESTIONS_TABLE . " qes 516 WHERE con.question_id = qes.question_id 517 AND confirm_id = '" . $db->sql_escape($this->confirm_id) . "' 518 AND session_id = '" . $db->sql_escape($user->session_id) . "' 519 AND qes.lang_iso = '" . $db->sql_escape($this->question_lang) . "' 520 AND confirm_type = " . $this->type; 521 $result = $db->sql_query($sql); 522 $row = $db->sql_fetchrow($result); 523 $db->sql_freeresult($result); 524 525 if ($row) 526 { 527 $this->question = $row['question_id']; 528 529 $this->attempts = $row['attempts']; 530 $this->question_strict = $row['strict']; 531 $this->question_text = $row['question_text']; 532 533 return true; 534 } 535 536 return false; 537 } 538 539 /** 540 * The actual validation 541 */ 542 function check_answer() 543 { 544 global $db; 545 546 $answer = ($this->question_strict) ? utf8_normalize_nfc(request_var('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc(request_var('qa_answer', '', true))); 547 548 $sql = 'SELECT answer_text 549 FROM ' . CAPTCHA_ANSWERS_TABLE . ' 550 WHERE question_id = ' . (int) $this->question; 551 $result = $db->sql_query($sql); 552 553 while ($row = $db->sql_fetchrow($result)) 554 { 555 $solution = ($this->question_strict) ? $row['answer_text'] : utf8_clean_string($row['answer_text']); 556 557 if ($solution === $answer) 558 { 559 $this->solved = true; 560 561 break; 562 } 563 } 564 $db->sql_freeresult($result); 565 566 return $this->solved; 567 } 568 569 /** 570 * API function - clean the entry 571 */ 572 function delete_code() 573 { 574 global $db, $user; 575 576 $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " 577 WHERE confirm_id = '" . $db->sql_escape($confirm_id) . "' 578 AND session_id = '" . $db->sql_escape($user->session_id) . "' 579 AND confirm_type = " . $this->type; 580 $db->sql_query($sql); 581 } 582 583 /** 584 * API function 585 */ 586 function get_attempt_count() 587 { 588 return $this->attempts; 589 } 590 591 /** 592 * API function 593 */ 594 function reset() 595 { 596 global $db, $user; 597 598 $sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . " 599 WHERE session_id = '" . $db->sql_escape($user->session_id) . "' 600 AND confirm_type = " . (int) $this->type; 601 $db->sql_query($sql); 602 603 // we leave the class usable by generating a new question 604 $this->select_question(); 605 } 606 607 /** 608 * API function 609 */ 610 function is_solved() 611 { 612 if (request_var('qa_answer', false) && $this->solved === 0) 613 { 614 $this->validate(); 615 } 616 617 return (bool) $this->solved; 618 } 619 620 /** 621 * API function - The ACP backend, this marks the end of the easy methods 622 */ 623 function acp_page($id, &$module) 624 { 625 global $db, $user, $auth, $template; 626 global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; 627 628 $user->add_lang('acp/board'); 629 $user->add_lang('captcha_qa'); 630 631 if (!$this->is_installed()) 632 { 633 $this->install(); 634 } 635 636 $module->tpl_name = 'captcha_qa_acp'; 637 $module->page_title = 'ACP_VC_SETTINGS'; 638 $form_key = 'acp_captcha'; 639 add_form_key($form_key); 640 641 $submit = request_var('submit', false); 642 $question_id = request_var('question_id', 0); 643 $action = request_var('action', ''); 644 645 // we have two pages, so users might want to navigate from one to the other 646 $list_url = $module->u_action . "&configure=1&select_captcha=" . $this->get_class_name(); 647 648 $template->assign_vars(array( 649 'U_ACTION' => $module->u_action, 650 'QUESTION_ID' => $question_id , 651 'CLASS' => $this->get_class_name(), 652 )); 653 654 // show the list? 655 if (!$question_id && $action != 'add') 656 { 657 $this->acp_question_list($module); 658 } 659 else if ($question_id && $action == 'delete') 660 { 661 if ($this->get_class_name() !== $config['captcha_plugin'] || !$this->acp_is_last($question_id)) 662 { 663 if (confirm_box(true)) 664 { 665 $this->acp_delete_question($question_id); 666 667 trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url)); 668 } 669 else 670 { 671 confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 672 'question_id' => $question_id, 673 'action' => $action, 674 'configure' => 1, 675 'select_captcha' => $this->get_class_name(), 676 )) 677 ); 678 } 679 } 680 else 681 { 682 trigger_error($user->lang['QA_LAST_QUESTION'] . adm_back_link($list_url), E_USER_WARNING); 683 } 684 } 685 else 686 { 687 // okay, show the editor 688 $error = false; 689 $input_question = request_var('question_text', '', true); 690 $input_answers = request_var('answers', '', true); 691 $input_lang = request_var('lang_iso', '', true); 692 $input_strict = request_var('strict', false); 693 $langs = $this->get_languages(); 694 695 foreach ($langs as $lang => $entry) 696 { 697 $template->assign_block_vars('langs', array( 698 'ISO' => $lang, 699 'NAME' => $entry['name'], 700 )); 701 } 702 703 $template->assign_vars(array( 704 'U_LIST' => $list_url, 705 )); 706 707 if ($question_id) 708 { 709 if ($question = $this->acp_get_question_data($question_id)) 710 { 711 $answers = (isset($input_answers[$lang])) ? $input_answers[$lang] : implode("\n", $question['answers']); 712 713 $template->assign_vars(array( 714 'QUESTION_TEXT' => ($input_question) ? $input_question : $question['question_text'], 715 'LANG_ISO' => ($input_lang) ? $input_lang : $question['lang_iso'], 716 'STRICT' => (isset($_REQUEST['strict'])) ? $input_strict : $question['strict'], 717 'ANSWERS' => $answers, 718 )); 719 } 720 else 721 { 722 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url)); 723 } 724 } 725 else 726 { 727 $template->assign_vars(array( 728 'QUESTION_TEXT' => $input_question, 729 'LANG_ISO' => $input_lang, 730 'STRICT' => $input_strict, 731 'ANSWERS' => $input_answers, 732 )); 733 } 734 735 if ($submit && check_form_key($form_key)) 736 { 737 $data = $this->acp_get_question_input(); 738 739 if (!$this->validate_input($data)) 740 { 741 $template->assign_vars(array( 742 'S_ERROR' => true, 743 )); 744 } 745 else 746 { 747 if ($question_id) 748 { 749 $this->acp_update_question($data, $question_id); 750 } 751 else 752 { 753 $this->acp_add_question($data); 754 } 755 756 add_log('admin', 'LOG_CONFIG_VISUAL'); 757 trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url)); 758 } 759 } 760 else if ($submit) 761 { 762 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url), E_USER_WARNING); 763 } 764 } 765 } 766 767 /** 768 * This handles the list overview 769 */ 770 function acp_question_list(&$module) 771 { 772 global $db, $template; 773 774 $sql = 'SELECT * 775 FROM ' . CAPTCHA_QUESTIONS_TABLE; 776 $result = $db->sql_query($sql); 777 778 $template->assign_vars(array( 779 'S_LIST' => true, 780 )); 781 782 while ($row = $db->sql_fetchrow($result)) 783 { 784 $url = $module->u_action . "&question_id={$row['question_id']}&configure=1&select_captcha=" . $this->get_class_name() . '&'; 785 786 $template->assign_block_vars('questions', array( 787 'QUESTION_TEXT' => $row['question_text'], 788 'QUESTION_ID' => $row['question_id'], 789 'QUESTION_LANG' => $row['lang_iso'], 790 'U_DELETE' => "{$url}action=delete", 791 'U_EDIT' => "{$url}action=edit", 792 )); 793 } 794 $db->sql_freeresult($result); 795 } 796 797 /** 798 * Grab a question and bring it into a format the editor understands 799 */ 800 function acp_get_question_data($question_id) 801 { 802 global $db; 803 804 if ($question_id) 805 { 806 $sql = 'SELECT * 807 FROM ' . CAPTCHA_QUESTIONS_TABLE . ' 808 WHERE question_id = ' . $question_id; 809 $result = $db->sql_query($sql); 810 $question = $db->sql_fetchrow($result); 811 $db->sql_freeresult($result); 812 813 if (!$question) 814 { 815 return false; 816 } 817 818 $question['answers'] = array(); 819 820 $sql = 'SELECT * 821 FROM ' . CAPTCHA_ANSWERS_TABLE . ' 822 WHERE question_id = ' . $question_id; 823 $result = $db->sql_query($sql); 824 825 while ($row = $db->sql_fetchrow($result)) 826 { 827 $question['answers'][] = $row['answer_text']; 828 } 829 $db->sql_freeresult($result); 830 831 return $question; 832 } 833 } 834 835 /** 836 * Grab a question from input and bring it into a format the editor understands 837 */ 838 function acp_get_question_input() 839 { 840 $answers = utf8_normalize_nfc(request_var('answers', '', true)); 841 $question = array( 842 'question_text' => request_var('question_text', '', true), 843 'strict' => request_var('strict', false), 844 'lang_iso' => request_var('lang_iso', ''), 845 'answers' => (strlen($answers)) ? explode("\n", $answers) : '', 846 ); 847 848 return $question; 849 } 850 851 /** 852 * Update a question. 853 * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data 854 */ 855 function acp_update_question($data, $question_id) 856 { 857 global $db, $cache; 858 859 // easier to delete all answers than to figure out which to update 860 $sql = 'DELETE FROM ' . CAPTCHA_ANSWERS_TABLE . " WHERE question_id = $question_id"; 861 $db->sql_query($sql); 862 863 $langs = $this->get_languages(); 864 $question_ary = $data; 865 $question_ary['lang_id'] = $langs[$question_ary['lang_iso']]['id']; 866 unset($question_ary['answers']); 867 868 $sql = 'UPDATE ' . CAPTCHA_QUESTIONS_TABLE . ' 869 SET ' . $db->sql_build_array('UPDATE', $question_ary) . " 870 WHERE question_id = $question_id"; 871 $db->sql_query($sql); 872 873 $this->acp_insert_answers($data, $question_id); 874 875 $cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE); 876 } 877 878 /** 879 * Insert a question. 880 * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data 881 */ 882 function acp_add_question($data) 883 { 884 global $db, $cache; 885 886 $langs = $this->get_languages(); 887 $question_ary = $data; 888 889 $question_ary['lang_id'] = $langs[$data['lang_iso']]['id']; 890 unset($question_ary['answers']); 891 892 $sql = 'INSERT INTO ' . CAPTCHA_QUESTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $question_ary); 893 $db->sql_query($sql); 894 895 $question_id = $db->sql_nextid(); 896 897 $this->acp_insert_answers($data, $question_id); 898 899 $cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE); 900 } 901 902 /** 903 * Insert the answers. 904 * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data 905 */ 906 function acp_insert_answers($data, $question_id) 907 { 908 global $db, $cache; 909 910 foreach ($data['answers'] as $answer) 911 { 912 $answer_ary = array( 913 'question_id' => $question_id, 914 'answer_text' => $answer, 915 ); 916 917 $sql = 'INSERT INTO ' . CAPTCHA_ANSWERS_TABLE . ' ' . $db->sql_build_array('INSERT', $answer_ary); 918 $db->sql_query($sql); 919 } 920 921 $cache->destroy('sql', CAPTCHA_ANSWERS_TABLE); 922 } 923 924 /** 925 * Delete a question. 926 */ 927 function acp_delete_question($question_id) 928 { 929 global $db, $cache; 930 931 $tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE); 932 933 foreach ($tables as $table) 934 { 935 $sql = "DELETE FROM $table 936 WHERE question_id = $question_id"; 937 $db->sql_query($sql); 938 } 939 940 $cache->destroy('sql', $tables); 941 } 942 943 /** 944 * Check if the entered data can be inserted/used 945 * param mixed $data : an array as created from acp_get_question_input or acp_get_question_data 946 */ 947 function validate_input($question_data) 948 { 949 $langs = $this->get_languages(); 950 951 if (!isset($question_data['lang_iso']) || 952 !isset($question_data['question_text']) || 953 !isset($question_data['strict']) || 954 !isset($question_data['answers'])) 955 { 956 return false; 957 } 958 959 if (!isset($langs[$question_data['lang_iso']]) || 960 !strlen($question_data['question_text']) || 961 !sizeof($question_data['answers']) || 962 !is_array($question_data['answers'])) 963 { 964 return false; 965 } 966 967 return true; 968 } 969 970 /** 971 * List the installed language packs 972 */ 973 function get_languages() 974 { 975 global $db; 976 977 $sql = 'SELECT * 978 FROM ' . LANG_TABLE; 979 $result = $db->sql_query($sql); 980 981 $langs = array(); 982 while ($row = $db->sql_fetchrow($result)) 983 { 984 $langs[$row['lang_iso']] = array( 985 'name' => $row['lang_local_name'], 986 'id' => (int) $row['lang_id'], 987 ); 988 } 989 $db->sql_freeresult($result); 990 991 return $langs; 992 } 993 994 995 996 /** 997 * See if there is a question other than the one we have 998 */ 999 function acp_is_last($question_id) 1000 { 1001 global $config, $db; 1002 1003 if ($question_id) 1004 { 1005 $sql = 'SELECT question_id 1006 FROM ' . CAPTCHA_QUESTIONS_TABLE . " 1007 WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "' 1008 AND question_id <> " . (int) $question_id; 1009 $result = $db->sql_query_limit($sql, 1); 1010 $question = $db->sql_fetchrow($result); 1011 $db->sql_freeresult($result); 1012 1013 if (!$question) 1014 { 1015 return true; 1016 } 1017 return false; 1018 } 1019 } 1020 } 1021 1022 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 2 15:03:47 2013 | Cross-referenced by PHPXref 0.7.1 |