Append Playa field via Safecracker - expressionengine

I'm building an artist directory and using Pixel & Tonic's Playa to manage each member's "fans."
In each user's profile, there is a multi-select Playa field that displays all of the members that user has "fanned" (similar to "like" on Facebook).
What I'd like to do is have a "link" that's actually a safecracker submission that will add a member's name to the user's Playa field.
Essentially, it will be a form with hidden fields for the User's ID and the screen name of the member whose page is being viewed. I want to append the screen name to the user's existing Playa field entries.
What's the best way to achieve this?
Thanks!
ty

You can use Safecracker too, and create hidden field for the Playa:
<input type="hidden" name="my_playa_field_name[selections][]" />
You must use the Playa field name here (not the field_id).
Then you can submit your Safecracker form in ajax.

You'll need to add a custom plugin to do this, so you can perform a custom SQL insert.
Not sure if you're familar with writing plugins, but you can get started by creating one via pkg.io, and then adding this function to the resulting file. Then you can create a link to a template where you place your new tag, and perhaps pass the ids for the member and the new fan via segments:
{exp:my_plugin:add_fan member_id="{segment_3}" fan_id="{segment_4}"}
This function makes the (perhaps mistaken) assumption that you're storing your members in channels (I assume so, because you're using a Playa field), and that you have access in your templates to the entry_id of both the member and fan. If not, you may need to perform some more queries to find the entry_id of each. It also calls your Playa field field_id_10 ... you'll need to replace 10 with the proper field_id of your Playa field.
function add_fan()
{
$this->EE =& get_instance();
$member_id = $this->EE->TMPL->fetch_param('member_id');
$fan_id = $this->EE->TMPL->fetch_param('fan_id');
$data = array(
'parent_entry_id' => $member_id,
'child_entry_id' => $fan_id,
'parent_field_id' => 10
);
$this->EE->db->query(
$this->EE->db->insert_string('exp_playa_relationships', $data)
);
}

Related

Is it possible to create my own custom KvExt table to fully implement and manage User Defined Fields for my custom table and page?

I have a custom table in SQL Server called AnimalBreed and maintenance page.
I wish to add User Defined Field support via the KvExt approach instead of
traditional practices involving either CSAnswers or a CacheExtension of the
DAC and underlying "Usr" fields.
Is this possible?
Can it be done for line-level (child) DACs, such as
existing INLocation and INLocationKvExt?
Thanks!
UPDATE:
It appears the feature needs at least:
ensure your table has the NoteID column as uniqueidentifier datatype and the DAC has the corresponding field: Guid? NoteID and [PXNote()] attribute.
In the ASPX, if not ListView, add the following to the PXDataSource tag:
EnableAttributes="true"
By making these changes, I can Manage User Defined Fields, choose Attributes to include, and I can store values to the KvExt table.
I am using Version = 19.205.0023
Sales Order page observation: if I add two UDFs on SO Order Entry page, one is combobox and one is checkbox, setting their values saves just fine, but then updating the combobox and save leads to loss of the checkbox (from true to false), unless you uncheck and recheck prior to the save. Is this a bug?
Maybe technically possible but definitely not recommended to use undocumented feature like KvExt.
If you need to deploy User Defined Fields on a page which already contains them. Configure them manually and then add them in a customization package in the user defined fields section for deployment as described here:
https://help-2019r2.acumatica.com/Help?ScreenId=ShowWiki&pageid=e01f29d3-b6b1-40f4-a2d1-45c9d01bdde3
Example:

Function for listing user parameters

I want to add a form into my application for generating rules considering the attributes of Liferay Users.
Do you know a function for getting a list of this attributes? (List of parameter names)
Example:
1. Address,
2. FullName,
3. AccountId,
4. Create Date,
5. Employee Numbre,
6. And so on.....
Do you know a function for getting the type of each parameter? (Due to check type errors)
Example:
1. Address -> String
2. FullName -> String
Thank you,
Oriol
AFAIK, there is not such a method. But even if it existed, it would not provide all the info you're going for, because some of it, is not an attribute of the User Class, or the corresponding 'user_' table in the LF database.
If you understand how ServiceBuilder Model works, you'll see that there's a complex Model running under the hood, and it's not working like attributes.
For example, there is no 'user.getAddress()'., Because, Address is a Complex Class, subclassing Contact, and keeps a FK to the User. If you want one of his addresses, You can only get all his addresses (User.getAddresses()), and iterate through them, check by ContantactType and e.g. get his "business address". Respectfully, you can't call 'user.setAddress(String)', not even a "user.addAddress(Address)". A working code would look much more like :
//update an existing Address
existingAddr.setStreet1(street);
existingAddr.setZip(zip);
existingAddr.setCity(city);
AddressLocalServiceUtil.updateAddress(existingAddr);
//then update the user, to store the changes.
UserLocalServiceUtil.updateUser(user);
The same goes for the birthday, the Phones, websites and facebook urls etc
For the rest of the 'Attributes' (names and Types), you should look here
You can get a User object by calling:
User u = userService.getUserById(0);
or check liferay docs for UserService
then you can use getters like:
u.getAddresses();
u.getBirthday();
u.getFullName();
you can get it from:
User user = UserLocalServiceUtil.getUser(userId);
user.getFullName();
user.getEmailAddress();

Orchard - Query Custom Fields in Content Item

I have a Content Type "News" with custom field "NewsDate" (DateTimeField) and "Active" (BooleanField)
Now I'm need to get 3 active atimes order desc by NewsDate
Get all news, make them toList() and from there manipulate the data is not a solution.
P.S. I need to do something like:
var items = contentManager
.Query(Entities[PageType.Press])
.OrderByDescending<CommonPartRecord, DateTime?>(record => record.PublishedUtc)
.Slice(0, 3);
but instead of PublishedUTC use my custom field "NewsDate" and add Active == true, However it is not possible due to Orchard architecture of storing custom data in a separate field as XML data.
UPDATED:
In a nutshell I want to generate from code behind the following Query:
DECLARE #temp as TABLE(id int, xmldata xml)
INSERT #temp VALUES(1,'<Data><News><NewsDate>07/14/2011 11:42:00</NewsDate><Link Title="" DisplayText="" Link="www.example.com" OpenInNewTab="True">www.example.com</Link></News></Data>')
INSERT #temp VALUES(2,'<Data><News><NewsDate>07/11/2011 12:11:00</NewsDate><Link Title="" DisplayText="" Link="www.example.com" OpenInNewTab="True">www.example.com</Link></News></Data>')
INSERT #temp VALUES(3,'<Data><News><NewsDate>02/21/2012 16:56:00</NewsDate><Link Title="" DisplayText="" Link="www.example.com" OpenInNewTab="True">www.example.com</Link><NewsLink></NewsLink></News></Data>')
SELECT
TOP 3 [id],
[xmldata].value('(Data/News/NewsDate)[1]', 'datetime') as NewsDate
FROM #temp
ORDER BY NewsDate DESC
P.S. I looked through the code for DynamicContentQueryTests, however all the examples uses the Part, and in my case Fields are just in the ContentItem:
E.g. News content type contains NewsDate field (datetime field) and some parts as well
Any suggestions are greatly appreciated.
Querying fields is possible since 1.4 through Projector and underlying index tables and new APIs on Content Manager. Your simplest bet actually may be to create a projection.
To get the values of fields that have been attached directly to a Content Item, you need to first look for the Content Part with the same name as the item, which is created by Orchard. So in your case in the Parts list for each News Content Item you'll find a part called "NewsPart", and inside this the Fields property will have your NewsDate and Active fields.
However, like you say Orchard serializes the field values into XML for storage to prevent it having to change the database structure every time you add/remove a field to/from a content type. For this reason, querying and ordering by fields is not recommended because all the serialized data needs to be de-serialized for each Content Item. If you want to be able to do this, the best way is to make your own Content Part with a Content Part Record and use your own table for storage, then you can do this:
contentManager.Query<NewsPart, NewsPartRecord>()...
...and query/sort on whatever values you like.
Bertrand is correct. Check this link : http://www.davidhayden.me/blog/projector-module-in-orchard-cms. You can implement your requirements easily with Projection Module. The link will tell you the steps to do that. If you don't want a widget, you can create a page with your query too. Once the module is enabled, you will see the option to create a Projection Page in the left hand side navigation.
EDIT :
Can't you simply parse the XML? You can query your content type 'News'. Something like -
var contentItems = contentManager.Query<ContentPart>("News").Join<TitlePartRecord>().Join<AutoroutePartRecord>().Join<CommonPartRecord>().List();
Once you have that, you can access the XML data by :
foreach (var item in contentItems)
{
var contentItem = (ContentItem)item.ContentItem;
ContentItemVersionRecord contentItemRecord = contentItem.VersionRecord;
string data = contentItemRecord.Data;
//Call some function here to parse 'data' and store the object in the list.
}
'data' has the information in XML format that you need.
You can parse it and then store the objects in your list that you can order by your custom field.

Is it possible to add Extra Fields Under Create User in Liferay

I am using Liferay 6 for portal Development .
During Creating Users under Liferay , i need to add some extra Fields also ??
Please let me know if this is ppossible or not ??
Please see the screen shot attached here , and also please let me know in which table this will be stored in Database ??
Yes, you can use Custom Attributes functionality for liferay entities (in your case, User) and can add as many extra fields as necessary for each liferay entity.
Custom field for the user-entity can be created through:
Control Panel -> Portal -> Custom Fields -> User.
And programmatically can be created as follows:
user.getExpandoBridge().addAttribute("yourCustomFieldKey");
Then set the value as:
user.getExpandoBridge().setAttribute("yourCustomFieldKey", "valueForCustomField");
If your custom field is already present you can check like this:
if (user.getExpandoBridge().hasAttribute("yourCustomFieldKey")) { ... };
The data is stored in tables prefixed with "EXPANDO":
EXPANDOCOLUMN: stores the custom field key and other settings
(contains the tableId refrences)
EXPANDODATA: stores the custom field value for the key (contains the
columnId and tableId refrences)
EXPANDOTABLE: stores for which liferay entity (user) are you adding
the custom field
EXPANDOROW: stores linking information between a user and its values
(contains tableId and userId refrences)
Hope this helps.
yes, you can add custom fields to user-entity and add them the field-values to user:
user.getExpandoBridge().addAttribute(...);
Custim field for the user-entity you can create by Control Panel Portal->Custom Fields or programmaticaly at liferay start.
The data will be stored in ExpandoValue tables.
Just in case somebody try to retrieve the values from the custom fields and is having problems with null values returned by the method user.getExpandoBridge().getAttribute("yourCustomFieldKey") (even when you followed the threads about permissions), I found other way to retrieve the Custom Fields values:
ExpandoTable table = ExpandoTableLocalServiceUtil.getDefaultTable(user.getCompanyId(), User.class.getName() );
ExpandoColumn column = ExpandoColumnLocalServiceUtil.getColumn(table.getTableId(), "yourCustomFieldKey");
ExpandoValue expandoValue = ExpandoValueLocalServiceUtil.getValue(table.getTableId(), column.getColumnId(), user.getUserId());
Then you can do a simple (if the field is text) expandoValue.getString();
Not so pretty, but do the work.
User creation page in liferay can be customized. You can infact decide which fields to be present in the user creation page. More about this in here.
Use the following commands if you get the permission problem in adding or setting attribute.
user.getExpandoBridge().addAttribute("yourCustomFieldKey",false);
user.getExpandoBridge().setAttribute("yourCustomFieldKey", "valueForCustomField",false);

How to create a lookup column that targets a Doc Lib and uses the 'Name' of the document?

How do you create a lookup column to a Document Library that uses the 'Name' of the document as the lookup value?
I found a blog post that recommends adding another custom field like "FileName" and then using a item reciever to populate the custom field with the value from the Name field but that seems cheesy.
Link to the blog in case people are interested:
http://blogs.msdn.com/pranab/archive/2008/01/08/sharepoint-2007-moss-wss-issue-with-lookup-column-to-doc-lib-name-field.aspx
I've got a bunch of custom document content types that I dont want to clutter with a work around that should really work anyway.
I created a one step workflow to set the title from the name, fired on modify and created. Seems to work and took seconds to create.
One way you can do this (although not the easiest way) is by creating a custom field type that extends the SPFieldLookup class. SharePoint's field editor for Lookup fields purposefully hides any columns types that aren't supported by Lookup fields, but you can create a field editor for your custom field type that shows them.
However, I have created a Lookup column that points to a Name column in a Document Library before, and it probably doesn't work like you'd expect. While the value stored in the lookup column is valid, it doesn't show up right in List view or on the View Properties form.
The solution you posted may actually be the best way to handle this. Lookup fields require some kludges if you want to handle more complex scenarios, but that's because they're not meant to provide the same functionality as a foreign key relationship in a database.
Coding in any form always scares me. So Here's what I did: I simply renamed the Stupid "Title" Field to something else, say "Keywords", since you cant do anything with that field: cant even make it mandatory.
Then I created another Single line field called "Title" and used this field for the Lookups
Well there is a simple solution to that and in might work in some case.
In the nutshell if you make the Title field Mandatory, this will force the user to enter a title. In that manner we can use title field as a lookup field.
Now How to do that?
One you are done create a document library go to the library setting. Select Advance Setting and Select Yes for the option "Allow management of content types?".
Then go back to the Library setting and Under content types select the "Document" Content type. THen Select Title Column and then Select "Required (Must contain information)" and say OK.
Now try uploading a document to this document library. You will see Title field in the form.
Hope this helps
Cheers
Vaqar
You have to add the field as XML with the ShowField as 'FileLeafRef'
var XmlFieldDefinition = "<Field DisplayName='myLookupColumn' Type='LookupMulti' StaticName='myLookupColumn' Name='myLookupColumn' Required='FALSE' List='THE LOOKUP ID HERE' WebId='THE WEB ID HERE' UnlimitedLengthInDocumentLibrary='TRUE' Mult='TRUE' Sortable='FALSE' ShowField='FileLeafRef' />"
Field fld = fieldCollection.AddFieldAsXml(XmlFieldDefinition, true, AddFieldOptions.DefaultValue);
ClientContext.Load(fld);
ClientContext.ExecuteQuery();

Resources