statamic / ideas

💡Discussions on ideas and feature requests for Statamic
https://statamic.dev
31 stars 1 forks source link

Computed Value Classes #921

Open jacksleight opened 1 year ago

jacksleight commented 1 year ago

Really loving the computed values feature, but one thing I've been struggling with a little is how best to organise them. Doing everything in a service provider doesn't always feel like the tidiest option, particularly when they have other dependencies or you want to add multiple that are related and need to share logic.

It would be great if you could wrap one or more in a class, keeping them organised in one place and making sharing dependencies and logic easy. You could implement something like this yourself already, but an official built-in way to do it would be ace.

Perhaps something like this:

<?php

namespace App\Entries;

class TweeterValues extends \Statamic\Entries\ComputedValues
{
    protected $collections = ['pages', 'articles'];

    protected $api;

    public function __construct(TweeterApi $api)
    {
        $this->api = $api;
    }

    /*
     * $entry->share_count;
     */
    public function shareCount($entry, $value)
    {
        return $this->fetchData($entry, 'get-tweet')['share-count'];
    }

    /*
     * $entry->share_url;
     */
    public function shareUrl($entry, $value)
    {
        return $this->fetchData($entry, 'get-share-url');
    }

    private function fetchData($entry, $action)
    {
        return Cache::remember("tweeter:{$entry->id}:{$action}", 3600, function () {
            $response = $this->api->fetch($action, $entry->permalink);
            $data = $response->json();
            return $data['data'];
        });
    }
}

Just like tags, scopes etc. these could automatically register when added to the app, or be listed in an addon's service provider.

Semi-related to: https://github.com/statamic/cms/pull/7165

jacksleight commented 1 year ago

If anyone's interested in this I have a working solution for now:

https://gist.github.com/jacksleight/37740ac27d3dd4b13d0a2150b2311e6b

It'll auto-load any classes in the app/Values folder and link up their public methods as computed values/callbacks.