We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Disable caching view for search engine page

Hi there,

I am implementing my own website based on Phalcon Website.

After many customizations I came to question as in the title.

Phalcon creates cache for every page.

I implemented clearing cache for all pages, but I need to disable caching on search engine page, so user could see different results for different terms, not only for first one.

Probably I could use mechanism made for clearing cache from CMS (it is separate app), which sends request to the frontend to clear one or more caches.

Any help or ideas very appreciate :)

Hmmm sounds strange? Can you share some code and more details?

Arent search results different depending on the Search Criteria? Never ever had such a problem, perhaps you are caching fragments or?

@nikolay-mihaylov,

Here is my view configuration:

    /**
     * Initializes the View services and Volt
     */
    protected function initView()
    {
        $config     = $this->diContainer->getShared('config');
        $profiler   = null;

        if ($config->app->debug && $config->app->profiler) {
            $profiler = $this->diContainer->getShared('profiler');
            $benchmark = $profiler->start(__METHOD__, [], 'Bootstrap');
        }

        /** @var \Phalcon\Registry $registry */
        $registry = $this->diContainer->getShared('registry');

        $options  = [
            'compiledPath'      => $config->app->cacheDir . '/volt/',
            'compiledSeparator' => '_',
            'compiledExtension' => '.php',
            'compileAlways'     => boolval('development' === $registry->mode),
            'stat'              => true,
        ];

        $view  = new PhViewSimple();

        $view->setViewsDir(APP_PATH . '/app/views/');
        $view->registerEngines(
            [
                '.volt' => function ($view) use ($config, $options) {
                    $volt  = new PhVolt($view, $this->diContainer);
                    $volt->setOptions($options);

                    $compiler = $volt->getCompiler();

                    /**
                     * Register the PHP extension, to be able to use PHP functions in Volt
                     */
                    $compiler->addExtension(new Php());
                    $compiler->addFunction('replace', 'preg_replace');
                    $compiler->addFunction('substring', 'mb_substr');
                    $compiler->addFunction('strtotime', 'strtotime');

                    $compiler->addFunction('implode', 'implode');

//                    $compiler->addFunction('first_letter', function ($text) {
//                        return mb_substr($text, 0, 1);
//                    });

                    $compiler->addFunction(
                        'latinize',
                        function($resolvedArgs, $exprArgs) use ($compiler)
                        {
                            $text = $compiler->expression($exprArgs[0]['expr']);

                            return 'transliterator_transliterate(
                                \'Any-Latin; Latin-ASCII;\', ' .
                                $text .
                            ')';
//                            return iconv('UTF-8', 'ASCII//TRANSLIT', $text);
                        }
                    );

                    // return e.g. https://img.website.com/api/image/ad0733dc-1042-59ab-d5c1-dccfc23fe997/size/640x291
                    $compiler->addFunction(
                        'get_image_url',
                        function ($resolvedArgs, $exprArgs) use ($compiler, $config)
                        {
                            $filename   = $compiler->expression($exprArgs[0]['expr']);
                            $resolution = $compiler->expression($exprArgs[1]['expr']);

                            return Image::getImageUrl($filename, $resolution, $config->app);
                        }
                    );

                    $compiler->addFunction(
                        'resolve_image_urls',
                        function ($resolvedArgs, $exprArgs) use ($compiler, $config)
                        {
                            $htmlBody   = $compiler->expression($exprArgs[0]['expr']);

                            return Image::resolveImageUrlsInHtmlBody($htmlBody, $config->app);
                        }
                    );

                    return $volt;
                },
            ]
        );

        $this->diContainer->setShared('viewSimple', $view);

        if ($config->app->debug && $config->app->profiler) {
            $profiler->stop($benchmark);
        }
    }

The most important thing is this line:

        $options  = [
            // [...]
            'compileAlways'     => boolval('development' === $registry->mode),
            // [...]
        ];

Let's say I have my search engine under following url:

  • https://website.test/en/search
  • https://website.test/pl/szukaj
  • https://website.test/pl/szukaj/strona/2?q=some-term

Phalcon PHP will create following cache files in production mode:

  • _en_search.cache
  • _pl_szukaj.cache
  • _pl_szukaj.cache_strona_2_.cache

I don't see any other way than disabling production mode.

Maybe someone will have better idea...

I do not think your volt service is causing those caches, see here 'compiledExtension' => '.php', and you are showing .cache files list.

Also the compiled volt files should be inside your $config->app->cacheDir . '/volt/', directory. Which are actually the same HTML just with PHP instead of Volt tags.

I think you are manually caching the view in your controller file, can we see your search method code?

Cache files are stored in $config->app->cacheDir . '/view/' only when mode is set as development.

I can switch it in .env file:

APP_ENV=development

My controller is quite normal:

<?php
namespace Website\Controllers;

use Website\Controller as WebsiteController;
use Website\Services\SearchEngineService;

class SearchEngineController extends WebsiteController
{
    /**
     * Specifies a limit for search results placed on single blog page
     */
    const RESULTS_LIMIT = 10;

    public function searchAction()
    {
        $slug           = $this->registry->slug;
        $slugInEnglish  = $this->route_map->translate($slug);
        $template       = $slugInEnglish;

        $this->title[] = $this->locale->translate('X Europe');
        $this->title[] = $this->locale->translate('Search engine');

        $searchEngineService = new SearchEngineService($this->registry->language);

        $query      = '';
        $results    = [];

        $params = $this->router->getParams();

        if ($this->request->isPost()) {
            $query = $this->request->getPost('q', 'striptags');
        } else {
            $query = $this->request->get('q', 'striptags');
        }

        $pageNo = (int) ($params['pageNo'] ?? 1);

        if (! empty($query)) {
            $paginator = $searchEngineService->paginateSearch(
                $query,
                self::RESULTS_LIMIT,
                $pageNo
            );

            $pagedData = $paginator->getPaginate();
            /** @var \Elastica\ResultSet $resultset */
            $resultset = $paginator->getData();
            $results   = $pagedData->items;

            $this->viewSimple->results   = $results;
            $this->viewSimple->totalHits = $resultset->getTotalHits();
            $this->viewSimple->totalTime = (int) $resultset->getTotalTime();

            $this->injectPagingVariablesToView($pageNo, $pagedData);
        } else {
            $results = [];
        }

        // set data to view
        $this->title = array_reverse($this->title);
        $this->tag->setTitle(implode(self::PAGE_TITLE_DELIMETER, $this->title));

        $this->viewSimple->query    = $query;

        $this->registry->view = sprintf('search-engine/%s', $template);
    }
}

Why? I dont understand this part?

$this->registry->view = sprintf('search-engine/%s', $template);

Just use one template for all of the search parameters.

Also what is $this->registry? Is it your DI?

My website is based on this project: https://github.com/phalcon/website/

Here is sample controller, which I adapted to my needs: https://github.com/phalcon/website/blob/master/app/controllers/PagesController.php

Project is based on Micro application, not the Simple.

It is using templates in different way than e.g. in Vokuro application. As I remember we do not have dispatcher here and we use Middleware.

And thank you... I have found my caching source!!

It is in ViewMiddleware: https://github.com/phalcon/website/blob/master/app/library/Middleware/ViewMiddleware.php

Registry is a registry, which stores some key-value items, which can be checked in the code.



93.7k
Accepted
answer

Yep! Good job :)

Exactly line 38 from your link:

if (true === $application->viewCache->exists($cacheKey)) {

Now it is piece of cake :)

I can make exclude for given slugs e.g. search-engine in my case.

Thank you @nikolay-mihaylov for your questions. I don't know every piece of code if I was not the only developer.

Now it is much more clear for me.

I thought that this was some internal Phalcon PHP mechanism.

We can close this topic!

Have a good day!

If its not your code I would suggest that you take a look through all files starting from your index -> bootstrap -> module -> services etc, so you dotn get suprised in future :)

You can "accept" your last comment to solve this thred.

I know this application, but not all code :) In this case I didn't know that it was added, not built in behaviour.

I am developing my website from the January 2018 and I am also learing Phalcon PHP.

I can read the code, but I would learn much more if I need some part of it.

Eg. crrently I have a problem with model migrations, which seems to not work at all. The same thing in Vokuro, which I used as CMS background.

I think I will learn much more if I start new app from the beginning in the future.

thank you for solving this. i had the same problem.

Fact Buddies