Field http://lobsterr.me/ en How to extract entity id from autocomplete string in Drupal? http://lobsterr.me/post/how-extract-entity-id-autocomplete-string-drupal <span class="field field--name-title field--type-string field--label-hidden">How to extract entity id from autocomplete string in Drupal?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">02/22/2021</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>When we use autocomplete field, the submitted value will look something like this "Title of the entity (10)". To extract the current entity id from this string we can use helper function <strong>extractEntityIdFromAutocompleteInput </strong> from <strong>EntityAutocomplete</strong></p> <pre> <code class="language-php">$autocomplete_data = 'Title of the entity (10)'; $entity_id = EntityAutocomplete::extractEntityIdFromAutocompleteInput($autocomplete_data);</code></pre> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> <div class="field__item btn btn-secondary"><a href="/tags/entity" hreflang="en">Entity</a></div> <div class="field__item btn btn-secondary"><a href="/tags/field" hreflang="en">Field</a></div> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Mon, 22 Feb 2021 11:57:48 +0000 LOBsTerr 40 at http://lobsterr.me How to change the type of the field in Drupal 9? http://lobsterr.me/post/how-change-type-field-drupal-9 <span class="field field--name-title field--type-string field--label-hidden">How to change the type of the field in Drupal 9?</span> <div class="field field--name-f-intro field--type-string-long field--label-hidden field__item">There are many cases when we need to switch a type of a field from one to another based on a new business requirement. How to do it and keep the old data.</div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">01/19/2021</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>First you HAVE TO make a back up :) </p> <p>I will provide the full code and then step by step we will break it down. To perform this operation we will use hook_update.</p> <h3>Steps to change the type of the field</h3> <ol><li>Load field storage</li> <li>Fetch the data for this field</li> <li>Configure a new field storage</li> <li>Delete the old storage</li> <li>Purge the data</li> <li>Create a new storage configuration</li> <li>Add field to bundles</li> <li>Insert the data back to db</li> </ol><pre> <code class="language-php">&lt;?php use \Drupal\field\Entity\FieldStorageConfig; use \Drupal\field\Entity\FieldConfig; /** * Change node__field_quote from string_long to string type. */ function yourmodule_update_8XXX() { $database = \Drupal::database(); $table = 'node__field_quote '; $entity_type = 'node'; $field_name = 'field_quote'; // #1 Load storage configuration. $field_storage = FieldStorageConfig::loadByName($entity_type, $field_name); // if storage config is not found, there is nothing to do. if (is_null($field_storage)) { return; } $rows = []; // #2 Fetch the data for the old field. if ($database-&gt;schema()-&gt;tableExists($table)) { // The table data to restore after the update is completed. $rows = $database-&gt;select($table, 'n') -&gt;fields('n') -&gt;execute() -&gt;fetchAll(); } $new_fields = []; // Use existing field config for new field. foreach ($field_storage-&gt;getBundles() as $bundle =&gt; $label) { $field = FieldConfig::loadByName($entity_type, $bundle, $field_name); $new_field = $field-&gt;toArray(); $new_field['field_type'] = 'string'; $new_field['settings'] = []; $new_fields[] = $new_field; } // #3 Take the old storage configuration present it as an array and update it's settings. $new_field_storage = $field_storage-&gt;toArray(); $new_field_storage['type'] = 'string'; $new_field_storage['settings'] = [ 'max_length' =&gt; 255, 'is_ascii' =&gt; FALSE, 'case_sensitive' =&gt; FALSE, ]; // #4 Deleting field storage which will also delete bundles(fields). $field_storage-&gt;delete(); // #5 Purge field data now to allow new field and field_storage with same name // to be created. You may need to increase batch size. field_purge_batch(100); // #6 Create new field storage, create a new storage based on configuration above. $new_field_storage = FieldStorageConfig::create($new_field_storage); $new_field_storage-&gt;save(); // #7 Create new fields. foreach ($new_fields as $new_field) { $new_field = FieldConfig::create($new_field); $new_field-&gt;save(); } // #8 Restore existing data in the same table. if (!empty($rows)) { foreach ($rows as $row) { // We can do some manipulation with data here. $database-&gt;insert($table) -&gt;fields((array) $row) -&gt;execute(); } } }</code></pre> <p> </p> <h3>Step 1 - Load the old field storage</h3> <p>First of all of course we need to load the old field storage configuration. A field storage always attached to entity type: node, media, paragraph and etc.</p> <pre> <code class="language-php"> $field_storage = FieldStorageConfig::loadByName($entity_type, $field_name);</code></pre> <p><strong>Step 2 - </strong>Fetch the data for this field</p> <p>We fetch all the data for the old field, for any fields and for any bundles. For example this fiels used in articles (node content type) and pages (node content type). We want to keep the data for all of the fields. Later we can perform some transformation of the data. Keep in mind if you have many items in this table, you will need to use batch operations.<br /><br />  </p> <pre> <code class="language-php">// #2 Fetch the data for the old field. if ($database-&gt;schema()-&gt;tableExists($table)) { // The table data to restore after the update is completed. $rows = $database-&gt;select($table, 'n') -&gt;fields('n') -&gt;execute() -&gt;fetchAll(); }</code></pre> <p> </p> <h3>Step 3  -  Configure a new field storage</h3> <p>In this example we actually use the old storage configuration and just update few settings.</p> <pre> <code class="language-php">// #3 Take the old storage configuration present it as an array and update it's settings. $new_field_storage = $field_storage-&gt;toArray(); $new_field_storage['type'] = 'string'; $new_field_storage['settings'] = [ 'max_length' =&gt; 255, 'is_ascii' =&gt; FALSE, 'case_sensitive' =&gt; FALSE, ];</code></pre> <p>But in some cases we can get it from configuration files or just pass an array with configuration directly. For example<br />  </p> <pre> <code class="language-php">// Get field storage from config file. $install_storage = new ExtensionInstallStorage( \Drupal::service('config.storage'), InstallStorage::CONFIG_INSTALL_DIRECTORY ); $field_storage_config = $install_storage-&gt;read("field.storage.node.field_quote");</code></pre> <h3>Step 4  -  Delete the old storage</h3> <pre> <code class="language-php">// #4 Deleting field storage which will also delete bundles(fields). $field_storage-&gt;delete();</code></pre> <p> </p> <h3>Step 5 - Purge the data</h3> <p>Before recreating the new field we need to delete all the data for these fields. If you have a lot of items consider to change the value.</p> <pre> <code class="language-php">// #5 Purge field data now to allow new field and field_storage with same name // to be created. You may need to increase batch size. field_purge_batch(100);</code></pre> <p> </p> <h3>Step 6 - Create a new storage configuration</h3> <p>Here we just pass a field storage configuration to create method as an array</p> <pre> <code class="language-php">// #6 Create new field storage, create a new storage based on configuration above. $new_field_storage = FieldStorageConfig::create($new_field_storage); $new_field_storage-&gt;save();</code></pre> <p> </p> <h3>Step 7 - Add field to bundles</h3> <p>We recreate field instances here. We again use the previous configuration of the field and update the settings.<br />  </p> <pre> <code class="language-php">// #7 Create new fields. foreach ($new_fields as $new_field) { $new_field = FieldConfig::create($new_field); $new_field-&gt;save(); }</code></pre> <p>and then we can also recreate the field completely from scratch, something like this</p> <pre> <code class="language-php">FieldConfig::create([ 'field_storage' =&gt; FieldStorageConfig::loadByName($entity_type, $field_name), 'bundle' =&gt; $bundle, 'label' =&gt; t('Our field label'), 'required' =&gt; TRUE, 'default_value' =&gt; [[ 'value' =&gt; 1, ], ], ])-&gt;save();</code></pre> <p> </p> <h3>Step 8 - Insert the data back to the field table.</h3> <p>Here we can convert data or just insert as it is.</p> <pre> <code class="language-php"> // #8 Restore existing data in the same table. if (!empty($rows)) { foreach ($rows as $row) { // We can do some manipulation with data here. $database-&gt;insert($table) -&gt;fields((array) $row) -&gt;execute(); } }</code></pre> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> <div class="field__item btn btn-secondary"><a href="/tags/field" hreflang="en">Field</a></div> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Tue, 19 Jan 2021 09:49:49 +0000 LOBsTerr 26 at http://lobsterr.me How to update entity field in Drupal 8? http://lobsterr.me/post/how-update-entity-field-drupal-8 <span class="field field--name-title field--type-string field--label-hidden">How to update entity field in Drupal 8?</span> <div class="field field--name-f-intro field--type-string-long field--label-hidden field__item">Sometimes we need to update some settings for a field. In our case we will be update drop down field</div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">06/04/2020</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><pre> <code class="language-php">function your_module_update_8001() { // First we need to get update manager. $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); // Load the storage definition of the field. $field_storage = $definition_update_manager-&gt;getFieldStorageDefinition('field_name', 'node'); // Set a new list of options for the list field. $field_storage-&gt;setSettings([ 'allowed_values' =&gt; [ 'link' =&gt; 'Link', 'posts' =&gt; 'Posts', 'events' =&gt; 'Events', 'page' =&gt; 'Page', ], ]); // Update the field storage definition. $definition_update_manager-&gt;updateFieldStorageDefinition($field_storage); } </code></pre> <p> </p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/entity-api" hreflang="en">Entity API</a></div> <div class="field__item btn btn-secondary"><a href="/tags/entity" hreflang="en">Entity</a></div> <div class="field__item btn btn-secondary"><a href="/tags/field" hreflang="en">Field</a></div> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Wed, 03 Jun 2020 22:43:16 +0000 LOBsTerr 23 at http://lobsterr.me How to load entity by a specific field value in Drupal 9? http://lobsterr.me/post/how-load-entity-specific-field-value-drupal-9 <span class="field field--name-title field--type-string field--label-hidden">How to load entity by a specific field value in Drupal 9?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">LOBsTerr</span></span> <span class="field field--name-created field--type-created field--label-hidden">11/25/2019</span> <div class="field field--name-f-content field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--l-text paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-f-text field--type-text-long field--label-hidden field__item"><p>Quite often it is required to get data by a field value. In our example I will use nodes, but it can be any entity type.</p> <p>In first example we load entities by based fields. For example vid, type, language and etc.</p> <p>I want to get all the nodes of the type <strong>post </strong> for my custom block. For this we will use <strong>EntityTypeManager </strong>class</p> <pre> <code class="language-php">// Load a storage for node entity type $items = \Drupal::entityTypeManager() -&gt;getStorage('node') -&gt;loadByProperties(['type' =&gt; 'post']); // load all nodes with the node type</code></pre> <p>After we can run through the items and apply our custom logic here.</p> <p>In the second example, we will get entities based on custom fields. For example we have field "<strong>field_type</strong>"</p> <pre> <code class="language-php">$query = $this-&gt;entityTypeManager-&gt;getStorage('node')-&gt;getQuery(); $query-&gt;condition('status', 1) -&gt;condition('changed', REQUEST_TIME, '&lt;') -&gt;condition('field_type', 'post'); $nids = $query-&gt;execute();</code></pre> <p>More examples can be found here: <a href="https://www.drupal.org/node/1827278">EntityFieldQuery</a></p> </div> </div> </div> </div> <div class="field field--name-f-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item btn btn-secondary"><a href="/tags/drupal-9" hreflang="en">Drupal 9</a></div> <div class="field__item btn btn-secondary"><a href="/tags/entity-api" hreflang="en">Entity API</a></div> <div class="field__item btn btn-secondary"><a href="/tags/field" hreflang="en">Field</a></div> </div> <section class="field field--name-f-comments field--type-comment field--label-above comment-wrapper"> </section> Mon, 25 Nov 2019 13:54:44 +0000 LOBsTerr 20 at http://lobsterr.me