Liferay search content for a specific groupid - search

I would like to ask, how can I search web-content of my site for a specific group-id.
Now I have a method which searches correctly by keyword in all of the web-content but doesn't search for a specific group-id.
Any ideas?
HttpServletRequest httpReq = FacesService.getHttpServletRequest();
//PortalUtil.getHttpServletRequest((PortletRequest) facesContext.getExternalContext().getRequest() );
//(PortletRequest) facesContext.getExternalContext().getRequest()
SearchContext searchContext = SearchContextFactory.getInstance(httpReq );
searchContext.setKeywords(query);
searchContext.setEnd(2000);
searchContext.setStart(0);
String[] entryCalssName = {JournalArticle.class.getName()};
searchContext.setEntryClassNames(entryCalssName);
searchContext.setAttribute(Field.GROUP_ID, 14603);
Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);
assetEntriesFacet.setStatic(true);
searchContext.addFacet(assetEntriesFacet);
Facet scopeFacet = new ScopeFacet(searchContext);
scopeFacet.setStatic(true);
searchContext.addFacet(scopeFacet);
Indexer indexer = FacetedSearcher.getInstance();
Hits hits = indexer.search(searchContext);
List<JournalArticle> searchResults = new ArrayList<JournalArticle>();
documents = hits.toList();
if (documents != null && !documents.isEmpty()) {
for(Document doc : documents) {
Long classPK = Long.parseLong(doc.get(Field.ENTRY_CLASS_PK));
AssetEntry assetEntry = AssetEntryLocalServiceUtil.getEntry(JournalArticle.class.getName(), classPK);
JournalArticle article = JournalArticleLocalServiceUtil.getLatestArticle(assetEntry.getClassPK());
System.out.println(article.getGroupId());
// if(article.getGroupId() == groupId){//I would like to get rid of this
searchResults.add(article);
// }
}
}

Have you tried this way to set groupId in SearchContext?
searchContext.setGroupIds(long[] groupIds);

Related

How to add a Web Part into a SitePages/Home.aspx using CSOM

has anyone managed to add a Web Part into a Wiki page using CSOM?
Background: Home.aspx is a Wiki page and all its WPs are located in the rich text zone (in fact a "WikiField" column). Technically they are located in a hidden "wpz" web part zone and in addition to this there is always a placeholder with WP's ID in the WikiField column.
I've modified the existing server-side code seen on http://blog.mastykarz.nl/programmatically-adding-web-parts-rich-content-sharepoint-2010/ and http://640kbisenough.com/2014/06/26/sharepoint-2013-moving-webparts-programmatically-to-rich-content-zone/ into this:
using System;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.WebParts;
public class Class1
{
void DeployWebPart(ClientContext clientContext, string zone, string pattern, string position)
{
List library = clientContext.Web.GetList("/sites/site/SitePages/");
clientContext.Load(library);
clientContext.ExecuteQuery();
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
ListItemCollection itemColl = library.GetItems(query);
clientContext.Load(itemColl, items => items.Include(i => i.Id, i => i.DisplayName, i => i["WikiField"]));
clientContext.ExecuteQuery();
ListItem item = itemColl.Where(i => i.DisplayName == "Home").First();
clientContext.ExecuteQuery();
File page = item.File;
LimitedWebPartManager lwm = page.GetLimitedWebPartManager(PersonalizationScope.Shared);
string xmlWebPart = #"<webParts>...</webParts>";
WebPartDefinition wpd = lwm.ImportWebPart(xmlWebPart);
WebPartDefinition realWpd = lwm.AddWebPart(wpd.WebPart, "wpz", 0);
List targetList = clientContext.Web.GetList("/sites/site/Announcements/");
clientContext.Load(targetList, l => l.Views);
clientContext.Load(realWpd);
clientContext.ExecuteQuery();
string wpId = String.Format("g_{0}", realWpd.Id.ToString().Replace('-', '_'));
if (zone == "wpz")
{
string htmlcontent = String.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contenteditable=\"false\"><div class=\"ms-rtestate-notify ms-rtestate-read {0}\" id=\"div_{0}\"></div><div id=\"vid_{0}\" style=\"display:none;\"></div></div>", new object[] { realWpd.Id.ToString("D") });
string content = item["WikiField"] as string;
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(System.Text.RegularExpressions.Regex.Escape(pattern));
if (position == "before")
{
content = regex.Replace(content, (htmlcontent + pattern), 1);
}
else
{
content = regex.Replace(content, (pattern + htmlcontent), 1);
}
item.Update();
clientContext.ExecuteQuery();
}
}
}
Everything works fine until the last item.Update() and clientContext.ExecuteQuery() are being invoked. Before the Update() the new placeholder gets properly inserted into the WikiField contents. But after the Update() the WikiField contents reverts back to its original state (!)
Note: As an alternative it is possible to add the WP into another zone (eg. "Bottom"). In this case the WP gets displayed on the page. But it has two major drawbacks: The newly created zone is not well formatted and the WP cannot be moved or even deleted.
Thanks for any input on this.
The following example demonstrates how to add web part into Enterprise Wiki page:
public static void AddWebPartIntoWikiPage(ClientContext context, string pageUrl, string webPartXml)
{
var page = context.Web.GetFileByServerRelativeUrl(pageUrl);
var webPartManager = page.GetLimitedWebPartManager(PersonalizationScope.Shared);
var importedWebPart = webPartManager.ImportWebPart(webPartXml);
var webPart = webPartManager.AddWebPart(importedWebPart.WebPart, "wpz", 0);
context.Load(webPart);
context.ExecuteQuery();
string marker = String.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"></div></div>", webPart.Id);
ListItem item = page.ListItemAllFields;
context.Load(item);
context.ExecuteQuery();
item["PublishingPageContent"] = marker;
item.Update();
context.ExecuteQuery();
}
Usage
var webPartXml = System.IO.File.ReadAllText(filePath);
using (var ctx = new ClientContext(webUri))
{
AddWebPartIntoWikiPage(ctx, wikiPageUrl,webPartXml);
}
Result

Content query web part not updating

I built a content by query web part programmatically. The problem is that when I deploy the solution, the web part doesn't update the items automatically. I must go to "edit webpart" and just push ok, nothing more. Then it updates and I can see my items. I have tried using UseCatch = false, as you can see in my code below, but it's not working:
public void contentQuery(SPWeb web, SPList list)
{
ContentByQueryWebPart queryWP = new ContentByQueryWebPart();
//Properties
queryWP.Title = "Aktuella Dokument";
queryWP.ChromeType = PartChromeType.TitleAndBorder;
//Query from list
queryWP.ListName = list.ID.ToString("B").ToUpper();
queryWP.ListGuid = list.ID.ToString("B").ToUpper();
queryWP.WebUrl = web.ServerRelativeUrl;
//Query field
SPField fieldToQuery = list.Fields.GetFieldByInternalName("Aktuellt");
string fieldAsString = fieldToQuery.ToString();
string FieldValue = fieldToQuery.DefaultValue;
//queryWP.ListsOverride = fieldAsString;
queryWP.AdditionalFilterFields = fieldAsString;
queryWP.FilterField1 = fieldAsString;
queryWP.FilterOperator1 = ContentByQueryWebPart.FilterFieldQueryOperator.Eq;
queryWP.FilterValue1 = FieldValue;
queryWP.InitialAsyncDataFetch = true;
queryWP.UseCache = false;
AddWebPart(queryWP, web, "TopColumnZone", 0);
}

Bast Way On Passing Query Parameters to Solrnet

I have been working on making a Search using Solrnet which is working the way I want to. But I just would like some advice on the best way to pass my query parameters from my web page into Solrnet.
What I would ideally like to do is pass my query string parameters similar to how this site does it: http://www.watchfinder.co.uk/SearchResults.aspx?q=%3a&f_brand=Rolex&f_bracelets=Steel&f_movements=Automatic.
As you can see from the sites query string it looks like it is being passed into SolrNet directly. Here is I am doing it at the moment (facet query segment):
public class SoftwareSalesSearcher
{
public static SoftwareSalesSearchResults Facet()
{
ISolrOperations solr = SolrOperationsCache.GetSolrOperations(ConfigurationManager.AppSettings["SolrUrl"]);
//Iterate through querystring to get the required fields to query Solrnet
List queryCollection = new List();
foreach (string key in HttpContext.Current.Request.QueryString.Keys)
{
queryCollection.Add(new SolrQuery(String.Format("{0}:{1}", key, HttpContext.Current.Request.QueryString[key])));
}
var lessThan25 = new SolrQueryByRange("SoftwareSales", 0m, 25m);
var moreThan25 = new SolrQueryByRange("SoftwareSales", 26m, 50m);
var moreThan50 = new SolrQueryByRange("SoftwareSales", 51m, 75m);
var moreThan75 = new SolrQueryByRange("SoftwareSales", 76m, 100m);
QueryOptions options = new QueryOptions
{
Rows = 0,
Facet = new FacetParameters {
Queries = new[] { new SolrFacetQuery(lessThan25), new SolrFacetQuery(moreThan25), new SolrFacetQuery(moreThan50), new SolrFacetQuery(moreThan75) }
},
FilterQueries = queryCollection.ToArray()
};
var results = solr.Query(SolrQuery.All, options);
var searchResults = new SoftwareSalesSearchResults();
List softwareSalesInformation = new List();
foreach (var facet in results.FacetQueries)
{
if (facet.Value != 0)
{
SoftwareSalesFacetDetail salesItem = new SoftwareSalesFacetDetail();
salesItem.Price = facet.Key;
salesItem.Value = facet.Value;
softwareSalesInformation.Add(salesItem);
}
}
searchResults.Results = softwareSalesInformation;
searchResults.TotalResults = results.NumFound;
searchResults.QueryTime = results.Header.QTime;
return searchResults;
}
}
At the moment I can't seem to see how I can query all my results from my current code by add the following querystring: q=:.
I'm not sure what you mean by "parameters being passed into SolrNet directly". It seems that watchfinder is using some variant of the model binder included in the SolrNet sample app.
Also take a look at the controller in the sample app to see how the SolrNet parameters are built.

How to get Sharepoint User object from the "AssignedTo" field using client side object model?

I am using managed client side object model in sharepoint 2010. And I want to get loginaName of the AssignedTo user in Task list.
In server side object model I use SPFieldUserValue.User.LoginName to get this property but in client side object model FieldUserValue.User does not exists.
How can I resolve this situation ?
Thanks
Here is the code for that. I've taken an example of AssignedTo field from Task list. I hope that helps.
public static User GetUserFromAssignedToField(string siteUrl)
{
// create site context
ClientContext ctx = new ClientContext(siteUrl);
// create web object
Web web = ctx.Web;
ctx.Load(web);
// get Tasks list
List list = ctx.Web.Lists.GetByTitle("Tasks");
ctx.Load(list);
// get list item using Id e.g. updating first item in the list
ListItem targetListItem = list.GetItemById(1);
// Load only the assigned to field from the list item
ctx.Load(targetListItem,
item => item["AssignedTo"]);
ctx.ExecuteQuery();
// create and cast the FieldUserValue from the value
FieldUserValue fuv = (FieldUserValue)targetListItem["AssignedTo"];
Console.WriteLine("Request succeeded. \n\n");
Console.WriteLine("Retrieved user Id is: {0}", fuv.LookupId);
Console.WriteLine("Retrieved login name is: {0}", fuv.LookupValue);
User user = ctx.Web.EnsureUser(fuv.LookupValue);
ctx.Load(user);
ctx.ExecuteQuery();
// display the user's email address.
Consol.writeLine("User Email: " + user.Email);
return user;
}
The fuv.LookupValue may contain the display name, not the login name, so my suggestion is (assuming you have the FieldUserValue - fuv in code (as descibed by #ekhanna):
var userId = fuv.LookupId;
var user = ctx.Web.GetUserById(userId);
ctx.Load(user);
ctx.ExecuteQuery();
You get the column which as the FieldUserValue from the list, once you have that you use the lookup id value and then query against the Sites User Info List. In the example below I cache the results to prevent looking up the same id more than once since the query can be expensive.
private readonly Dictionary<int, string> userNameCache = new Dictionary<int, string>();
public string GetUserName(object user)
{
if (user == null)
{
return string.Empty;
}
var username = string.Empty;
var spUser = user as FieldUserValue;
if (spUser != null)
{
if (!userNameCache.TryGetValue(spUser.LookupId, out username))
{
var userInfoList = context.Web.SiteUserInfoList;
context.Load(userInfoList);
var query = new CamlQuery { ViewXml = "<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='ID' /><Value Type='int'>" + spUser.LookupId + "</Value></Eq></Where></Query></View>" };
var users = userInfoList.GetItems(query);
context.Load(users, items => items.Include(
item => item.Id,
item => item["Name"]));
if (context.TryExecuteQuery())
{
var principal = users.GetById(spUser.LookupId);
context.Load(principal);
context.ExecuteQuery()
username = principal["Name"] as string;
userNameCache.Add(spUser.LookupId, username);
}
}
}
return username;
}
Everything above worked for me, but instead of:
FieldUserValue fuv = (FieldUserValue)targetListItem["AssignedTo"];
I used:
FieldUserValue[] fuv = targetListItem["AssignedTo"] as FieldUserValue[];

Programmatically set a TaxonomyField on a list item

The situation:
I have a bunch of Terms in the Term Store and a list that uses them.
A lot of the terms have not been used yet, and are not available yet in the TaxonomyHiddenList.
If they are not there yet they don't have an ID, and I can not add them to a list item.
There is a method GetWSSIdOfTerm on Microsoft.SharePoint.Taxonomy.TaxonomyField that's supposed to return the ID of a term for a specific site.
This gives back IDs if the term has already been used and is present in the TaxonomyHiddenList, but if it's not then 0 is returned.
Is there any way to programmatically add terms to the TaxonomyHiddenList or force it happening?
Don't use
TaxonomyFieldValue tagValue = new TaxonomyFieldValue(termString);
myItem[tagsFieldName] = tagValue;"
because you will have errors when you want to crawl this item.
For setting value in a taxonomy field, you have just to use :
tagsField.SetFieldValue(myItem , myTerm);
myItem.Update();"
Regards
In case of usage
string termString = String.Concat(myTerm.GetDefaultLabel(1033),
TaxonomyField.TaxonomyGuidLabelDelimiter, myTerm.Id);
then during instantiation TaxonomyFieldValue
TaxonomyFieldValue tagValue = new TaxonomyFieldValue(termString);
exception will be thrown with message
Value does not fall within the expected range
You have additionally provide WssId to construct term string like shown below
// We don't know the WssId so default to -1
string termString = String.Concat("-1;#",myTerm.GetDefaultLabel(1033),
TaxonomyField.TaxonomyGuidLabelDelimiter, myTerm.Id);
On MSDN you can find how to create a Term and add it to TermSet. Sample is provided from TermSetItem class description. TermSet should have a method CreateTerm(name, lcid) inherited from TermSetItem. Therefore you can use it in the sample below int catch statement ie:
catch(...)
{
myTerm = termSet.CreateTerm(myTerm, 1030);
termStore.CommitAll();
}
As for assigning term to list, this code should work (i'm not sure about the name of the field "Tags", however it's easy to find out the proper internal name of the taxonomy field):
using (SPSite site = new SPSite("http://myUrl"))
{
using (SPWeb web = site.OpenWeb())
{
string tagsFieldName = "Tags";
string myListName = "MyList";
string myTermName = "myTerm";
SPListItem myItem = web.Lists[myListName].GetItemById(1);
TaxonomyField tagsField = (TaxonomyField) myList.Fields[tagsFieldName];
TaxonomySession session = new TaxonomySession(site);
TermStore termStore = session.TermStores[tagsField.SspId];
TermSet termSet = termStore.GetTermSet(tagsField.TermSetId);
Term myTerm = null;
try
{
myTerm = termSet.Terms[myTermName];
}
catch (ArgumentOutOfRangeException)
{
// ?
}
string termString = String.Concat(myTerm.GetDefaultLabel(1033),
TaxonomyField.TaxonomyGuidLabelDelimiter, myTerm.Id);
if (tagsField.AllowMultipleValues)
{
TaxonomyFieldValueCollection tagsValues = new TaxonomyFieldValueCollection(tagsField);
tagsValues.PopulateFromLabelGuidPairs(
String.Join(TaxonomyField.TaxonomyMultipleTermDelimiter.ToString(),
new[] { termString }));
myItem[tagsFieldName] = tagsValues;
}
else
{
TaxonomyFieldValue tagValue = new TaxonomyFieldValue(termString);
myItem[tagsFieldName] = tagValue;
}
myItem.Update();
}
}

Resources