What is the variable that refers to the number of likes on sharepoint 2013? - request

I want to write a request on the search result request webpart. My request should enables me to retrieve all documents that have the biggest number of likes. There is no variable for the number of likes proposed on the drop list while writing a request , that why I decided to set a refinableInt00 variable and give it the value : LikesCount but it doesn't work? it means that LikesCount doesn't exist as a variable on sharepoint so what is the variable on sharepoint that would enable me to have the number of likes?

You can get the number of likes using the listitem property "Number of Likes"
This is a code from a Sample console application
using (SPSite site=new SPSite("your site URL"))
{
using (SPWeb web=site.OpenWeb())
{
SPList list = web.Lists["Your List Name"];
foreach (SPListItem item in list.Items)
{
//Print the number of likes
Console.WriteLine(item["Number of Likes"].ToString());
}
}
}

I know this is old but I had the same question. The problem is the LikesCount property does not default to Sortable. To fix this:
-Open up Central Administration
-Go to Search Service Application
-Click on Search Schema
-Locate the "LikesCount" property and click edit
-Scroll down to Sortable and change to Yes
-Run a full crawl on your content source

Ratings for list must be enable.
List -> List settings -> Rating settings ->
Allow items in this list to be rated?
yes ? no
and
Which voting/rating experience you would like to enable for this list?
Likes ? Star Ratings
After that you can access likes by "Number of Likes" field name "LikesCount".
"Number of Ratings" field name "RatingCount"

Related

How to retrieve Images of a User being part of a Group with Collection Permissions in Wagtail?

I have a wagtail installation using the Multisite pattern, where I have a group of user per site and each group as it's own collection.
When the User logged in the admin interface, they see in the Summary section the image count from all the collections.
But when they click the image menu, they only see the images within their group collection. I found it confusing that they could know the total count of all collections. I wanted to get the count from the collection the user had rights for.
I figured out I could override the ImagesSummaryItem and I ended up coding the following snippet of code:
class CorrectedImagesSummaryItem(SummaryItem):
order = 200
template = 'wagtailimages/homepage/site_summary_images.html'
def get_context(self):
site_name = get_site_for_user(self.request.user)['site_name']
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=['change_image', 'add_image'])
collections = Collection.objects.filter(
group_permissions__group__in=self.request.user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
if collections:
image_count = get_image_model().objects.filter(collection__in=collections).count()
else:
image_count = 0
return {
'total_images': image_count,
'site_name': site_name,
}
def is_shown(self):
return permission_policy.user_has_any_permission(
self.request.user, ['change', 'add']
)
#hooks.register('construct_homepage_summary_items')
def add_corrected_images_summary_panel(request, items):
"""Replaces the Images summary panel to hide variants."""
for index, item in enumerate(items):
if item.__class__ is ImagesSummaryItem:
items[index] = CorrectedImagesSummaryItem(request)
This actually works fine, I am now showing the proper images count on the summary section but I am wondering is there a better way to query the collections of the user? Are these querysets right?
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=['change_image', 'add_image'])
collections = Collection.objects.filter(
group_permissions__group__in=self.request.user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
Update
I ended up customizing the queryset for the images selection in order to only show the images within the collection the user was having access to.
In addition of the first function, I added the following code in my wagtail_hooks.py file.
#hooks.register('construct_image_chooser_queryset')
def show_collection_images_only(images, request):
# Show only the images from the collection the User has access.
collections = get_collections_from_group_permissions(request.user, ['change_image', 'add_image'])
images = images.filter(collection__in=collections)
return images
The get_collections_from_group_permissions is just a simplified function that returns exactly the Collection out of the Groups permissions the User has.
def get_collections_from_group_permissions(user, permissions):
"""
This function gets the Collections from the user groups permissions.
:param user: the user
:param permissions: the requested permissions on a Collection object
:returns: the Collections the selected User has access rights for.
"""
permissions = Permission.objects.filter(
content_type=ContentType.objects.get_for_model(get_image_model()),
codename__in=permissions)
collections = Collection.objects.filter(
group_permissions__group__in=user.groups.all(),
group_permissions__permission__in=permissions
).distinct()
return collections
With this in place, the Summary Item for the images is the number of images within the collections the User can access and when he clicks on a ImageChooserField and gets to the Image chooser, he only gets to see what is in the collections he has been granted access.
This logic is already implemented in Wagtail's permission_policy class, so this could be reduced to:
image_count = permission_policy.instances_user_has_any_permission_for(
self.request.user, ['change', 'add']
).count()
(Incidentally, the reason Wagtail itself doesn't take permissions into account when displaying this figure is that all users can see the complete set of images via the chooser popup - there's currently no 'choose' permission - so showing a reduced number would be misleading. See the discussion at https://github.com/wagtail/wagtail/issues/5129)

Question: What is the best DB structure when adding follow/followers feature?

I have an app with the following DB structure currently, it uses Firebase Database and is on Swift IOS:
"Posts" : {
"Dm8iyaXXdTOJGsymEiLNVO6OdDK2" : {
"post:570915537" : {
"Media" : {
"image" : {
"mediaUrl" : "https://firebaseURL",
"postTimeStamp" : 5.70915539085856E8,
"timeStamp" : 5.7091551482329E8
}, ...
I was now going to add followers to it. I was thinking that I would either add a whole new group:
"Followers" : {
"Dm8iyaXXdTOJGsymEiLNVO6OdDK2" : {
"Following" : {
follower1: "Dm8iyaXXdTOJGsymEiLNVO6OdDK2";
//other followers
}, ...
Or add a new node to the original group and add them there. The last option is to do something similar to what is done above but in the "Users" section.
What is the best course of action?
A follow/unfollow schema using Firestore could be this one:
2 roots collections, one that holds users and another one that holds the following relationship between users through a composite key.
users/{userID}
.. userData
.. followerCount
.. followedCount
following/{followerID_followedID}
.. followerId
.. followedId
.. createdAt
When a userA starts to follow a userB:
set a new document with the id userAuid_userBuid in the
following collection.
triggers a Cloud Function that will run a transaction to update the
counters of both users.
Do the reverse thing when a user stops to follow another user.
In the client, you can know if userA follows userB simply by checking if the document userAuid_userBuid exists inside the following collection.
You can also get the list of a user's followers by querying the collection where the followedId == the current user Id.
Hope that helps you.

"Related Content" stored in which object / How to create "Related Content" records from Apex

If you navigate to account/contact/custom object we do have a related list "related content" (if content is enabled and related list is added to page layout).
My question is were are these "related content" records stored? in which object?
Using apex I'm able to upload file to content version, but not able to create or find the object which stores the "related content" information.
UPDATE
Tried to create a link to show up in "related content" section of account, but no success. Got error " Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, You cannot create a link for this type of entity through the api: [LinkedEntityId]"
Any idea?
ContentVersion cv = new ContentVersion(
versionData = EncodingUtil.Base64Decode(base64BlobValue),
Title = fileName,
PathOnClient = '/'+fileName,
FirstPublishLocationId = '058900000009KcL'
);
insert cv;
//fetch ContentDocumentId
cv = [Select Id,ContentDocumentId from ContentVersion where Id = :cv.Id];
insert new ContentDocumentLink(LinkedEntityId=parentId,ContentDocumentId=cv.ContentDocumentId,ShareType='V');
** USE CASE **
The use case is to allow user to attach content right from object detail page for eg say Account will have button say Attach Content, this will bring upload content page, once uploaded (i will create contentversion records - this is happening perfectly, no errors) and then I need to relate the uploaded content to account (from which request orginated) ie create "related content" records (here I'm facing difficulty, trying to create contentdocumentlink records but its erroring out).
The use case is just one click to attach content to account or opportunity instead of long current process were user goes to content, uploads there first and then comes back to account/opty and searches content again, and then attaches it to account/contact.
As you know the content is stored in the ContentDocument object and the links are stored in the ContentDocumentLink table.
I find that the http://workbench.developerforce.com really useful for figuring out these kinds of relationships.
See the ContentDocumentLink specification in the user docs, LinkedEntityId represents:
ID of the linked object. Can include Chatter users, groups, records
(any that support Chatter feed tracking including custom objects),
and Salesforce CRM Content libraries.
I'm thinking that based on that explanation, you can only create the ContentDocumentLink for Chatter based object fields, not for regular sObject records or custom sobjects, etc.

Adding a 1 to many file upload to CRUD

My app has sales listing functionality that will allow the user to add 1 or more photos for the product that they want to sell.
I'm attempting to use the upload/filestore_image of ATK with a Join table to create the relationship - my models:
class Model_Listing extends Model_Table {
public $entity_code='listing';
function init(){
parent::init();
$this->addField('name');
$this->addField('body')->type('text');
$this->addField('status');
$this->addField('showStatus')->calculated(true);
}
function calculate_showStatus(){
return ($this->status == 1) ? "Sold" : "For Sale" ;
}
}
class Model_listingimages extends Model_Table {
public $entity_code='listing_images';
function init(){
parent::init();
$this->addField('listing_id')->refModel('Model_Listing');
$this->addField('filestore_image_id')->refModel('Model_Filestore_Image');
}
}
In my page manager class I have added the file upload to the crud:
class page_manager extends Page {
function init(){
parent::init();
$tabs=$this->add('Tabs');
$s = $tabs->addTab('Sales')->add('CRUD');
$s->setModel('Listing',array('name','body','status'),array('name','status'));
if ($s->form) {
$f = $s->form;
$f->addField('upload','Add Photos')->setModel('Filestore_Image');
$f->add('FileGrid')->setModel('Filestore_Image');
}
}
}
My questions:
I am getting a "Unable to include FileGrid.php" error - I want the user to be able to see the images that they have uploaded and hoped that this would be the best way to do so - by adding the file grid to bottom of the form. - EDIT - ignore this question, I created a FileGrid class based on the code in the example link below - that fixed the issue.
How do I make the association between the CRUD form so that a submit will save the uploaded files and create entries in the join table?
I have installed the latest release of ATK4, added the 4 filestore tables to the db and referenced the following page in the documentation http://codepad.agiletoolkit.org/image
TIA
PG
By creating model based on Filestore_File
You need to specify a proper model. By proper I mean:
It must be extending Model_Filestore_File
It must have MasterField set to link it with your entry
In this case, however you must know the referenced ID when the images are being uploaded, so it won't work if you upload image before creating record. Just to give you idea the code would look
$mymodel=$this->add('Model_listingimages');
$mymodel->setMasterField('listing_id',$listing_id);
$upload_field->setModel($mymodel);
$upload_field->allowMultiple();
This way all the images uploaded through the field will automatically be associated with your listing. You will need to inherit model from Model_Filestore_File. The Model_Filestore_Image is a really great example which you can use. You should add related entity (join) and define fields in that table.
There is other way too:
By doing some extra work in linking images
When form is submitted, you can retrieve list of file IDs by simply getting them.
$form->get('add_photos')
Inside form submission handler you can perform some manual insertion into listingimages.
$form->onSubmit(function($form) uses($listing_id){
$photos = explode(',',$form->get('add_photos'));
$m=$form->add('Model_listingimages');
foreach($photos as $photo_id){
$m->unloadDdata()->set('listing_id',$listing_id)
->set('filestore_image_id',$photo_id)->update();
}
}); // I'm not sure if this will be called by CRUD, which has
// it's own form submit handler, but give it a try.
You must be careful, through, if you use global model inside the upload field without restrictions, then user can access or delete images uploaded by other users. If you use file model with MVCGrid you should see what files they can theoretically get access to. That's normal and that's why I recommend using the first method described above.
NOTE: you should not use spaces in file name, 2nd argument to addField, it breaks javascript.

Favoriting system on Appengine

I have the following model structure
class User(db.Model) :
nickname = db.StringProperty(required=True)
fullname = db.StringProperty(required=True)
class Article(db.Model) :
title = db.StringProperty(required=True)
body = db.StringProperty(required=True)
author = db.ReferenceProperty(User, required=True)
class Favorite(db.Model) :
who = db.ReferenceProperty(User, required=True)
what = db.ReferenceProperty(Article, required=True)
I'd like to display 10 last articles according to this pattern: article.title, article.body, article.author(nickname), info if this article has been already favorited by the signed in user.
I have added a function which I use to get the authors of these articles using only one query (it is described here)
But I don't know what to do with the favorites (I'd like to know which of the displayed articles have been favorited by me using less than 10 queries (I want to display 10 articles)). Is it possible?
You can actually do this with an amortized cost of 0 queries if you denormalize your data more! Add a favorites property to Authors which stores a list of keys of articles which the user has favorited. Then you can determine if the article is the user's favorite by simply checking this list.
If you retrieve this list of favorites when the user first logs in and just store it in your user's session data (and update it when the user adds/removes a favorite), then you won't have to query the datastore to check to see if an item is a favorite.
Suggested update to the Authors model:
class Authors(db.Model): # I think this would be better named "User"
# same properties you already had ...
favorites = db.ListProperty(db.Key, required=True, default=[])
When the user logs in, just cache their list of favorites in your session data:
session['favs'] = user.favorites
Then when you show the latest articles, you can check if they are a favorite just by seeing if each article's key is in the favorites list you cached already (or you could dynamically query the favorites list but there is really no need to).
favs = session['favs']
articles = get_ten_latest_articles()
for article in articles:
if article.key() in favs:
# ...
I think there is one more solution.
Let's add 'auto increment' fields to the User and Article class.
Then, when we want to add an entry to the Favorite class, we will also add the key name in the format which we will be able to know having auto increment value of the signed in user and the article, like this 'UserId'+id_of_the_user+'ArticleId'+id_of_an_article.
Then, when it comes to display, we will easily predict key names of the favorites and would be able to use Favorite.get_by_key_name(key_names).
An alternative solution to dound's is to store the publication date of the favorited article on the Favorite entry. Then, simply sort by that when querying.

Resources