public function get_maxima_available()
 {
     if ('unix' != stack_connection_helper::get_platform()) {
         return stack_string('healthunabletolistavail');
     }
     $this->command = 'maxima --list-avail';
     $rawresult = $this->call_maxima('');
     return $rawresult;
 }
 public function test_compute_miss_formed_command()
 {
     $connection = stack_connection_helper::make();
     // This will induce a timeout on the CAS because we don't have a well formed CAS statement.
     $strin = 'cab:block([],print("[TimeStamp= [ 0 ];';
     $return = $connection->compute($strin);
     $expected = array();
     $this->assertEquals($return, $expected);
 }
 protected function guess_maxima_command($path)
 {
     if ('default' == stack_connection_helper::get_maximaversion()) {
         throw new stack_exception("stack_cas_connection: maxima cannot be set to default on Windows platform. " . "Please choose an explicit version via the administration settings page.");
     }
     $cmd = $path . '/maxima.bat';
     if (!is_readable($cmd)) {
         throw new stack_exception("stack_cas_connection: maxima launch script {$cmd} does not exist.");
     }
     return $cmd;
 }
 public function compute($command)
 {
     $context = "Platform: " . stack_connection_helper::get_platform() . "\n";
     $context .= "Maxima shell command: " . $this->command . "\n";
     $context .= "Maxima initial command: " . $this->initcommand . "\n";
     $context .= "Maxima timeout: " . $this->timeout;
     $this->debug->log('Context used', $context);
     $this->debug->log('Maxima command', $command);
     $rawresult = $this->call_maxima($command);
     $this->debug->log('CAS result', $rawresult);
     $unpackedresult = $this->unpack_raw_result($rawresult);
     $this->debug->log('Unpacked result as', print_r($unpackedresult, true));
     if (!stack_connection_helper::check_stackmaxima_version($unpackedresult)) {
         stack_connection_helper::warn_about_version_mismatch($this->debug);
     }
     return $unpackedresult;
 }
 protected function guess_maxima_command($path)
 {
     global $CFG;
     if (stack_connection_helper::get_platform() == 'unix-optimised') {
         // We are trying to use a Lisp snapshot of Maxima with all the
         // STACK libraries loaded.
         $lispimage = $CFG->dataroot . '/stack/maxima-optimised';
         if (is_readable($lispimage)) {
             return $lispimage;
         }
     }
     if (is_readable('/Applications/Maxima.app/Contents/Resources/maxima.sh')) {
         // This is the path on Macs, if Maxima has been installed following
         // the instructions on Sourceforge.
         return '/Applications/Maxima.app/Contents/Resources/maxima.sh';
     }
     // Default guess on Linux.
     return 'maxima';
 }
 public function compute($command)
 {
     $cached = $this->get_cached_result($command);
     if ($cached->result) {
         $this->debug->log('Maxima command', $command);
         $this->debug->log('Unpacked result found in the DB cache', print_r($cached->result, true));
         if (!stack_connection_helper::check_stackmaxima_version($cached->result)) {
             stack_connection_helper::warn_about_version_mismatch($this->debug);
             // We could consider automatically purging the cache here.
         }
         return $cached->result;
     }
     $this->debug->log('Maxima command not found in the cache. Using the raw connection.');
     $result = $this->rawconnection->compute($command);
     // Only add to the cache if we didn't timeout!
     if (!stack_connection_helper::did_cas_timeout($result)) {
         $this->add_to_cache($command, $result, $cached->key);
     }
     return $result;
 }
// If we have a linux machine, and we are testing the raw connection then we should
// attempt to automatically create an optimized maxima image on the system.
if ($config->platform === 'unix' and $genuinecascall) {
    echo $OUTPUT->heading(stack_string('healthautomaxopt'), 3);
    echo html_writer::tag('p', stack_string('healthautomaxoptintro'));
    list($message, $debug, $result) = stack_connection_helper::stackmaxima_auto_maxima_optimise($genuinedebug);
    $summary[] = array($result, $message);
    echo html_writer::tag('p', $message);
    echo output_debug(stack_string('debuginfo'), $debug);
}
// Test the version of the STACK libraries that Maxima is using.
// When Maxima is being run pre-compiled (maxima-optimise) or on a server,
// it is possible for the version of the Maxima libraries to get out of synch
// with the qtype_stack code.
echo $OUTPUT->heading(stack_string('healthchecksstackmaximaversion'), 3);
list($message, $details, $result) = stack_connection_helper::stackmaxima_version_healthcheck();
$summary[] = array($result, stack_string($message, $details));
echo html_writer::tag('p', stack_string($message, $details));
// Test plots.
output_cas_text(stack_string('healthcheckplots'), stack_string('healthcheckplotsintro'), get_string('healthchecksampleplots', 'qtype_stack'));
// State of the cache.
echo $OUTPUT->heading(stack_string('settingcasresultscache'), 3);
$message = stack_string('healthcheckcache_' . $config->casresultscache);
$summary[] = array(null, $message);
echo html_writer::tag('p', $message);
if ('db' == $config->casresultscache) {
    echo html_writer::tag('p', stack_string('healthcheckcachestatus', stack_cas_connection_db_cache::entries_count($DB)));
    echo $OUTPUT->single_button(new moodle_url($PAGE->url, array('clearcache' => 1, 'sesskey' => sesskey())), stack_string('clearthecache'));
}
echo '<hr />';
$tab = '';
 public function instantiate()
 {
     if (null === $this->valid) {
         $this->validate();
     }
     if (!$this->valid) {
         return false;
     }
     // Lazy instantiation - only do this once...
     // Empty session.  Nothing to do.
     if ($this->instantiated || null === $this->session) {
         return true;
     }
     $connection = stack_connection_helper::make();
     $results = $connection->compute($this->construct_maxima_command());
     $this->debuginfo = $connection->get_debuginfo();
     // Now put the information back into the correct slots.
     $session = $this->session;
     $newsession = array();
     $newerrors = '';
     $allfail = true;
     $i = 0;
     // We loop over each entry in the session, not over the result.
     // This way we can add an error for missing values.
     foreach ($session as $cs) {
         $gotvalue = false;
         if ('' == $cs->get_key()) {
             $key = 'dumvar' . $i;
         } else {
             $key = $cs->get_key();
         }
         if (array_key_exists($i, $results)) {
             $allfail = false;
             // We at least got one result back from the CAS!
             $result = $results["{$i}"];
             // GOCHA!  Results have string represenations of numbers, not int....
             if ('' != $result['error'] and false === strstr($result['error'], 'clipped')) {
                 $cs->add_errors($result['error']);
                 $cs->decode_maxima_errors($result['error']);
                 $newerrors .= stack_maxima_format_casstring($cs->get_raw_casstring());
                 $newerrors .= ' ' . stack_string("stackCas_CASErrorCaused") . ' ' . $result['error'] . ' ';
             }
             if (array_key_exists('value', $result)) {
                 $val = str_replace('QMCHAR', '?', $result['value']);
                 $cs->set_value($val);
                 $gotvalue = true;
             } else {
                 $cs->add_errors(stack_string("stackCas_failedReturnOne"));
             }
             if (array_key_exists('display', $result)) {
                 // Need to add this in here also because strings may contain question mark characters.
                 $disp = str_replace('QMCHAR', '?', $result['display']);
                 $cs->set_display($disp);
             }
             if (array_key_exists('valid', $result)) {
                 $cs->set_valid($result['valid']);
             }
             if (array_key_exists('answernote', $result)) {
                 $cs->set_answernote($result['answernote']);
             }
             if (array_key_exists('feedback', $result)) {
                 $cs->set_feedback($result['feedback']);
             }
         } else {
             if (!$gotvalue) {
                 $errstr = stack_string("stackCas_failedReturn") . ' ' . stack_maxima_format_casstring($cs->get_raw_casstring());
                 $cs->add_errors($errstr);
                 $cs->set_answernote('CASFailedReturn');
                 $newerrors .= $errstr;
             }
         }
         $newsession[] = $cs;
         $i++;
     }
     $this->session = $newsession;
     if ('' != $newerrors) {
         $this->errors .= '<span class="error">' . stack_string('stackCas_CASError') . '</span>' . $newerrors;
     }
     if ($allfail) {
         $this->errors = '<span class="error">' . stack_string('stackCas_allFailed') . '</span>';
     }
     $this->instantiated = true;
 }
 /**
  * Initialises the database connection for the 'otherdb' cache type.
  * @return moodle_database the DB connection to use.
  */
 protected static function get_other_db()
 {
     if (!is_null(self::$otherdb)) {
         return self::$otherdb;
     }
     $dboptions = array();
     if (!empty(self::$config->cascachedbsocket)) {
         $dboptions['dbsocket'] = true;
     }
     self::$otherdb = moodle_database::get_driver_instance(self::$config->cascachedbtype, self::$config->cascachedblibrary);
     self::$otherdb->connect(self::$config->cascachedbhost, self::$config->cascachedbuser, self::$config->cascachedbpass, self::$config->cascachedbname, self::$config->cascachedbprefix, $dboptions);
     return self::$otherdb;
 }
 protected function call_maxima($command)
 {
     global $CFG;
     $err = '';
     $starttime = microtime(true);
     $request = curl_init($this->command);
     $postdata = 'input=' . urlencode($command) . '&timeout=' . $this->timeout * 1000 . '&ploturlbase=!ploturl!' . '&version=' . stack_connection_helper::get_required_stackmaxima_version();
     curl_setopt($request, CURLOPT_POST, true);
     curl_setopt($request, CURLOPT_POSTFIELDS, $postdata);
     curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($request, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
     if (!empty($this->serveruserpass)) {
         curl_setopt($request, CURLOPT_USERPWD, $this->serveruserpass);
     }
     $ret = curl_exec($request);
     $timedout = false;
     // The servlet will return 416 if the evaluation hits the timelimit.
     if (curl_getinfo($request, CURLINFO_HTTP_CODE) != '200') {
         if (curl_getinfo($request, CURLINFO_HTTP_CODE) != '416') {
             throw new Exception('stack_cas_connection: MaximaPool error: ' . curl_getinfo($request, CURLINFO_HTTP_CODE));
         } else {
             $timedout = true;
         }
     }
     // Did we get files?
     if (strpos(curl_getinfo($request, CURLINFO_CONTENT_TYPE), "text/plain") === false) {
         // We have to save the zip file on local disk before opening...
         // how come there is no core library solution to this!?
         // create temp file, save zip there.
         $ziptemp = $CFG->dataroot . "/stack/tmp/";
         $ziptemp = tempnam($ziptemp, "zip");
         $fp = fopen($ziptemp, "w");
         fwrite($fp, $ret);
         fclose($fp);
         $zip = zip_open($ziptemp);
         $entry = zip_read($zip);
         // Read the entrys of the archive.
         while ($entry !== false) {
             // This one contains the output from maxima.
             if (zip_entry_name($entry) == 'OUTPUT') {
                 zip_entry_open($zip, $entry);
                 $ret = zip_entry_read($entry, zip_entry_filesize($entry));
                 zip_entry_close($entry);
             } else {
                 $filename = $CFG->dataroot . "/stack/plots/" . zip_entry_name($entry);
                 zip_entry_open($zip, $entry);
                 $fp = fopen($filename, 'w');
                 $buffy = zip_entry_read($entry, 2048);
                 while ($buffy != '') {
                     fwrite($fp, $buffy);
                     $buffy = zip_entry_read($entry, 2048);
                 }
                 fclose($fp);
                 zip_entry_close($entry);
             }
             $entry = zip_read($zip);
         }
         zip_close($zip);
         // Clean up.
         unlink($ziptemp);
     }
     curl_close($request);
     $now = microtime(true);
     $this->debug->log('Timings', "Start: {$starttime}, End: {$now}, Taken = " . ($now - $starttime));
     // Add sufficient closing ]'s to allow something to be un-parsed from the CAS.
     // WARNING: the string 'The CAS timed out' is used by the cache to serach for a timout occurance.
     if ($timedout) {
         $ret .= ' The CAS timed out. ] ] ] ]';
     }
     return $ret;
 }