An alternative to UBB.threads
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.8 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Web.Core;
using Web.Core.DB;
using FLocal.Common;
using FLocal.Common.actions;
namespace FLocal.Common.dataobjects {
public class PMMessage : SqlObject<PMMessage> {
public const string ENUM_DIRECTION_INCOMING = "Incoming";
public const string ENUM_DIRECTION_OUTGOING = "Outgoing";
public class TableSpec : ISqlObjectTableSpec {
public const string TABLE = "PMMessages";
public const string FIELD_ID = "Id";
public const string FIELD_OWNERID = "OwnerId";
public const string FIELD_INTERLOCUTORID = "InterlocutorId";
public const string FIELD_DIRECTION = "Direction";
public const string FIELD_POSTDATE = "PostDate";
public const string FIELD_TITLE = "Title";
public const string FIELD_BODY = "Body";
public const string FIELD_BODYUBB = "BodyUBB";
public const string FIELD_INCOMINGPMID = "IncomingPMId";
public const string FIELD_ISREAD = "IsRead";
public static readonly TableSpec instance = new TableSpec();
public string name { get { return TABLE; } }
public string idName { get { return FIELD_ID; } }
public void refreshSqlObject(int id) { Refresh(id); }
}
protected override ISqlObjectTableSpec table { get { return TableSpec.instance; } }
private int _ownerId;
public int ownerId {
get {
this.LoadIfNotLoaded();
return this._ownerId;
}
}
public Account owner {
get {
return Account.LoadById(this.ownerId);
}
}
private int _interlocutorId;
public int interlocutorId {
get {
this.LoadIfNotLoaded();
return this._interlocutorId;
}
}
public Account interlocutor {
get {
return Account.LoadById(this.interlocutorId);
}
}
public Account poster {
get {
if(this.direction == ENUM_DIRECTION_INCOMING) {
return this.interlocutor;
} else {
return this.owner;
}
}
}
private string _direction;
public string direction {
get {
this.LoadIfNotLoaded();
return this._direction;
}
}
private DateTime _postDate;
public DateTime postDate {
get {
this.LoadIfNotLoaded();
return this._postDate;
}
}
private string _title;
public string title {
get {
this.LoadIfNotLoaded();
return this._title;
}
}
private string _body;
public string body {
get {
this.LoadIfNotLoaded();
return this._body;
}
}
private string _bodyUBB;
public string bodyUBB {
get {
this.LoadIfNotLoaded();
return this._bodyUBB;
}
}
private int? _incomingPMId;
public int? incomingPMId {
get {
this.LoadIfNotLoaded();
return this._incomingPMId;
}
}
public PMMessage incomingPM {
get {
return PMMessage.LoadById(this.incomingPMId.Value);
}
}
private bool _isRead;
public bool isRead {
get {
this.LoadIfNotLoaded();
return this._isRead;
}
}
public PMConversation conversation {
get {
return PMConversation.LoadByAccounts(this.owner, this.interlocutor);
}
}
protected override void doFromHash(Dictionary<string, string> data) {
this._ownerId = int.Parse(data[TableSpec.FIELD_OWNERID]);
this._interlocutorId = int.Parse(data[TableSpec.FIELD_INTERLOCUTORID]);
this._direction = data[TableSpec.FIELD_DIRECTION];
this._postDate = Util.ParseDateTimeFromTimestamp(data[TableSpec.FIELD_POSTDATE]).Value;
this._title = data[TableSpec.FIELD_TITLE];
this._body = data[TableSpec.FIELD_BODY];
this._bodyUBB = data[TableSpec.FIELD_BODYUBB];
this._incomingPMId = Util.ParseInt(data[TableSpec.FIELD_INCOMINGPMID]);
this._isRead = Util.string2bool(data[TableSpec.FIELD_ISREAD]);
}
public XElement exportToXml(UserContext context, params XElement[] additional) {
if((context.account == null) || (context.account.id != this.owner.id)) {
throw new AccessDeniedException();
}
XElement result = new XElement("message",
new XElement("id", this.id),
new XElement("poster", this.poster.exportToXml(context)),
new XElement("owner", this.owner.exportToXml(context)),
new XElement("interlocutor", this.interlocutor.exportToXml(context)),
new XElement("isRead", this.isRead.ToPlainString()),
new XElement("postDate", this.postDate.ToXml()),
new XElement("title", this.title),
new XElement("body", context.outputParams.preprocessBodyIntermediate(this.body)),
new XElement("bodyUBB", this.bodyUBB)
);
if(this.direction == ENUM_DIRECTION_OUTGOING) {
result.Add(new XElement("isReadByInterlocutor", this.incomingPM.isRead));
}
if(additional.Length > 0) {
result.Add(additional);
}
return result;
}
private readonly object MarkAsRead_locker = new object();
public void MarkAsRead(Account account) {
if(account.id != this.owner.id) throw new AccessDeniedException();
if(!this.isRead) {
lock(MarkAsRead_locker) {
//so we can safely decrease ReadPrivateMessages counter
//Note that this code implicitly uses assumption of single-instance Common.dll; race condition is possible with more than one server
if(!this.isRead) {
AccountIndicator indicator = AccountIndicator.LoadByAccount(this.owner);
ChangeSetUtil.ApplyChanges(
new UpdateChange(
TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ TableSpec.FIELD_ISREAD, new ScalarFieldValue("1") },
},
this.id
),
new UpdateChange(
AccountIndicator.TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ AccountIndicator.TableSpec.FIELD_UNREADPRIVATEMESSAGES, new IncrementFieldValue(IncrementFieldValue.DECREMENTOR) },
},
indicator.id
)
);
}
}
}
}
}
}