/**
  * Generates an URL back out of a route, including possible arguments
  *
  * @param array $arguments
  */
 public function generateUrl(array $arguments = null)
 {
     // ezpRestPrefixFilterInterface::getScheme() ==> '/v'
     $apiPrefix = ezpRestPrefixFilterInterface::getApiPrefix() . '/';
     $apiProviderName = ezpRestPrefixFilterInterface::getApiProviderName();
     return $apiPrefix . (!$apiProviderName ? '' : $apiProviderName . '/') . 'v' . $this->version . '/' . str_replace($apiPrefix, '', $this->route->generateUrl($arguments));
 }
Example #2
0
    /**
     * Extract REST routes from APC cache.
     * Cache is generated if needed
     * @return array The route objects
     */
    protected function getCachedRoutes()
    {
        $ttl = (int)eZINI::instance( 'rest.ini' )->variable( 'CacheSettings', 'RouteApcCacheTTL' );

        if( self::$isRouteCacheCreated === false )
        {
            $options = array( 'ttl' => $ttl );
            ezcCacheManager::createCache( self::ROUTE_CACHE_ID, self::ROUTE_CACHE_PATH, 'ezpRestCacheStorageApcCluster', $options );
            self::$isRouteCacheCreated = true;
        }

        $cache = ezcCacheManager::getCache( self::ROUTE_CACHE_ID );
        $cacheKey = self::ROUTE_CACHE_KEY . '_' . ezpRestPrefixFilterInterface::getApiProviderName();
        if( ( $prefixedRoutes = $cache->restore( $cacheKey ) ) === false )
        {
            try
            {
                $prefixedRoutes = $this->doCreateRoutes();
                $cache->store( $cacheKey, $prefixedRoutes );
            }
            catch( Exception $e )
            {
                // Sometimes APC can miss a write. No big deal, just log it.
                // Cache will be regenerated next time
                ezpRestDebug::getInstance()->log( $e->getMessage(), ezcLog::ERROR );
            }
        }

        return $prefixedRoutes;
    }
 protected function checkRoute( $selectedController, $selectedAction )
 {
     if (self::$parsedSkipRoutes === null )
     {
         self::$parsedSkipRoutes = array();
         foreach ( self::$skipRoutes as $routeRule )
         {
             list( $routeController, $routeAction ) = explode( '_', $routeRule[0] );
             $routeVersion = isset( $routeRule[1] ) ? (int)$routeRule[1] : 1;
             self::$parsedSkipRoutes[$routeController][$routeAction] = $routeVersion;
         }
     }
     $retVal = false;
     if ( isset( self::$parsedSkipRoutes[$selectedController] ) )
     {
         if ( isset( self::$parsedSkipRoutes[$selectedController][$selectedAction] ) )
         {
             $retVal = self::$parsedSkipRoutes[$selectedController][$selectedAction] === ezpRestPrefixFilterInterface::getApiVersion();
         }
         else if ( isset( self::$parsedSkipRoutes[$selectedController]['*'] ) )
         {
             $retVal = self::$parsedSkipRoutes[$selectedController]['*'] === ezpRestPrefixFilterInterface::getApiVersion();
         }
     }
     return !$retVal;
 }
    public function createView( ezcMvcRoutingInformation $routeInfo, ezcMvcRequest $request, ezcMvcResult $result )
    {
        $viewController = ezpRestProvider::getProvider( ezpRestPrefixFilterInterface::getApiProviderName() )->getViewController();
        $view = $viewController->loadView( $routeInfo, $request, $result );

        return $view;
    }
Example #5
0
    /**
     * Creates a new cache storage for a given location through eZ Publish cluster mechanism
     * Options can contain the 'ttl' ( Time-To-Life ). This is per default set
     * to 1 day.
     * @param string $location Path to the cache location inside the cluster
     * @param array(string=>string) $options Options for the cache.
     */
    public function __construct( $location, $options = array() )
    {
        $apiName = ezpRestPrefixFilterInterface::getApiProviderName();
        $apiVersion = ezpRestPrefixFilterInterface::getApiVersion();
        $location = eZSys::cacheDirectory().'/rest/'.$location;
        if( !file_exists( $location ) )
        {
            if( !eZDir::mkdir( $location, false, true ) )
            {
                throw new ezcBaseFilePermissionException(
                    $location,
                    ezcBaseFileException::WRITE,
                    'Cache location is not writeable.'
                );
            }
        }

        parent::__construct( $location );
        $this->properties['options'] = new ezpCacheStorageClusterOptions( $options );
    }
 /**
  * @group restApplicationCache
  * @group restCache
  * @dataProvider cacheIdVariableProvider
  * @param array $internalVariables
  * @param array $contentVariables
  */
 public function testGenerateCacheId(array $internalVariables, array $contentVariables)
 {
     /*
      * The cache ID is a MD5 hash and takes into account :
      *  - API Name
      *  - API Version
      *  - Controller class
      *  - Action
      *  - Internal variables (passed parameters, ResponseGroups...)
      *  - Content variables (Translation...)
      */
     $request = new ezpRestRequest();
     $request->uri = $this->restINI->variable('System', 'ApiPrefix') . '/test/rest/foo';
     $request->variables = $internalVariables;
     $request->contentVariables = $contentVariables;
     $request->protocol = 'http-get';
     $controller = $this->getTestControllerFromRequest($request);
     $routingInfos = $controller->getRouter()->getRoutingInformation();
     /*
      * Reproduce the hash algorythm
      */
     $aCacheId = array(ezpRestPrefixFilterInterface::getApiProviderName(), ezpRestPrefixFilterInterface::getApiVersion(), $routingInfos->controllerClass, $routingInfos->action);
     foreach ($contentVariables + $internalVariables as $name => $val) {
         if (is_array($val)) {
             $aCacheId[] = $name . '=' . implode(',', $val);
         } else {
             $aCacheId[] = $name . '=' . $val;
         }
     }
     $hashedCacheId = md5(implode('-', $aCacheId));
     $refObj = new ReflectionObject($controller);
     $refMethod = $refObj->getMethod('generateCacheId');
     $refMethod->setAccessible(true);
     self::assertSame($hashedCacheId, $refMethod->invoke($controller), 'Cache ID algo must take into account : API Name, API Version, Controller class, Action, Internal variables, Content variables');
     // Compare currently generated hash with the previous one. Must be different
     static $previousHash;
     self::assertNotEquals($hashedCacheId, $previousHash, 'Cache IDs must be unique !');
     $previousHash = $hashedCacheId;
 }
 /**
  * Returns base URI with protocol and host (e.g. http://myhost.com/foo/bar)
  *
  * @return string
  */
 public function getBaseURI()
 {
     $hostUri = $this->getHostURI();
     $apiName = ezpRestPrefixFilterInterface::getApiProviderName();
     $apiPrefix = eZINI::instance('rest.ini')->variable('System', 'ApiPrefix');
     $uri = str_replace($apiPrefix, $apiPrefix . '/' . $apiName, $this->uri);
     $baseUri = $hostUri . $uri;
     return $baseUri;
 }
 /**
  * Generates unique cache ID for current request.
  *
  * The cache ID is a MD5 hash and takes into account :
  *  - API Name
  *  - API Version
  *  - Controller class
  *  - Action
  *  - Internal variables (passed parameters, ResponseGroups...)
  *  - Content variables (Translation...)
  *
  * @return string
  */
 private function generateCacheId()
 {
     $routingInfos = $this->getRouter()->getRoutingInformation();
     $aCacheId = array(ezpRestPrefixFilterInterface::getApiProviderName(), ezpRestPrefixFilterInterface::getApiVersion(), $routingInfos->controllerClass, $routingInfos->action);
     // Add internal variables, caught in the URL. See ezpRestHttpRequestParser::fillVariables()
     // Also add content variables
     foreach ($this->request->contentVariables + $this->request->variables as $name => $val) {
         $aCacheId[] = $name . '=' . (is_array($val) ? implode(',', $val) : $val);
     }
     return md5(implode('-', $aCacheId));
 }
    /**
     * Generates unique cache ID for current request.
     * The cache ID is a MD5 hash and takes into account :
     *  - API Name
     *  - API Version
     *  - Controller class
     *  - Action
     *  - Internal variables (passed parameters, ResponseGroups...)
     *  - Content variables (Translation...)
     * @return string
     */
    private function generateCacheId()
    {
        $apiName = ezpRestPrefixFilterInterface::getApiProviderName();
        $apiVersion = ezpRestPrefixFilterInterface::getApiVersion();
        $routingInfos = $this->getRouter()->getRoutingInformation();

        $aCacheId = array( $apiName, $apiVersion, $routingInfos->controllerClass, $routingInfos->action );
        // Add internal variables, caught in the URL. See ezpRestHttpRequestParser::fillVariables()
        // Also add content variables
        $allInternalVariables = array_merge( $this->request->variables, $this->getAllContentVariables() );
        foreach( $allInternalVariables as $name => $val )
        {
            if( is_array( $val ) )
                $aCacheId[] = $name.'='.implode( ',', $val );
            else
                $aCacheId[] = $name.'='.$val;
        }

        $cacheId = implode( '-', $aCacheId );
        return md5( $cacheId );
    }
Example #10
0
 public function createRoutes()
 {
     $providerRoutes = ezpRestProvider::getProvider(ezpRestPrefixFilterInterface::getApiProviderName())->getRoutes();
     $routes = array(new ezcMvcRailsRoute('/fatal', 'ezpRestErrorController', 'show'), new ezcMvcRailsRoute('/http-basic-auth', 'ezpRestAuthController', 'basicAuth'), new ezcMvcRailsRoute('/login/oauth', 'ezpRestAuthController', 'oauthRequired'), new ezcMvcRailsRoute('/oauth/token', 'ezpRestOauthTokenController', 'handleRequest'), new ezpRestVersionedRoute(new ezcMvcRailsRoute('/foo', 'myController', 'myActionOne'), 1), new ezpRestVersionedRoute(new ezcMvcRailsRoute('/foo', 'myController', 'myActionOneBetter'), 2));
     return ezcMvcRouter::prefix('/api', array_merge($providerRoutes, $routes));
 }