JosephSilber / page-cache

Caches responses as static files on disk for lightning fast page loads.
MIT License
1.21k stars 118 forks source link

How to cache for XML file #80

Closed ghost closed 3 years ago

ghost commented 3 years ago

I can cache JSON and HTML file but How can I cache XML files which are used for sitemaps?

Function I got:

    protected function getFileExtension($response)
    {
        if ($response instanceof JsonResponse) {
            return '.json';
        }
        return '.html';
    }

XML File Format:

`<?xml version="1.0" encoding="UTF-8"?>

http://www.example.com/ 2005-01-01 monthly 0.8 `
JosephSilber commented 3 years ago

How would XML be different than HTML? The fact that it's stored with an .html suffix shouldn't matter.

ghost commented 3 years ago

Thankyou for response but sorry as Response Header changes from text/xml to text/html and view isn also changed.

JosephSilber commented 3 years ago

Yeah. That makes sense. Didn't realize you cared about the header.

I don't have time to dive into it this second, but can you dd($response) from inside getFileExtension, to see what information there is on the response object that indicates that it's XML?

If there isn't anything else, we may need to check for the existence of that header. I'd be OK with that if there's nothing else.

ghost commented 3 years ago

Can you modify this file? I tried but It didn't help.

<?php

namespace App\Services;

use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\HttpFoundation\JsonResponse;

class CacheService
{
    private $files;
    private $cache_path;

    public function __construct()
    {
        $this->files = new Filesystem();
        $this->cache_path = public_path() . '/cache/';
    }

    /**
     * @param $request
     * @return string
     */
    public function cacheKey($url)
    {
        return md5($url);
    }

    /**
     * @return bool
     */
    protected function makeCacheDirectory()
    {
        return $this->files->makeDirectory($this->cache_path, 0775, true, true);
    }

    /**
     * @param $key
     * @return bool
     */
    public function isAlreadyCached($key)
    {
        return Cache::has($key);
    }

    /**
     * @param $key
     * @return mixed
     */
    public function getCache($key)
    {
        return Cache::get($key);
    }

    /**
     * remove folder
     */
    protected function removeFolder($key = '')
    {
        $this->files->deleteDirectory($this->cache_path.$key);
    }

    /**
     * @return bool
     */
    public function clearCache($slug='')
    {
        if ($slug){
            $url = env('APP_URL').config('constants.cache.urls')[$slug];
            $cache_key = $this->cacheKey($url);
            Cache::forget($cache_key);
            $this->removeFolder($slug);
        }else{
            Artisan::call('cache:clear');
            $this->removeFolder();
        }

        return true;
    }

    /**
     * @param $response
     * @return string
     */
    protected function getFileExtension($response)
    {
        if ($response instanceof JsonResponse) {
            return '.json';
        }
        return '.html';
    }

    /**
     * @param $key
     * @param $response
     * @param $value
     */
    protected function storeCacheFiles($key, $response, $value, $folder_name)
    {
        $this->cache_path = $this->cache_path.'/'.$folder_name;
        $this->makeCacheDirectory();
        $extension = $this->getFileExtension($response);
        $this->files->put($this->cache_path .'/' . $key . $extension, $value, true);
    }

    public function cacheUrls()
    {
        return config('constants.cache.urls');
    }

    /**
     * @param $key
     * @param $response
     * @return bool
     */
    public function cache($cache_key, $response, $folder_name)
    {
        // info('cache key cache '.$cache_key);

        if (!$this->isAlreadyCached($cache_key)) {
            $value = $response->getContent();
            $this->storeCacheFiles($cache_key, $response, $value, $folder_name);
            Cache::put($cache_key, $value, now()->addDays(config('constants.cache.time')));
            return true;
        }
        return false;
    }
}
JosephSilber commented 3 years ago

Again, you first need to figure out how the response is marked as XML.

Can you dd($response) from inside getFileExtension, to see what information there is on the response object that indicates that it's XML?

What did you use to generate that XML file?

ghost commented 3 years ago

Here it is how I create xml Controller:

public function pagesitemaps(Request $request)
    {
        return response()->view('sitemap.ok-page-sitemap')->header('Content-Type', 'application/xml');
    }

View file:

<?php $date = Carbon\Carbon::yesterday()->format('Y-m-d'); ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    @foreach( App\Models\Pages::all() as $page )
    <url>
         <loc>{{ url('page',$page->slug) }}</loc>
         <lastmod>{{$date}}</lastmod>
         <priority>0.8</priority>
   </url>
 @endforeach

</urlset> 
JosephSilber commented 3 years ago

Try it out in master, and let me know if it works for you.

If it's all good, I'll tag a release :+1:

ghost commented 3 years ago

Try it out in master, and let me know if it works for you.

If it's all good, I'll tag a release 👍

Ok