changing one wrong string.
[moodle.git] / lib / environmentlib.php
CommitLineData
f58b518f 1<?php //$Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 2001-3001 Martin Dougiamas http://dougiamas.com //
11// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
12// //
13// This program is free software; you can redistribute it and/or modify //
14// it under the terms of the GNU General Public License as published by //
15// the Free Software Foundation; either version 2 of the License, or //
16// (at your option) any later version. //
17// //
18// This program is distributed in the hope that it will be useful, //
19// but WITHOUT ANY WARRANTY; without even the implied warranty of //
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21// GNU General Public License for more details: //
22// //
23// http://www.gnu.org/copyleft/gpl.html //
24// //
25///////////////////////////////////////////////////////////////////////////
26
27// This library includes all the necessary stuff to execute some standard
28// tests of required versions and libraries to run Moodle. It can be
29// used from the admin interface, and both at install and upgrade.
30//
31// All the info is stored in the admin/environment.xml file,
00d3a0fd 32// supporting to have an updated version in dataroot/environment
f58b518f 33
049c0f4a 34/// Add required files
35 require_once($CFG->libdir.'/xmlize.php');
36
37/// Define a buch of XML processing errors
00d3a0fd 38 define('NO_ERROR', 0);
39 define('NO_VERSION_DATA_FOUND', 1);
40 define('NO_DATABASE_SECTION_FOUND', 2);
41 define('NO_DATABASE_VENDORS_FOUND', 3);
42 define('NO_DATABASE_VENDOR_MYSQL_FOUND', 4);
43 define('NO_DATABASE_VENDOR_POSTGRES_FOUND', 5);
44 define('NO_PHP_SECTION_FOUND', 6);
45 define('NO_PHP_VERSION_FOUND', 7);
46 define('NO_PHP_EXTENSIONS_SECTION_FOUND', 8);
47 define('NO_PHP_EXTENSIONS_NAME_FOUND', 9);
48 define('NO_DATABASE_VENDOR_VERSION_FOUND', 10);
f58b518f 49
50/**
51 * This function will perform the whole check, returning
52 * true or false as final result. Also, he full array of
53 * environment_result will be returned in the parameter list.
54 * The function looks for the best version to compare and
55 * everything. This is the only function that should be called
56 * ever from the rest of Moodle.
57 * @param string version version to check.
58 * @param array results array of results checked.
59 * @return boolean true/false, depending of results
60 */
049c0f4a 61function check_moodle_environment($version, &$environment_results, $print_table=true) {
62
63 $status = true;
f58b518f 64
878d309c 65/// This are cached per request
66 static $result = true;
67 static $env_results;
68 static $cache_exists = false;
69
70/// if we have results cached, use them
71 if ($cache_exists) {
72 $environment_results = $env_results;
73/// No cache exists, calculate everything
74 } else {
75 /// Get the more recent version before the requested
76 if (!$version = get_latest_version_available($version)) {
77 $status = false;
78 }
f58b518f 79
878d309c 80 /// Perform all the checks
81 if (!($environment_results = environment_check($version)) && $status) {
82 $status = false;
83 }
f58b518f 84
878d309c 85 /// Iterate over all the results looking for some error in required items
86 /// or some error_code
87 if ($status) {
88 foreach ($environment_results as $environment_result) {
89 if ((!$environment_result->getStatus() &&
90 $environment_result->getLevel() == 'required') ||
91 $environment_result->getErrorCode()) {
92 $result = false;
93 }
049c0f4a 94 }
f58b518f 95 }
878d309c 96 /// Going to end, we store environment_results to cache
97 $env_results = $environment_results;
98 $cache_exists = true;
99 } ///End of cache block
f58b518f 100
049c0f4a 101/// If we have decided to print all the information, just do it
102 if ($print_table) {
e909788d 103 print_moodle_environment($result && $status, $environment_results);
049c0f4a 104 }
105
878d309c 106
049c0f4a 107 return ($result && $status);
108}
109
110/**
111 * This function will print one beautiful table with all the environmental
112 * configuration and how it suits Moodle needs.
113 * @param boolean final result of the check (true/false)
114 * @param array environment_results array of results gathered
115 */
116function print_moodle_environment($result, $environment_results) {
117
118/// Get some strings
119 $strname = get_string('name');
120 $strinfo = get_string('info');
121 $strreport = get_string('report');
122 $strstatus = get_string('status');
123 $strok = get_string('ok');
124 $strerror = get_string('error');
125 $strcheck = get_string('check');
e909788d 126 $strenvironmenterrortodo = get_string('environmenterrortodo', 'admin');
049c0f4a 127
9e2d15e5 128/// Here we'll store all the feedback found
129 $feedbacktext = '';
130
049c0f4a 131/// Table header
132 $table->head = array ($strname, $strinfo, $strreport, $strstatus);
133 $table->align = array ('center', 'center', 'left', 'center');
134 $table->wrap = array ('nowrap', '', '', 'nowrap');
135 $table->size = array ('10', 10, '100%', '10');
136 $table->width = '90%';
137 $table->class = 'environmenttable';
138
139/// Iterate over each environment_result
140 $continue = true;
141 foreach ($environment_results as $environment_result) {
142 $errorline = false;
143 if ($continue) {
144 $type = $environment_result->getPart();
145 $info = $environment_result->getInfo();
146 $status = $environment_result->getStatus();
147 $error_code = $environment_result->getErrorCode();
148 /// Process Report field
878d309c 149 $rec = new stdClass();
049c0f4a 150 /// Something has gone wrong at parsing time
151 if ($error_code) {
152 $stringtouse = 'environmentxmlerror';
153 $rec->error_code = $error_code;
154 $status = $strerror;
155 $errorline = true;
156 $continue = false;
157 }
158
159 if ($continue) {
160 /// We are comparing versions
161 if ($rec->needed = $environment_result->getNeededVersion()) {
162 $rec->current = $environment_result->getCurrentVersion();
163 if ($environment_result->getLevel() == 'required') {
164 $stringtouse = 'environmentrequireversion';
165 } else {
166 $stringtouse = 'environmentrecommendversion';
167 }
168 /// We are checking installed & enabled things
169 } else {
170 if ($environment_result->getLevel() == 'required') {
171 $stringtouse = 'environmentrequireinstall';
172 } else {
173 $stringtouse = 'environmentrecommendinstall';
174 }
175 }
176 /// Calculate the status value
177 if (!$status and $environment_result->getLevel() == 'required') {
178 $status = $strerror;
179 $errorline = true;
180 } else if (!$status and $environment_result->getLevel() == 'optional') {
181 $status = $strcheck;
182 } else {
183 $status = $strok;
184 }
185 }
186
187 /// Build the text
188 $report = get_string($stringtouse, 'admin', $rec);
189 /// Format error line
190 if ($errorline) {
191 $type = '<span class="error">'.$type.'</span>';
192 $info = '<span class="error">'.$info.'</span>';
193 $report = '<span class="error">'.$report.'</span>';
194 $status = '<span class="error">'.$status.'</span>';
195 }
196 /// Add the row to the table
197 $table->data[] = array ($type, $info, $report, $status);
9e2d15e5 198 ///Process the feedback if necessary
199 if ($feedbackstr = $environment_result->getFeedbackStr()) {
200 $feedbacktext .= '<li class="environmenttable">'.get_string($feedbackstr, 'admin').'</li>';
201 }
049c0f4a 202 }
203 }
204
205/// Print table
206 print_table($table);
e909788d 207
9e2d15e5 208/// And feedback accumulated text
209 if ($feedbacktext) {
210 print_simple_box('<ul>'.$feedbacktext.'</ul>', 'center', '90%');
211 }
212
e909788d 213/// Finally, if any error has happened, print the summary box
214 if (!$result) {
215 print_simple_box($strenvironmenterrortodo, 'center', '', '', '', 'errorbox');
216 }
9e2d15e5 217
f58b518f 218}
219
220
221/**
222 * This function will normalize any version to just a serie of numbers
223 * separated by dots. Everything else will be removed.
224 * @param string $version the original version
225 * @return string the normalized version
226 */
227function normalize_version($version) {
228/// Replace everything but numbers and dots by dots
229 $version = preg_replace('/[^\.\d]/', '.', $version);
230/// Combine multiple dots in one
231 $version = preg_replace('/(\.{2,})/', '.', $version);
232/// Trim possible leading and trailing dots
233 $version = trim($version, '.');
234
235 return $version;
236}
237
238
239/**
240 * This function will load the environment.xml file and xmlize it
241 * @return mixed the xmlized structure or false on error
242 */
243function load_environment_xml() {
244
245 global $CFG;
246
247 static $data; //Only load and xmlize once by request
248
249 if (!empty($data)) {
250 return $data;
251 }
252
00d3a0fd 253/// First of all, take a look inside $CFG->dataroot/environment/environment.xml
254 $file = $CFG->dataroot.'/environment/environment.xml';
f58b518f 255 if (!is_file($file) || !is_readable($file) || !$contents = file_get_contents($file)) {
d83f8373 256 /// Fallback to fixed $CFG->admin/environment.xml
257 $file = $CFG->dirroot.'/'.$CFG->admin.'/environment.xml';
f58b518f 258 if (!is_file($file) || !is_readable($file) || !$contents = file_get_contents($file)) {
259 return false;
260 }
261 }
262/// XML the whole file
263 $data = xmlize($contents);
264
265 return $data;
266}
267
268
269/**
270 * This function will return the list of Moodle versions available
271 * @return mixed array of versions. False on error.
272 */
273function get_list_of_environment_versions ($contents) {
274
275 static $versions = array();
276
277 if (!empty($versions)) {
278 return $versions;
279 }
280
281 if (isset($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'])) {
282 foreach ($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'] as $version) {
283 $versions[] = $version['@']['version'];
284 }
285 }
286
287 return $versions;
288}
289
290
291/**
292 * This function will return the most recent version in the environment.xml
293 * file previous or equal to the version requested
294 * @param string version top version from which we start to look backwards
295 * @return string more recent version or false if not found
296 */
297function get_latest_version_available ($version) {
298
299/// Normalize the version requested
300 $version = normalize_version($version);
301
302/// Load xml file
303 if (!$contents = load_environment_xml()) {
304 return false;
305 }
306
307/// Detect available versions
308 if (!$versions = get_list_of_environment_versions($contents)) {
309 return false;
310 }
311/// First we look for exact version
312 if (in_array($version, $versions)) {
313 return $version;
314 } else {
315 $found_version = false;
316 /// Not exact match, so we are going to iterate over the list searching
317 /// for the latest version before the requested one
318 foreach ($versions as $arrversion) {
319 if (version_compare($arrversion, $version, '<')) {
320 $found_version = $arrversion;
321 }
322 }
323 }
324
325 return $found_version;
326}
327
328
329/**
330 * This function will return the xmlized data belonging to one Moodle version
331 * @return mixed the xmlized structure or false on error
332 */
333function get_environment_for_version($version) {
334
335/// Normalize the version requested
336 $version = normalize_version($version);
337
338/// Load xml file
339 if (!$contents = load_environment_xml()) {
340 return false;
341 }
342
343/// Detect available versions
344 if (!$versions = get_list_of_environment_versions($contents)) {
345 return false;
346 }
347
348/// If the version requested is available
349 if (!in_array($version, $versions)) {
350 return false;
351 }
352
353/// We now we have it. Extract from full contents.
354 $fl_arr = array_flip($versions);
355
356 return $contents['COMPATIBILITY_MATRIX']['#']['MOODLE'][$fl_arr[$version]];
357}
358
359
360/**
361 * This function will check for everything (DB, PHP and PHP extensions for now)
362 * returning an array of environment_result objects.
363 * @param string $version xml version we are going to use to test this server
364 * @return array array of results encapsulated in one environment_result object
365 */
366function environment_check($version) {
367
368/// Normalize the version requested
369 $version = normalize_version($version);
370
371 $results = array(); //To store all the results
372
373 $results[] = environment_check_database($version);
374 $results[] = environment_check_php($version);
375
376 $phpext_results = environment_check_php_extensions($version);
377
378 $results = array_merge ($results, $phpext_results);
379
380 return $results;
381}
382
383
384/**
385 * This function will check if php extensions requirements are satisfied
386 * @param string $version xml version we are going to use to test this server
387 * @return array array of results encapsulated in one environment_result object
388 */
389function environment_check_php_extensions($version) {
390
391 $results = array();
392
393/// Get the enviroment version we need
394 if (!$data = get_environment_for_version($version)) {
395 /// Error. No version data found
049c0f4a 396 $result = new environment_results('php_extension');
f58b518f 397 $result->setStatus(false);
398 $result->setErrorCode(NO_VERSION_DATA_FOUND);
399 return $result;
400 }
401
402/// Extract the php_extension part
403 if (!isset($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'])) {
404 /// Error. No PHP section found
049c0f4a 405 $result = new environment_results('php_extension');
f58b518f 406 $result->setStatus(false);
407 $result->setErrorCode(NO_PHP_EXTENSIONS_SECTION_FOUND);
408 return $result;
9e2d15e5 409 }
410/// Iterate over extensions checking them and creating the needed environment_results
411 foreach($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'] as $extension) {
412 $result = new environment_results('php_extension');
413 /// Check for level
414 if (isset($extension['@']['level'])) {
415 $level = $extension['@']['level'];
416 if ($level != 'optional') {
417 $level = 'required';
f58b518f 418 }
9e2d15e5 419 }
420 /// Check for extension name
421 if (!isset($extension['@']['name'])) {
422 $result->setStatus(false);
423 $result->setErrorCode(NO_PHP_EXTENSIONS_NAME_FOUND);
424 } else {
425 $extension_name = $extension['@']['name'];
426 /// The name exists. Just check if it's an installed extension
427 if (!extension_loaded($extension_name)) {
f58b518f 428 $result->setStatus(false);
f58b518f 429 } else {
9e2d15e5 430 $result->setStatus(true);
f58b518f 431 }
9e2d15e5 432 $result->setLevel($level);
433 $result->setInfo($extension_name);
f58b518f 434 }
9e2d15e5 435 /// Process messages, modifying the $result if needed.
436 process_environment_messages($extension, $result);
437 /// Add the result to the array of results
438 $results[] = $result;
f58b518f 439 }
440
9e2d15e5 441
f58b518f 442 return $results;
443}
444
445
446/**
447 * This function will check if php requirements are satisfied
448 * @param string $version xml version we are going to use to test this server
449 * @return object results encapsulated in one environment_result object
450 */
451function environment_check_php($version) {
452
453 $result = new environment_results('php');
454
455/// Get the enviroment version we need
456 if (!$data = get_environment_for_version($version)) {
457 /// Error. No version data found
458 $result->setStatus(false);
459 $result->setErrorCode(NO_VERSION_DATA_FOUND);
460 return $result;
461 }
462
463/// Extract the php part
464 if (!isset($data['#']['PHP'])) {
465 /// Error. No PHP section found
466 $result->setStatus(false);
467 $result->setErrorCode(NO_PHP_SECTION_FOUND);
468 return $result;
469 } else {
470 /// Extract level and version
471 if (isset($data['#']['PHP']['0']['@']['level'])) {
00d3a0fd 472 $level = $data['#']['PHP']['0']['@']['level'];
f58b518f 473 if ($level != 'optional') {
474 $level = 'required';
475 }
476 }
477 if (!isset($data['#']['PHP']['0']['@']['version'])) {
478 $result->setStatus(false);
479 $result->setErrorCode(NO_PHP_VERSION_FOUND);
480 return $result;
481 } else {
482 $needed_version = $data['#']['PHP']['0']['@']['version'];
483 }
484 }
485
486/// Now search the version we are using
487 $current_version = normalize_version(phpversion());
488
489/// And finally compare them, saving results
490 if (version_compare($current_version, $needed_version, '>=')) {
491 $result->setStatus(true);
492 } else {
493 $result->setStatus(false);
f58b518f 494 }
495 $result->setLevel($level);
496 $result->setCurrentVersion($current_version);
497 $result->setNeededVersion($needed_version);
9e2d15e5 498/// Process messages, modifying the $result if needed.
499 process_environment_messages($data['#']['PHP'][0], $result);
f58b518f 500
501 return $result;
502}
503
504
505/**
506 * This function will check if database requirements are satisfied
507 * @param string $version xml version we are going to use to test this server
508 * @return object results encapsulated in one environment_result object
509 */
510function environment_check_database($version) {
511
512 global $db;
513
514 $result = new environment_results('database');
515
516 $vendors = array(); //Array of vendors in version
517
518/// Get the enviroment version we need
519 if (!$data = get_environment_for_version($version)) {
520 /// Error. No version data found
521 $result->setStatus(false);
522 $result->setErrorCode(NO_VERSION_DATA_FOUND);
523 return $result;
524 }
525
526/// Extract the database part
527 if (!isset($data['#']['DATABASE'])) {
528 /// Error. No DATABASE section found
529 $result->setStatus(false);
530 $result->setErrorCode(NO_DATABASE_SECTION_FOUND);
531 return $result;
532 } else {
533 /// Extract level
534 if (isset($data['#']['DATABASE']['0']['@']['level'])) {
00d3a0fd 535 $level = $data['#']['DATABASE']['0']['@']['level'];
f58b518f 536 if ($level != 'optional') {
537 $level = 'required';
538 }
539 }
540 }
541
542/// Extract DB vendors. At least 2 are mandatory (mysql & postgres)
543 if (!isset($data['#']['DATABASE']['0']['#']['VENDOR'])) {
544 /// Error. No VENDORS found
545 $result->setStatus(false);
546 $result->setErrorCode(NO_DATABASE_VENDORS_FOUND);
547 return $result;
548 } else {
549 /// Extract vendors
550 foreach ($data['#']['DATABASE']['0']['#']['VENDOR'] as $vendor) {
551 if (isset($vendor['@']['name']) && isset($vendor['@']['version'])) {
552 $vendors[$vendor['@']['name']] = $vendor['@']['version'];
9e2d15e5 553 $vendorsxml[$vendor['@']['name']] = $vendor;
f58b518f 554 }
555 }
556 }
557/// Check we have the mysql vendor version
558 if (empty($vendors['mysql'])) {
559 $result->setStatus(false);
560 $result->setErrorCode(NO_DATABASE_VENDOR_MYSQL_FOUND);
561 return $result;
562 }
563/// Check we have the postgres vendor version
564 if (empty($vendors['postgres'])) {
565 $result->setStatus(false);
566 $result->setErrorCode(NO_DATABASE_VENDOR_POSTGRES_FOUND);
567 return $result;
568 }
569
570/// Now search the version we are using (depending of vendor)
571 $current_vendor = $db->databaseType;
e3058eb3 572 if ($current_vendor == 'postgres7') { //Normalize a bit postgresql
573 $current_vendor ='postgres';
574 }
f58b518f 575 $dbinfo = $db->ServerInfo();
576 $current_version = normalize_version($dbinfo['version']);
577 $needed_version = $vendors[$current_vendor];
578
e3058eb3 579/// Check we have a needed version
580 if (!$needed_version) {
581 $result->setStatus(false);
582 $result->setErrorCode(NO_DATABASE_VENDOR_VERSION_FOUND);
583 return $result;
584 }
585
f58b518f 586/// And finally compare them, saving results
587 if (version_compare($current_version, $needed_version, '>=')) {
588 $result->setStatus(true);
589 } else {
590 $result->setStatus(false);
f58b518f 591 }
592 $result->setLevel($level);
593 $result->setCurrentVersion($current_version);
594 $result->setNeededVersion($needed_version);
595 $result->setInfo($current_vendor);
596
9e2d15e5 597/// Process messages, modifying the $result if needed.
598 process_environment_messages($vendorsxml[$current_vendor], $result);
599
f58b518f 600 return $result;
601
602}
603
9e2d15e5 604/**
605 * This function will detect if there is some message available to be added to the
606 * result in order to clarify enviromental details.
607 * @param string xmldata containing the messages data
608 * @param object reult object to be updated
609 */
610function process_environment_messages($xml, &$result) {
611
612/// If there is feedback info
613 if (isset($xml['#']['FEEDBACK'][0]['#'])) {
614 $feedbackxml = $xml['#']['FEEDBACK'][0]['#'];
615
616 if (!$result->status and $result->getLevel() == 'required') {
617 if (isset($feedbackxml['ON_ERROR'][0]['@']['message'])) {
618 $result->setFeedbackStr($feedbackxml['ON_ERROR'][0]['@']['message']);
619 }
620 } else if (!$result->status and $result->getLevel() == 'optional') {
621 if (isset($feedbackxml['ON_CHECK'][0]['@']['message'])) {
622 $result->setFeedbackStr($feedbackxml['ON_CHECK'][0]['@']['message']);
623 }
624 } else {
625 if (isset($feedbackxml['ON_OK'][0]['@']['message'])) {
626 $result->setFeedbackStr($feedbackxml['ON_OK'][0]['@']['message']);
627 }
628 }
629 }
630}
631
f58b518f 632
633//--- Helper Class to return results to caller ---//
634
635
636/**
637 * This class is used to return the results of the environment
638 * main functions (environment_check_xxxx)
639 */
640class environment_results {
641
049c0f4a 642 var $part; //which are we checking (database, php, php_extension)
f58b518f 643 var $status; //true/false
644 var $error_code; //integer. See constants at the beginning of the file
645 var $level; //required/optional
646 var $current_version; //current version detected
647 var $needed_version; //version needed
648 var $info; //Aux. info (DB vendor, library...)
9e2d15e5 649 var $feedback_str; //String to show on error|on check|on ok
650 var $bypass_str; //String to show if some bypass has happened
f58b518f 651
652 /**
653 * Constructor of the environment_result class. Just set default values
654 */
655 function environment_results($part) {
656 $this->part=$part;
657 $this->status=false;
049c0f4a 658 $this->error_code=NO_ERROR;
f58b518f 659 $this->level='required';
660 $this->current_version='';
661 $this->needed_version='';
662 $this->info='';
9e2d15e5 663 $this->feedback_str='';
664 $this->bypass_str='';
f58b518f 665 }
666
667 /**
668 * Set the status
669 * @param boolean the status (true/false)
670 */
671 function setStatus($status) {
672 $this->status=$status;
673 if ($status) {
674 $this->setErrorCode(NO_ERROR);
675 }
676 }
677
678 /**
679 * Set the error_code
680 * @param integer the error code (see constants above)
681 */
682 function setErrorCode($error_code) {
683 $this->error_code=$error_code;
684 }
685
686 /**
687 * Set the level
688 * @param string the level (required, optional)
689 */
690 function setLevel($level) {
691 $this->level=$level;
692 }
693
694 /**
695 * Set the current version
696 * @param string the current version
697 */
698 function setCurrentVersion($current_version) {
699 $this->current_version=$current_version;
700 }
701
702 /**
703 * Set the needed version
704 * @param string the needed version
705 */
706 function setNeededVersion($needed_version) {
707 $this->needed_version=$needed_version;
708 }
709
710 /**
711 * Set the auxiliary info
712 * @param string the auxiliary info
713 */
9e2d15e5 714 function setInfo($info) {
715 $this->info=$info;
716 }
717
718 /**
719 * Set the feedback string
720 * @param string the feedback string
721 */
722 function setFeedbackStr($str) {
723 $this->feedback_str=$str;
724 }
f58b518f 725
726 /**
727 * Get the status
728 * @return boolean result
729 */
730 function getStatus() {
731 return $this->status;
732 }
733
734 /**
735 * Get the error code
736 * @return integer error code
737 */
738 function getErrorCode() {
739 return $this->error_code;
740 }
741
742 /**
743 * Get the level
744 * @return string level
745 */
746 function getLevel() {
747 return $this->level;
748 }
749
750 /**
751 * Get the current version
752 * @return string current version
753 */
754 function getCurrentVersion() {
755 return $this->current_version;
756 }
757
758 /**
759 * Get the needed version
760 * @return string needed version
761 */
762 function getNeededVersion() {
763 return $this->needed_version;
764 }
765
766 /**
767 * Get the aux info
768 * @return string info
769 */
770 function getInfo() {
771 return $this->info;
772 }
773
774 /**
775 * Get the part this result belongs to
776 * @return string part
777 */
778 function getPart() {
779 return $this->part;
780 }
9e2d15e5 781
782 /**
783 * Get the feedback string
784 * @return string feedback string
785 */
786 function getFeedbackStr() {
787 return $this->feedback_str;
788 }
f58b518f 789}
790
9e2d15e5 791/// Here all the bypass functions are coded to be used by the environment
792/// checker. All those functions will receive the result object and will
793/// return it modified as needed (status and bypass string)
794
f58b518f 795?>