20#if __DCL_HAVE_THIS_FILE__
28 const String& strAttachDir,
29 const String& strDsID,
30 const String& strMessageID,
31 const String& strAttachNo
37 + strAttachNo + L
".dat";
45 __nThumbnailImageSize = 0;
57 if (
__mapParams.lookup(L
"THUMBNAIL_SIZE", rValue)) {
59 if (__nThumbnailImageSize <= 0)
60 __nThumbnailImageSize = 110;
64static String __GetLinkInsertedString(
const wchar_t* psz)
69 L
"http://[^ \t\r\n\"\'<>]+",
76 const wchar_t* begin = psz;
77 const wchar_t* end = psz + String::length(psz);
81 while (begin < end && re.search(begin, end, m)) {
84 if (begin < m[0].first) {
85 r.append(begin, m[0].first);
87 r.append(L
"<a href=\"")
88 .append(m[0].first, m[0].second)
89 .append(L
"\" target=\"_new\">")
90 .append(m[0].first, m[0].second)
107 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
110 String strTableID = String::valueOf(
__nTableID);
111 String strDsID = String::valueOf(
__nDsID);
113 String strMessageID =
getDefault(mapQuery, L
"modify");
114 if (strMessageID.isEmpty()) {
116 assign(L
"BODY_TYPE", L
"-1");
117 assign(L
"BODY_VALUE", L
"");
119 assign(L
"WRITER", session.__strUserName);
125 strMessageID =
getDefault(mapQuery, L
"reply");
126 if (strMessageID.isEmpty() || strMessageID == L
"0") {
128 if (session.isSysAdmin()) {
129 TextTemplate& IS_ADMIN = (*this)[L
"IS_ADMIN"];
130 IS_ADMIN.assign(L
"VNO",
VNO());
131 assign(L
"IS_ADMIN", IS_ADMIN);
136 assign(L
"SUBJECT", String());
141 assign(L
"ACTION_EX", L
"reply=" + strMessageID);
143 StringBuilder strRe = L
"Re: ";
146 "\n FROM DCL_MESSAGE_" + strTableID + L
""
147 "\n WHERE DS_ID = " + strDsID + L
""
148 "\n AND MESSAGE_ID = " + strMessageID
152 strRe += q.
fields()[0].asString();
154 assign(L
"SUBJECT", strRe);
160 TextTemplate& IS_MODIFY = (*this)[L
"IS_MODIFY"];
161 IS_MODIFY.assign(L
"VNO",
VNO());
162 assign(L
"IS_MODIFY", IS_MODIFY);
163 assign(L
"ACTION_EX", L
"modify=" + strMessageID);
166 "SELECT M.TYPE AS BODY_TYPE, M.SUBJECT, M.BODY_ORG,"
167 "\n U.USER_NAME AS WRITER,"
168 "\n A.NO, A.FILENAME, CEILING(A.SIZE / 1024) AS KSIZE"
169 "\n FROM (DCL_MESSAGE_" + strTableID + L
" AS M"
170 "\n INNER JOIN DCLWC_USER AS U"
171 "\n ON(M.USER_ID = U.USER_ID))"
172 "\n LEFT OUTER JOIN DCL_MESSAGE_A_" + strTableID + L
" AS A"
173 "\n ON (M.DS_ID = A.DS_ID AND M.MESSAGE_ID = A.MESSAGE_ID)"
174 "\n WHERE M.DS_ID = " + strDsID + L
""
175 "\n AND M.MESSAGE_ID = " + strMessageID + L
""
176 "\n ORDER BY A.NO ASC"
183 if (!fBODY_ORG.isNull()) {
184 strBodyValue = fBODY_ORG.asString();
185 strBodyValue = String::escape(strBodyValue, strBodyValue.length());
187 assign(L
"BODY_VALUE", strBodyValue);
190 if (AttachNo.isNull())
193 TextTemplate& ATTACH = (*this)[L
"ATTACH"];
194 TextTemplate& LIST = ATTACH[L
"LIST"];
196 LIST.assign(L
"VNO",
VNO());
197 LIST.assign(L
"MESSAGE_ID", strMessageID);
198 LIST.assign(L
"NO", q.
fields().
byName(L
"NO").asString());
199 LIST.assign(L
"FILENAME", q.
fields().
byName(L
"FILENAME").asString());
200 LIST.assign(L
"KSIZE", q.
fields().
byName(L
"KSIZE").asString());
201 ATTACH.append(L
"LIST", LIST);
205 assign(L
"ATTACH", ATTACH);
215 const char* pszSrcFile,
216 const char* pszContentType,
217 const char* pszThumbnailFile,
228 ListedStringToStringArrayMap& mapQuery = session.__ctx.__queryMap;
229 ListedStringToStringArrayMap& mapForm = session.__ctx.__formMap;
232 String strTableID = String::valueOf(
__nTableID);
233 String strDsID = String::valueOf(
__nDsID);
235 String strListPage =
getDefault(mapQuery, L
"list");
237 if (session.isSysGuest()) {
238 StringBuilder strRefresh = L
"?page=";
239 if (!strListPage.isEmpty())
240 strRefresh += strListPage;
242 strRefresh += __strListPage;
243 __pPage->refresh(session, strRefresh);
248#define CM_INSERT_START 1
249#define CM_INSERT_REPLY 2
252 bool bNotice =
false;
255 String strMessageID =
getDefault(mapQuery, L
"modify");
256 if (strMessageID.isEmpty()) {
257 strMessageID =
getDefault(mapQuery, L
"reply");
258 if (strMessageID.isEmpty() || strMessageID == L
"0")
274 if (mapForm.find(L
"NOTICE") != mapForm.end()) {
282 String strSubject =
getDefault(mapForm, L
"SUBJECT");
283 String strBodyOrg =
getDefault(mapForm, L
"BODY_VALUE");
287 if (!strSubject.trim().isEmpty()) {
294 __GetLinkInsertedString(
305 __GetLinkInsertedString(
315 strBodyHtml = strBodyOrg.replace_r(L
"<[ \t\r\n]*body", L
"<div",
true);
316 strBodyHtml = strBodyHtml.replace_r(L
"/[ \t\r\n]*body", L
"/div",
true);
319 L
"!,--,html,head,title,meta,link,script,style,body"
320 ",mapForm,input,button,textarea,select,option"
329 "\n FROM DCL_MESSAGE_" + strTableID + L
""
330 "\n WHERE DS_ID = " + strDsID + L
""
331 "\n AND MESSAGE_ID = " + strMessageID + L
""
332 "\n AND USER_ID = " + String::valueOf(session.__nUserID)
337 "UPDATE DCL_MESSAGE_" + strTableID + L
""
338 "\n SET TYPE = :TYPE, SUBJECT = :SUBJECT"
339 ", BODY_ORG = :BODY_ORG, BODY_PLAIN = :BODY_PLAIN"
340 ", BODY_HTML = :BODY_HTML, UPDATE_TIME = CURRENT_TIMESTAMP"
341 "\n WHERE DS_ID = " + strDsID + L
""
342 " AND MESSAGE_ID = " + strMessageID
345 params.
byName(L
"TYPE").setValue(nBodyType);
346 params.
byName(L
"SUBJECT").setValue(strSubject);
347 params.
byName(L
"BODY_ORG").setValue(strBodyOrg);
348 params.
byName(L
"BODY_PLAIN").setValue(strBodyPlain);
349 params.
byName(L
"BODY_HTML").setValue(strBodyHtml);
353 StringArray& vDeleteAttach = mapForm[L
"DELETE_ATTACH"];
354 String strEraseAttach = String::join(vDeleteAttach, L
',');
355 if (!strEraseAttach.isEmpty()) {
357 "DELETE FROM DCL_MESSAGE_A_" + strTableID + L
""
358 "\n WHERE DS_ID = " + strDsID + L
""
359 "\n AND MESSAGE_ID = " + strMessageID + L
""
360 "\n AND NO IN (L" + strEraseAttach + L
")"
363 for(
size_t i = 0; i < vDeleteAttach.size(); i++) {
365 __pPage->site()->strAttachmentDir,
378 "SELECT MAX(NO) FROM DCL_MESSAGE_A_" + strTableID + L
""
379 "\n WHERE DS_ID = " + strDsID + L
""
380 "\n AND MESSAGE_ID = " + strMessageID
383 if (!q.
fields()[0].isNull())
384 nAttachNo = q.
fields()[0].asInteger() + 1;
398 int nMessageID, nStartID, nChild = 0;
399 int64_t nReplyID = 1;
401 q.
execute(L
"SET AUTOCOMMIT = 0");
404 "SELECT MESSAGE_ID, NOTICE_ID"
405 "\n FROM DCLWC_DATA_SOURCE"
406 "\n WHERE DS_ID = " + strDsID + L
""
411 nMessageID = nStartID = q.
fields()[1].asInteger();
413 nMessageID = nStartID = q.
fields()[0].asInteger();
419 "SELECT MESSAGE_ID, START_ID, REPLY_ID, NCHILD"
420 "\n FROM DCL_MESSAGE_" + strTableID + L
""
421 "\n WHERE DS_ID = " + strDsID + L
""
422 "\n AND MESSAGE_ID = " + strMessageID
429 nParentID = q.
fields()[0].asInteger();
430 nStartID = q.
fields()[1].asInteger();
431 nReplyID = q.
fields()[2].asInt64();
432 nChild = q.
fields()[3].asInteger();
436 if (nChild == mt.
width()
447 int64_t nPrevReplyID = 0;
449 int64_t _r = nReplyID;
455 int64_t _r = nReplyID;
464 "SELECT MESSAGE_ID FROM DCL_MESSAGE_" + strTableID + L
""
465 "\n WHERE DS_ID = " + strDsID + L
""
466 "\n AND START_ID = " + String::valueOf(nStartID) + L
""
471 nPrevID = q.
fields()[0].asInteger();
475 StringBuilder strSQL = L
""
476 "SELECT MAX(MESSAGE_ID) FROM DCL_MESSAGE_" + strTableID + L
""
477 "\n WHERE DS_ID = " + strDsID + L
""
478 "\n AND PARENT_ID = 0";
480 strSQL += L
" AND MESSAGE_ID <= 2000000000";
486 if (!q.
fields()[0].isNull())
487 nPrevID = q.
fields()[0].asInteger();
492 "INSERT INTO DCL_MESSAGE_" + strTableID + L
""
493 "\n (DS_ID, MESSAGE_ID, PREV_ID, NEXT_ID, PARENT_ID, START_ID, REPLY_ID,"
494 " TYPE, USER_ID, SUBJECT, BODY_ORG, BODY_PLAIN, BODY_HTML,"
497 "\n (:DS_ID, :MESSAGE_ID, :PREV_ID, :NEXT_ID, :PARENT_ID, :START_ID, :REPLY_ID,"
498 " :BODY_TYPE, :USER_ID, :SUBJECT, :BODY_ORG, :BODY_PLAIN, :BODY_HTML,"
499 " CURRENT_TIMESTAMP)"
503 params.
byName(L
"MESSAGE_ID").setValue(nMessageID);
505 params.
byName(L
"PREV_ID").setValue(0);
506 params.
byName(L
"NEXT_ID").setValue(nPrevID);
509 params.
byName(L
"PREV_ID").setValue(nPrevID);
510 params.
byName(L
"NEXT_ID").setValue(0);
512 params.
byName(L
"PARENT_ID").setValue(nParentID);
513 params.
byName(L
"START_ID").setValue(nStartID);
514 params.
byName(L
"REPLY_ID").setValue(nReplyID);
515 params.
byName(L
"BODY_TYPE").setValue(nBodyType);
516 params.
byName(L
"USER_ID").setValue(session.__nUserID);
517 params.
byName(L
"SUBJECT").setValue(strSubject);
518 params.
byName(L
"BODY_ORG").setValue(strBodyOrg);
519 params.
byName(L
"BODY_PLAIN").setValue(strBodyPlain);
520 params.
byName(L
"BODY_HTML").setValue(strBodyHtml);
526 "UPDATE DCL_MESSAGE_" + strTableID + L
""
527 "\n SET PREV_ID = " + String::valueOf(nMessageID) + L
""
528 "\n WHERE DS_ID = " + strDsID + L
""
529 "\n AND MESSAGE_ID = " + String::valueOf(nPrevID)
533 "UPDATE DCL_MESSAGE_" + strTableID + L
""
534 "\n SET NEXT_ID = " + String::valueOf(nMessageID) + L
""
535 "\n WHERE DS_ID = " + strDsID + L
""
536 "\n AND MESSAGE_ID = " + String::valueOf(nPrevID)
543 strChildID = L
", CHILD_ID = " + String::valueOf(nMessageID);
546 "UPDATE DCL_MESSAGE_" + strTableID + L
""
547 "\n SET NCHILD = NCHILD + 1" + strChildID + L
""
548 "\n WHERE DS_ID = " + strDsID + L
""
549 "\n AND MESSAGE_ID = " + strMessageID
555 "UPDATE DCLWC_DATA_SOURCE"
556 "\n SET NOTICE_ID = NOTICE_ID + 1"
557 "\n WHERE DS_ID = " + strDsID
561 "UPDATE DCLWC_DATA_SOURCE"
562 "\n SET MESSAGE_ID = MESSAGE_ID + 1"
563 "\n WHERE DS_ID = " + strDsID
566 q.
execute(L
"SET AUTOCOMMIT = 1");
567 strMessageID = String::valueOf(nMessageID);
573 String strDir =
__pPage->site()->strAttachmentDir + strDsID;
577 if (__nThumbnailImageSize > 0) {
578 strDir =
__pPage->site()->strThumbnailDir + strDsID;
584 "INSERT INTO DCL_MESSAGE_A_" + strTableID + L
""
585 "\n (DS_ID, MESSAGE_ID, NO, FILENAME, TYPE)"
587 "\n (L" + strDsID + L
", L" + strMessageID + L
""
588 ", :NO, :FILENAME, :TYPE)"
590 for(
size_t i = 0; i < formFile.
size(); i++) {
591 StoredHttpFormData::FileInfoArray& v = formFile[i];
592 for(
size_t j = 0; j < v.size(); j++)
594 StoredHttpFormData::FileInfo& info = v[j];
597 __pPage->site()->strAttachmentDir,
600 String::valueOf(nAttachNo)
606 if (__nThumbnailImageSize > 0) {
612 __pPage->site()->strThumbnailDir,
615 String::valueOf(nAttachNo)
617 __nThumbnailImageSize
621 q.
params()[0].setValue(nAttachNo);
622 q.
params()[1].setValue(info.filename);
623 q.
params()[2].setValue(info.contentType);
631 StringBuilder strNext =
getDefault(mapQuery, L
"next");
632 if (!strNext.isEmpty())
633 strNext = L
"?page=" + strNext.toString();
635 strNext = L
"?page=" + __strDetailPage;
636 strNext += L
"&msg=" + strMessageID;
639 if (!strListPage.isEmpty())
642 __pPage->refresh(session, strNext);
#define IMPLEMENT_CLASSINFO_EX(class_name, base_class_name)
__DCL_BEGIN_NAMESPACE String __GetLocalFileName(const String &strAttachDir, const String &strDsID, const String &strMessageID, const String &strAttachNo)
#define BODY_TYPE_PLAIN_P
#define BODY_TYPE_PLAIN_BR
#define __DCL_ASSERT(expr)
#define __DCL_TRACE2(fmt, arg1, arg2)
__DCL_BEGIN_NAMESPACE bool GenThumbnailImage(const char *pszSrcFile, const char *pszContentType, const char *pszThumbnailFile, int nSize)
static void mkdir(const String &_path, int _mode=0755) __DCL_THROWS1(IOException *)
static bool exists(const String &_path)
static void rename(const String &_oldpath, const String &_newpath) __DCL_THROWS1(IOException *)
static void unlink(const String &_path) __DCL_THROWS1(IOException *)
static String strip(const String &_str, const wchar_t *_elementNames)
static String format(const String &_str, int _tab2Space, const String &_beginOfLine, const String &_endOfLine)
static String escape(const String &_str, const wchar_t *_chars)
StringToStringMap __mapParams
static String getDefault(ListedStringToStringArrayMap &map, const String &strKey)
String toString(unsigned _base=10) const
static int parse(const wchar_t *_number, unsigned _base=10) __DCL_THROWS1(NumericConvertException *)
void getPosition(int64_t nReplyID, Position &rPos) const
int64_t getChildID(int64_t nReplyID, int nWidthIndex) const
virtual void init(SQLFields &fields) __DCL_THROWS1(Exception *)
virtual void onPrint(Session &session) __DCL_THROWS1(Exception *)
_CONST SQLField & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
void prepare(const String &_sql) __DCL_THROWS1(SQLException *)
_CONST SQLParams & params() _CONST
_CONST SQLFields & fields() _CONST
void execute() __DCL_THROWS1(SQLException *)
int64_t affectedRows() const
void fetch() __DCL_THROWS1(SQLException *)
static ByteString encode(const ByteString &_str)