<p>The answer below is mostly taken from Brandon Kelly's answer on Github which I suggest to read for more detailed information: <a href="https://github.com/craftcms/cms/issues/12847" rel="nofollow noreferrer">https://github.com/craftcms/cms/issues/12847</a></p>
<p>The reason for the endless recursion is that fetching globals creates an element query. Element queries need to fetch all custom fields to give them a chance to modify the query. Therefore, fetching Globals in the <code>init()</code> of a Custom Field creates an endless recursion.</p>
<p>The solution is to fetch the Globals elsewhere, for example in <code>inputHtml()</code> or <code>settingsHtml()</code>. However, the <code>Dropdown</code> and alike expect their <code>options</code> to be set from the <code>init()</code> and not change dynamically. To avoid problems, one can inherit from <code>Field</code> directly, for example:</p>
<pre class="lang-php prettyprint-override"><code>use craft\base\ElementInterface;
use craft\base\Field;
use craft\helpers\Cp;

class SphColorField extends Field
{
    /**
     * @var array
     */
    private $options;

    protected function inputHtml($value, ElementInterface $element = null): string
    {
        return Cp::selectFieldHtml([
            'id' =&gt; $this-&gt;getInputId(),
            'describedBy' =&gt; $this-&gt;describedBy,
            'name' =&gt; $this-&gt;handle,
            'value' =&gt; $value,
            'options' =&gt; $this-&gt;options(),
        ]);
    }

    private function options(): array
    {
        if (!isset($this-&gt;options)) {
            $this-&gt;options = [];
            $global = Craft::$app-&gt;globals-&gt;getSetByHandle('globalTest');
            if ($global) {
                foreach ($global-&gt;entries as $entry) {
                    $this-&gt;options[] = [
                        'label' =&gt; $entry['title'],
                        'value' =&gt; $entry['id']
                    ];
                }
            }
        }

        return $this-&gt;options;
    }
}
</code></pre>

CC BY-SA 4.0
2023-03-10T15:38:00.103Z
2023-03-10T15:38:00.103Z
Roman Sobkuliak
<p>When running code inside the init() function for a field type, you're running it every time the field is instantiated. Typically you would put Event functions inside of the init, which tells the system when to run that code. Here's the docs:</p>
<p><a href="https://craftcms.com/docs/4.x/extend/field-types.html#registering-custom-field-types" rel="nofollow noreferrer">https://craftcms.com/docs/4.x/extend/field-types.html#registering-custom-field-types</a></p>
<pre><code>Event::on(
            Fields::class,
            Fields::EVENT_REGISTER_FIELD_TYPES,
            function(RegisterComponentTypesEvent $event) {
                $event-&gt;types[] = MyField::class;
            }
        );
</code></pre>
<p>I think for your use case you might want this EVENT_REGISTER_FIELD_TYPES but the other event codes can be found here:</p>
<p><a href="https://craftcms.com/docs/4.x/extend/events.html#event-code-generator" rel="nofollow noreferrer">https://craftcms.com/docs/4.x/extend/events.html#event-code-generator</a></p>

CC BY-SA 4.0
2023-03-08T20:05:56.807Z
I linked to Craft 4.x documents but for this, its the same for 3.x, if you need to swap docs there is a drop down on the top left for Craft CMS version number.
cherrykoda
CC BY-SA 4.0
2023-03-08T20:04:07.173Z
2023-03-08T20:04:07.173Z
cherrykoda
<p>I'm creating a Custom Field Type whose possible values depend on the Globals. Therefore, I'm querying the Globals from the Custom Field's <code>init()</code>:</p>
<pre class="lang-php prettyprint-override"><code>class CustomField extends Checkboxes
{
    public function init()
    {
        // This line causes 502 Bad Gateway.
        $image = Craft::$app-&gt;globals-&gt;getSetByHandle('general')-&gt;image-&gt;one();
        // The rest is removed for clarity.
    }
}

class CustomFieldTypes extends Module {
  public function init()
  {
      // Register our Field
      Event::on(
          Fields::class,
          Fields::EVENT_REGISTER_FIELD_TYPES,
          function (RegisterComponentTypesEvent $event) {
              Craft::debug(
                  'Fields::EVENT_REGISTER_FIELD_TYPES',
                  __METHOD__
              );
              $event-&gt;types[] = CustomField::class;
          }
      );
  }

}
</code></pre>
<p>However, the above results in <code>502 Bad Gateway</code>. When I place the query into the <code>CustomFieldTypes</code> module, it works as expected.</p>
<p>When looking at the <a href="https://drive.google.com/file/d/18okzRLZ6XfkK90Rv-pmoTARDsx3DL_z_/view" rel="nofollow noreferrer">logs</a>, the following query</p>
<pre><code>SELECT `fields`.`id`, `fields`.`dateCreated`, `fields`.`dateUpdated`, `fields`.`groupId`, `fields`.`name`, `fields`.`handle`, `fields`.`context`, `fields`.`instructions`, `fields`.`translationMethod`, `fields`.`translationKeyFormat`, `fields`.`type`, `fields`.`settings`, `fields`.`uid`, `fields`.`searchable`, `fields`.`columnSuffix`
FROM `fields` `fields`
ORDER BY `fields`.`name`, `fields`.`handle`
</code></pre>
<p>gets ran almost 2000 times, among others.</p>
<p>Can you please help me find what's causing the error and what workaround should I use?</p>
<h2>Extra info</h2>
<p>I'm using Craft Pro 3.7.67 with plugins:</p>
<pre><code>Control Panel CSS   2.4.0
Excerptify  1.0.1
Freeform    3.13.25
Mailchimp Subscribe 3.1.1.1
Navigation  1.4.31
Neo 2.13.16
Opening Hours   1.0.0
Redactor    2.10.11
Redactor Custom Styles  3.0.4
Redirect Manager    1.1.1
SS Entry Importer   1.0.3
Super Table
</code></pre>

CC BY-SA 4.0
2023-03-06T16:38:49.037Z
Are you seeing any error messages in the logs?
MoritzLost
CC BY-SA 4.0
2023-03-06T16:57:27.680Z
Good point, here's the full log: https://drive.google.com/file/d/18okzRLZ6XfkK90Rv-pmoTARDsx3DL_z_/view

There's one query repeated almost 2000 times, I updated my answer. I'll be very grateful if you can think of why this is the case.
Roman Sobkuliak
CC BY-SA 4.0
2023-03-07T11:19:52.493Z
Probably not a good idea to execute an element query in a custom field type's `init()` method. Can you describe the use case for when/where/why the `$image` asset is needed in your field type?
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2023-03-07T18:11:47.437Z
Thanks a lot for chiming in. The image example is made up, but basically, I'm trying to give our Content Creators an option from the Admin Panel through the use of Globals to affect options of a Checkbox field. For example, having a Color checkbox field whose options can be altered from the Admin Panel.

What would you say is the idiomatic way to achieve this in CraftCMS? (I'm a new maintainer of the project and I don't have a lot of experience with Craft)
Roman Sobkuliak
<craft3><custom-fieldtype><globals>
Querying Globals from a Custom Field Type gives 502 Bad Gateaway
# Querying Globals from a Custom Field Type gives 502 Bad Gateaway

(Asked by: username_0 on 2023-03-06)

I'm creating a Custom Field Type whose possible values depend on the Globals. Therefore, I'm querying the Globals from the Custom Field's init():
class CustomField extends Checkboxes
{
    public function init()
    {
        // This line causes 502 Bad Gateway.
        $image = Craft::$app->globals->getSetByHandle('general')->image->one();
        // The rest is removed for clarity.
    }
}

class CustomFieldTypes extends Module {
  public function init()
  {
      // Register our Field
      Event::on(
          Fields::class,
          Fields::EVENT_REGISTER_FIELD_TYPES,
          function (RegisterComponentTypesEvent $event) {
              Craft::debug(
                  'Fields::EVENT_REGISTER_FIELD_TYPES',
                  __METHOD__
              );
              $event->types[] = CustomField::class;
          }
      );
  }

}

However, the above results in 502 Bad Gateway. When I place the query into the CustomFieldTypes module, it works as expected.
When looking at the logs, the following query
SELECT `fields`.`id`, `fields`.`dateCreated`, `fields`.`dateUpdated`, `fields`.`groupId`, `fields`.`name`, `fields`.`handle`, `fields`.`context`, `fields`.`instructions`, `fields`.`translationMethod`, `fields`.`translationKeyFormat`, `fields`.`type`, `fields`.`settings`, `fields`.`uid`, `fields`.`searchable`, `fields`.`columnSuffix`
FROM `fields` `fields`
ORDER BY `fields`.`name`, `fields`.`handle`

gets ran almost 2000 times, among others.
Can you please help me find what's causing the error and what workaround should I use?
Extra info
I'm using Craft Pro 3.7.67 with plugins:
Control Panel CSS   2.4.0
Excerptify  1.0.1
Freeform    3.13.25
Mailchimp Subscribe 3.1.1.1
Navigation  1.4.31
Neo 2.13.16
Opening Hours   1.0.0
Redactor    2.10.11
Redactor Custom Styles  3.0.4
Redirect Manager    1.1.1
SS Entry Importer   1.0.3
Super Table

**Tags:** craft3, custom-fieldtype, globals
> **Comments:**
> **username_1**: Are you seeing any error messages in the logs?  
> **username_0**: Good point, here's the full log: https://drive.google.com/file/d/18okzRLZ6XfkK90Rv-pmoTARDsx3DL_z_/view  There's one query repeated almost 2000 times, I updated my answer. I'll be very grateful if you can think of why this is the case.  
> **username_2**: Probably not a good idea to execute an element query in a custom field type's `init()` method. Can you describe the use case for when/where/why the `$image` asset is needed in your field type?  
> **username_0**: Thanks a lot for chiming in. The image example is made up, but basically, I'm trying to give our Content Creators an option from the Admin Panel through the use of Globals to affect options of a Checkbox field. For example, having a Color checkbox field whose options can be altered from the Admin Panel.  What would you say is the idiomatic way to achieve this in CraftCMS? (I'm a new maintainer of the project and I don't have a lot of experience with Craft)  

---

## 2 answers

### Answer by username_0 on 2023-03-10. Score: 2 | Accepted answer

The answer below is mostly taken from Brandon Kelly's answer on Github which I suggest to read for more detailed information: https://github.com/craftcms/cms/issues/12847
The reason for the endless recursion is that fetching globals creates an element query. Element queries need to fetch all custom fields to give them a chance to modify the query. Therefore, fetching Globals in the init() of a Custom Field creates an endless recursion.
The solution is to fetch the Globals elsewhere, for example in inputHtml() or settingsHtml(). However, the Dropdown and alike expect their options to be set from the init() and not change dynamically. To avoid problems, one can inherit from Field directly, for example:
use craft\base\ElementInterface;
use craft\base\Field;
use craft\helpers\Cp;

class SphColorField extends Field
{
    /**
     * @var array
     */
    private $options;

    protected function inputHtml($value, ElementInterface $element = null): string
    {
        return Cp::selectFieldHtml([
            'id' => $this->getInputId(),
            'describedBy' => $this->describedBy,
            'name' => $this->handle,
            'value' => $value,
            'options' => $this->options(),
        ]);
    }

    private function options(): array
    {
        if (!isset($this->options)) {
            $this->options = [];
            $global = Craft::$app->globals->getSetByHandle('globalTest');
            if ($global) {
                foreach ($global->entries as $entry) {
                    $this->options[] = [
                        'label' => $entry['title'],
                        'value' => $entry['id']
                    ];
                }
            }
        }

        return $this->options;
    }
}


---

### Answer by username_3 on 2023-03-08. Score: 1

When running code inside the init() function for a field type, you're running it every time the field is instantiated. Typically you would put Event functions inside of the init, which tells the system when to run that code. Here's the docs:
https://craftcms.com/docs/4.x/extend/field-types.html#registering-custom-field-types
Event::on(
            Fields::class,
            Fields::EVENT_REGISTER_FIELD_TYPES,
            function(RegisterComponentTypesEvent $event) {
                $event->types[] = MyField::class;
            }
        );

I think for your use case you might want this EVENT_REGISTER_FIELD_TYPES but the other event codes can be found here:
https://craftcms.com/docs/4.x/extend/events.html#event-code-generator

> **Comments:**
> **username_3**: I linked to Craft 4.x documents but for this, its the same for 3.x, if you need to swap docs there is a drop down on the top left for Craft CMS version number.  

---

