Drupal 8, get programmatically the list of fields of a custom content - drupal-8

I want create programmatically a custom content (custom content created via the admin UI). But, before the creation, I want check programmatically the types of fields of my custom content
My custom content contains a field "body" (type text), a field "description" (type text), an int field (type int), an attached file field (type fid ?)...
I test several ways with the new api of Drupal 8, my last try..
// I get the entity object "my_custom_content"
$entity_object = NodeType::load("my_custom_content");
dpm($entity_object); //Work perfectly
$test = \Drupal::getContainer()->get("entity_field.manager")->getFieldDefinitions("my_custom_content",$entity_object->bundle())
//The \Drupal::getConta... Return an error : The "my_custom_content" entity type does not exist.
With this $entity_object, how can I get the list of the fields of my custom content ?
I see the EntityFieldManager Class, the FieldItemList Class...But I still do not understand how to play with drupal 8 / class / poo ... :/
Thanks !

NodeType is the (config) bundle entity for the Node (content) entity.
The correct call would be:
\Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'my_custom_content');
To get the field definitions of any entity_type use the following structure:
\Drupal::service('entity_field.manager')->getFieldDefinitions(ENTITY_TYPE_ID, BUNDLE_ID);
For example, if you want to get all the field definitions of a paragraph bundle with the id multy_purpose_link then replace ENTITY_TYPE_ID with paragraph and BUNDLE_ID with multy_purpose_link
\Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', 'multy_purpose_link');

The given answers are deprecated. You should now load the entity and just use getFieldDefinitions() to fetch the field definitions.
$node = Node::load($slide_id);
$field_defs = $node->getFieldDefinitions();

Or
$field_defs = \Drupal::service('entity_field.manager')->getFieldDefinitions('taxonomy_term', '<taxonomy machine name here>');
If you want to get the list of field_definitions for a taxonomy vocabulary

If the entity type does not have a bundle, for example the user entity.
Try this:
// All user fields and ones added
$user_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('user','user');
// Just default
$default_user_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('user', NULL);

Related

Search custom property in SharePoint User Profile

I created a custom property in the user profile.
I want to search through all the user profiles and output those profiles in which the custom property contains a certain string
For example:
User1- Custom Property value is 1,2,3
User2- Custom Property value in 2,4,5
User3- Custom Property value is 4,6,8
I want to output all the profiles in which Custom Property contains 2
(using c# code)
So the output should have User1 and User2
Can someone suggest the best way to implement this?
I did find some links in the internet for searching user profiles use KeyWord search but and not sure if those methods could be used to search through Custom Properties.
Example: https://www.collaboris.com/how-to-use-search-keywordquery-to-query-user-profiles-in-sharepoint/
I am using SharePoint 2013
We ended up promoting the Custom Property that we added to the User profile to a Managed property.
Also it seems like we can do wildcard searches on managed properties so we do People searches like "CustomProperty:*,2,*" so that it would return all the user profiles which have the number 2 in the custom property of their user profile
Interestingly the wildcard works only on the end for OOTB properties like FirstName so we cant do things like FirstName:oh and expect it would return John Doe's profile
But we can certainly do this - FirstName:joh* and that would return all the people whose first name starts with Joh (which would include John Doe)
But it seems like the wildcard works both at the beginning and the end for the custom managed properties (which helped a great deal for us)
On how to return the results of the search using c# we used this-
private DataTable GetPeople(SPSite spSite, string queryText)
{
var keywordQuery = new KeywordQuery(spSite)
{
QueryText = queryText,
KeywordInclusion = KeywordInclusion.AllKeywords,
SourceId = System.Guid.Parse("b09a7990-05ea-4af9-81ef-edfab16c4e31")
};
keywordQuery.RowLimit = this.MaxProfilesToDisplay;
keywordQuery.SelectProperties.Add("AccountName");
keywordQuery.SelectProperties.Add("PictureURL");
SearchExecutor e = new SearchExecutor();
ResultTableCollection rt = e.ExecuteQuery(keywordQuery);
var tab = rt.Filter("TableType", KnownTableTypes.RelevantResults);
var result = tab.FirstOrDefault();
DataTable DT = result.Table;
return DT;
}
and we would invoke this like
DataTable dt = GetPeople(SPContext.Current.Site, "CustomProperty:*,2,*" );

Sitecore how to show item's field in a datasource instead of item name

In a templateItem I have following information for a field.
Name : Product type
field type : 'Droplink'
DataSource : DataSource=/sitecore/content/Enumerations/Products/Product type/
When the content editor creates an item based on above template, for the field 'Product type' in the dropdown he will see the items under ../Product type. My question is for the items which are show in dropdown how to show some other field instead of item name
This functionality does not exist out of the box, although the code for the DropLink field looks like has code in there to be able to do this (take a look at the GetItemHeader() method in Sitecore.Shell.Applications.ContentEditor.LookupEx), I do not know how to utilize the parameter through the Content Editor though...
It's simple enough to create a custom field to achieve this though:
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Shell.Applications.ContentEditor;
namespace MyProject.Custom.Fields
{
public class CustomDropLink : LookupEx
{
protected override string GetItemHeader(Item item)
{
if (string.IsNullOrEmpty(this.FieldName))
this.FieldName = StringUtil.ExtractParameter("FieldName", this.Source).Trim();
return base.GetItemHeader(item);
}
}
}
Then register your custom class in the core database under /sitecore/system/Field types/. You can do this by duplicating /sitecore/system/Field types/Link Types/Droplink and setting the following values:
Assembly: MyProject.Custom
Class: MyProject.Custom.Fields.CustomDropLink
Control: <set this to empty>
Then when you utilise this field set the Source of your field like so:
Datasource=/sitecore/content/path/to/items&FieldName=Title

Camunda Custom Form Field Type

We are implementing Camunda on our application and we have a problem with forms
We need to implement our own form field type. We use the Camunda Modeler and use the custom type in the Type attribute of the field but when we try to deploy the war we always see the same error
ENGINE-16004 Exception while closing command context: ENGINE-09005 Could not parse BPMN process. Errors:
* unknown type 'file' [...]
We searched in the documentation but we don't see how to implement custom form field types
Any idea how to solve this?
Thanks in advance
You didn't provide much information on your project and how you try to use custom types in embedded? TaskForms.
Camunda has a nice example how to do this with embedded TaskForms here:
https://github.com/camunda/camunda-bpm-examples/tree/master/usertask/task-form-embedded-serialized-java-object
The custom type in generated forms is for types which can be rendered as the value of a single html input field, it is not useful to render complex structures like tables or multiple inputs for bean properties.
https://forum.camunda.org/t/camunda-custom-form-field-type/501 describes how the custom type works:
The custom type must extend AbstractFormFieldType, which provides mappings between model types and form display types, see DateTypeValue for an example. Then you must tell the bpmn engine about your custom type using ProcessEngineConfiguration.setCustomFormTypes() in a ProcessEnginePlugin which has access to the bpm engine configuration.
The generated form will render the form display type as a single input field, only alternatives are datepicker for date and select for enum, as you see in HtmlFormEngine#renderFormField:
if(isEnum(formField)) {
// <select ...>
renderSelectBox(formField, documentBuilder);
} else if (isDate(formField)){
renderDatePicker(formField, documentBuilder);
} else {
// <input ...>
renderInputField(formField, documentBuilder);
}
This is org.camunda.bpm.engine.impl.form.engine.HtmlFormEngine#renderInputField, it renders a single input:
protected void renderInputField(FormField formField,
HtmlDocumentBuilder documentBuilder) {
HtmlElementWriter inputField = new HtmlElementWriter(INPUT_ELEMENT, true);
addCommonFormFieldAttributes(formField, inputField);
String inputType = !isBoolean(formField) ? TEXT_INPUT_TYPE : CHECKBOX_INPUT_TYPE;
inputField.attribute(TYPE_ATTRIBUTE, inputType);
// add default value
Object defaultValue = formField.getDefaultValue();
if(defaultValue != null) {
inputField.attribute(VALUE_ATTRIBUTE, defaultValue.toString());
}
// <input ... />
documentBuilder.startElement(inputField).endElement();
}

tt_address: add categorys of address to the template

Is it somehow possible to add the sub-group of a cetrain group the address is assigned to the html output?
In the template I have ###MAINGROUP### and ###GROUPLIST###. I can't use maingroup, cause it's not the case that the group I need is always the maingroup. And with the grouplist I can't say which group is the sub-group of the one group.
Anyone have an idea how I could do it?
And in addition to that I also need the value of a self created field in the tt_address table.
Edit:
I try it like #lorenz say. What I have so far:
ext_localconf.php:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][]
='EXT:txnextaddresssort/class.tx_next_address_sort_addmarkers.php:tx_next_address_sort_addmarkers';
class.tx_next_address_sort_addmarkers.php:
<?php
class tx_next_address_sort_addmarkers {
function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf,
&$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###SORTBEREICH###'] =
$lcObj->stdWrap($address['tx_nextaddresssort_sort_bereich'],
$lConf['tx_nextaddresssort_sort_bereich.']);
}
}
Extentionkey: next_address_sort
All I get is a blank screen, but no errors in apache log
No, there is no possibility to do that.
Yet you can write a custom extension that integrates the extraItemMarkerProcessorhook in tt_address. In ext_localconf.php, add:
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][] ='EXT:myextension/class.tx_myextension_filename.php:tx_myextension_classname';
Then add a file class.tx_myextension_filename.php to your extension.:
class tx_myextension_classname {
public function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf, &$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###MYFIELD###'] = $lcObj->stdWrap($address['myfieldlikeindatabase'], $lConf['myfieldlikeindatabase.']);
return $markerArray;
}
}
This would be an example for getting a field that is in the tt_address table and adding it to the markers so they can be used in a template. It is also stdWrap enabled.
Now, instead of getting a field, you should replace $address['myfieldlikeindatabase'] with a variable that contains the information you need. To receive the data, you can use the TYPO3 database API functions ($GLOBALS['TYPO3_DB']).

How to create a dynamic source for a multilist in Sitecore?

I have the following content tree structure:
Home
Products
Product A
Product B
Organizations
Org 1
Org 2
Org Config X
Org Config Y
Each Organization beneath Organizations has a field called "Associated Products" which is a multilist. This tells the system which Products go with each Organization. The Org Config data template has a field called "Selected Products". When I add a new Org Config content item (which always lives directly beneath an Organization) I would like to be able to restrict the items that are displayed in the "Selected Products" field (which is a multilist) to only display Products that are already associated with the parent Organization. I am thinking there might be a way to do this with Sitecore Query but I can't figure it out. Any ideas?
With the help of Sitecore I figured it out. Basically you have to create a custom control that inherits from MultilistEx. Then you need to override the DoRender() event. Before you call base.DoRender() you must change the source (this.Source) to use a Sitecore query. Previously I was trying to do it in the OnLoad event. So my code now looks like this:
public class CustomMultiList : MultilistEx
{
private void ExcludeItems()
{
...custom code here that builds a list of Item IDs to exclude from the Multilist source...
...list should look like this "##id != 'some guid' and ##id != 'some guid' and so forth...
...you could also build a list of item ids to include. Any Sitecore query will do...
...you can use this.ItemID to get a reference to the current item that is being edited in the Content Editor...
this.Source = "query:" + this.Source + "/*[" + myListOfItemIdsToExclude + "]";
}
protected override void DoRender(output)
{
this.ExcludeItems();
base.DoRender(output);
}
}
I think you'll probably need to create a custom field for this. Here's some articles related to the subject:
http://www.sitecore.net/unitedkingdom/Community/Best-Practice-Blogs/Martin-Knudsen/Posts/2012/09/Creating-a-custom-Sitecore-Field.aspx
http://gettingtoknowsitecore.blogspot.co.uk/2010/03/custom-fields-part-1.html
http://sitecoreblog.blogspot.co.uk/2012_04_01_archive.html