Along with the thumbnail photo, I may want to display other properties in my master pages that are imported from AD such as "company" using User Profile sync
If I use SPServices.SPGetCurrentUser() (https://spservices.codeplex.com/documentation), I can get selected properties held in user profile settings. However, I can't make this call since the property does not exist here (yet).
var company = $().SPServices.SPGetCurrentUser({
fieldName: "Company",
debug: false
});
It is however, is displayed both in http://mysite.mydomain.com/_layouts/EditProfile.aspx when in Mysite and _layouts/ProfAdminEdit.aspx (Edit user properties in Central Admin). I guess my question is then to be able to use SPServices, do I somehow edit the default properties and include my "Company" attribute held in the user' mysite profile? Alternatively, is there another way to access the properties held in the user profile with JavaScript ?
Thanks
Daniel
$().SPServices.SPGetCurrentUser calls this page : http://you.site.com/_layouts/userdisp.aspx?Force=True&1376982818371. For me the function is not able to parse the page correctly, but you could simply use jQuery (or pure JS or whatever) to get by yourself the same page, and then parse it to find the data you want.
Otherwise you can use $SP().people() to query the User Profile Service and gets the info for the user. See the example from the provided link. In theory that should return you the same information or even more info.
Related
We want to display customer (actually customer-group) specific information on product detail pages in Shopware 6.
There seems to be the HTTP cache and we are afraid that the page would be cached if a specific customer group displays the page and the information would be leaked to non-customers.
Is this assumption correct?
The documentation does not reveal much information about this.
Is there a way to set specific cache tags, so that the information is only displayed to the correct customer group?
Or do we need to fetch the data dynamically via AJAX?
Bonus question: Can the HTTP cache be simulated in automatic tests to ensure the functionality works?
What I found out so far:
The is annotation #httpCache for controller, which seems to control whether a page is cached or not
The cache key is generated in \Shopware\Storefront\Framework\Cache\HttpCacheKeyGenerator::generate. It take the full request URI into account, and some cacheHash which is injected. I believe it would not take the customer group into account
Maybe this generate() method could be decorated, but I am not sure if that is the right way.
There is a cookie being set sw-cache-hash which influences the caching. It takes the customer into account.
sw-cache-hash is created here:
if ($context->getCustomer() || $cart->getLineItems()->count() > 0) {
$cookie = Cookie::create(self::CONTEXT_CACHE_COOKIE, $this->buildCacheHash($context));
$cookie->setSecureDefault($request->isSecure());
$response->headers->setCookie($cookie);
} else {
$response->headers->removeCookie(self::CONTEXT_CACHE_COOKIE);
$response->headers->clearCookie(self::CONTEXT_CACHE_COOKIE);
}
So as soon you are logged in or have some items in the cart, a different cache hash is used. This depends on the following, but not on the customer group it self:
private function buildCacheHash(SalesChannelContext $context): string
{
return md5(json_encode([
$context->getRuleIds(),
$context->getContext()->getVersionId(),
$context->getCurrency()->getId(),
]));
}
Additionally there is the notion of cache-invalidation states, that describe when the caching should not be used.
You can configure that inside the shopware.yaml config file for the http-cache as a whole or on route level for the store-api routes.
From the default config inside platform:
shopware:
cache:
invalidation:
http_cache: ['logged-in', 'cart-filled']
product_listing_route: []
As you can see by default the http-cache won't be used if a user logs in or has something in his cart.
As you can see in the last code snippet, it takes into account the active Rule ids.
This means that if you create a rule (through Settings > Rule Builder) that is active on a certain group, but not on another or no group, it will be taken into account & create a different cache hash for the different customer groups.
I'm trying to retrieve a document library by path using the Graph API and I'm not sure how to proceed.
The url to the library is for example the following:
https://hostname/sites/sitename/subsite/nameofdocumentlibrary/
I would like to have all the children through the Graph API. The issue: I know the document of the library but I don't know the ID of the library. It seems that it's possible to access it through the relative path but I'm not succeeding to it.
How do I do this?
My get url was the following:
/v1.0/sites/hostname:/sites/sitename/subsite/nameofdoccumentlibary/items
I'm always getting:
The provided path does not exist, or does not represent a site or UnknownError.
Any ideas ?
Try to use this:
GET https://graph.microsoft.com/v1.0/sites/{hostname},{spsite-id},{spweb-id}/lists/{list-id}
I don't check this in real life because I don't have SP Online. But it must working.
Use this link with SharePoint Graph API.
To get site id (site collection) you can go to your site collection and browse this endpoint:
https://hostname/sites/sitename/_api/site?$select=Id
To get web id (subsite) you can go to your subsite and browse this endpoint:
https://hostname/sites/sitename/subsite/_api/web?$select=Id
To get library Id you can just open Document Library Settings page. URL have library ID. You can transform it to real guid. Like this:
/_layouts/15/listedit.aspx?List=%7B603D7FA3-C801-46EB-A044-421234452901%7D
Must transformed to:
603D7FA3-C801-46EB-A044-421234452901
Following your feedback, I could now retrieve the document library using the display name (not the path in the url).
This is my request:
https://graph.microsoft.com/v1.0/sites/fullsubsiteid/lists/69369/items
69369 is my display Name here.
I can also use:
https://graph.microsoft.com/v1.0/sites/fullsubsiteid/lists/69369/drive
Now the first request, is returning an empty value array, while there is a "Documents" folder in the document library. How could I retrieve all folders/files etc in this document library? How can I use relative path?
Tx!
This has really been bugging me for some time so any help to confirm or affirm this is much appreciated! This is also the first time I actually post a question despite being developing for a long time :)
So I have a nodejs app integrating with the Google Drive API and I want users to authorize multiple Google Drive accounts and be able to view and open (and in general just interact with) all files from the accounts that they add.
I authorize my app using the highest available scope: https://www.googleapis.com/auth/drive and because I don't want users to have to sign-in again when the access_token runs out so I also include the approval_prompt: "force" and ``access_type: "offline"` when I request my access tokens.
Everything is fine - I authorize nicely, I can delete files, I can open them, I can share them, I can download them. Except for one thing:
If I e.g. authorize horse#gmail.com and then beaver#gmail.com. Then I can still delete, share, download and preview files from both accounts. But I simply cannot open documents from horse#gmail.com in google docs for editing (because beaver#gmail.com is signed in on my local machine). The best I can do is getting to a point where it shows me the document, with the right account logged in in the top right corner of the screen, but asks me to sign-in with a button. When I click the button it just refreshes and give me the same message and the same screen.
What I've tried is:
Simply redirecting the user to the file resources alternateLink from the API
Taking the alternateLink and appending my access_token to it and then redirect the user to it.
(and a ton of other random things I found various places that didn't work).
In both cases I have also tried signing out from all google accounts.
Now I checked a couple of webservices like Jollicloud and Odrive that tries something similar. However, both of them appear to force the user to login to google to access a file.
Is it really true that you can do all kinds of crazy things with the users files like deleting and downloading, but you can't open them in Google Docs own apps?
Not completely sure what kind of code I should add to show you what I've got. But here's some. This is my open action (what happens when the user clicks on a file and wants to open the file in the Google Docs/Sheet/etc.) (the orientdb stuff is because we're using the OrientDB graph database - it just fetches an account where we store the tokens). The link is the link property of the file (see below):
open: function(req,res,next){
var link = req.param("link");
var uid = req.param("uid");
orientdb.select().from('Account').where({uid: uid}).one()
.then(function(account){
var URL = link + "&access_token=" + account.tokens.access_token;
res.redirect(URL);
});
}
Here's an example file document from our database (I've replaced all compromising data with a descriptive
ODocument - Class: File id: #13:20499 v.6
name : Hummer2
service : Gdrive
kind : Google Doc
created : Nov 17, 2014
changed : Nov 17, 2014
users : [MB]
uid : mrb#flowtale.com
childID : <FILE.ID>
exportLinks : {DOCX=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=docx, Open Office doc=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=odt, Rich text=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=rtf, HTML=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=html, Plain text=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=txt, PDF=https://docs.google.com/feeds/download/documents/export/Export?id=<FILE.ID>&exportFormat=pdf}
usernames : [<ARRAY OF USERNAMES ASSOCIATED WITH THIS FILE>]
in_hasFile : User#11:0{out_hasFile:[size=2237],out_hasAccount:[size=4],username:null,email:h#h.com,password:<SOME ENCRYPTED PASSWORD>} v2244
out_belongsTo : Account#12:3{in_belongsTo:[size=6],type:Gdrive,uid:<SOME UID>,tokens:{access_token=<OUR ACCOUNT ACCESS TOKEN>, token_type=Bearer, refresh_token=<OUR ACCOUNT REFRESH TOKEN>, expiry_date=1416258913290},rootFolderID:<ROOT FOLDER ID>,email:<THE ACCOUNT EMAIL>,filesCached:2,usersCached:2,job:4,in_hasAccount:#11:0} v15
in_folderContains : File#13:20495{out_folderContains:[size=2],name:Testhest,service:Gdrive,kind:folder,created:Oct 12, 2014,changed:Oct 12, 2014,users:[1],link:https://docs.google.com/a/flowtale.com/folderview?id=<FOLDER.ID>&usp=drivesdk,uid:mrb#flowtale.com,childID:<FOLDER.ID>,exportLinks:{},usernames:[1],parents:[1],in_hasFile:#11:0,out_belongsTo:#12:3,in_folderContains:#13:13891} v36
link : https://docs.google.com/a/flowtale.com/document/d/<FILE.ID>/edit?usp=drivesdk
Looking forward to hear if anybody can help me or have experienced this before.
Thanks!
The API will allow you to do several actions in your drive account. I haven't been able to reproduce the behavior you mention with files that I haven't granted permissions to another account.
When you authenticate through the OAuth process, you will grant access to your account only to the application which created the OAuth request. You can not edit the content of a file without manually opening it through GDocs. Therefore, when the browser opens the AlternateUrl, it will require you to login to the account, in order to access the file.
I am very new to liferay. Please help me implementing the below requirement.
Using Document and media portlet in liferay, If any new document is uploaded or uploaded document is modified(Version changed) by admin user, then
How can i identify that the particular document is modified or newly uploaded as i have to show a popup message to user based upon if any new files is uploaded or modified after log on.
That is not a little change request - this required bit more development. And here is more different variants:
Simple but nonperformance variant:
With UserLocalServiceUtil you can check the last user-login date
Similarly iterate over all documents and check last modification date
Create Liferay-Portlet that shows the list of documents with modification date after last user-login date
~
Here are the steps:
Use corresponding Document Listener i.e
DlFolderListener or DlFileEntryListener. You have to use hook to
add your listner in portal.properties.
For Example, you would need to workaround below property.
value.object.listener.com.liferay.portlet.documentlibrary.model.FileEntry
= com.my.custom.MyFileEntryListener
This class would be extending BaseModelListener<FileEntry>
Override and use onAfterUpdate method to notify appropriate audience
(users).
Now this can be done by setting this notification in user
preferences.
On user Login, check corresponding user preferences for this
notification and notify user. You can use hook LoginPostAction to read user preferences for notification.
Hope this helps.
Create customfield for user. Create table with service builder to store the fileEntry Id which modified.
Create DLFileEntry Listener and write
code on FileUpdate. Add DLFileEntryID in same table created in step 1. Set
custom field true for all the user.
Create LoginPostActionHook and on Check the user's flag and fetch the FileEntryId get info of that fileEntryId and display notification with all file's information. Set customfield Flag false for particular user and remove the fileentryid from table or mark them all as read.
I found this library for creating an ACL (access control list) for mongoose:
https://github.com/scttnlsn/mongoose-acl
It looks like a good module, but I'm a little confused on how to use it for my purpose.
I have a site where anybody (logged in or not) can visit a profile page, like example.com/users/chovy
However if the user 'chovy' is logged into this page, I want to give them admin privileges for editing the details of the account.
If the user is not 'chovy' or is not logged in, they would just see the read-only profile page for 'chovy'.
Can someone give me a concrete example of how I would do this?
That sounds so common, that I don't think you need an ACL. You will need to have sessions, and then you can change how the view looks based upon the current logged in user. An incomplete example would like like this:
// Assumes:
// - You set req.session.user when user logs in
// - The url route has a :name so you can do req.param() to get the name of the page being viewed
db.users.getCurrentUser(req.session.user, gotLoggedInUser)
db.users.getUserByName({name: req.param('name')}, gotUser)
And then pass this to the view, when you do a res.render():
var is_viewing_own_page = currentUser._id.toString() === loggedInUser._id.toString()
And then the view can do something like this (assuming jade):
- if (is_viewing_own_page)
div You are looking at your own page
- else
div You are viewing someone else's page