json-api-server/writing.html

83 lines
30 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Field Writability | json-api-server</title>
<meta name="generator" content="VuePress 1.8.2">
<meta name="description" content="A fully automated JSON:API server implementation in PHP.">
<link rel="preload" href="/json-api-server/assets/css/0.styles.57b98ad2.css" as="style"><link rel="preload" href="/json-api-server/assets/js/app.67f738be.js" as="script"><link rel="preload" href="/json-api-server/assets/js/2.45932810.js" as="script"><link rel="preload" href="/json-api-server/assets/js/26.1472df94.js" as="script"><link rel="prefetch" href="/json-api-server/assets/js/10.f39ec3a0.js"><link rel="prefetch" href="/json-api-server/assets/js/11.724dd987.js"><link rel="prefetch" href="/json-api-server/assets/js/12.9934b242.js"><link rel="prefetch" href="/json-api-server/assets/js/13.01e72a34.js"><link rel="prefetch" href="/json-api-server/assets/js/14.0a2e817f.js"><link rel="prefetch" href="/json-api-server/assets/js/15.88e8e5d1.js"><link rel="prefetch" href="/json-api-server/assets/js/16.c308b4df.js"><link rel="prefetch" href="/json-api-server/assets/js/17.8ed4f1c9.js"><link rel="prefetch" href="/json-api-server/assets/js/18.3550a25e.js"><link rel="prefetch" href="/json-api-server/assets/js/19.65cfb425.js"><link rel="prefetch" href="/json-api-server/assets/js/20.b9e8a752.js"><link rel="prefetch" href="/json-api-server/assets/js/21.80416eea.js"><link rel="prefetch" href="/json-api-server/assets/js/22.c8abdf2c.js"><link rel="prefetch" href="/json-api-server/assets/js/23.298bad12.js"><link rel="prefetch" href="/json-api-server/assets/js/24.f0bf2e90.js"><link rel="prefetch" href="/json-api-server/assets/js/25.5bf262d7.js"><link rel="prefetch" href="/json-api-server/assets/js/3.54f7104d.js"><link rel="prefetch" href="/json-api-server/assets/js/4.a1fa2109.js"><link rel="prefetch" href="/json-api-server/assets/js/5.42433e02.js"><link rel="prefetch" href="/json-api-server/assets/js/6.60d915b0.js"><link rel="prefetch" href="/json-api-server/assets/js/7.62c9b4c8.js"><link rel="prefetch" href="/json-api-server/assets/js/8.2eaea85f.js"><link rel="prefetch" href="/json-api-server/assets/js/9.e517d767.js">
<link rel="stylesheet" href="/json-api-server/assets/css/0.styles.57b98ad2.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/json-api-server/" class="home-link router-link-active"><!----> <span class="site-name">json-api-server</span></a> <div class="links"><!----> <nav class="nav-links can-hide"><div class="nav-item"><a href="/json-api-server/" class="nav-link">
Guide
</a></div> <a href="https://github.com/tobyz/json-api-server" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/json-api-server/" class="nav-link">
Guide
</a></div> <a href="https://github.com/tobyz/json-api-server" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Getting Started</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/json-api-server/" aria-current="page" class="sidebar-link">Introduction</a></li><li><a href="/json-api-server/install.html" class="sidebar-link">Installation</a></li><li><a href="/json-api-server/requests.html" class="sidebar-link">Handling Requests</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Defining Resources</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/json-api-server/adapters.html" class="sidebar-link">Adapters</a></li><li><a href="/json-api-server/scopes.html" class="sidebar-link">Scopes</a></li><li><a href="/json-api-server/attributes.html" class="sidebar-link">Attributes</a></li><li><a href="/json-api-server/relationships.html" class="sidebar-link">Relationships</a></li><li><a href="/json-api-server/visibility.html" class="sidebar-link">Field Visibility</a></li><li><a href="/json-api-server/writing.html" aria-current="page" class="active sidebar-link">Field Writability</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#writable-once" class="sidebar-link">Writable Once</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#default-values" class="sidebar-link">Default Values</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#validation" class="sidebar-link">Validation</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#transformers" class="sidebar-link">Transformers</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#setters" class="sidebar-link">Setters</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#savers" class="sidebar-link">Savers</a></li><li class="sidebar-sub-header"><a href="/json-api-server/writing.html#events" class="sidebar-link">Events</a></li></ul></li><li><a href="/json-api-server/filtering.html" class="sidebar-link">Filtering</a></li><li><a href="/json-api-server/sorting.html" class="sidebar-link">Sorting</a></li><li><a href="/json-api-server/pagination.html" class="sidebar-link">Pagination</a></li><li><a href="/json-api-server/meta.html" class="sidebar-link">Meta Information</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Endpoints</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/json-api-server/list.html" class="sidebar-link">Listing Resources</a></li><li><a href="/json-api-server/show.html" class="sidebar-link">Showing Resources</a></li><li><a href="/json-api-server/create.html" class="sidebar-link">Creating Resources</a></li><li><a href="/json-api-server/update.html" class="sidebar-link">Updating Resources</a></li><li><a href="/json-api-server/delete.html" class="sidebar-link">Deleting Resources</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Advanced</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/json-api-server/errors.html" class="sidebar-link">Error Handling</a></li><li><a href="/json-api-server/laravel.html" class="sidebar-link">Laravel Helpers</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="field-writability"><a href="#field-writability" class="header-anchor">#</a> Field Writability</h1> <p>By default, fields are read-only. You can allow a field to be written to in <code>PATCH</code> and <code>POST</code> requests using the <code>writable</code> and <code>readonly</code> methods.</p> <p>You can optionally supply a closure to these methods which will receive the model instance, and should return a boolean value.</p> <p>For example, the following schema will make an email attribute that is only writable by the self:</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">writable</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token variable">$model</span><span class="token operator">-&gt;</span><span class="token property">id</span> <span class="token operator">===</span> <span class="token variable">$context</span><span class="token operator">-&gt;</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'userId'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="writable-once"><a href="#writable-once" class="header-anchor">#</a> Writable Once</h2> <p>You may want a field to only be writable when creating a new resource, but not when an existing resource is being updated. This can be achieved by calling the <code>once</code> method:</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">hasOne</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'author'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">writable</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">once</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="default-values"><a href="#default-values" class="header-anchor">#</a> Default Values</h2> <p>You can provide a default value to be used when creating a new resource if there is no value provided by the consumer. Pass a value or a closure to the <code>default</code> method:</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'joinedAt'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token keyword">default</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">DateTime</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'ipAddress'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token keyword">default</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token variable">$context</span><span class="token operator">-&gt;</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">getServerParams</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'REMOTE_ADDR'</span><span class="token punctuation">]</span> <span class="token operator">??</span> <span class="token constant">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>If you're using Eloquent, you could also define <a href="https://laravel.com/docs/8.x/eloquent#default-attribute-values" target="_blank" rel="noopener noreferrer">default attribute values<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> to achieve a similar thing. However, the Request instance will not be available in this context.</p></div> <h2 id="validation"><a href="#validation" class="header-anchor">#</a> Validation</h2> <p>You can ensure that data provided for a field is valid before the resource is saved. Provide a closure to the <code>validate</code> method, and call the first argument if validation fails:</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">callable</span> <span class="token variable">$fail</span><span class="token punctuation">,</span> <span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span> <span class="token function">filter_var</span><span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token constant">FILTER_VALIDATE_EMAIL</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$fail</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Invalid email'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>You can easily use Laravel's <a href="https://laravel.com/docs/8.x/validation" target="_blank" rel="noopener noreferrer">Validation<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> component for field validation with the <a href="/json-api-server/laravel.html#validation"><code>rules</code> helper function</a>.</p></div> <p>This works for relationships, too. The related models will be retrieved via your adapter and passed into your validation function.</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">hasMany</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'groups'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token keyword type-hint">callable</span> <span class="token variable">$fail</span><span class="token punctuation">,</span> <span class="token keyword type-hint">array</span> <span class="token variable">$groups</span><span class="token punctuation">,</span> <span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$groups</span> <span class="token keyword">as</span> <span class="token variable">$group</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$group</span><span class="token operator">-&gt;</span><span class="token property">id</span> <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$fail</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'You cannot assign this group'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="transformers"><a href="#transformers" class="header-anchor">#</a> Transformers</h2> <p>Use the <code>transform</code> method on an attribute to mutate any incoming value before it is saved to the model.</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'firstName'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">transform</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">ucfirst</span><span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>If you're using Eloquent, you could also define attribute <a href="https://laravel.com/docs/8.x/eloquent-mutators#attribute-casting" target="_blank" rel="noopener noreferrer">casts<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> or <a href="https://laravel.com/docs/8.x/eloquent-mutators#defining-a-mutator" target="_blank" rel="noopener noreferrer">mutators<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> on your model to achieve a similar thing.</p></div> <h2 id="setters"><a href="#setters" class="header-anchor">#</a> Setters</h2> <p>Use the <code>set</code> method to define custom mutation logic for your field, instead of just setting the value straight on the model property.</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'firstName'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$model</span><span class="token operator">-&gt;</span><span class="token property">first_name</span> <span class="token operator">=</span> <span class="token function">ucfirst</span><span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$model</span><span class="token operator">-&gt;</span><span class="token property">first_name</span> <span class="token operator">===</span> <span class="token string single-quoted-string">'Toby'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$model</span><span class="token operator">-&gt;</span><span class="token property">last_name</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'Zerner'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="savers"><a href="#savers" class="header-anchor">#</a> Savers</h2> <p>If your field corresponds to some other form of data storage rather than a simple property on your model, you can use the <code>save</code> method to provide a closure that will be run <em>after</em> your model has been successfully saved. If specified, the adapter will NOT be used to set the field on the model.</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'locale'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">save</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token variable">$model</span><span class="token operator">-&gt;</span><span class="token function">preferences</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'locale'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'value'</span> <span class="token operator">=&gt;</span> <span class="token variable">$value</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="events"><a href="#events" class="header-anchor">#</a> Events</h2> <h3 id="onsaved"><a href="#onsaved" class="header-anchor">#</a> <code>onSaved</code></h3> <p>Run after a field has been successfully saved.</p> <div class="language-php extra-class"><pre class="language-php"><code><span class="token variable">$type</span><span class="token operator">-&gt;</span><span class="token function">attribute</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'email'</span><span class="token punctuation">)</span>
<span class="token operator">-&gt;</span><span class="token function">onSaved</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token variable">$model</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Context</span> <span class="token variable">$context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">event</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">EmailWasChanged</span><span class="token punctuation">(</span><span class="token variable">$model</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/tobyz/json-api-server/edit/master/docs/writing.md" target="_blank" rel="noopener noreferrer">Edit this page</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/json-api-server/visibility.html" class="prev">
Field Visibility
</a></span> <span class="next"><a href="/json-api-server/filtering.html">
Filtering
</a>
</span></p></div> </main></div><div class="global-ui"></div></div>
<script src="/json-api-server/assets/js/app.67f738be.js" defer></script><script src="/json-api-server/assets/js/2.45932810.js" defer></script><script src="/json-api-server/assets/js/26.1472df94.js" defer></script>
</body>
</html>