Программизм. Серия 3
|
|
15.11.2010 02:53
|
#
У меня тут тележка вопросов образовалась... 1. Каким образом узнать входит ли юзер с ID=N в некоторую группу с ID=M. Точнее задача такова: есть список ID (например, такой: 1006, 1007, 1008) и получив на входе идентификатор N текущего пользователя узнать, а входит ли он в этот список напрямую (ну, это просто на равенство сравнить) или в группу, если таковая есть в вышеуказанном списке.
2. Каким образом обеспечить возможность работы с аттачментами? Каким образом обеспечить обработку вставки картинок (контрол rte допускает их ставку). Что необходимо обеспечить в своем модуле, чтобы работало добавление аттачей и картинок. Это несколько разные задачи или они схожи по реализации?
3. Что необходимо делать для поддержки поиска (при помощи встроенного поиска)? Я так понимаю что для того, чтобы работал поиск по тексту, то везде где модуль использует текст, его необходимо 'скормить' внутреннему индексатору.
4. А каким образом осуществляется выполнение фильтрации (как в модуле Задания, там значок такой в виде воронки)? Это делается через встроенные возможности поиска или просто поиском подстроки? Что делает эта конструкция: if (!TeamWox.isMobile) 5. Каков логический смысл действия 'Отложить' для заданий? Меняется статус задания (я так понял есть всего три состояния: открыто/завершено/закрыто или для событий есть еще дополнительное 'отложено')? Каков смысл команды 'Закрыть' для событий?
6. Что есть такое snippet? TeamWox.Control("Input", "rte", ......
7. Что за интерфейсы запрашивает у модуля сервер??? И что дает реализация каждого из них (а то может и нужен он вовсе) Вот как-то так. 8-) |
|
|
TeamWox SDK: Настройка окружения пользовательских модулей - Часть 2
Во второй части статьи вы узнаете как добавить советы по использованию вашего модуля в ротацию на главной странице TeamWox, а также как создать виджет для собственного модуля. |
|
|
15.11.2010 13:17
|
#
6. Что есть такое snippet? TeamWox.Control("Input", "rte", ...... .Append("onsnippetcreate",CreateSnippet) .Append("onsnippetinsert",InsertSnippet) Это встроенный механизм работы с шаблонами. Подробнее они описаны в справке Шаблоны. Любой модуль может добавить в этот шаблон необходимые ему данные, например задания добавляют назначенных, важность, приватность и т.д. Для этих целей и служат события. Событие "onsnippetcreate" говорит о том что создается новый шаблон. параметром в это событие передается объект, свойства которого будут сохранены. "onsnippetinsert" генерируется при вставке шаблона, параметром также передается объект содержащий ранее сохраненные свойства. Для того что бы этот механизм заработал в rte необходимо указать параметрами идентификатор модуля var rte = TeamWox.Control('Input','rte','name','<b>text!</b>',{upload:'/module/upload/',moduleId:24});
|
|
|
|
15.11.2010 15:05
|
#
trophim: 1. Каким образом узнать входит ли юзер с ID=N в некоторую группу с ID=M. Точнее задача такова: есть список ID (например, такой: 1006, 1007, 1008) и получив на входе идентификатор N текущего пользователя узнать, а входит ли он в этот список напрямую (ну, это просто на равенство сравнить) или в группу, если таковая есть в вышеуказанном списке. Для того, чтобы узнать в какие группы входит пользователь нужно вызвать следующие методы интерфейса IUser
В контексте запроса (Context) список групп для текущего пользователя (context->user) уже доступен для запроса и использования. В случае, если Вы запрашиваете информацию о пользователе через интерфейс IUserManager, то при запросе Вам необходимо указать флаг USER_INFO_USERS_GROUPS. Например: CSmartInterface<IUser> user; if(RES_FAILED(res=m_user_manager->UserGet(NULL, user_id, USER_INFO_USERS_GROUPS, &user)) || user==NULL) return(res); //--- ищем группу const INT64* groups =user->Groups(); bool founded=false; for(int i=0, count=user->GroupsCount(); i<count; i++) { //--- сравниваем id группы if(groups[i]==group_id) { founded=true; break; } } |
|
|
|
15.11.2010 21:47
|
#
Спасибо за ответы. Что насчет остальных вопросов?
|
|
|
|
17.11.2010 01:33
|
#
Остальное не поддается отвечанию? :-(
|
|
|
|
17.11.2010 12:58
|
#
trophim:
Остальное не поддается отвечанию? :-( Приносим свои извинения за задержку. В ближайшее время Вы получите ответ на остальные вопросы. |
|
|
|
22.11.2010 00:42
|
#
Уж полночь близится, а ансверов все нет...
|
|
|
|
22.11.2010 12:21
|
#
Приносим прощения за долги ответ. Разработчики были заняты подготовкой нового релиза 2.Каким образом обеспечить обработку вставки картинок (контрол rte допускает их ставку). Что необходимо обеспечить в своем модуле, чтобы работало добавление аттачей и картинок. Возможность вставка изображений в редактируемый текст происходит в два этапа. На первом, во время набора текста картинки загружаются на сервер и сохраняются как временные файлы. Для этого вам понадобится реализовать обработку таких загружаемых файлов. Допустим мы будем принимать ихпо адресу "/testmodule/upload/". TeamWox.Control("Input","rte","content","",{upload:"/testmodule/upload"}).Style("height","300px"); Далее в методе ProcessPage вашего модуля необходимо обработать приходящие с клиента файлы if(PathCompare(L"upload",path)) { IRichTextEdit *rte=NULL; //--- получим интерфейс упрощающий работу с редактором if(RES_SUCCEEDED(res=m_server->GetInterface(L"IRichTextEdit",(void **)&rte)) && rte!=NULL) { //--- сохраним пришедший файл как временный и сделаем его доступным по адресу /testmodule/image/ + id файла res=rte->Upload(context, L"/testmodule/image/"); rte->Release(); return(res); } //--- ReturnError(res); } Далее для того что бы файл отображался во время редактирования и после записи текста, вам необходимо реализовать возврат этого файла по адресу /testmodule/image/. Для этого все в том же ProcessPage реализуем обработку этого адреса if(PathCompare(L"image",path)) { // конечно делать прямо так в рабочем проекте нельзя, необходимы проверки корректности // которые в данном случае убраны для простоты примера. // задача кода получить идентификатор файла из пути вид /testmodule/image/122 где 122 искомый id INT64 id = _wtoi64(path+6); // в зависимости от вашей задачи, здесь может быть проверка прав доступа пользователя к этому файлу. // получим файловый менеджер IFilesManager* files_mngr=NULL; if(RES_FAILED(server->GetInterface(L"IFilesManager", (void**)&files_mngr))) ReturnError(RES_E_FAIL); // скажем файловому менеджеру отправить файл кэшируемым и inline объектом (без заголовка Content-Disposition:attachment) return(files_mngr->FileSend(context,download_id,IFilesManager::SEND_MODE_CACHE | IFilesManager::SEND_MODE_INLINE)); } Теперь вам необходимо при записи содержимого набранного в редакторе перевести файлы из временных в постоянные. Делается это момоходом, при обработке присланного текста IHtmlCleaner для удаления мусора и прочих не разрешенных html тэгов и аттрибутов. В следующем примере мы получаем данные присланные редактором с именем content, созданным нами в примере кода на JavaScript CSmartInterface<IHtmlCleaner> cleaner; const wchar_t *cleaned=NULL; // получим присланное содердимое редактора content =(wchar_t*)context->request->GetString(IRequest::POST,L"content"); content_len=0; // получим у сервера интерфейс IHtmlCleaner if(RES_FAILED(server->GetInterface(L"IHtmlCleaner",(void**)&cleaner)) || cleaner==NULL) { ExtLogger.Out(context,LOG_STATUS_ERROR,"Update: failed create cleaner"); //--- return(RES_E_FAIL); } //--- укажем URL на котором подсчитываем картинки cleaner->SetImageUrl(L"/board/image/"); //--- запускаем обработку через чистильщик if(RES_FAILED(res=cleaner->Process(context,L"PostRule",content)) || (cleaned=cleaner->GetBuffer(NULL))==NULL) { ReturnErrorExt(res,context,"failed body clean"); } //--- if(cleaned!=NULL && StringCchLength(cleaned,STRSAFE_MAX_CCH,&content_len)==S_OK) { // здесь необходимо сохранить полученный текст туда где вы его будете хранить. Мы настоятельно рекомендуем // использовать для этих целей файловое хранилище. Подробнее все это можно увидеть в модуле Board в SDK }На живом примере все это можно увидеть и проследить под отладчиком на примере модуля Board из TeamWox SDK
|
|
|
|
22.11.2010 16:23
|
#
trophim: У меня тут тележка вопросов образовалась... 2. Каким образом обеспечить возможность работы с аттачментами? Каким образом обеспечить обработку вставки картинок (контрол rte допускает их ставку). Что необходимо обеспечить в своем модуле, чтобы работало добавление аттачей и картинок. Это несколько разные задачи или они схожи по реализации? Объясню на примере модуля Board, входящего в состав SDK. Шаблонная частьСоздание контрола Attachments внутри edit.tpl: ...
attaches = TeamWox.Control("Attachments",
"attachments",
[<tw:attachments />],
"/board/download/",
top.TeamWox.ATTACHMETS_ALL,
"/board/attachments/upload");
...Параметры контрола (начинаются со 2го параметра в функции TeamWox.Control. Первый параметр - название) : {String} name
Имя POST переменных с добавленными файлами.
{Array} files
Уже прикрепленные файлы. Каждый элемент массива описывает файл.
{
"id":"411", // Идентификатор файла в TeamWox
"name":"photo.jpg", // Имя файла
"mime":"image/jpeg", // MIME тип файла
"size":407286, // Размер файла в байтах
"type":1 // Внутренний тип файла, для встроенного просмотрщика
}
Лучше всего выводить эти данные при помощи метода IAttachments::WriteList,
который по имеющимся файлам построит массив нужного вида.
{String} link
Cсылка по которой (с указанием ID) происходит получение файла
{Number} flags Optional
Задает встроенные объекты? которые можно добавить к прикрепленным файлам. Возможные значения:
top.TeamWox.ATTACHMETS_OBJECTS,
top.TeamWox.ATTACHMETS_MINDMAP,
top.TeamWox.ATTACHMETS_CHARTS,
top.TeamWox.ATTACHMETS_DIAGRAM,
top.TeamWox.ATTACHMETS_ALL
{String} uploadLink Optional
Ссылка для загрузки файлов на сервер. Необходима только при добавлении объектов через Flash редактор.
C++ частьФайл PageEdit.cpp. Функция Tag. По определенному тэгу выводим список аттачей: //+------------------------------------------------------------------+ //| Обработка тэга | //+------------------------------------------------------------------+ bool CPageEdit::Tag(const Context *context,const TagInfo *tag) { ... //--- ПРИКРЕПЛЕННЫЕ ФАЙЛЫ if(TagCompare(L"attachments",tag)) { IAttachments *attachments; if(RES_FAILED(m_server->GetInterface(TWX_SERVER,L"IAttachments",(void **)&attachments))) return(false); attachments->WriteList(context,m_server,m_message->GetAttachments(),m_message->GetAttachmentsCount()); //--- return(false); } ...
Файл PageEdit.cpp. Функция OnUpdate. Идет получение удаленных и новых приложенных файлов. Также идет получение файлов, вставленных из других модулей (в нашем случае - это Документы): //+------------------------------------------------------------------+ //| Обработка action'а на обновления | //+------------------------------------------------------------------+ TWRESULT CPageEdit::OnUpdate(const Context *context,const wchar_t *path,IBoards *i_manager) { ... //--- УДАЛЕННЫЕ ФАЙЛЫ if(context->request->Exist(IRequest::POST,L"attachments_deleted") && (id_str=context->request->GetString(IRequest::POST,L"attachments_deleted"))!=NULL) { //--- очистим ZeroMemory(id_list,sizeof(id_list)); id_count=_countof(id_list); //--- распарсим строку и сохраним удаляемые файлы if(StringParse(id_str,id_list,&id_count)==RES_S_OK && id_count>0) { for(int i=0;i<id_count;i++) message->DelAttachments(id_list[i]); } } //--- НОВЫЕ ФАЙЛЫ context->request->PrepareIterator(&it); while(context->request->GetFile(L"attachments",NULL,&file_desc,&it)) { message->AddAttachments(&file_desc); } //--- получим интерфейс для обработки вставки из модулей CSmartInterface <IAttachmentsFiles> attach_files; //--- if(RES_SUCCEEDED(server->GetInterface(L"IAttachmentsFiles",(void**)&attach_files)) && attach_files!=NULL) { CBoardMessage *message_obj=(CBoardMessage*)message; if(RES_SUCCEEDED(attach_files->Init(context))) { for(int tt=0,count=attach_files->Count(); tt<count; tt++) { INT64 id=attach_files->FileId(context, tt); if(id>0) message_obj->AddAttachments(id); } } //--- освободим интерфейс attach_files=NULL; } ... Для более подробной информации смотрите реализацию механизма в модуле Board из SDK. |
|
|
|
23.11.2010 16:22
|
#
Большое спасибо, завтра буду пробовать И, соответственно, писать благодарности... или гневные отзывы :-). P.S. Кстати, почему вы не используете CSmartInterface везде, где это необходимо? Или это зависит от стиля конкретного разработчика? |
|
| К списку тем | 12 |