Beispiel #1
0
 /**
  * Führt das Modul entsprechend der Commands.json und Component.json Definitionen aus
  */
 public function run()
 {
     // runs the CConfig
     $com = new CConfig($this->_prefix, $this->_path, $this->_noInfo, $this->_noHelp);
     // lädt die Konfiguration des Moduls
     if ($com->used()) {
         return;
     }
     $conf = $com->loadConfig();
     $this->_conf = $conf;
     $this->_com = $com;
     $commands = $com->commands(array(), true, true);
     // multi Requests werden noch nicht unterstützt, das Model soll automatisch die Möglichkeit bieten,
     // mehrere Anfragen mit einmal zu beantworten
     ////$commands[] = array('name' => 'postMultiGetRequest','method' => 'POST', 'path' => '/multiGetRequest', 'inputType' => 'Link', 'outputType' => '');
     // Erstellt für jeden angebotenen Befehl einen Router
     // Ein Router stellt einen erlaubten Aufruf dar (mit Methode und URI), sodass geprüft werden kann,
     // welcher für die Beantwortung zuständig ist
     $router = new \Slim\Router();
     foreach ($commands as &$command) {
         if (!isset($command['name'])) {
             continue;
         }
         if (!isset($command['method'])) {
             $command['method'] = 'GET';
         }
         if (!isset($command['callback'])) {
             $command['callback'] = $command['name'];
         }
         if (!isset($command['seqInput'])) {
             $command['seqInput'] = 'TRUE';
         }
         if (!isset($command['singleOutput'])) {
             $command['singleOutput'] = 'FALSE';
         }
         if (!isset($command['placeholder'])) {
             $command['placeholder'] = array();
         }
         // Methoden können durch Komma getrennt aufgelistet sein
         $methods = explode(',', $command['method']);
         foreach ($methods as $method) {
             $route = new \Slim\Route($command['path'], array($this->_class, $command['callback']), false);
             $route->via(strtoupper($method));
             $route->setName($command['name']);
             $router->map($route);
             // wenn es ein GET Befehl ist, wird automatisch HEAD unterstützt
             if (strtoupper($method) == 'GET') {
                 // erzeugt einen HEAD Router
                 $route = new \Slim\Route($command['path'], array($this->_class, $command['callback']), false);
                 $route->via('HEAD');
                 $route->setName($command['name']);
                 $router->map($route);
             }
         }
     }
     // hier wird die eingehende URI erzeugt
     // Bsp.: /user/1
     $scriptName = $_SERVER['SCRIPT_NAME'];
     $requestUri = $_SERVER['REQUEST_URI'];
     $path = str_replace('?' . (isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''), '', substr_replace($requestUri, '', 0, strlen(strpos($requestUri, $scriptName) !== false ? $scriptName : str_replace('\\', '', dirname($scriptName)))));
     // ermittelt den zuständigen Befehl
     $matches = $router->getMatchedRoutes(strtoupper($_SERVER['REQUEST_METHOD']), $path);
     if (count($matches) > 0) {
         // mindestens ein zutreffender Befehl wurde gefunden (nimm den Ersten)
         $matches = $matches[0];
         // suche den zugehörigen $commands Eintrag
         $selectedCommand = null;
         foreach ($commands as $command) {
             if ($command['name'] === $matches->getName()) {
                 $selectedCommand = $command;
                 break;
             }
         }
         if ($selectedCommand == null) {
             http_response_code(500);
             return;
         }
         // lies die eingehenden PHP Daten
         $rawInput = \Slim\Environment::getInstance()->offsetGet('slim.input');
         if (!$rawInput) {
             $rawInput = @file_get_contents('php://input');
         }
         // wir wollen wissen, ob die Eingabedaten als Liste rein kommen
         $arr = true;
         // wenn zu diesem Befehl ein inputType angegeben wurde, wird eine Type::decodeType() aufgerufen
         if (isset($selectedCommand['inputType']) && trim($selectedCommand['inputType']) != '') {
             $inputType = $selectedCommand['inputType'];
             $rawInput = call_user_func_array('\\' . $inputType . '::decode' . $inputType, array($rawInput));
             if (!is_array($rawInput)) {
                 // es ist keine Liste, also mach eine daraus (damit man sie einheitlich behandeln kann)
                 $rawInput = array($rawInput);
                 $arr = false;
             }
         }
         if (strtoupper($selectedCommand['seqInput']) != 'TRUE') {
             $arr = false;
         }
         $params = $matches->getParams();
         $placeholder = array();
         // prüfe die Bedingungen für die Platzhalter
         foreach ($selectedCommand['placeholder'] as $holder) {
             if (!isset($holder['name'])) {
                 continue;
             }
             if (!isset($holder['regex'])) {
                 continue;
             }
             $placeholder[$holder['name']] = $holder['regex'];
         }
         /*foreach ($params as $key => $value){
               if (isset($placeholder[$key])){
                   if (is_array($value)){
                       // wenn es ein Array ist, wurde ein :Element+ verwendet (Slim)
                       // daher wird der Ausdruck auf jedes Element angewendet
                       foreach($value as $val){
                           $pregRes = @preg_match($placeholder[$key], $val);
                           if ($pregRes === false){
                               error_log(__FILE__.':'.__LINE__.' '.$placeholder[$key].' konnte nicht interpretiert werden');
                               $this->finishRequest(self::isError());
                               return;
                           } else if ($pregRes === 0){
                               error_log(__FILE__.':'.__LINE__.' '.$val.' passt nicht zu '.$placeholder[$key]);
                               $this->finishRequest(self::isPreconditionError());
                               return;
                           }
                       }
                   } else {
                       // einzelnes Element für Slim verwendet :Element
                       $pregRes = @preg_match($placeholder[$key], $value);
                       if ($pregRes === false){
                           error_log(__FILE__.':'.__LINE__.' '.$placeholder[$key].' konnte nicht interpretiert werden');
                           $this->finishRequest(self::isError());
                           return;
                       } else if ($pregRes === 0){
                           error_log(__FILE__.':'.__LINE__.' '.$value.' passt nicht zu '.$placeholder[$key]);
                           $this->finishRequest(self::isPreconditionError());
                           return;
                       }
                   }
               }
           }*/
         // nun soll die zugehörige Funktion im Modul aufgerufen werden
         if (isset($selectedCommand['inputType']) && trim($selectedCommand['inputType']) != '' && isset($rawInput)) {
             // initialisiert die Ausgabe positiv
             $result = array("status" => 201, "content" => array());
             if (strtoupper($selectedCommand['seqInput']) == 'TRUE') {
                 try {
                     // für jede Eingabe wird die Funktion ausgeführt
                     foreach ($rawInput as $input) {
                         // Aufruf der Modulfunktion
                         $res = call_user_func_array($matches->getCallable(), array($selectedCommand['name'], "input" => $input, $params));
                         // wenn es ein Ausgabeobjekt gibt, wird versucht dort einen Status zu setzen
                         if (is_callable(array($res['content'], 'setStatus'))) {
                             $res['content']->setStatus($res['status']);
                         }
                         // setze Status und Ausgabe
                         $result["content"][] = $res['content'];
                         if (isset($res['status'])) {
                             $result["status"] = $res['status'];
                         }
                     }
                 } catch (Exception $e) {
                     header_remove();
                     error_log($e->getMessage());
                     $this->finishRequest(self::isError());
                     return;
                 }
             } else {
                 try {
                     // Aufruf der Modulfunktion
                     $res = call_user_func_array($matches->getCallable(), array($selectedCommand['name'], "input" => $rawInput, $params));
                     // wenn es ein Ausgabeobjekt gibt, wird versucht dort einen Status zu setzen
                     if (is_callable(array($res['content'], 'setStatus'))) {
                         $res['content']->setStatus($res['status']);
                     }
                     // setze Status und Ausgabe
                     $result["content"] = $res['content'];
                     if (isset($res['status'])) {
                         $result["status"] = $res['status'];
                     }
                 } catch (Exception $e) {
                     header_remove();
                     error_log($e->getMessage());
                     $this->finishRequest(self::isError());
                     return;
                 }
             }
         } else {
             // wenn keinen vorgegebenen Eingabetyp gibt, wird die Eingabe direkt an die Modulfunktion weitergegeben
             $result = call_user_func_array($matches->getCallable(), array($selectedCommand['name'], "input" => $rawInput, $params));
         }
         if ($selectedCommand['method'] == 'HEAD') {
             // Bei einer HEAD Funktion (die eventuell im Modul als GET bearbeitet wird),
             // kann die Ausgabe verworfen werden
             $result['content'] = '';
         } elseif (isset($selectedCommand['outputType']) && trim($selectedCommand['outputType']) != '' && trim($selectedCommand['outputType']) != 'binary') {
             // wenn ein Ausgabetyp angegeben ist, wird eine Typ::encodeTyp() ausgeführt
             $outputType = $selectedCommand['outputType'];
             if (isset($result['content'])) {
                 if (!is_array($result['content'])) {
                     $result['content'] = array($result['content']);
                 }
                 if ($command['singleOutput'] !== 'FALSE' && count($result['content']) >= 1) {
                     $result['content'] = $result['content'][0];
                 } elseif (!$arr && count($result['content']) == 1) {
                     $result['content'] = $result['content'][0];
                 }
                 $result['content'] = call_user_func_array('\\' . $outputType . '::encode' . $outputType, array($result['content']));
             }
             header('Content-Type: application/json');
         } elseif (isset($selectedCommand['outputType']) && trim($selectedCommand['outputType']) == 'binary') {
             // wenn der Ausgabetyp "binär" ist, erfolgt keine Anpassung
         } else {
             // selbst wenn nichts zutrifft, wird json kodiert
             if (isset($result['content'])) {
                 $result['content'] = json_encode($result['content']);
             }
             header('Content-Type: application/json');
         }
     } else {
         // es wurde kein zutreffender Befehl gefunden, also gibt es eine leere Antwort
         $this->finishRequest(self::isError());
         return;
     }
     // ab hier werden die Ergebnisse ausgegeben
     $this->finishRequest($result);
 }
Beispiel #2
0
 /**
  * Test that router returns matched routes based on URI only, not
  * based on the HTTP method.
  */
 public function testRouterMatchesRoutesByUriOnly()
 {
     \Slim\Environment::mock(array('REQUEST_METHOD' => 'GET', 'REMOTE_ADDR' => '127.0.0.1', 'SCRIPT_NAME' => '', 'PATH_INFO' => '/foo', 'QUERY_STRING' => 'one=1&two=2&three=3', 'SERVER_NAME' => 'slim', 'SERVER_PORT' => 80, 'slim.url_scheme' => 'http', 'slim.input' => '', 'slim.errors' => fopen('php://stderr', 'w'), 'HTTP_HOST' => 'slim'));
     $this->env = \Slim\Environment::getInstance();
     $this->req = new \Slim\Http\Request($this->env);
     $this->res = new \Slim\Http\Response();
     $router = new \Slim\Router();
     $router->setResourceUri($this->req->getResourceUri());
     $router->map('/foo', function () {
     })->via('GET');
     $router->map('/foo', function () {
     })->via('POST');
     $router->map('/foo', function () {
     })->via('PUT');
     $router->map('/foo/bar/xyz', function () {
     })->via('DELETE');
     $this->assertEquals(3, count($router->getMatchedRoutes()));
 }
Beispiel #3
0
 /**
  * the getl function uses a list of links to find a
  * relevant component for the $data request
  *
  * @param $data a slim generated array of URI segments (String[])
  */
 public function getl($data)
 {
     Logger::Log('starts Controller routing', LogLevel::DEBUG);
     // if no URI is received, abort process
     if (count($data) == 0) {
         Logger::Log('Controller nothing to route', LogLevel::DEBUG);
         $this->_app->response->setStatus(409);
         $this->_app->stop();
         return;
     }
     $URI = '/' . implode('/', $data);
     // get possible links
     $list = CConfig::getLinks($this->_conf->getLinks(), 'out');
     foreach ($list as $links) {
         $componentURL = $links->getAddress();
         $similar = Controller2::UrlAnd($componentURL, $URI);
         if ($similar != null) {
             $URI2 = substr($URI, Controller2::UrlAnd($componentURL, $URI));
             $relevanz = explode(' ', $links->getRelevanz());
             $found = false;
             foreach ($relevanz as $rel) {
                 if ($rel == 'ALL') {
                     $found = true;
                     break;
                 }
                 $sub = strpos($rel, '_');
                 if ($sub !== false) {
                     $method = substr($rel, 0, $sub);
                     $path = substr($rel, $sub + 1);
                     if (strtoupper($method) == strtoupper($this->_app->request->getMethod())) {
                         $router = new \Slim\Router();
                         $route = new \Slim\Route($path, 'is_array');
                         $route->via(strtoupper($method));
                         $router->map($route);
                         $routes = count($router->getMatchedRoutes(strtoupper($method), $URI2), true);
                         if ($routes === 0) {
                             continue;
                         }
                         $found = true;
                         break;
                     }
                 }
             }
             if (!$found) {
                 continue;
             }
             // create a custom request
             $ch = Request::custom($this->_app->request->getMethod(), $componentURL . substr($URI, $similar), array(), $this->_app->request->getBody());
             // checks the answered status code
             if ($ch['status'] >= 200 && $ch['status'] <= 299) {
                 // finished
                 $this->_app->response->setStatus($ch['status']);
                 $this->_app->response->setBody($ch['content']);
                 if (isset($ch['headers']['Content-Type'])) {
                     $this->_app->response->headers->set('Content-Type', $ch['headers']['Content-Type']);
                 }
                 if (isset($ch['headers']['Content-Disposition'])) {
                     $this->_app->response->headers->set('Content-Disposition', $ch['headers']['Content-Disposition']);
                 }
                 Logger::Log('Controller2 search done', LogLevel::DEBUG);
                 $this->_app->stop();
             }
         }
     }
     // no positive response or no operative link
     $this->_app->response->setStatus(409);
     $this->_app->response->setBody('');
 }