欢迎光临 移山之道 登录 | 注册 | 帮助

about:blank

编程与生活一样, 都是严肃而富有艺术的
CommunityServer是如何实现注册自动创建Blog和Gallery的

最近因为要维护一个基于CommunityServer的社区, 所以重新捡起了已经很久没有再读的代码. 期间要解决两个易用性的小问题:

1. 个人用户不容易找到自己的Blog和Gallery入口
2. 实现一个注册策略: 用户可以自由注册但需要管理员approval, approval后自动添加个人Blog和Gallery.

这两个小feature都要求在不影响其他功能的情况下解决.

第一个问题很容易解决, 只要在NavigationBar控件上添加一个用户自己的ControlPanel按钮就可以了. 因为CS几乎所有链接都是在SiteUrls.config文件中进行配置的, 所以很容易就找到了NavigationBar的资源位置. 在SiteUrls.config文件中找到

<link name="controlpanel" resourceUrl="controlpanel" resourceName="controlpanel" roles="SystemAdministrator,BlogAdministrator,ForumsAdministrator,Moderator,GalleryAdministrator,FileAdministrator,ReaderAdministrator,MembershipAdministrator" />

在roles属性中添加Registered Users就可以让所有登录后的用户轻松看见自己的ControlPanel入口按钮.

第二个问题稍微比较费周折, 虽然CS也已经提供了注册后立即自动开通Blog和Gallery的feature, 但是它是只要用户注册就不管三七二十一先给创建一个Blog和Gallery, 即使用户一直没有被Approval也是一样会创建, 这样无形中就会因为一些恶意注册而留下无用信息, 我们需要的是当用户不需要Approval时, 则象原有那样根据站点设置判断自动创建Blog和Gallery, 而当需要Approval时, 只有在管理员Approval后再根据站点设置判断是否自动创建.

从源入手: 从web/user/CreateUser.aspx中查到有<CS:CreateUser runat="server" />这一控件, 找到对应文件CommunityServerControls20/user/CreateUser.cs, 根据其中createButton.Click += new System.EventHandler(CreateUser_Click);定位到CreateUser_Click方法, 再定位到核心的protected CreateUserStatus CreateNewUser(User user)方法, 最后定位到Users.Create()方法, 在Users.Create方法主体中可以顺着对数据层调用的链一层层分析下去, 一直到SqlCommanDataProvider中的CreateUpdateDeleteUser方法, 都没有找到自动创建的相关代码, 于是把注意力集中到User.Create方法中CSEvents.AfterUser(createdUser,ObjectState.Create);这一事件触发代码上, 又是一层层剖析下去发现CSUserEventHandler为事件相关handler, 于是在整个项目文件中搜索CSUserEventHandler(因为若是挂接事件, 必然有一个形如 += new CSUserEventHandler(handler_function)的代码), 一共找到14处匹配在6个文件中, 一眼就在6个文件中看出了

D:\MyWorks\ASP.NET\CS_2.1.61129.2_SDK\source\Galleries\Components\Modules\AutoGalleryCreate.cs(25): csa.PostUserUpdate += new CSUserEventHandler(csa_PostUserUpdate);
D:\MyWorks\ASP.NET\CS_2.1.61129.2_SDK\source\Blogs\Components\Modules\AutoBlogCreate.cs(28): csa.PostUserUpdate +=new CSUserEventHandler(csa_PostUserUpdate);

这两项, Bingo! 原来CS把这个feature做成了HttpModule的实现, 用事件挂接, 没有直接引用关系, 找起来的确费力一些...

接下来读一下代码改起来就很简单了, 两个文件改的方式都差不多, 以AutoBlogCreate.cs为例, 将判断语句
if(user != null && e.State == ObjectState.Create)
改为if(user != null && e.State == ObjectState.Create && CSContext.Current.SiteSettings.AccountActivation != AccountActivation.AdminApproval), 这样就实现了未经Approval就不能自动创建的功能.
而Approval后自动创建就有很多种实现方式了, 我用了最偷懒的方法, 先把自动创建的代码提取出来, 独立成AutoBlogCreate类的一个静态方法public static void CreateDefaultBlog(string username), 然后找到进行approval操作的页面, \Web\ControlPanel\Membership\UserEdit.aspx, 幸亏管理功能都是codebehind的实现, 轻松找到其中的protected virtual bool Update( User userToEdit )方法, 在其最后一行return true;前加上

//Added by ChenYuan 07-3-23 to enable create the default blog/gallery after admin approval
CommunityServer.Blogs.Components.AutoBlogCreate.CreateDefaultBlog(userToEdit.Username);
CommunityServer.Galleries.Components.AutoGalleryCreate.CreateDefaultGallery(userToEdit.Username);
//end

重新编译整个项目, 这样就解决了这两个问题, 其中注意一点是AutoGalleryCreate.cs中创建Gallery最后一行原来是CommunityServer.Galleries.Galleries.GetGalleries(cSContext.User.UserID, true, true, true);而在我们自定义的CreateDefaultGallery()静态方法中应该改为CommunityServer.Galleries.Galleries.GetGalleries(Users.FindUserByUsername(username).UserID, true, true, true);这样才能正确更新对应用户的cache(前者会造成更新管理员的cache而不是对应用户的).

最后发一句牢骚: 学校的网络太烂了, 用远程桌面慢得跟牛一样, 郁闷...

Posted: 2007年3月25日 6:24 作者 小飞
归档在:

评论

小东彭彭 说:

感谢小飞了,这两个功能都不错。

# 三月 25, 2007 17:54
说说您的看法?

(必填) 

(必填) 

(可选)

(必填) validate code

(必填) 

评论通知

如果您想在帖子更新时接到邮件通知,请先登录。这里

订阅帖子评论使用 RSS