Email Notifications on Calendar Events in Alfresco - alfresco

I'm using Alfresco 4.0
I need to send email notification to selected members or all the members if a calendar event is created.
I'm a newbie.
Kindly help me, as I'm on a deadline.

You can set a simple rule on "Sites/yoursite/calendar" folder that executes a javascript script which sends the email.
If you need something more complicated then you can use alfresco's "onCreateNode" policy and bind it to "ia:calendarEvent" type.
From the top of my head something like this:
...
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT);
this.policyComponent.bindClassBehaviour(QName.createQName(
NamespaceService.ALFRESCO_URI, "onCreateNode"),
"ia:calendarEvent", this.onCreateNode);
...
...
...
public void onCreateNode(ChildAssociationRef childAssocRef)
{
//send email here
}

Should roughly go like this:
Create a spring mananged bean, inject policyComponent
<bean id="calendarType" class="your.CalendarType"
init-method="init">
<property name="policyComponent" ref="policyComponent" />
</bean>
with methods:
public void init()
{
policyComponent.bindClassBehaviour(NodeServicePolicies.OnCreateNodePolicy.QNAME, CalendarModel.TYPE_EVENT ,
new JavaBehaviour(this, "onCreateNode"));
}
public void onCreateNode(ChildAssociationRef childAssocRef)
{
// do stuff here
}
Have a look at http://wiki.alfresco.com/wiki/Policy_Component for more details.

Thanks for all the valuable answers, I was able to complete my work on time. However after some search I got a complete script with all steps. You can follow this link, please read the 6th post for the answer:
https://forums.alfresco.com/en/viewtopic.php?f=47&t=42366

Related

Implement push notification server in php

This is my first post, sorry my English
Hello every one. I am a new programmer in PHP and i would like to use Zend Mobile Framework to implement my push notificator server.
I'm searching how to implement the tomcat project used in
http://developer.android.com/guide/google/gcm/demo.html
but written in PHP.
In the code most below I written the used sources.
When I call the submit button, always have response with InvalidRegistration error.
Can anyone see where the error?
Thank You very much
http://pastebin.com/MauzLX71
According with Android GCM's architectural overview you have an invalidRegistration error when:
Invalid Registration ID Check the formatting of the registration ID
that you pass to the server. Make sure it matches the registration ID
the phone receives in the com.google.android.c2dm.intent.REGISTRATION
intent and that you're not truncating it or adding additional
characters. Happens when error code is InvalidRegistration.
Check the official GCM documentaion here, please.
One of the things that you are likely having happen here is the following:
Your code is actually processing and attempting to send a message prior to your call of sendPush which may be causing part of the issue.
I've modified the code and had put the registration id in there: http://pastebin.com/NhrD5N6i
Did you sign up for an API key and replace that portion in the code?
In the demo client application; it shows how to actually leverage the registration; see my comment on the following GitHub issue: https://github.com/mwillbanks/Zend_Mobile/issues/16
Your server needs to have the registration id from the device; this is likely what you do not have.
One way of getting the registration ID is on the onRegistered call inside the client app, do a Log.i("MY_APP_TAG", regId); then look at the logcat output.
Android Example
public class GCMIntentService extends GCMBaseIntentService {
public GCMIntentService() {
super(Constants.SENDER_ID);
}
#Override
protected void onRegistered(Context context, String regId) {
Log.i("MY_APP_TAG", "Registered: " + regId);
}
#Override
protected void onUnregistered(Context context, String regId) {
// write a call here to send the regId to your server and unregister it
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.i("MY_APP_TAG", "Received message!");
// grabbing data looks like the following; the assumption
// is title is part of the data string.
String title = intent.getExtras().getString("title");
}
}
*Zend_Mobile_Push_Gcm Example*
See the updated link (http://pastebin.com/NhrD5N6i) I provided of your pasted code; you will want to use the registration ID above in the textbox.

How to make a Custom Deployer to write data to MS SQL database?

I've added a custom module in the default processor in config/cd_deployer_conf.xml:
<Processor Action="Deploy" Class="com.tridion.deployer.Processor">
...
<Module Type="MyCustomModuleDeploy" Class="com.tridion.new.extensions.MyCustomModule">
</Module>
</Processor>
The code for the module looks something like this:
public class MyCustomModule extends com.tridion.deployer.modules.PageDeploy {
static Logger logger = Logger.getLogger("customDeployerFirst");
public MyCustomModule(Configuration config, Processor processor)
throws ConfigurationException {
super(config, processor);
// TODO Auto-generated constructor stub
}
public void processPage(Page page, File pageFile) throws ProcessingException {
// TODO Auto-generated method stub
Date d = new Date();
log.info("WORKING");
log.info("Page ID: " + page.getId().toString());
log.info("Publication date: "+ d.toString());
}
}
In my log file I get the info I wanted, every time a page is published.
What I want to do next is to write the page ID and publication date to my Microsoft SQL database, in a table I previously created. How can I do that? How can I access the database table from MyCustomModule?
Thanks
Not sure of your requirement, but you already chose the deployer extension model vs storage extensions. With storage extensions, Tridion will provide a model on how you can extend storages (like JPAFramework and Base DAOEntities that you can extend). If you are going the deployer extension route, as Quirin and Nuno mentioned it is like writing a standard JDBC code like any other app.
But, I would suggest you also look at storage extension model and see if it fits your requirement. A very good starting point is to look at the below article: http://www.sdltridionworld.com/articles/sdltridion2011/tutorials/extending-content-delivery-storage-sdltridion-2011-1.aspx
Ok, so what I did here to solve my problem is exactly what Quirijn suggested. Used the JDBC driver to connect to my database and then executed an sql update query:
int sqlStatement = st.executeUpdate("insert into Pages values ('" + page.getId().toString()+ "', '" + ... + "')");
This way each time a Page is published some data will be written to my database.

Asp.Net / SignalR : Ajax Partial View

I did a lot of research and testing with SignalR and I have an issue with it.
I'm creating a .Net MVC3 web application. The user interface is like this :
I'am not allowed to post images, so you can check the User Interface at this link :
http://deasign.free.fr/InterfaceVadis.jpeg
The goal is :
User1 enter the Webapp, click on an Item, and see the Editing partial view.
User2 enter the WebApp, click on the same Item. I want to LOCK the view for him.
Goal : Only one user at a time can edit an Item.
When the User1 leave the editing view by click previous/next/clicking on the list, logout or just close his browser the User2 had to receive instantly (via SignalR) a notification and the editing page is not locked Anymore
I have tried several thing but not achieved it.
1°) In which part do I have to declare the SignalR Hub ? In the Right Partial view or on the parent page ? I tried both but was unable to make the Disconnect function work as I want :(
I hope I've been clear, sorry for my English
If you need other information, don't hesitate
Thanks to all :)
For all user operations such as previous/next/click etc, you could just call a function on the hub that would unlock the item:
JS:
$("#Next").click(function(e) {
myHub.next();
});
CS:
public class MyHub : Hub {
public void next() {
var itemId = ClientManager.GetCurrentEditedItemForClient(Caller.id);
ItemManager.UnlockItem(itemId);
}
public void previous() {
var itemId = ClientManager.GetCurrentEditedItemForClient(Caller.id);
ItemManager.UnlockItem(itemId);
}
}
As for client leaving by closing, I know you can implement the IDisconnect interface and handle disconnects from there:
public class MyHub : Hub, IDisconnect {
public void Disconnect()
{
var itemId = ClientManager.GetCurrentEditedItemForClient(Context.ClientId);
ItemManager.UnlockItem(itemId);
}
}
However, I also know that I haven't had much luck with the disconnect implementation. Maybe a routine that would check peridicaly the status of every client, or a pinger, anything. Someone else may have a better idea on this.

How to set log4net context property specific to an ASP.NET request?

I've been using log4net to log our ASP.NET web site's log messages, and lately I wanted to add information about the page/handler where the error happened. I decided therefore to add the following line to Global.asax:
void Application_BeginRequest(object sender, EventArgs e)
{
log4net.ThreadContext.Properties["page"] = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
}
and like wise I added %property{page} to my conversion pattern:
<conversionPattern value="%newline%date %-5level %property{page} - %message%newline%newline%newline" />
This worked fine for single requests. But then I noticed in my logs that the page property may change during an ASP.NET request. I have logging in one ASHX handler, and in the midst of its processing, the page property would change to a different value that points to an ASPX page. I concluded that there is another request coming to ASP.NET and its BeginRequest gets executed and the static page property in log4net.ThreadContext gets changed to another value.
Now, I would like to maintain the page property per request, so that I can have the path of the executing page logged to the log consistently. I tried to find an answer, but I came out with nothing. What is the recommended way to solve this problem? I'm sure this is very basic functionality of web server event logging.
Since ASP.NET does not guarantee that the entire page request will be processed on the same thread, I prefer getting the answer from HttpContext.Current as log4net processes the logging event.
The following GetCurrentPage class implements what the log4net manual calls an "Active Property Value" by overriding its ToString method:
public class GetCurrentPage
{
public override string ToString()
{
if (null != HttpContext.Current)
{
return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
}
return string.Empty; // or "[No Page]" if you prefer
}
}
Register this class in Global.asax's Application_Start in log4net's GlobalContext.
protected void Application_Start(object sender, EventArgs e)
{
XmlConfigurator.Configure();
GlobalContext.Properties["page"] = new GetCurrentPage();
}
When log4net writes the %property{page} part of the line it will call the ToString method of our GetCurrentPage class which will lookup the value in the current request.
Have you tried using Application_PostAcquireRequestState instead of Application_BeginRequest as outlined in this article? How can I include SessionID in log files using log4net in ASP.NET?
We have never felt the need to add the page to the logging since we create our logger in each class with the method name:
private static new readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
and have a conversion pattern like this:
<conversionPattern value="%date %P{user} %P{addr} [%property{SessionID}] %level %logger - %message%newline" />
So we end up seeing the class name in the log output. This also lets you differentiate whether the logging happened in the page class file itself, vs. a base class it inherits from. Your solution would have the advantage of showing the page name even when the code is executing in the base class. I think we will look at adding {page} to our setup.
Store property value in ASP.NET context HttpContext.Current.Items.Add("yourProperty", value)
It will be available from log4net layout:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%aspnet-context{yourProperty}" />
</layout>
Find more detail here.

Using ASP.net membership to get aspnet_Users in silverlight

Hope somebody can help.
Have looked around on the net but cannot seem to solve (or understand) this.
I have tried the code posted at
http://blogs.msdn.com/b/kylemc/archive/2010/05/10/using-asp-net-membership-in-silverlight.aspx
(not going to repeat the class MembershipServiceUser here as it is quite long and can be seen on the mentioned page)
I have set up the domain service with the class and the code to return the users:
//[RequiresRole("Managers")]
public IEnumerable<MembershipServiceUser> GetAllUsers()
{
return Membership.GetAllUsers().Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
I took out the RequiresRole for testing.
What I seem to be a bit blonde about is the calling of the GetAllUsers() method.
In my code behind I am using:
MembershipDataContext context = new MembershipDataContext();
EntityQuery<MembershipServiceUser> users = context.GetAllUsersQuery();
I am not 100% sure if this is the correct way to use the method or if something else is wrong because
context.GetAllUsersQuery(); returns "Enumeration yielded no results"
One question is also in the code kylmc uses //RequiresRole("Admin")]. Is this a custom role created in the ASP.NET Configuration editor?
Looking at another tutorial regarding using the ASP.NET authentication service in Silverlight, I create a role called "Managers" and added the login user to that role.
Logging in using a user with role Managers doesn't help and results are still not yielded.
Any ideas I could possible look at?
Many thanks
Neill
There are two steps involved with querying.
Get a query object from the Domain Service context (synchronous).
Load the query from the Domain Service context (asynchronous).
Example:
public void Load()
{
// define the query
var query = context.GetAllUsersQuery();
// start running the query, and when the results return call
// OnGetAllUsersLoaded
context.Load(query, OnGetAllUsersLoaded, null);
}
public void OnGetAllUsersLoaded(LoadOperation op)
{
var results = op.Entities;
}

Resources