public function __construct($app, $query = null, $defaultFrom = '$', $defaultTo = '€')
 {
     if (!self::$reRules) {
         self::$reRules = array(self::$reNumber . self::$reFrom . self::$reTo => 'from %n %f to %t', self::$reFrom . self::$reNumber . self::$reTo => 'from %f %n to %t', self::$reNumber . self::$reTo . self::$reFrom => 'to %n %f from %t', self::$reTo . self::$reNumber . self::$reFrom => 'to %t %n from %f', self::$reTo . self::$reNumber . self::$reFrom => 'to %t from %n %f', self::$reTo . self::$reFrom . self::$reNumber => 'to %t from %f %n');
     }
     $this->app = $app;
     // Set default values
     $this->defaultFrom = new e4Currency($defaultFrom);
     $this->defaultFrom->parse();
     $this->defaultTo = new e4Currency($defaultTo);
     $this->defaultTo->parse();
     // Initialize object data
     $this->setQuery($query);
     $this->from = new e4Currency();
     $this->to = new e4Currency();
 }
 public function run($inQuery, $args)
 {
     // Parsing user request
     $inQuery = $inQuery;
     $inDefaultFrom = $this->app->getDefault('from');
     $inDefaultTo = $this->app->getDefault('to');
     $out = array();
     $objQuery = new e4QueryParser($this->app, $inQuery, $inDefaultFrom, $inDefaultTo);
     if ($objQuery->parse()) {
         $tmpFrom = $objQuery->getFrom();
         $tmpTo = $objQuery->getTo();
         $tmpAmount = $objQuery->getAmount();
         if (count($tmpFrom) > 1) {
             foreach ($tmpFrom as $currency) {
                 $suggest = $objQuery->getSuggestion('from', $currency);
                 $out[] = array('uid' => $currency, 'arg' => 'none', 'title' => $suggest, 'subtitle' => e4Currency::currencyName($currency) . ' (' . $currency . ')', 'autocomplete' => $suggest, 'icon' => 'icon.png', 'valid' => 'no');
             }
         } else {
             if (count($tmpTo) > 1) {
                 foreach ($tmpTo as $currency) {
                     $suggest = $objQuery->getSuggestion('to', $currency);
                     $out[] = array('uid' => $currency, 'arg' => 'none', 'title' => $suggest, 'subtitle' => e4Currency::currencyName($currency) . ' (' . $currency . ')', 'autocomplete' => $suggest, 'icon' => 'icon.png', 'valid' => 'no');
                 }
             } else {
                 $tmpResponse = new e4QuerySend($this->app, $tmpAmount, $tmpFrom[0], $tmpTo[0]);
                 if ($tmpResponse->sendRequest()) {
                     $out[] = array('uid' => 'none', 'arg' => $tmpResponse->getToAmount(), 'title' => implode(' ', array($tmpResponse->getFromAmount(), $tmpResponse->getFromCurrency(), '=', $tmpResponse->getToAmount(), $tmpResponse->getToCurrency())), 'subtitle' => 'Processed by ' . $tmpResponse->getService(), 'icon' => 'icon.png', 'valid' => 'yes');
                 }
             }
         }
     }
     // Invalid response matched
     if (!count($out)) {
         $out[] = array('uid' => 'none', 'arg' => 'none', 'title' => 'Invalid query ' . $inQuery, 'subtitle' => 'Try ‘12 €‘ or ‘12 € to $‘ or ‘€‘ and have fun!', 'icon' => 'icon.png', 'valid' => 'no');
     }
     return $out;
 }
<?php

// Library autoloader
define('ROOT', dirname($_SERVER['SCRIPT_NAME']) . '/');
function __autoload($className)
{
    include ROOT . 'libs/' . $className . '.php';
}
$config = json_decode(file_get_contents(ROOT . 'appTest.json'), true);
$testData = array('from' => 'currency', 'to' => 'currency', 'amount' => 'float');
echo str_repeat("\n", 15);
foreach ($config['testList'] as $i => $test) {
    $errors = false;
    $objQuery = new e4QueryParser($test['query'], $config['defaultFrom'], $config['defaultTo']);
    $objQuery->parse();
    if ($objQuery->isValid() != $test['valid']) {
        // Unexpected different result
        $errors .= '{ e4QueryParser: ' . ($objQuery->isValid() ? 'parsed' : 'invalid') . ' } ';
        $errors .= '!= ';
        $errors .= '{ expected: ' . ($test['valid'] ? 'parsed' : 'invalid') . ' } ';
    } elseif ($objQuery->isValid()) {
        // Ok, both are valid; check every property
        foreach ($testData as $key => $type) {
            $newKey = $key . '.in';
            switch ($type) {
                case 'currency':
                    $getType = 'get' . ucfirst($key);
                    $test[$newKey] = $objQuery->{$getType}();
                    break;
                case 'float':
                    $test[$newKey] = $objQuery->getAmount();