コード例 #1
0
 /**
  * Discoverer constructor.
  * @param Config $config
  */
 public function __construct(Config $config)
 {
     $paths = $config->getDiscovererPaths();
     if (count($paths) == 0) {
         throw new \DomainException('The Config object has no discoverable paths');
     }
     //@TODO check mandatory properties of API declaration (url, type)
     foreach ($paths as $path) {
         if (!is_dir($path)) {
             throw new \InvalidArgumentException(sprintf('%s is not a directory', $path));
         }
         if (!is_readable($path)) {
             throw new \DomainException(sprintf('%s is not a readable directory', $path));
         }
     }
     $this->config = $config;
 }
コード例 #2
0
 /**
  *
  * @param ServerRequestInterface|null $request
  * @param ResponseInterface|null $response
  * @param CacheProvider|null $cache
  * @return array
  */
 public function route(ServerRequestInterface $request = null, ResponseInterface $response = null, CacheProvider $cache = null)
 {
     $cacheDir = $this->config->getCacheDirectory();
     $cacheKey = $this->config->getApiProperty('id');
     $cacheLifetime = $this->config->getCacheLifetime();
     $request = $request ?: ServerRequestFactory::fromGlobals();
     $response = $response ?: new Response();
     $cache = $cache ?: new FilesystemCache($cacheDir);
     if (count($request->getHeader('Ext-Direct-Token1')) == 0) {
         throw new \InvalidArgumentException('The Token1 is invalid');
     }
     if (count($request->getHeader('Ext-Direct-Token2')) == 0) {
         throw new \InvalidArgumentException('The Token2 is invalid');
     }
     $token1 = $request->getHeader('Ext-Direct-Token1')[0];
     $token2 = $request->getHeader('Ext-Direct-Token2')[0];
     session_id($token1);
     session_start();
     if (!$_SESSION['Ext-Direct-Token2']) {
         throw new \InvalidArgumentException('The session data is invalid');
     }
     if (strcmp($_SESSION['Ext-Direct-Token2'], $token2) != 0) {
         throw new \InvalidArgumentException('Token2 verification failed');
     }
     if ($cache->contains($cacheKey)) {
         $classMap = $cache->fetch($cacheKey);
     } else {
         $discoverer = new Discoverer($this->config);
         $classMap = $discoverer->mapClasses();
         $cache->save($cacheKey, $classMap, $cacheLifetime);
     }
     $actionsResults = [];
     $actions = $this->getActions($request, $classMap);
     $upload = false;
     foreach ($actions as $action) {
         $actionsResults[] = $action->run();
         if ($action->isUpload()) {
             $upload = true;
         }
     }
     if ($upload) {
         $result = sprintf('<html><body><textarea>%s</textarea></body></html>', preg_replace('/&quot;/', '\\&quot;', json_encode($actionsResults[0], \JSON_UNESCAPED_UNICODE)));
         $response->getBody()->write($result);
         $this->response = $response->withHeader('Content-Type', 'text/html');
     } else {
         if (count($actionsResults) == 1) {
             $response->getBody()->write(json_encode($actionsResults[0], \JSON_UNESCAPED_UNICODE));
         } else {
             $response->getBody()->write(json_encode($actionsResults, \JSON_UNESCAPED_UNICODE));
         }
         $this->response = $response->withHeader('Content-Type', 'application/json');
     }
 }
コード例 #3
0
 /**
  * Start discovery process
  *
  * @param ResponseInterface|null $response
  * @param CacheProvider|null $cache
  * @return array
  */
 public function start(ResponseInterface $response = null, CacheProvider $cache = null)
 {
     $cacheDir = $this->config->getCacheDirectory();
     $cacheKey = $this->config->getApiProperty('id');
     $cacheLifetime = $this->config->getCacheLifetime();
     $response = $response ?: new Response();
     $cache = $cache ?: new FilesystemCache($cacheDir);
     if ($cache->contains($cacheKey)) {
         $classMap = $cache->fetch($cacheKey);
     } else {
         $classMap = $this->mapClasses();
         $cache->save($cacheKey, $classMap, $cacheLifetime);
     }
     $api = $this->buildApi($classMap);
     $body = sprintf('%s=%s;', $this->config->getApiDescriptor(), json_encode($api, \JSON_UNESCAPED_UNICODE));
     $response->getBody()->write($body);
     if (function_exists('openssl_random_pseudo_bytes')) {
         $token1 = bin2hex(openssl_random_pseudo_bytes(16));
         $token2 = bin2hex(openssl_random_pseudo_bytes(16));
     } else {
         $token1 = uniqid();
         $token2 = uniqid();
     }
     if (isset($_COOKIE['Ext-Direct-Token1'])) {
         $token1 = $_COOKIE['Ext-Direct-Token1'];
     } else {
         session_id($token1);
     }
     session_start();
     if (isset($_SESSION['Ext-Direct-Token2'])) {
         $token2 = $_SESSION['Ext-Direct-Token2'];
     }
     $_SESSION['Ext-Direct-Token2'] = $token2;
     setcookie('Ext-Direct-Token1', $token1, 0, '/', session_get_cookie_params()['domain']);
     $response->getBody()->write(sprintf('Ext.define(\'Ext.overrides.data.Connection\',{' . 'override:\'Ext.data.Connection\',request:function(o){o=Ext.apply(o||{},{' . 'withCredentials:true,cors:true,' . 'headers:{\'Ext-Direct-Token1\':\'%s\',\'Ext-Direct-Token2\':\'%s\'}});' . 'this.callParent([o]);}});', $token1, $token2));
     $this->response = $response->withHeader('Content-Type', 'text/javascript')->withHeader('Set-Ext-Direct-Token1', $token1)->withHeader('Set-Ext-Direct-Token2', $token2);
 }
コード例 #4
0
 /**
  * Scan discoverable paths and get actions
  *
  * @return array
  */
 public function mapClasses()
 {
     $paths = $this->config->getDiscovererPaths();
     $files = $classMap = [];
     foreach ($paths as $path) {
         $files = array_merge($files, $this->loadDir($path));
     }
     foreach ($files as $file) {
         $fileContent = file_get_contents($file);
         $classes = array_keys(AnnotationsParser::parsePhp($fileContent));
         Config::includeFile($file);
         foreach ($classes as $className) {
             $class = new \ReflectionClass($className);
             if (!$class->isInstantiable()) {
                 continue;
             }
             $classAnnotations = AnnotationsParser::getAll($class);
             if (!isset($classAnnotations['ExtDirect'])) {
                 continue;
             }
             $methods = $this->getMethods($class);
             $classAlias = null;
             if (isset($classAnnotations['ExtDirect\\Alias'])) {
                 if (is_array($classAnnotations['ExtDirect\\Alias']) && is_string($classAnnotations['ExtDirect\\Alias'][0])) {
                     $classAlias = $classAnnotations['ExtDirect\\Alias'][0];
                 }
             }
             $actionName = $classAlias ?: $className;
             $classMap[$actionName]['action'] = $actionName;
             $classMap[$actionName]['class'] = $className;
             $classMap[$actionName]['file'] = $file;
             $classMap[$actionName]['methods'] = $methods;
         }
     }
     return $classMap;
 }