SavableComponentInterface

Type
Interface
Namespace
craft\base
Extends
craft\base\ComponentInterface
Implemented by
craft\base\EagerLoadingFieldInterface, craft\base\ElementAction, craft\base\ElementActionInterface, craft\base\Field, craft\base\FieldInterface, craft\base\FlysystemVolume, craft\base\SavableComponent, craft\base\Volume, craft\base\VolumeInterface, craft\base\Widget, craft\base\WidgetInterface, craft\elements\actions\CopyReferenceTag, craft\elements\actions\Delete, craft\elements\actions\DeleteAssets, craft\elements\actions\DeleteUsers, craft\elements\actions\DownloadAssetFile, craft\elements\actions\Edit, craft\elements\actions\EditImage, craft\elements\actions\NewChild, craft\elements\actions\PreviewAsset, craft\elements\actions\RenameFile, craft\elements\actions\ReplaceFile, craft\elements\actions\SetStatus, craft\elements\actions\SuspendUsers, craft\elements\actions\UnsuspendUsers, craft\elements\actions\View, craft\fields\BaseOptionsField, craft\fields\Checkboxes, craft\fields\Color, craft\fields\Date, craft\fields\Dropdown, craft\fields\Email, craft\fields\Lightswitch, craft\fields\Matrix, craft\fields\MissingField, craft\fields\MultiSelect, craft\fields\Number, craft\fields\PlainText, craft\fields\RadioButtons, craft\fields\Table, craft\fields\Url, craft\mail\transportadapters\BaseTransportAdapter, craft\mail\transportadapters\Gmail, craft\mail\transportadapters\Sendmail, craft\mail\transportadapters\Smtp, craft\mail\transportadapters\TransportAdapterInterface, craft\volumes\Local, craft\volumes\MissingVolume, craft\volumes\Temp, craft\widgets\CraftSupport, craft\widgets\Feed, craft\widgets\MissingWidget, craft\widgets\NewUsers, craft\widgets\QuickPost, craft\widgets\RecentEntries, craft\widgets\Updates
Since
3.0

SavableComponentInterface defines the common interface to be implemented by savable Craft component classes.

A class implementing this interface should also use craft\base\SavableComponentTrait.

View source

Public Methods

MethodDescription
afterDelete()Performs actions after a component is deleted.
afterSave()Performs actions after a component is saved.
beforeDelete()Performs actions before a component is deleted.
beforeSave()Performs actions before a component is saved.
displayName()Returns the display name of this class.
getIsNew()Returns whether the component is new (unsaved).
getSettings()Returns an array of the component’s settings.
getSettingsHtml()Returns the component’s settings HTML.
isSelectable()Returns whether the component should be selectable in component Type selects.
settingsAttributes()Returns the list of settings attribute names.
validate()Validates the component.

afterDelete()

Performs actions after a component is deleted.

View source

Signature

public abstract void afterDelete ( )

afterSave()

Performs actions after a component is saved.

View source

Arguments

  • $isNew (boolean) – Whether the component is brand new

Signature

public abstract void afterSave ( \craft\base\bool $isNew )

beforeDelete()

Performs actions before a component is deleted.

View source

Returns

boolean – Whether the component should be deleted

Signature

public abstract boolean beforeDelete ( )

beforeSave()

Performs actions before a component is saved.

View source

Arguments

  • $isNew (boolean) – Whether the component is brand new

Returns

boolean – Whether the component should be saved

Signature

public abstract boolean beforeSave ( \craft\base\bool $isNew )

getIsNew()

Returns whether the component is new (unsaved).

View source

Returns

boolean – Whether the component is new

Signature

public abstract boolean getIsNew ( )

getSettings()

Returns an array of the component’s settings.

View source

Returns

array – The component’s settings.

Signature

public abstract array getSettings ( )

getSettingsHtml()

Returns the component’s settings HTML. An extremely simple implementation would be to directly return some HTML:

return '<textarea name="foo">'.$this->foo.'</textarea>';

For more complex settings, you might prefer to create a template, and render it via craft\web\View::renderTemplate(). For example, the following code would render a template located at src/templates/_settings.html, passing the settings to it:

return Craft::$app->view->renderTemplate('plugin-handle/_widget-settings', [
    'widget' => $this
]);

If you need to tie any JavaScript code to your settings, it’s important to know that any name= and id= attributes within the returned HTML will probably get namespaced, however your JavaScript code will be left untouched. For example, if getSettingsHtml() returns the following HTML:

<textarea id="foo" name="foo"></textarea>
<script type="text/javascript">
    var textarea = document.getElementById('foo');
</script>

…then it might actually look like this before getting output to the browser:

<textarea id="namespace-foo" name="namespace[foo]"></textarea>
<script type="text/javascript">
    var textarea = document.getElementById('foo');
</script>

As you can see, that JavaScript code will not be able to find the textarea, because the textarea’s id= attribute was changed from foo to namespace-foo. Before you start adding namespace- to the beginning of your element ID selectors, keep in mind that the actual namespace is going to change depending on the context. Often they are randomly generated. So it’s not quite that simple.

Thankfully, craft\web\View service provides a couple handy methods that can help you deal with this:

So here’s what a getSettingsHtml() method that includes field-targeting JavaScript code might look like:

public function getSettingsHtml()
{
    // Come up with an ID value for 'foo'
    $id = Craft::$app->getView()->formatInputId('foo');
    // Figure out what that ID is going to be namespaced into
    $namespacedId = Craft::$app->view->namespaceInputId($id);
    // Render and return the input template
    return Craft::$app->view->renderTemplate('plugin-handle/_widget-settings', [
        'id'           => $id,
        'namespacedId' => $namespacedId,
        'widget'       => $this
    ]);
}

And the _widget-settings.twig template might look like this:

<textarea id="{{ id }}" name="foo">{{ widget.foo }}</textarea>
<script type="text/javascript">
    var textarea = document.getElementById('{{ namespacedId }}');
</script>

The same principles also apply if you’re including your JavaScript code with craft\web\View::registerJs().

View source

Returns

string, null

Signature

public abstract string, null getSettingsHtml ( )

isSelectable()

Returns whether the component should be selectable in component Type selects.

View source

Returns

boolean – Whether the component should be selectable in component Type selects.

Signature

public abstract static boolean isSelectable ( )

settingsAttributes()

Returns the list of settings attribute names. By default, this method returns all public non-static properties that were defined on the called class. You may override this method to change the default behavior. See also getSettings()View source

Returns

array – The list of settings attribute names

Signature

public abstract array settingsAttributes ( )

validate()

Validates the component.

View source

Arguments

  • $attributeNames (string[], null) – List of attribute names that should be validated. If this parameter is empty, it means any attribute listed in the applicable validation rules should be validated.
  • $clearErrors (boolean) – Whether existing errors should be cleared before performing validation

Returns

boolean – Whether the validation is successful without any error.

Signature

public abstract boolean validate ( $attributeNames = null, $clearErrors = true )