[SOLVED] Cache EEL Helper or its results (http requests)


(Peter Bucher) #1

Hello there

I made a slightly different implementation like on the linked github page, which does 3 web requests with curl.

Example which i used to make a similiary implementation:

The cache mode is set to “cache”, yet the site has really long loading time. I dont think, there is anything cached with in the Neos Frontend Cache, or the EEL Helper Cache.

I played with the settings, but found no solution, that worked.
For example, i added the CacheAwareInterface to the EEL Helper.

So my Question is: How can i cache the EEL Helper Output with the Neos Frontend Cache, or how to use some Caching at PHP level that works?

My tries:

prototype(vendor.instagram:InstagramGallery) < prototype(Neos.Neos:Content) {
templatePath = ‘resource://vendor.instagram/Private/Templates/Instagram.html’

@context.accessTokens = ${q(node).property('accessTokens')}
@context.countImagesPerAccount = ${q(node).property('countImagesPerAccount')}
@context.randomizeImages = ${q(node).property('randomizeImages')}

instagramCollection = ${Instagram.getInstagramFeed('users/self/media/recent', '&count=' + countImagesPerAccount, accessTokens, randomizeImages)}
test = ${Date.now().timestamp}

@cache {
	mode = 'cached'
	maximumLifetime = '3600'
}

}

PHP:

class Instagram implements ProtectedContextAwareInterface, CacheAwareInterface {
private $accessTokenString;
private $randomizeImages;

public function getInstagramFeed($requestType, $get_param, $accessTokensString, $randomizeImages) {
    $this->accessTokenString = $accessTokensString;
    $this->randomizeImages = $randomizeImages;

    $accessTokensArray = explode("\n", $accessTokensString);
    $instagramData = [];

    foreach($accessTokensArray as $accessToken) {
        $response = $this->getRecentImages($requestType, $get_param, $accessToken);
        $decoded_response = json_decode($response);
        $newData = isset($decoded_response->data) ? $decoded_response->data : [];

        $instagramData = array_merge($instagramData, $newData);

        if($randomizeImages) {
            shuffle($instagramData);
        }
    }

    return isset($instagramData) ? $instagramData : [];
}

function getRecentImages($requestType, $get_params, $access_token){
    $url = "https://api.instagram.com/v1/$requestType/?access_token=$access_token&$get_params";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

public function allowsCallOfMethod($methodName) {
    return true;
}

public function getCacheEntryIdentifier() {
    return $this->accessTokenString + $this->randomizeImages.toString();
}

}

Regards, Peter


(Benjamin Klix) #2

You need to specify entryIdentifier with all variables that could change, as those variables will be used to determine, if there already is a cached item that could be used.

Also specify entryTags to flush the cache when the expected nodes have changed.

For example:

@cache {
    mode = 'cached'
    entryIdentifier {
        node = ${node}
        # add all other strings/values that could modify the output here
    }
    
    # choose which entryTags you need:
    entryTags {
        # flush cache if the current node changes
        1 = ${'Node_' + node.identifier}

        # flush cache if the current page node changes:
        2 = ${'Node_' + documentNode.identifier}
        
        # flush cache if a specific node type changes:
        3 = 'NodeType_Your.Package:Node.Type'
        
        # flush cache if any item on the page changes:
        4 = ${'DescendantOf_' + q(documentNode).children('main').get(0).identifier}
    }
}

(Peter Bucher) #3

Hi Benjamin

I needed to as so said. The main problem was, that the Content Element was within a Content Element that was “uncached”, so the underlying Element did not cache because of that.

Here is my configuration, with that the cache will be invalidated, when a property of the node changes:

	@cache {
		mode = 'cached'
		maximumLifetime = '3600'
		entryIdentifier {
			node = ${node}
		}

		entryTags {
			# flush cache if the current node changes
			1 = ${'Node_' + node.identifier}
		}
	}

Thank you, regards Peter


(Christian Müller) #4

Yep, closing this as solved. As Peter wrote it was an uncached element above. As soon as something was uncached anything cached below behaves uncached as well due to how the cache works.


(Christian Müller) #5

(Dmitri Pisarev) #6

Ah yes, this was something I tried to remember. Also I think if the top level cache entry gets invalidated, the child cache entries are invalidated too, correct?