verbb / icon-picker

A Craft CMS field to select SVG or font icons from a folder for use in your content.
Other
17 stars 8 forks source link

Register icon source event triggered hundreds of times #34

Closed bertoost closed 4 years ago

bertoost commented 4 years ago

Description

I am trying to add custom font resources, also my self-hosted Font Awesome 5 PRO icon-set. Using the IconSources::EVENT_REGISTER_ICON_SOURCE event to hook in. After a while of debugging I disabled the event-trigger in IconSources.php and dumped a debug text-line. I discovered the code is passing by 936 times. Exactly the amount of icons included in the Font Awesome 5 Free set which is embedded within the plugin.

But triggering this so many times, and adding my custom (remote) icon-sets is causing the CP page to timeout. A 504 Gateway Time-out. I don't know yet why, but probably because of calling IconPicker::$plugin->getIconSources() every time again, this initiates a new instance and the init() method is firing the getRegisteredIconSources(). But I am investigating it.

FYI; The reason I want to add my own FA5 PRO icon-sets is because of the different styles. I'd like the client to choose from all the different types (light, regular, solid, duotone & brands). Which is not provided by the default FA5 one, since that's the free icon set. Also adding in the fonts is not working either since I have multiple font-icon sets to add (which are stored in separated sub-directories (and I don't want to merge them into one).

Example

I am using the icons.json file which is provided when you download FA5 PRO. I ran over all the icons an create an icon-list over all the categories, like this;

Event::on(
    IconSources::class,
    IconSources::EVENT_REGISTER_ICON_SOURCE,
    static function (RegisterIconSourceEvent $event) {

        // add-in the different category styles
        $categories = [
            'light'   => ['font' => 'Font Awesome 5 Pro', 'prefix' => 'fal fa-'],
            'regular' => ['font' => 'Font Awesome 5 Pro', 'prefix' => 'far fa-'],
            'solid'   => ['font' => 'Font Awesome 5 Pro', 'prefix' => 'fas fa-'],
            'duotone' => ['font' => 'Font Awesome 5 Duotone', 'prefix' => 'fad fa-'],
            'brands'  => ['font' => 'Font Awesome 5 Brands', 'prefix' => 'fab fa-'],
        ];

        $icons = [];
        $iconData = Json::decode(file_get_contents(Craft::getAlias('@application') . '/resources/icon-files/fa5.json'));

        foreach ($iconData as $iconName => $details) {
            foreach ($details['styles'] as $styleName) {
                // first check if we want to have the style at all
                if (!array_key_exists($styleName, $categories)) {
                    continue;
                }

                // create icons per category/style name
                if (!array_key_exists($styleName, $icons)) {
                    $icons[$styleName] = [];
                }

                $icons[$styleName][] = $iconName;
            }
        }

        foreach ($categories as $category => $details) {

            if (!array_key_exists($category, $icons)) {
                continue;
            }

            $event->sources['font-awesome-' . $category] = [
                'label'    => Craft::t('app', 'Font Awesome 5 PRO (' . ucwords($category) . ')'),
                'url'      => Craft::getAlias('@web') . '/assets/css/cms-fa5.min.css',
                'icons'    => $icons[$category],
                'classes'  => $details['prefix'],
                'fontName' => $details['font'],
            ];
        }
    });

Additional info

bertoost commented 4 years ago

By the way.. it's only triggering so many times on the entry where the icon-picker field is on. Not in the field edit/settings page itself It's this controller action which is running into trouble index.php?p=cms/actions/icon-picker/icons/icons-for-field&fieldId={id}