we are working on orchard, we need to create a activity feed of users,means all the activities of users like updations,deletions, or insertions of their details neddto be shownas they did in their home page. how to create custom activity feed using orchard cms? or is there any existing design for that ?
You can intercept "activities" on user details by creating a content handler for the UserPart like so
public class MyHandler : Orchard.ContentManagement.Handlers.ContentHandler
{
// public
public MyHandler()
{
// listen to user events
OnPublishing<Orchard.Users.Models.UserPart>(UserPublishing);
OnRemoving<Orchard.Users.Models.UserPart>(UserRemoving);
...
}
// private
private void UserPublishing(Orchard.ContentManagement.Handlers.PublishContentContext aContext, Orchard.Users.Models.UserPart aUserPart)
{
// do some stuff on user publishing
}
private void UserRemoving(Orchard.ContentManagement.Handlers.RemoveContentContext aContext, Orchard.Users.Models.UserPart aUserPart)
{
// do some stuff on user removal
}
...
}
Extensive documentation can be found here:
http://docs.orchardproject.net/en/latest/Documentation/Understanding-content-handlers/
There is also a module called Orchard Audit which seems to record user activities:
http://gallery.orchardproject.net/Packages/Orchard.Module.Downplay.Audit
Related
I have entity which does have MyUser author; attribute. I use also this class in custom authorization process to create MyUserPrincipal instance. (I have taken inspiration from Callicoder blog post and repository.)
Snippet of logging procedure part:
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
#Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
// He I use myUserRepository, to load MyUser instance and than return MyUserPrincipal which implements OAuth2User, UserDetails...
}
}
Now I have repository for Book entity for example. Book can look like this:
#Entity
#Getters // project lombook magic here
#Setters
public class Book {
private MyUser author;
private String title;
}
I can create new resource using POST request to http://localhost/api/books with data like this:
{
"author":"api/authors/42",
"title":"stackoverflow forever"
}
My question: Is it possible to easily (without custom controller) make use of "authentication.principal.userId" from SecurityContext to fill in author ow newly created resource/entiry? I would like to forbid for user of my API to send author field at all.
Well, I don't know what you mean by "custom controller", but the #RestController behind your /api/books URI can make use of #AuthenticationPrincipal. Then you don't have to send in your author id anymore, if it is part of MyUserPrincipal.
#PostMapping("/api/books")
public SomeDTO saveBook(#AuthenticationPrincipal MyUserPrincipal principal) {
if (principal != null) { // user is logged in and not e.g. anonymous
// principal.getId(); use this to save your book
}
}
When i call my admin controller- Index Action method will get all the user details
when i want select particular user again i dont want to hit the DB.
both action method same controller and i'm using model popup for display details.
My Question
I dont want to use entity framework.
- when admin form load i will get all the user details this is Index Action Method
-based on user id i need to display particular user so again i dont want hit to the DB already i'm having all the user details. that details how to get another action method?
i can remember asp.net i used session to share the data globally. like that asp.net mvc is possible? please help me.
Thanks
It looks you're looking for a cache mechanism. For simple scenarios, I use a simple static variable, but I keep it in a separated class. Let's suppose you have a User class like this:
public class User
{
public string Id { get; set; }
public string Name { get; set; }
}
You could create a class like this:
public static class UserCacheService
{
private static IEnumerable<User> _users;
private static readonly object lockObj = new object();
public static IEnumerable<User> GetUsers()
{
lock (lockObj)
{
if (_users == null)
{
using (var db = new MyNiceDbContext())
{
_users = db.Users.ToList();
}
}
return _users;
}
}
public static void InvalidateCache()
{
lock (lockObj)
{
_users = null;
}
}
}
Then you can get your shared users in any action, of any controller like this:
public class AdminController : Controller
{
public ActionResult Index()
{
// the first time, it'll need to get users from DB (e.g with Entity Framework)
var users = UserCacheService.GetUsers();
return View();
}
}
The first time, the _users in your UserCacheService will be null, and as expected, it'll need to load users from database. However, the next time it won't, no matter if you are using another controller:
public class AnotherController : Controller
{
public ActionResult Index(string userId)
{
// now, it won't load from DB anymore, because _users is already populated...
var users = UserCacheService.GetUsers();
var currentUser = users.Where(u => u.Id == userId).FirstOrDefault();
if (currentUser != null)
{
// do something with the user...
}
return View();
}
}
There are times when unfortunately your _users will become null again, for example when you restart your ApplicationPool in IIS, but UserCacheService is already prepared for fetching database once if that's the case.
Be careful about three things:
Whenever you keep data in memory (like _users), you are consuming
your server's memory, which might be limited. Don't start trying to
keep everything in memory, only data you know you'll need everytime.
Whenever you update something in your users, like a name, an address or something else, since the _users will not get from database everytime, you need to call the UserCacheService.InvalidateCache() method, in order to force the next call to load again from database, thus making sure you have _users up to date.
This only works for simplistic scenarios. If you have your application distributed in two or more servers, this won't work, as each server has it's own memory and they can't share it out of the box. That's when you would look forward for something like Redis. Though, I don't think it's your case here.
I have a gwt and grails legacy app that I'm upgrading and modifying.. Its a reservation calendar basically with different "views".. the problem I'm having is I want the user to be able to choose a default view for themselves upon logging in..I've done this with a grails only application before but gwt is much different..how can I pass something from config.groovy to the gwt part that select which view to show..and this view isn't a view like a grails view..think of it like restaurants..and a user may only want to see the reservations for a particular restaurant instead of the default of all restaurants
Maybe not a direct answer to your question but you can just make a ordinary GWT remote service UserPreferencesService which will store user preferences
public interface UserPreferencesService extends RemoteService {
List<Restaurant> getRestaurants(Account user);
void setRestaurants(Account user, List<Restaurant> restaurants);
}
In your entry point you can then make a decision on what kind of view you'll show to user
public final class Application implements EntryPoint {
private AuthServiceAsync authService =
GWT.create(AuthService.class);
private UserPreferencesAsync preferencesService =
GWT.create(UserPreferencesService.class);
#Override
public void onModuleLoad() {
// handle login
authService.getAccount(new Callback<Account>() {
#Override
public void onSuccess(final Account account) {
// check if user have a preferred restourants
preferencesService.getRestaurants(account,
new Callback<Account>() {
#Override
public void onSuccess(final List<Restaurant> restaurants) {
// user did not select any restaurants yet.
// Show a selection widget
if (restaurants.isEmpty) {
RestaurantSelectorWidget widget =
new RestaurantSelectorWidget();
// your custom handler here
widget.addHandler(new Handler() {
#Override
public void onSelected(/*...*/) {
// save user preferences
// and switch to normal view
}
})
RootPanel.get("container")
.add(widget);
} else {
// show normal view
}
}
}
}
}
}
}
}
Also you may take look to this plugin which is adds GWT support to grails.
I would like to run some code when a user publishes or deletes a page. What is the best way to do this?
I have a custom index service that works as a search for html content, so I would like to submit new content to this service when a user publishes a page in Umbraco. Also I would like to submit a delete to the index service when a user deletes or pages.
Create a class and inhert from IApplicationEventHandler
in the OnApplicationStarting you can create all kind of events
Like this
public class ApplicationEventHandler : IApplicationEventHandler
{
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Saving += ContentService_Saved;
ContentService.Published += ContentService_Published;
ContentService.UnPublishing +=ContentServiceOnUnPublishing;
ContentService.Deleting += ContentServiceOnDeleting;
ContentService.Moved +=ContentServiceOnMoved;
MediaService.Saving+=MediaService_Saving;
MemberService.Created+=MemberServiceOnCreated;
MemberService.Deleting += MemberServiceOnDeleted;
}
void ContentService_Published(IPublishingStrategy sender, PublishEventArgs<IContent> e)
{
}
Problem: user operates over some entity in a domain. The last one changes its status so that user recieves e-mail notifications (using smtp server) repeatedly until the given time.
So I need to fire an event somehow.
What are the alternative ways to do that? I know there're no events in ASP.NET MVC framework.
Thanks!
You can use my Inversion Of Control container which has built in support for in-process domain events:
Subscribing
Subscribing is easy. Simply let any class implement IHandlerOf:
[Component]
public class ReplyEmailNotification : IHandlerOf<ReplyPosted>
{
ISmtpClient _client;
IUserQueries _userQueries;
public ReplyEmailNotification(ISmtpClient client, IUserQueries userQueries)
{
_client = client;
_userQueries = userQueries;
}
public void Invoke(ReplyPosted e)
{
var user = _userQueries.Get(e.PosterId);
_client.Send(new MailMessage(user.Email, "bla bla"));
}
}
Dispatching
Domain events are dispatched using the DomainEvent class. The actual domain event can be any class, there are no restrictions. I do however recommend that you treat them as DTO's.
public class UserCreated
{
public UserCreated(string id, string displayName)
{
}
}
public class UserService
{
public void Create(string displayName)
{
//create user
// [...]
// fire the event.
DomainEvent.Publish(new UserCreated(user.Id, user.DisplayName));
}
}
The code is from my article: http://www.codeproject.com/Articles/440665/Having-fun-with-Griffin-Container
ASP.NET MVC3 installation:
Use package manager console: install-package griffin.container.mvc3
Follow these instructions: http://griffinframework.net/docs/container/mvc3/