diff --git a/client/js/views/activity_view.js b/client/js/views/activity_view.js
index 84280b517..029a2e223 100644
--- a/client/js/views/activity_view.js
+++ b/client/js/views/activity_view.js
@@ -172,7 +172,7 @@ App.ActivityView = Backbone.View.extend({
this.model.save({}, {
patch: true,
success: function(model, response) {
- self.flash('danger', "Undo Succeed");
+ self.flash('danger', i18next.t('Undo Succeed'));
if (!_.isUndefined(response.activity)) {
var activity = new App.Activity();
activity.set(response.activity);
diff --git a/client/js/views/admin_activity_index_view.js b/client/js/views/admin_activity_index_view.js
index 8de7f294d..9afd97313 100644
--- a/client/js/views/admin_activity_index_view.js
+++ b/client/js/views/admin_activity_index_view.js
@@ -68,7 +68,7 @@ App.AdminActivityIndexView = Backbone.View.extend({
this.model.save({}, {
patch: true,
success: function(model, response) {
- self.flash('danger', "Undo Succeed");
+ self.flash('danger', i18next.t('Undo Succeed'));
emojify.run();
}
});
diff --git a/client/js/views/admin_board_view.js b/client/js/views/admin_board_view.js
index 26aa8c89f..d84b3095e 100644
--- a/client/js/views/admin_board_view.js
+++ b/client/js/views/admin_board_view.js
@@ -155,7 +155,10 @@ App.AdminBoardView = Backbone.View.extend({
if (this.starred_boards.length === 0 || $('.js-header-starred-boards > .js-board-view').length === 0) {
$('.js-header-starred-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No starred boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('starred boards')]
+ }),
id: 'js-starred-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12 media-list'
}).el);
@@ -179,9 +182,6 @@ App.AdminBoardView = Backbone.View.extend({
success: function(model, response) {
App.boards.get(self.model.attributes.id).boards_stars.reset(self.boardStar);
self.model.boards_stars.add(self.boardStar);
- self.footerView = new App.FooterView({
- model: authuser
- }).renderStarredBoards();
}
});
return false;
@@ -338,7 +338,7 @@ App.AdminBoardView = Backbone.View.extend({
this.model.set('organization_id', parseInt(data.organization_id));
- $('.js-sidebar-board-visibility').html('Change Visibility');
+ $('.js-sidebar-board-visibility').html(i18next.t('Change Visibility'));
var board = new App.Board();
this.model.url = api_url + 'boards/' + this.model.attributes.id + '.json';
diff --git a/client/js/views/admin_boards_index_view.js b/client/js/views/admin_boards_index_view.js
index 919754450..ed50cceb5 100644
--- a/client/js/views/admin_boards_index_view.js
+++ b/client/js/views/admin_boards_index_view.js
@@ -18,7 +18,8 @@ App.AdminBoardsIndexView = Backbone.View.extend({
* Constructor
* initialize default values and actions
*/
- initialize: function() {
+ initialize: function(options) {
+ this.filter_count = options.filter_count;
if (!_.isUndefined(this.model) && this.model !== null) {
this.model.showImage = this.showImage;
}
@@ -35,6 +36,7 @@ App.AdminBoardsIndexView = Backbone.View.extend({
'change .js-more-action-user': 'boardsMoreActions',
'click .js-delete-board': 'deleteBoard',
'click .js-sort': 'sortBoard',
+ 'click .js-filter': 'filterBoard',
},
/**
* deleteBoard()
@@ -68,13 +70,63 @@ App.AdminBoardsIndexView = Backbone.View.extend({
*/
render: function() {
this.$el.html(this.template({
- 'board': this.model
+ 'board': this.model,
+ filter_count: this.filter_count
}));
$('.js-admin-board-menu').addClass('active');
$('.js-admin-activity-menu, .js-admin-setting-menu, .js-admin-email-menu, .js-admin-role-menu, .js-admin-user-menu').removeClass('active');
this.showTooltip();
return this;
},
+ /**
+ * filterBoard()
+ * @param NULL
+ * @return object
+ *
+ */
+ filterBoard: function(e) {
+ var _this = this;
+ _this.current_page = (!_.isUndefined(_this.current_page)) ? _this.current_page : 1;
+ _this.filterField = (!_.isUndefined(e)) ? $(e.currentTarget).data('filter') : _this.filterField;
+ var boards = new App.BoardCollection();
+ boards.url = api_url + 'boards.json?page=' + _this.current_page + '&filter=' + _this.filterField;
+ app.navigate('#/' + 'boards/list?page=' + _this.current_page + '&filter=' + _this.filterField, {
+ trigger: false,
+ trigger_function: false,
+ });
+ $('.js-my-boards').html('');
+ boards.fetch({
+ cache: false,
+ abortPending: true,
+ success: function(boards, response) {
+ if (boards.length !== 0) {
+ boards.each(function(board) {
+ $('.js-my-boards').append(new App.AdminBoardView({
+ model: board
+ }).el);
+ });
+ } else {
+ $('.js-my-boards').html('
No record found ');
+ }
+ $('.js-filter-list').children().removeClass('active');
+ $(e.currentTarget).parent().addClass('active');
+ $('.js-my-boards').find('.timeago').timeago();
+ $('.pagination-boxes').unbind();
+ $('.pagination-boxes').pagination({
+ total_pages: response._metadata.noOfPages,
+ current_page: _this.current_page,
+ display_max: 4,
+ callback: function(event, page) {
+ event.preventDefault();
+ if (page) {
+ _this.current_page = page;
+ _this.sortBoard();
+ }
+ }
+ });
+ }
+ });
+ },
/**
* sortBoard()
* @param NULL
@@ -89,6 +141,10 @@ App.AdminBoardsIndexView = Backbone.View.extend({
var boards = new App.BoardCollection();
boards.setSortField(_this.sortField, _this.sortDirection);
boards.url = api_url + 'boards.json?page=' + _this.current_page + '&sort=' + _this.sortField + '&direction=' + _this.sortDirection;
+ app.navigate('#/' + 'boards/list?page=' + _this.current_page + '&sort=' + _this.sortField + '&direction=' + _this.sortDirection, {
+ trigger: false,
+ trigger_function: false,
+ });
if (!_.isUndefined(e)) {
if ($(e.currentTarget).data('direction') == 'desc') {
$(e.currentTarget).data('direction', 'asc');
@@ -141,7 +197,7 @@ App.AdminBoardsIndexView = Backbone.View.extend({
alert('Please select atleast one record!');
return false;
} else {
- if (window.confirm('Are you sure you want to do this action?')) {
+ if (window.confirm(i18next.t('Are you sure you want to do this action?'))) {
var Board = Backbone.Model.extend({});
var Boards = Backbone.BatchCollection.extend({
model: Board,
@@ -161,7 +217,7 @@ App.AdminBoardsIndexView = Backbone.View.extend({
boards.save({
'success': function(response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
+ self.flash('success', i18next.t('Checked boards are closed successfully.'));
app.navigate('#/boards/list', {
trigger: true,
});
diff --git a/client/js/views/admin_boards_list_view.js b/client/js/views/admin_boards_list_view.js
index 051c21905..540873e1f 100644
--- a/client/js/views/admin_boards_list_view.js
+++ b/client/js/views/admin_boards_list_view.js
@@ -36,6 +36,10 @@ App.AdminBoardsListView = Backbone.View.extend({
_this.current_page = (!_.isUndefined(_this.current_page)) ? _this.current_page : 1;
_this.boards = new App.BoardCollection();
_this.boards.url = api_url + 'boards.json?page=' + _this.current_page;
+ app.navigate('#/' + 'boards/list?page=' + _this.current_page, {
+ trigger: false,
+ trigger_function: false,
+ });
_this.boards.fetch({
cache: false,
abortPending: true,
@@ -46,7 +50,9 @@ App.AdminBoardsListView = Backbone.View.extend({
});
$('#header').html(_this.headerView.el);
$('#js-navbar-default').remove();
- var view = $('#content').html(new App.AdminBoardsIndexView({}).el);
+ var view = $('#content').html(new App.AdminBoardsIndexView({
+ filter_count: response.filter_count
+ }).el);
boards.each(function(board) {
$('.js-my-boards').append(new App.AdminBoardView({
model: board
diff --git a/client/js/views/admin_user_add_view.js b/client/js/views/admin_user_add_view.js
index f359ff4fb..d0f98e56f 100644
--- a/client/js/views/admin_user_add_view.js
+++ b/client/js/views/admin_user_add_view.js
@@ -48,11 +48,15 @@ App.AdminUserAddView = Backbone.View.extend({
user.url = api_url + 'users.json';
user.save(data, {
success: function(model, response) {
- if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ if (response.error) {
+ if (response.error === 1) {
+ self.flash('danger', i18next.t('Email address already exist. Your registration process is not completed. Please, try again.'));
+ } else if (response.error === 2) {
+ self.flash('danger', i18next.t('Username already exists. Your registration process is not completed. Please, try again.'));
+ }
$('#inputPassword').val('');
} else {
- self.flash('success', 'User added successfully.');
+ self.flash('success', i18next.t('User added successfully.'));
target[0].reset();
app.navigate('#/users', {
trigger: true,
diff --git a/client/js/views/admin_user_index_view.js b/client/js/views/admin_user_index_view.js
index c0fdd2b24..265245802 100644
--- a/client/js/views/admin_user_index_view.js
+++ b/client/js/views/admin_user_index_view.js
@@ -36,6 +36,10 @@ App.AdminUserIndexView = Backbone.View.extend({
_this.current_page = (!_.isUndefined(_this.current_page)) ? _this.current_page : 1;
_this.users = new App.UserCollection();
_this.users.url = api_url + 'users.json?page=' + _this.current_page;
+ app.navigate('#/' + 'users?page=' + _this.current_page, {
+ trigger: false,
+ trigger_function: false,
+ });
_this.users.fetch({
cache: false,
abortPending: true,
@@ -46,7 +50,10 @@ App.AdminUserIndexView = Backbone.View.extend({
});
$('#header').html(_this.headerView.el);
$('#js-navbar-default').remove();
- var view = $('#content').html(new App.UserIndexContainerView({}).el);
+ var view = $('#content').html(new App.UserIndexContainerView({
+ filter_count: response.filter_count,
+ roles: response.roles
+ }).el);
users.each(function(user) {
$('.js-user-list').append(new App.UserIndex({
model: user
diff --git a/client/js/views/application_view.js b/client/js/views/application_view.js
index e8c93f9f8..ad34657df 100644
--- a/client/js/views/application_view.js
+++ b/client/js/views/application_view.js
@@ -8,7 +8,7 @@ if (typeof App == 'undefined') {
App = {};
}
var loginExceptionUrl = ['register', 'login', 'forgotpassword', 'user_activation', 'aboutus'];
-var adminUrl = ['roles', 'activities', 'users', 'settings', 'email_templates'];
+var adminUrl = ['roles', 'activities', 'users', 'plugins', 'settings', 'email_templates'];
/**
* Application View
* @class ApplicationView
@@ -23,6 +23,8 @@ App.ApplicationView = Backbone.View.extend({
* initialize default values and actions
*/
initialize: function(options) {
+ $('#content').html('');
+ $('#footer').removeClass('action-open');
var page = this;
page.page_view_type = options.type;
page.page_view_id = options.id;
@@ -63,6 +65,7 @@ App.ApplicationView = Backbone.View.extend({
success: function(model, response) {
api_token = response.access_token;
window.sessionStorage.setItem('links', response.links);
+ window.sessionStorage.setItem('languages', response.languages);
role_links.add(JSON.parse(response.links));
settings.url = api_url + 'settings.json';
settings.fetch({
@@ -76,23 +79,40 @@ App.ApplicationView = Backbone.View.extend({
LABEL_ICON = settings_response.LABEL_ICON;
SITE_TIMEZONE = settings_response.SITE_TIMEZONE;
LDAP_LOGIN_ENABLED = settings_response.LDAP_LOGIN_ENABLED;
+ DEFAULT_LANGUAGE = settings_response.DEFAULT_LANGUAGE;
STANDARD_LOGIN_ENABLED = settings_response.STANDARD_LOGIN_ENABLED;
- if (page.model === "admin_user_add" || page.model === "register") {
- if ((!_.isEmpty(LDAP_LOGIN_ENABLED) && LDAP_LOGIN_ENABLED === "false") || (!_.isEmpty(STANDARD_LOGIN_ENABLED) && (STANDARD_LOGIN_ENABLED === "true"))) {
- page.call_function();
+ PLUGINS = settings_response.plugins;
+ IMAP_EMAIL = settings_response.IMAP_EMAIL;
+ var current_language = DEFAULT_LANGUAGE;
+ if (window.sessionStorage.getItem('auth') !== undefined && window.sessionStorage.getItem('auth') !== null) {
+ current_language = authuser.user.language;
+ }
+ i18next.use(window.i18nextXHRBackend).use(window.i18nextSprintfPostProcessor).init({
+ lng: current_language,
+ fallbackLng: current_language,
+ load: "all",
+ keySeparator: '~',
+ backend: {
+ loadPath: "locales/{{lng}}/{{ns}}.json"
+ }
+ }, function() {
+ if (page.model === "admin_user_add" || page.model === "register") {
+ if ((!_.isEmpty(LDAP_LOGIN_ENABLED) && LDAP_LOGIN_ENABLED === "false") || (!_.isEmpty(STANDARD_LOGIN_ENABLED) && (STANDARD_LOGIN_ENABLED === "true"))) {
+ page.call_function();
+ } else {
+ changeTitle(i18next.t('404 Page not found'));
+ this.headerView = new App.HeaderView({
+ model: authuser
+ });
+ $('#header').html(this.headerView.el);
+ var view = new App.Error404View();
+ $('#content').html(view.el);
+ return;
+ }
} else {
- changeTitle('404 not found');
- this.headerView = new App.HeaderView({
- model: authuser
- });
- $('#header').html(this.headerView.el);
- var view = new App.Error404View();
- $('#content').html(view.el);
- return;
+ page.call_function();
}
- } else {
- page.call_function();
- }
+ });
}
});
},
@@ -116,23 +136,40 @@ App.ApplicationView = Backbone.View.extend({
LABEL_ICON = settings_response.LABEL_ICON;
SITE_TIMEZONE = settings_response.SITE_TIMEZONE;
LDAP_LOGIN_ENABLED = settings_response.LDAP_LOGIN_ENABLED;
+ DEFAULT_LANGUAGE = settings_response.DEFAULT_LANGUAGE;
STANDARD_LOGIN_ENABLED = settings_response.STANDARD_LOGIN_ENABLED;
- if (page.model === "admin_user_add" || page.model === "register") {
- if ((!_.isEmpty(LDAP_LOGIN_ENABLED) && LDAP_LOGIN_ENABLED === "false") || (!_.isEmpty(STANDARD_LOGIN_ENABLED) && (STANDARD_LOGIN_ENABLED === "true"))) {
- page.call_function();
+ PLUGINS = settings_response.plugins;
+ IMAP_EMAIL = settings_response.IMAP_EMAIL;
+ var current_language = DEFAULT_LANGUAGE;
+ if (window.sessionStorage.getItem('auth') !== undefined && window.sessionStorage.getItem('auth') !== null && authuser.user.language !== null && authuser.user.language !== undefined) {
+ current_language = authuser.user.language;
+ }
+ i18next.use(window.i18nextXHRBackend).use(window.i18nextSprintfPostProcessor).init({
+ lng: current_language,
+ fallbackLng: current_language,
+ load: "all",
+ keySeparator: '~',
+ backend: {
+ loadPath: "locales/{{lng}}/{{ns}}.json"
+ }
+ }, function() {
+ if (page.model === "admin_user_add" || page.model === "register") {
+ if ((!_.isEmpty(LDAP_LOGIN_ENABLED) && LDAP_LOGIN_ENABLED === "false") || (!_.isEmpty(STANDARD_LOGIN_ENABLED) && (STANDARD_LOGIN_ENABLED === "true"))) {
+ page.call_function();
+ } else {
+ changeTitle(i18next.t('404 Page not found'));
+ this.headerView = new App.HeaderView({
+ model: authuser
+ });
+ $('#header').html(this.headerView.el);
+ var view = new App.Error404View();
+ $('#content').html(view.el);
+ return;
+ }
} else {
- changeTitle('404 not found');
- this.headerView = new App.HeaderView({
- model: authuser
- });
- $('#header').html(this.headerView.el);
- var view = new App.Error404View();
- $('#content').html(view.el);
- return;
+ page.call_function();
}
- } else {
- page.call_function();
- }
+ });
}
});
} else {
@@ -140,7 +177,7 @@ App.ApplicationView = Backbone.View.extend({
if ((!_.isEmpty(LDAP_LOGIN_ENABLED) && LDAP_LOGIN_ENABLED === "false") || (!_.isEmpty(STANDARD_LOGIN_ENABLED) && (STANDARD_LOGIN_ENABLED === "true"))) {
page.call_function();
} else {
- changeTitle('404 not found');
+ changeTitle(i18next.t('404 Page not found'));
this.headerView = new App.HeaderView({
model: authuser
});
@@ -160,67 +197,70 @@ App.ApplicationView = Backbone.View.extend({
},
set_page_title: function() {
if (this.model == 'login') {
- changeTitle('Login');
+ changeTitle(i18next.t('Login'));
}
if (this.model == 'aboutus') {
- changeTitle('About');
+ changeTitle(i18next.t('About'));
}
if (this.model == 'admin_user_add') {
- changeTitle('Admin Add User');
+ changeTitle(i18next.t('Admin Add User'));
}
if (this.model == 'register') {
- changeTitle('Register');
+ changeTitle(i18next.t('Register'));
}
if (this.model == 'forgotpassword') {
- changeTitle('Forgot Password');
+ changeTitle(i18next.t('Forgot your password'));
}
if (this.model == 'user_activation') {
- changeTitle('User Activation');
+ changeTitle(i18next.t('User Activation'));
}
if (this.model == 'changepassword') {
- changeTitle('Change Password');
+ changeTitle(i18next.t('Change Password'));
}
if (this.model == 'settings') {
- changeTitle('Settings');
+ changeTitle(i18next.t('Settings'));
}
if (this.model == 'boards_index') {
- changeTitle('Boards');
+ changeTitle(i18next.t('Boards'));
}
if (this.model == 'starred_boards_index') {
- changeTitle('Starred Boards');
+ changeTitle(i18next.t('Starred Boards'));
}
if (this.model == 'closed_boards_index') {
- changeTitle('Closed Boards');
+ changeTitle(i18next.t('Closed Boards'));
}
if (this.model == 'organizations_view') {
- changeTitle('Organization');
+ changeTitle(i18next.t('Organization'));
}
if (this.model == 'organizations_view_type') {
- changeTitle('Organization');
+ changeTitle(i18next.t('Organization'));
}
if (this.model == 'organizations_user_view') {
- changeTitle('Organization User');
+ changeTitle(i18next.t('Organization User'));
}
if (this.model == 'users_index') {
- changeTitle('Users');
+ changeTitle(i18next.t('Users'));
}
if (this.model == 'admin_boards_index') {
- changeTitle('Boards');
+ changeTitle(i18next.t('Boards'));
}
if (this.model == 'role_settings') {
- changeTitle('Role Settings');
+ changeTitle(i18next.t('Role Settings'));
+ }
+ if (this.model == 'plugins' || this.model == 'plugin_settings') {
+ changeTitle(i18next.t('Plugins'));
}
if (this.model == 'organizations_index') {
- changeTitle('Organizations');
+ changeTitle(i18next.t('Organizations'));
}
if (this.model == 'email_templates') {
- changeTitle('Email Templates');
+ changeTitle(i18next.t('Email Templates'));
}
if (this.model == 'email_template_type') {
- changeTitle('Email Templates');
+ changeTitle(i18next.t('Email Templates'));
}
if (this.model == 'activity_index') {
- changeTitle('Activities');
+ changeTitle(i18next.t('Activities'));
}
},
/**
@@ -437,13 +477,16 @@ App.ApplicationView = Backbone.View.extend({
var page = this;
$('.company').addClass('hide');
if (page.model == 'boards_view') {
- $('body').css('background', 'transparent');
+ if (!$('body').hasClass('board-view')) {
+ $('body').css('background', 'transparent');
+ }
if (!_.isEmpty(role_links.where({
slug: 'view_board'
}))) {
page.board_view();
}
} else if (page.model == 'organizations_view') {
+ changeTitle(i18next.t('Organization'));
page.organization_view();
} else if (_.isEmpty(authuser.user) && _.indexOf(loginExceptionUrl, page.model) <= -1) {
app.navigate('#/users/login', {
@@ -452,6 +495,7 @@ App.ApplicationView = Backbone.View.extend({
});
} else if (!_.isEmpty(authuser.user) && _.indexOf(loginExceptionUrl, page.model) > -1) {
if (page.model == 'aboutus') {
+ changeTitle(i18next.t('About'));
this.pageView = new App.AboutusView();
$('#content').html(this.pageView.el);
} else {
@@ -464,12 +508,14 @@ App.ApplicationView = Backbone.View.extend({
}
} else {
if (page.model == 'admin_user_add') {
+ changeTitle(i18next.t('Admin Add User'));
var AdminUser = new App.User();
this.pageView = new App.AdminUserAddView({
model: AdminUser
});
$('#content').html(this.pageView.el);
} else if (page.model == 'register') {
+ changeTitle(i18next.t('Register'));
$('.company').removeClass('hide');
var User = new App.User();
this.pageView = new App.RegisterView({
@@ -477,6 +523,7 @@ App.ApplicationView = Backbone.View.extend({
});
$('#content').html(this.pageView.el);
} else if (page.model == 'login') {
+ changeTitle(i18next.t('Login'));
$('.company').removeClass('hide');
var LoginUser = new App.User();
this.pageView = new App.LoginView({
@@ -484,6 +531,7 @@ App.ApplicationView = Backbone.View.extend({
});
$('#content').html(this.pageView.el);
} else if (page.model == 'forgotpassword') {
+ changeTitle(i18next.t('Forgot your password'));
$('.company').removeClass('hide');
var ForgotPasswordUser = new App.User();
this.pageView = new App.ForgotpasswordView({
@@ -491,6 +539,7 @@ App.ApplicationView = Backbone.View.extend({
});
$('#content').html(this.pageView.el);
} else if (page.model == 'user_activation') {
+ changeTitle(i18next.t('User Activation'));
var UserActivation = new App.User();
UserActivation.user_id = page.id;
UserActivation.hash = page.page_view_hash;
@@ -498,6 +547,7 @@ App.ApplicationView = Backbone.View.extend({
model: UserActivation
});
} else if (page.model == 'changepassword') {
+ changeTitle(i18next.t('Change Password'));
var ChangePasswordUser = new App.User();
ChangePasswordUser.user_id = page.id;
this.pageView = new App.ChangepasswordView({
@@ -505,13 +555,17 @@ App.ApplicationView = Backbone.View.extend({
});
$('#content').html(this.pageView.el);
} else if (page.model == 'aboutus') {
+ changeTitle(i18next.t('About'));
this.pageView = new App.AboutusView();
$('#content').html(this.pageView.el);
} else if (page.model == 'boards_index' || page.model == 'starred_boards_index' || page.model == 'closed_boards_index') {
+ changeTitle(i18next.t('Boards'));
var page_title = 'My Boards';
if (page.model == 'starred_boards_index') {
+ changeTitle(i18next.t('Starred Boards'));
page_title = 'Starred Boards';
} else if (page.model == 'closed_boards_index') {
+ changeTitle(i18next.t('Closed Boards'));
page_title = 'Closed Boards';
}
this.headerView = new App.BoardIndexHeaderView({
@@ -575,7 +629,10 @@ App.ApplicationView = Backbone.View.extend({
if ($('.js-header-starred-boards > .js-board-view').length === 0) {
$('.js-header-starred-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No starred boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('starred boards')]
+ }),
id: 'js-starred-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12'
}).el);
@@ -583,7 +640,10 @@ App.ApplicationView = Backbone.View.extend({
} else {
$('.js-header-starred-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No starred boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('starred boards')]
+ }),
id: 'js-starred-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12'
}).el);
@@ -616,7 +676,10 @@ App.ApplicationView = Backbone.View.extend({
if ($('.js-header-closed-boards > .js-board-view').length === 0) {
$('.js-header-closed-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No closed boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('closed boards')]
+ }),
id: 'js-closed-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12'
}).el);
@@ -624,7 +687,10 @@ App.ApplicationView = Backbone.View.extend({
} else {
$('.js-header-closed-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No closed boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('closed boards')]
+ }),
id: 'js-closed-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12'
}).el);
@@ -662,7 +728,10 @@ App.ApplicationView = Backbone.View.extend({
} else {
$('.js-my-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('boards')]
+ }),
id: 'js-my-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12'
}).el);
@@ -675,10 +744,13 @@ App.ApplicationView = Backbone.View.extend({
}
});
} else if (page.model == 'users_index') {
+ changeTitle(i18next.t('Users'));
new App.AdminUserIndexView();
} else if (page.model == 'admin_boards_index') {
+ changeTitle(i18next.t('Boards'));
new App.AdminBoardsListView();
} else if (page.model == 'settings') {
+ changeTitle(i18next.t('Settings'));
$('#js-navbar-default').remove();
$('#content').html(new App.SettingView({
id: page.page_view_id
@@ -709,9 +781,10 @@ App.ApplicationView = Backbone.View.extend({
trigger_function: false,
});
Backbone.history.loadUrl('#/boards');
- page.flash('danger', 'Permission denied');
+ page.flash('danger', i18next.t('Permission denied'));
}
} else if (page.model == 'role_settings') {
+ changeTitle(i18next.t('Role Settings'));
// User View
var acl_links = new App.ACLCollection();
acl_links.url = api_url + 'acl_links.json';
@@ -730,6 +803,7 @@ App.ApplicationView = Backbone.View.extend({
}
});
} else if (page.model == 'organizations_index') {
+ changeTitle(i18next.t('Organizations'));
var organizations = new App.OrganizationCollection();
organizations.url = api_url + 'organizations.json';
organizations.fetch({
@@ -741,12 +815,43 @@ App.ApplicationView = Backbone.View.extend({
}).el);
}
});
+ } else if (page.model == 'plugins') {
+ changeTitle(i18next.t('Plugins'));
+ var plugins = new App.PluginCollection();
+ plugins.url = api_url + 'plugins.json';
+ plugins.fetch({
+ cache: false,
+ abortPending: true,
+ success: function(collections, response) {
+ $('#js-navbar-default').remove();
+ $('#content').html(new App.PluginsView({
+ model: response,
+ }).el);
+ }
+ });
+ } else if (page.model == 'plugin_settings') {
+ changeTitle(i18next.t('Plugin Settings'));
+ var plugin_settings = new App.PluginCollection();
+ plugin_settings.url = api_url + 'plugins/settings.json?plugin=' + page.page_view_id;
+ plugin_settings.fetch({
+ cache: false,
+ abortPending: true,
+ success: function(collections, response) {
+ $('#js-navbar-default').remove();
+ $('#content').html(new App.PluginSettingsView({
+ plugin_settings: response,
+ folder: page.page_view_id
+ }).el);
+ }
+ });
} else if (page.model == 'email_template_type') {
+ changeTitle(i18next.t('Email Templates'));
$('#js-navbar-default').remove();
$('#content').html(new App.EmailTemplateView({
id: page.page_view_id
}).el);
} else if (page.model == 'activity_index') {
+ changeTitle(i18next.t('Activities'));
$('#js-navbar-default').remove();
$('#content').html(new App.ActivityIndexView({
id: page.page_view_id
diff --git a/client/js/views/board_header_view.js b/client/js/views/board_header_view.js
index 91edc493b..8d5dc437b 100644
--- a/client/js/views/board_header_view.js
+++ b/client/js/views/board_header_view.js
@@ -87,6 +87,7 @@ App.BoardHeaderView = Backbone.View.extend({
'click .js-close-sub-popover': 'closeSubPopup',
'click #js-select-google-sync-url': 'selectGoogleSyncUrl',
'click .js-change-background': 'showChangeBackground',
+ 'click .js-email-to-board-settings': 'showEmailToBoardSetting',
'click .js-open-dropdown': 'openDropdown',
'click .js-change-visibility': 'showAllVisibility',
'click .js-show-board-modal': 'showListModal',
@@ -229,10 +230,10 @@ App.BoardHeaderView = Backbone.View.extend({
e.preventDefault();
var name = $(e.currentTarget).attr('name');
var value = 'unsubscribe';
- var content = '
Unsubscribe';
+ var content = '
' + i18next.t('Unsubscribe');
if (name == 'unsubscribe') {
value = 'subscribe';
- content = '
Subscribe';
+ content = '
' + i18next.t('Subscribe');
}
$(e.currentTarget).attr('name', value);
$(e.currentTarget).attr('title', value);
@@ -308,9 +309,6 @@ App.BoardHeaderView = Backbone.View.extend({
App.boards.get(self.model.attributes.id).boards_stars.reset(self.boardStar);
}
self.model.boards_stars.add(self.boardStar);
- self.footerView = new App.FooterView({
- model: authuser
- }).renderStarredBoards();
}
});
return false;
@@ -326,11 +324,11 @@ App.BoardHeaderView = Backbone.View.extend({
closeBoard: function(e) {
e.preventDefault();
this.model.url = api_url + 'boards/' + this.model.id + '.json';
- App.boards.get(this.model.id).set('is_closed', true);
- this.footerView = new App.FooterView({
- model: authuser,
- board_id: this.model.id
- }).renderClosedBoards();
+ App.boards.get(this.model.id).set({
+ is_closed: true
+ }, {
+ silent: true
+ });
var board_id = this.model.id;
this.model.save({
is_closed: true
@@ -352,6 +350,28 @@ App.BoardHeaderView = Backbone.View.extend({
parent.addClass('open');
return false;
},
+ /**
+ * showEmailToBoardSetting()
+ * display Email to board setting form
+ * @return false
+ *
+ */
+ showEmailToBoardSetting: function() {
+ $('.js-side-bar-' + this.model.id).addClass('side-bar-large');
+ var el = this.$el;
+ el.find('.js-setting-response').html(new App.EmailToBoardSettingView({
+ model: this.model
+ }).el);
+ var headerH = $('header').height();
+ var windowH = $(window).height();
+ var footerH = $('footer').height();
+ var boardH = windowH - headerH - footerH - 14;
+ $('.member-modal.js-pre-scrollable').css({
+ 'max-height': boardH - 50,
+ 'overflow-y': 'auto'
+ });
+ return false;
+ },
/**
* showChangeBackground()
* display the board background change form
@@ -1678,8 +1698,8 @@ App.BoardHeaderView = Backbone.View.extend({
contentType: false,
success: function(model, response) {
$('#custom-dropzone-cssloader').removeClass('cssloader');
- if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ if (response.error) {
+ self.flash('danger', i18next.t('File extension not supported. It supports only jpg, png, bmp and gif.'));
} else {
self.model.set({
background_picture_url: ''
@@ -1774,15 +1794,15 @@ App.BoardHeaderView = Backbone.View.extend({
selectBoardVisibility: function(e) {
var name = $(e.currentTarget).attr('name');
var value = 0;
- var content = '
Private';
+ var content = '
' + i18next.t('Private');
$('#js-board-add-organization').html('');
if (name == 'org') {
value = 1;
- content = '
Organization';
+ content = '
' + i18next.t('Organization');
$('#js-change-visible-content').html(content);
this.showBoardAddeOrganizationForm(e);
} else if (name == 'public') {
- content = '
Public';
+ content = '
' + i18next.t('Public');
value = 2;
}
diff --git a/client/js/views/board_member_add_search_result_view.js b/client/js/views/board_member_add_search_result_view.js
index 4dcaaa807..0fbf68f10 100644
--- a/client/js/views/board_member_add_search_result_view.js
+++ b/client/js/views/board_member_add_search_result_view.js
@@ -62,6 +62,7 @@ App.BoardMemberAddSearchResultView = Backbone.View.extend({
}, {
success: function(model, response) {
response.boards_users.is_admin = 0;
+ response.boards_users.user_id = parseInt(response.boards_users.user_id);
board_user.set(response.boards_users);
self.board.board_users.add(board_user);
}
diff --git a/client/js/views/board_simple_view.js b/client/js/views/board_simple_view.js
index e4ab66c34..dae620c36 100644
--- a/client/js/views/board_simple_view.js
+++ b/client/js/views/board_simple_view.js
@@ -144,7 +144,10 @@ App.BoardSimpleView = Backbone.View.extend({
if (this.starred_boards.length === 0 || $('.js-header-starred-boards > .js-board-view').length === 0) {
$('.js-header-starred-boards').append(new App.BoardSimpleView({
model: null,
- message: 'No starred boards available.',
+ message: i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('starred boards')]
+ }),
id: 'js-starred-board-empty',
className: 'col-lg-3 col-md-3 col-sm-4 col-xs-12 media-list'
}).el);
@@ -168,9 +171,6 @@ App.BoardSimpleView = Backbone.View.extend({
success: function(model, response) {
App.boards.get(self.model.attributes.id).boards_stars.reset(self.boardStar);
self.model.boards_stars.add(self.boardStar);
- self.footerView = new App.FooterView({
- model: authuser
- }).renderStarredBoards();
}
});
return false;
@@ -327,7 +327,7 @@ App.BoardSimpleView = Backbone.View.extend({
this.model.set('organization_id', parseInt(data.organization_id));
- $('.js-sidebar-board-visibility').html('Change Visibility');
+ $('.js-sidebar-board-visibility').html(i18next.t('Change Visibility'));
var board = new App.Board();
this.model.url = api_url + 'boards/' + this.model.attributes.id + '.json';
diff --git a/client/js/views/board_view.js b/client/js/views/board_view.js
index c8e8d290b..459fba6c6 100644
--- a/client/js/views/board_view.js
+++ b/client/js/views/board_view.js
@@ -306,10 +306,10 @@ App.BoardView = Backbone.View.extend({
e.preventDefault();
var name = $(e.currentTarget).attr('name');
var value = 'unsubscribe';
- var content = '
Unsubscribe';
+ var content = '
' + i18next.t('Unsubscribe');
if (name == 'unsubscribe') {
value = 'subscribe';
- content = '
Subscribe';
+ content = '
' + i18next.t('Subscribe');
}
$(e.currentTarget).attr('name', value);
$(e.currentTarget).attr('title', value);
@@ -640,6 +640,11 @@ App.BoardView = Backbone.View.extend({
this.renderListsCollection();
this.setBoardBackground();
if (!_.isUndefined(authuser.user)) {
+ var setintervalid = '',
+ is_moving_right = '',
+ previous_offset = 0,
+ previous_move = '',
+ is_create_setinterval = true;
$('#js-board-lists', this.$el).sortable({
containment: 'window',
axis: 'x',
@@ -660,21 +665,48 @@ App.BoardView = Backbone.View.extend({
$(ev.target).find('.js-list-head').children('div.dropdown').removeClass('open');
},
stop: function(ev, ui) {
+ clearInterval(setintervalid);
+ is_create_setinterval = true;
+ previous_offset = 0;
$(ev.target).find('.js-list-head').addClass('cur-grab');
},
over: function(ev, ui) {
var scrollLeft = 0;
- if ((($(window).width() - ui.offset.left) < 520) || (ui.offset.left > $(window).width())) {
- scrollLeft = $('#js-board-lists').scrollLeft() + ($(window).width() - ui.offset.left);
- $('#js-board-lists').stop().animate({
- scrollLeft: scrollLeft
- }, 800);
- } else if (ui.offset.left <= 260) {
- scrollLeft = $('#js-board-lists').scrollLeft() - ($(window).width() - ui.offset.left);
- $('#js-board-lists').stop().animate({
- scrollLeft: scrollLeft
- }, 800);
+ var list_per_page = Math.floor($(window).width() / 270);
+ if (previous_offset !== 0 && previous_offset != ui.offset.left) {
+ if (previous_offset > ui.offset.left) {
+ is_moving_right = false;
+ } else {
+ is_moving_right = true;
+ }
+ }
+ if (previous_move !== is_moving_right) {
+ clearInterval(setintervalid);
+ is_create_setinterval = true;
+ }
+ if (is_moving_right === true && ui.offset.left > (list_per_page - 1) * 270) {
+ if (is_create_setinterval) {
+ setintervalid = setInterval(function() {
+ scrollLeft = parseInt($('#js-board-lists').scrollLeft()) + 50;
+ $('#js-board-lists').animate({
+ scrollLeft: scrollLeft
+ }, 10);
+ }, 100);
+ is_create_setinterval = false;
+ }
+ } else if (is_moving_right === false && ui.offset.left < 50) {
+ if (is_create_setinterval) {
+ setintervalid = setInterval(function() {
+ scrollLeft = parseInt($('#js-board-lists').scrollLeft()) - 50;
+ $('#js-board-lists').animate({
+ scrollLeft: scrollLeft
+ }, 10);
+ }, 100);
+ is_create_setinterval = false;
+ }
}
+ previous_offset = ui.offset.left;
+ previous_move = is_moving_right;
}
});
}
@@ -702,6 +734,18 @@ App.BoardView = Backbone.View.extend({
*
*/
renderListsCollection: function() {
+ App.sortable = {};
+ App.sortable.setintervalid_horizontal = '';
+ App.sortable.setintervalid_vertical = '';
+ App.sortable.is_moving_right = '';
+ App.sortable.is_moving_top = '';
+ App.sortable.previous_offset_horizontal = 0;
+ App.sortable.previous_offset_vertical = 0;
+ App.sortable.previous_move_horizontal = '';
+ App.sortable.previous_move_vertical = '';
+ App.sortable.is_create_setinterval_horizontal = true;
+ App.sortable.is_create_setinterval_vertical = true;
+ App.sortable.previous_id = '';
var self = this;
var view_list = self.$('#js-add-list-block');
var list_content = '';
@@ -971,10 +1015,18 @@ App.BoardView = Backbone.View.extend({
}
data.is_archived = false;
data.board_id = self.model.id;
- if (_.isUndefined(data.clone_list_id)) {
+ var view = '';
+ if (!_.isUndefined(data.clone_list_id)) {
list.set(data, {
silent: true
});
+ view = new App.ListView({
+ model: list,
+ attributes: {
+ 'data-list_id': list.attributes.id,
+ },
+ });
+ $(view.render().el).insertAfter($(e.target).parents('.js-board-list'));
}
list.url = api_url + 'boards/' + self.model.id + '/lists.json';
list.save(data, {
@@ -998,7 +1050,9 @@ App.BoardView = Backbone.View.extend({
}
list.set(response.list);
list.set('cards', response.list.cards);
- self.model.cards.add(response.list.cards);
+ self.model.cards.add(response.list.cards, {
+ silent: true
+ });
var i = 1;
_.each(response.list.attachments, function(attachment) {
var options = {
@@ -1078,15 +1132,15 @@ App.BoardView = Backbone.View.extend({
});
App.boards.get(list.attributes.board_id).lists.add(list);
list.board_users = self.model.board_users;
- var view = new App.ListView({
- model: list,
- attributes: {
- 'data-list_id': list.attributes.id,
- },
- });
if (!_.isUndefined(data.clone_list_id)) {
$(view.render().el).insertAfter($(e.target).parents('.js-board-list'));
} else {
+ view = new App.ListView({
+ model: list,
+ attributes: {
+ 'data-list_id': list.attributes.id,
+ },
+ });
$(view.render().el).insertBefore($('#js-add-list-block'));
}
}
diff --git a/client/js/views/card_checklist_view.js b/client/js/views/card_checklist_view.js
index c6f10de64..be297257f 100644
--- a/client/js/views/card_checklist_view.js
+++ b/client/js/views/card_checklist_view.js
@@ -249,7 +249,7 @@ App.CardCheckListView = Backbone.View.extend({
updateChecklist: function(e) {
if (!$.trim($('#checklistEditName').val()).length) {
$('.error-msg').remove();
- $('
Whitespace alone not allowed
').insertAfter('#checklistEditName');
+ $('
' + i18next.t('Whitespace alone not allowed') + '
').insertAfter('#checklistEditName');
} else {
$('.error-msg').remove();
e.preventDefault();
@@ -369,7 +369,7 @@ App.CardCheckListView = Backbone.View.extend({
addChecklistItem: function(e) {
if (!$.trim($('#ChecklistItem').val()).length) {
$('.error-msg').remove();
- $('
Whitespace alone not allowed
').insertAfter('#ChecklistItem');
+ $('
' + i18next.t('Whitespace alone not allowed') + '
').insertAfter('#ChecklistItem');
return false;
} else {
$('.error-msg').remove();
diff --git a/client/js/views/card_view.js b/client/js/views/card_view.js
index fb9c2df11..1047e7098 100644
--- a/client/js/views/card_view.js
+++ b/client/js/views/card_view.js
@@ -335,7 +335,7 @@ App.CardView = Backbone.View.extend({
content_position += '
' + i + ' ';
}
self.$el.find('.js-card-add-position').val(i);
- content_position += '
' + i + ' (current) ';
+ content_position += '
' + i + ' ' + i18next.t('(current)') + ' ';
self.$el.find('.js-position').html(content_position);
return false;
},
@@ -366,7 +366,10 @@ App.CardView = Backbone.View.extend({
return false;
}
if (!_.isEmpty(this.model.attributes.name)) {
- changeTitle('Card - ' + _.escape(this.model.attributes.name) + ' on ' + _.escape(this.model.list.collection.board.attributes.name));
+ changeTitle(i18next.t('Card - %s on %s', {
+ postProcess: 'sprintf',
+ sprintf: [_.escape(this.model.attributes.name), _.escape(this.model.list.collection.board.attributes.name)]
+ }));
}
var current_param = Backbone.history.fragment;
if (!_.isUndefined(this.model.id) && (card_ids_ref[0] === 0 || _.indexOf(card_ids_ref, this.model.id) === -1)) {
diff --git a/client/js/views/checklist_actions_view.js b/client/js/views/checklist_actions_view.js
index 8a6deaa77..0b0f3f46c 100644
--- a/client/js/views/checklist_actions_view.js
+++ b/client/js/views/checklist_actions_view.js
@@ -28,7 +28,7 @@ App.ChecklistActionsView = Backbone.View.extend({
tagName: 'a',
className: 'js-show-confirm-checklist-delete',
attributes: {
- 'title': 'Delete This Checklist',
+ 'title': i18next.t('Delete This Checklist'),
'href': '#'
},
/**
diff --git a/client/js/views/email_template_view.js b/client/js/views/email_template_view.js
index a028366e2..846ea1b76 100644
--- a/client/js/views/email_template_view.js
+++ b/client/js/views/email_template_view.js
@@ -41,9 +41,9 @@ App.EmailTemplateView = Backbone.View.extend({
email_template.save(data, {
success: function(model, response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
+ self.flash('success', i18next.t('Email Template has been updated successfully.'));
} else {
- self.flash('danger', 'Email Template not updated properly.');
+ self.flash('danger', i18next.t('Email Template not updated properly.'));
}
}
});
diff --git a/client/js/views/email_to_board_setting_view.js b/client/js/views/email_to_board_setting_view.js
new file mode 100644
index 000000000..2126e63ea
--- /dev/null
+++ b/client/js/views/email_to_board_setting_view.js
@@ -0,0 +1,78 @@
+/**
+ * @fileOverview This file has functions related to archived items view. This view calling from board header view.
+ * Available Object:
+ * App.boards : this object contain all boards(Based on logged in user)
+ * this.model : board model and it's related values. It contain all board based object @see Available Object in App.BoardView
+ */
+if (typeof App == 'undefined') {
+ App = {};
+}
+/**
+ * Email To Board Setting View
+ * @class EmailToBoardSettingView
+ * @constructor
+ * @extends Backbone.View
+ */
+App.EmailToBoardSettingView = Backbone.View.extend({
+ tagName: 'li',
+ template: JST['templates/email_to_board_setting'],
+ /**
+ * Constructor
+ * initialize default values and actions
+ */
+ initialize: function() {
+ if (!_.isUndefined(this.model) && this.model !== null) {
+ this.model.showImage = this.showImage;
+ }
+ this.render();
+ },
+ /**
+ * Events
+ * functions to fire on events (Mouse events, Keyboard Events, Frame/Object Events, Form Events, Drag Events, etc...)
+ */
+ events: {
+ 'change .js-select-list, .js-select-position': 'updateDefaultEmailDetail',
+ 'click .js-select-list, .js-select-position, .js-board-email': 'updateDefaultEmailDetail',
+ },
+ /**
+ * render()
+ * populate the html to the dom
+ * @param NULL
+ * @return object
+ *
+ */
+ render: function() {
+ var imap_email = IMAP_EMAIL.split('@');
+ var board_email = imap_email[0] + '+' + this.model.id + '+' + calcMD5(SecuritySalt + this.model.id + SITE_NAME) + '@' + imap_email[1];
+ this.$el.html(this.template({
+ board: this.model,
+ board_email: board_email
+ }));
+ this.showTooltip();
+ return this;
+ },
+ updateDefaultEmailDetail: function(e) {
+ var data = {};
+ if ($(e.currentTarget).hasClass('js-select-list')) {
+ data = {
+ default_email_list_id: $(e.currentTarget).val()
+ };
+ } else if ($(e.currentTarget).hasClass('js-select-position')) {
+ data = {
+ is_default_email_position_as_bottom: $(e.currentTarget).val()
+ };
+ }
+ if (!_.isEmpty(data)) {
+ var board = new App.Board();
+ this.model.set(data);
+ App.boards.get(this.model.attributes.id).set(data);
+ board.set(data);
+ board.set('id', this.model.id);
+ board.url = api_url + 'boards/' + this.model.id + '.json';
+ board.save(data, {
+ patch: true
+ });
+ }
+ return false;
+ }
+});
diff --git a/client/js/views/footer_view.js b/client/js/views/footer_view.js
index 3fd8be9ed..5e2142003 100644
--- a/client/js/views/footer_view.js
+++ b/client/js/views/footer_view.js
@@ -27,6 +27,7 @@ App.FooterView = Backbone.View.extend({
'click .js-show-organizations-add-form': 'showOrganizationsAddForm',
'click .js-show-instant-card-from': 'showInstantCardFrom',
'click .js-show-chat': 'showChat',
+ 'click .js-show-qr-code': 'showQrCode',
'click .js-show-boards-list': 'showBoardsList',
'click .js-collapse-myboards': 'collapseMyBoards',
'click .js-collapse-closedboards': 'collapseClosedBoards',
@@ -38,6 +39,7 @@ App.FooterView = Backbone.View.extend({
'click .js-all-activities': function() {
$('#js-load-link2, .js-all-activity-list').removeClass('hide');
$('#js-load-link1, .js-boards-activity-list').addClass('hide');
+ $('#js-all-activities').empty();
this.userActivities(false, 2);
},
'click .js-all-user-activities': 'showUserActivities',
@@ -47,6 +49,7 @@ App.FooterView = Backbone.View.extend({
$('#js-notification-load-more-all').removeClass('js-all-load-more-all').addClass('js-board-load-more-all');
$('#js-load-link2, .js-all-activity-list').addClass('hide');
$('#js-load-link1, .js-boards-activity-list').removeClass('hide');
+ $('#js-board-activities').empty();
this.boardActivities();
},
'click .js-all-board-activities': 'showBoardActivities',
@@ -57,6 +60,7 @@ App.FooterView = Backbone.View.extend({
'focusout .js-search': 'searchClose',
'submit form.js-instantCardAddForm': 'addInstantCard',
'click .js-show-notification': 'showNotification',
+ 'click .js-change-language': 'changeLanguage',
'click .js-back-boards-list': 'showBackBoardsList',
'click .js-board-load-more': function(e) {
e.preventDefault();
@@ -81,6 +85,9 @@ App.FooterView = Backbone.View.extend({
'click .js-enable-desktop-notification': 'enabledesktopNotification',
'click .js-show-board-import-form': 'showBoardImportForm',
'change .js-board-import-file': 'importBoard',
+ 'click .js-closed-boards': 'renderClosedBoards',
+ 'click .js-starred-boards': 'renderStarredBoards',
+ 'click .js-my-boards-listing': 'renderMyBoards',
},
/**
* Constructor
@@ -102,9 +109,6 @@ App.FooterView = Backbone.View.extend({
this.board = options.board;
this.boards = options.boards;
_.bindAll(this, 'renderClosedBoards', 'renderStarredBoards');
- if (!_.isUndefined(App.boards)) {
- App.boards.bind('add remove change', this.renderClosedBoards);
- }
},
/**
* render()
@@ -135,6 +139,7 @@ App.FooterView = Backbone.View.extend({
this.$el.html(this.template({
model: this.model,
board_id: this.board_id,
+ languages: window.sessionStorage.getItem('languages').split(',')
}));
if (_.isEmpty(this.board_id)) {
if (!_.isUndefined(authuser.user)) {
@@ -217,6 +222,38 @@ App.FooterView = Backbone.View.extend({
}
return false;
},
+ /**
+ * changeLanguage()
+ * Change language
+ * @param e
+ * @type Object(DOM event)
+ * @return false
+ *
+ */
+ changeLanguage: function(e) {
+ e.preventDefault();
+ var self = this;
+ authuser.user.language = $(e.currentTarget).data('lang');
+ var Auth = JSON.parse(window.sessionStorage.getItem('auth'));
+ Auth.user.language = $(e.currentTarget).data('lang');
+ window.sessionStorage.setItem('auth', JSON.stringify(Auth));
+ var user = new App.User();
+ user.url = api_url + 'users/' + authuser.user.id + '.json';
+ user.set('id', parseInt(authuser.user.id));
+ user.save({
+ 'language': $(e.currentTarget).data('lang')
+ }, {
+ success: function(user, response) {
+ i18next.changeLanguage($(e.currentTarget).data('lang'));
+ if (!_.isEmpty(response.success)) {
+ $('.js-change-language-form-response').find('i').remove();
+ self.flash('success', i18next.t('Language changed successfully.'));
+ $(e.currentTarget).append('
');
+ }
+ }
+ });
+ return false;
+ },
/**
* showInstantCardFrom()
* show instant card add form
@@ -252,6 +289,21 @@ App.FooterView = Backbone.View.extend({
});
return false;
},
+ /**
+ * showQrCode()
+ * show QR code form
+ * @param e
+ * @type Object(DOM event)
+ * @return false
+ *
+ */
+ showQrCode: function(e) {
+ e.preventDefault();
+ var qr_code = new App.QrCodeView({
+ model: qr_code,
+ });
+ return false;
+ },
/**
* showBackBoardsList()
* Back to Boards list form
@@ -406,10 +458,16 @@ App.FooterView = Backbone.View.extend({
var my_boards = '';
var self = this;
self.boards = App.boards;
- if (!_.isUndefined(App.boards)) {
- App.boards.bind('add remove change', this.renderClosedBoards);
- }
- if (!_.isEmpty(role_links.where({
+ },
+ /**
+ * renderMyBoards()
+ * collapse my board lists
+ * @return false
+ *
+ */
+ renderMyBoards: function() {
+ this.boards = App.boards;
+ if (!_.isEmpty(this.boards) && !_.isEmpty(role_links.where({
slug: 'view_my_boards'
}))) {
var view_my_board = $('.js-myboard-list');
@@ -439,9 +497,6 @@ App.FooterView = Backbone.View.extend({
}).el);
}
}
- this.renderStarredBoards();
- this.renderClosedBoards();
-
},
/**
* renderStarredBoards()
@@ -690,6 +745,7 @@ App.FooterView = Backbone.View.extend({
success: function() {
$('#js-activity-loader').remove();
if (!_.isEmpty(activities.models)) {
+ $('#js-load-link').removeClass('hide');
var last_activity = _.min(activities.models, function(activity) {
return activity.id;
});
@@ -1379,7 +1435,7 @@ App.FooterView = Backbone.View.extend({
model: response.hits.hits
}).el;
} else {
- content = 'No results.';
+ content = i18next.t('No record found.');
}
$('.js-show-search-result').html(content);
$('.js-boards-list-container-search').addClass('hide');
@@ -1505,7 +1561,7 @@ App.FooterView = Backbone.View.extend({
if (type === 'user') {
view_activity = $('#js-all-activities');
query_string = (last_user_activity_id !== 0 && !_.isUndefined(last_user_activity_id)) ? '&last_activity_id=' + last_user_activity_id : '';
- activities.url = api_url + 'users/' + authuser.user.id + '/activities.json?type=all' + query_string;
+ activities.url = api_url + 'users/' + authuser.user.id + '/activities.json?type=profile' + query_string;
} else {
view_activity = $('#js-board-activities');
query_string = (load_more_last_board_activity_id !== 0 && !_.isUndefined(load_more_last_board_activity_id)) ? '&last_activity_id=' + load_more_last_board_activity_id : '';
@@ -1542,6 +1598,7 @@ App.FooterView = Backbone.View.extend({
modeType = '';
}
activities.each(function(activity) {
+ activity.from_footer = true;
var view = new App.ActivityView({
model: activity,
board: self.board,
@@ -1551,6 +1608,7 @@ App.FooterView = Backbone.View.extend({
});
} else {
if (type == 'user') {
+ $('#js-load-link').addClass('hide');
$('#js-load-link2').addClass('hide');
} else if (type == 'board') {
$('#js-load-link1').addClass('hide');
@@ -1626,12 +1684,7 @@ App.FooterView = Backbone.View.extend({
replace: true
});
} else {
- var error = 'Unable to import. please try again.';
- if (!_.isUndefined(response.error)) {
- error = response.error;
- }
- self.flash('danger', error);
-
+ self.flash('danger', i18next.t('Unable to import. please try again.'));
}
}
});
diff --git a/client/js/views/header_view.js b/client/js/views/header_view.js
index 659e6340c..458aa8987 100644
--- a/client/js/views/header_view.js
+++ b/client/js/views/header_view.js
@@ -59,8 +59,11 @@ App.HeaderView = Backbone.View.extend({
*/
render: function() {
this.model.is_show_enable_notification = false;
- var current_param = Backbone.history.fragment;
- var current_param_split = current_param.split('/');
+ var current_param = Backbone.history.fragment.split('?');
+ if (current_param[0].indexOf('/') === 0) {
+ current_param[0] = current_param[0].substr(1);
+ }
+ var current_param_split = current_param[0].split('/');
this.model.current_param = (current_param.indexOf('changepassword') === -1 && current_param.indexOf('login') === -1 && current_param.indexOf('forgotpassword') === -1 && current_param.indexOf('register') === -1 && current_param.indexOf('activation') === -1) ? current_param_split[0] : '';
if (!_.isEmpty(current_param_split[1]) && current_param_split[1] === 'list') {
this.model.current_param = 'admin_boards_list';
@@ -70,6 +73,37 @@ App.HeaderView = Backbone.View.extend({
}
this.$el.html(this.template(this.model));
this.showTooltip();
+ if (load_count === 1) {
+ load_count++;
+ _.each(PLUGINS, function(plugin, key) {
+ var s, l, v = '';
+ if (key === 'settings') {
+ s = document.createElement('script');
+ _.each(plugin, function(client_id, key) {
+ v += "var " + client_id.name + " = '" + client_id.value + "';";
+ });
+ s.text = v;
+ document.body.appendChild(s);
+ }
+ if (key === 'js') {
+ _.each(plugin, function(js, key) {
+ s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.src = js;
+ document.body.appendChild(s);
+ });
+ }
+ if (key === 'css') {
+ _.each(plugin, function(css, key) {
+ l = document.createElement('link');
+ l.rel = 'stylesheet';
+ l.type = 'text/css';
+ l.href = css;
+ document.head.appendChild(l);
+ });
+ }
+ });
+ }
return this;
},
renderList: function() {
diff --git a/client/js/views/instant_card_add_view.js b/client/js/views/instant_card_add_view.js
index 6f2af1bfb..706a6ae01 100644
--- a/client/js/views/instant_card_add_view.js
+++ b/client/js/views/instant_card_add_view.js
@@ -46,7 +46,7 @@ App.InstantCardAddView = Backbone.View.extend({
className: 'js-instant-card-from',
tagName: 'div',
attributes: {
- 'title': 'Instant Add Card'
+ 'title': i18next.t('Instant Add Card')
},
bindings: {
'#board_id': {
@@ -101,7 +101,10 @@ App.InstantCardAddView = Backbone.View.extend({
this.$('.js-instant-card-user-ids').val('');
this.$('.js-instant-card-member-search-response').nextAll().remove();
this.$('#inputInstantCardAddUserSearch').val('');
- $('
Search for a person in ' + SITE_NAME + ' by name or email address.
').insertAfter(this.$('.js-instant-card-member-search-response'));
+ $('
' + i18next.t('Search for a person in %s by name or email address.', {
+ postProcess: 'sprintf',
+ sprintf: [SITE_NAME]
+ }) + '
').insertAfter(this.$('.js-instant-card-member-search-response'));
var list_arr = [];
if (!_.isUndefined(board)) {
_.each(board.attributes.lists, function(list) {
@@ -143,7 +146,7 @@ App.InstantCardAddView = Backbone.View.extend({
var self = this;
$('.js-hidden-blocks').append(this.$el.html(this.template({
boards: this.boards
- })).attr('title', 'Instant Add Card'));
+ })).attr('title', i18next.t('Instant Add Card')));
this.$el.dockmodal({
initialState: 'docked',
height: 300,
@@ -399,7 +402,7 @@ App.InstantCardAddView = Backbone.View.extend({
this.$('.js-instant-user').parent().addClass('js-tooltip').attr('data-original-title', this.card_users_names.join(',')).attr('title', this.card_users_names.join(','));
$('.js-tooltip').tooltip();
if (this.card_users.length === 0) {
- this.$('.js-instant-user').removeClass('text-primary').parent().removeClass('js-tooltip').attr('data-original-title', '').attr('title', 'Users');
+ this.$('.js-instant-user').removeClass('text-primary').parent().removeClass('js-tooltip').attr('data-original-title', '').attr('title', i18next.t('Users'));
}
this.$('.js-card-user-ids').val(this.card_users.join(','));
},
@@ -434,7 +437,7 @@ App.InstantCardAddView = Backbone.View.extend({
var _labels = _.pluck(self.$('.js-card-label').select2('data'), 'text');
self.$('.js-instant-label').parent().attr('data-original-title', _labels.join(',')).attr('title', _labels.join(','));
if (self.$('.js-card-label').select2('data').length === 0) {
- self.$('.js-instant-label').removeClass('text-primary').parent().removeClass('js-tooltip').attr('data-original-title', '').attr('title', 'Labels');
+ self.$('.js-instant-label').removeClass('text-primary').parent().removeClass('js-tooltip').attr('data-original-title', '').attr('title', i18next.t('Labels'));
}
});
}
diff --git a/client/js/views/list_view.js b/client/js/views/list_view.js
index bfabd6162..b365074f5 100644
--- a/client/js/views/list_view.js
+++ b/client/js/views/list_view.js
@@ -55,16 +55,18 @@ App.ListView = Backbone.View.extend({
}
_.bindAll(this, 'render', 'renderCardsCollection', 'removeRender');
this.model.bind('change:name', this.render);
- this.model.collection.board.labels.bind('add', this.renderCardsCollection);
- this.model.collection.board.attachments.bind('add', this.renderCardsCollection);
- this.model.collection.board.attachments.bind('remove', this.renderCardsCollection);
- this.model.collection.board.cards.bind('add', this.renderCardsCollection);
- this.model.collection.board.cards.bind('add:name', this.renderCardsCollection);
- this.model.collection.board.cards.bind('add:id', this.renderCardsCollection);
- this.model.collection.board.cards.bind('remove', this.renderCardsCollection);
- this.model.collection.board.cards.bind('change:position', this.renderCardsCollection);
- this.model.collection.board.cards.bind('change:is_archived', this.renderCardsCollection);
- this.model.collection.board.cards.bind('change:list_id', this.renderCardsCollection);
+ if (!_.isUndefined(this.model.collection)) {
+ this.model.collection.board.labels.bind('add', this.renderCardsCollection);
+ this.model.collection.board.attachments.bind('add', this.renderCardsCollection);
+ this.model.collection.board.attachments.bind('remove', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('add', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('add:name', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('add:id', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('remove', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('change:position', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('change:is_archived', this.renderCardsCollection);
+ this.model.collection.board.cards.bind('change:list_id', this.renderCardsCollection);
+ }
this.model.bind('remove', this.removeRender);
},
template: JST['templates/list'],
@@ -677,8 +679,11 @@ App.ListView = Backbone.View.extend({
list_id: list_id
});
_.each(archived_cards, function(archived_card) {
- self.model.collection.board.cards.get(archived_card.attributes.id).set('is_archived', 1);
+ self.model.collection.board.cards.get(archived_card.attributes.id).set('is_archived', 1, {
+ silent: true
+ });
});
+ this.renderCardsCollection();
var card = new App.Card();
card.set('id', list_id);
card.url = api_url + 'boards/' + this.board.id + '/lists/' + list_id + '/cards.json';
@@ -709,7 +714,7 @@ App.ListView = Backbone.View.extend({
placeholder: 'card-list-placeholder',
appendTo: document.body,
dropOnEmpty: true,
- cursor: 'grabbing',
+ cursor: 'grab',
helper: 'clone',
tolerance: 'pointer',
scrollSensitivity: 100,
@@ -725,35 +730,101 @@ App.ListView = Backbone.View.extend({
},
stop: function(ev, ui) {
$('.js-show-modal-card-view ').addClass('cur');
+ clearInterval(App.sortable.setintervalid_horizontal);
+ clearInterval(App.sortable.setintervalid_vertical);
+ App.sortable.is_create_setinterval_horizontal = true;
+ App.sortable.is_create_setinterval_vertical = true;
+ App.sortable.previous_offset_horizontal = 0;
+ App.sortable.previous_offset_vertical = 0;
},
over: function(ev, ui) {
+ if ($(ui.placeholder).parents('.js-board-list-cards').attr('id') == App.sortable.previous_id) {
+ clearInterval(App.sortable.setintervalid_horizontal);
+ }
var scrollLeft = 0;
- if ((($(window).width() - ui.offset.left) < 520) || (ui.offset.left > $(window).width())) {
- scrollLeft = $('#js-board-lists').stop().scrollLeft() + ($(window).width() - ui.offset.left);
- $('#js-board-lists').animate({
- scrollLeft: scrollLeft
- }, 800);
- } else if (ui.offset.left <= 260) {
- scrollLeft = $('#js-board-lists').stop().scrollLeft() - ($(window).width() - ui.offset.left);
- $('#js-board-lists').animate({
- scrollLeft: scrollLeft
- }, 800);
+ var list_per_page = Math.floor($(window).width() / 270);
+ if (App.sortable.previous_offset_horizontal !== 0 && App.sortable.previous_offset_horizontal != ui.offset.left) {
+ if (App.sortable.previous_offset_horizontal > ui.offset.left) {
+ App.sortable.is_moving_right = false;
+ } else {
+ App.sortable.is_moving_right = true;
+ }
}
-
+ if (App.sortable.previous_move_horizontal !== App.sortable.is_moving_right) {
+ clearInterval(App.sortable.setintervalid_horizontal);
+ App.sortable.is_create_setinterval_horizontal = true;
+ }
+ if (App.sortable.is_moving_right === true && ui.offset.left > (list_per_page - 1) * 230) {
+ if (App.sortable.is_create_setinterval_horizontal) {
+ App.sortable.setintervalid_horizontal = setInterval(function() {
+ scrollLeft = parseInt($('#js-board-lists').scrollLeft()) + 50;
+ $('#js-board-lists').animate({
+ scrollLeft: scrollLeft
+ }, 10);
+ }, 100);
+ App.sortable.is_create_setinterval_horizontal = false;
+ }
+ } else if (App.sortable.is_moving_right === false && ui.offset.left < (list_per_page - 1) * 100) {
+ if (App.sortable.is_create_setinterval_horizontal) {
+ App.sortable.setintervalid_horizontal = setInterval(function() {
+ scrollLeft = parseInt($('#js-board-lists').scrollLeft()) - 50;
+ $('#js-board-lists').animate({
+ scrollLeft: scrollLeft
+ }, 10);
+ }, 100);
+ App.sortable.is_create_setinterval_horizontal = false;
+ }
+ }
+ App.sortable.previous_offset_horizontal = ui.offset.left;
+ App.sortable.previous_move_horizontal = App.sortable.is_moving_right;
},
- change: function(event, ui) {
+ sort: function(event, ui) {
+ App.sortable.previous_id = $(ui.placeholder).parents('.js-board-list-cards').attr('id');
var scrollTop = 0;
- if ((($(window).height() - ui.offset.top) < 350) || (ui.offset.top > $(window).height())) {
- scrollTop = $(this).scrollTop() + ($(window).height() - ui.offset.top);
- $(this).stop().animate({
- scrollTop: scrollTop
- }, 800);
- } else if (ui.offset.top <= 230) {
- scrollTop = $(this).scrollTop() - ($(window).height() - ui.offset.top);
- $(this).stop().animate({
- scrollTop: scrollTop
- }, 800);
+ var decrease_height = 0;
+ var list_height = $('#' + App.sortable.previous_id).height();
+ var additional_top = parseInt($('#js-board-lists').position().top) + parseInt($('#' + App.sortable.previous_id).position().top);
+ var total_top = parseInt(list_height) + parseInt(additional_top);
+ if (ui.placeholder.height() > list_height) {
+ decrease_height = parseInt(ui.placeholder.height()) - parseInt(list_height);
+ } else {
+ decrease_height = parseInt(list_height) - parseInt(ui.placeholder.height());
+ }
+ var total_top1 = (parseInt($('#js-board-lists').position().top) + parseInt(ui.placeholder.position().top)) - decrease_height;
+ if (App.sortable.previous_offset_vertical !== 0) {
+ if (App.sortable.previous_offset_vertical > ui.offset.top) {
+ App.sortable.is_moving_top = false;
+ } else {
+ App.sortable.is_moving_top = true;
+ }
+ }
+ if (App.sortable.previous_move_vertical !== App.sortable.is_moving_top) {
+ clearInterval(App.sortable.setintervalid_vertical);
+ App.sortable.is_create_setinterval_vertical = true;
+ }
+ if (App.sortable.is_moving_top === true && (ui.offset.top > total_top || (total_top1 > 0 && ui.offset.top > total_top1))) {
+ if (App.sortable.is_create_setinterval_vertical) {
+ App.sortable.setintervalid_vertical = setInterval(function() {
+ scrollTop = parseInt($('#' + App.sortable.previous_id).scrollTop()) + 50;
+ $('#' + App.sortable.previous_id).animate({
+ scrollTop: scrollTop
+ }, 50);
+ }, 100);
+ App.sortable.is_create_setinterval_vertical = false;
+ }
+ } else if (App.sortable.is_moving_top === false && ui.offset.top < (additional_top - 20)) {
+ if (App.sortable.is_create_setinterval_vertical) {
+ App.sortable.setintervalid_vertical = setInterval(function() {
+ scrollTop = parseInt($('#' + App.sortable.previous_id).scrollTop()) - 50;
+ $('#' + App.sortable.previous_id).animate({
+ scrollTop: scrollTop
+ }, 50);
+ }, 100);
+ App.sortable.is_create_setinterval_vertical = false;
+ }
}
+ App.sortable.previous_offset_vertical = ui.offset.top;
+ App.sortable.previous_move_vertical = App.sortable.is_moving_top;
}
});
}
@@ -1147,7 +1218,7 @@ App.ListView = Backbone.View.extend({
var current_position = this.model.collection.indexOf(this.model) + 1;
for (var i = 1; i <= board_lists.length; i++) {
if (self.model.attributes.board_id == board.attributes.id && i == current_position) {
- content_position += '
' + i + '(current) ';
+ content_position += '
' + i + i18next.t('(current)') + ' ';
} else {
content_position += '
' + i + ' ';
}
@@ -1181,7 +1252,7 @@ App.ListView = Backbone.View.extend({
var current_position = this.model.collection.indexOf(this.model) + 1;
for (var i = 1; i <= list.attributes.card_count; i++) {
if (self.model.attributes.list_id == list.attributes.id && i == current_position) {
- content_position += '
' + self.model.attributes.position + '(current) ';
+ content_position += '
' + self.model.attributes.position + i18next.t('(current)') + ' ';
} else {
content_position += '
' + i + ' ';
}
@@ -1213,7 +1284,7 @@ App.ListView = Backbone.View.extend({
var is_first_list = true;
board.lists.each(function(list) {
if (self.model.attributes.list_id == self.model.attributes.id) {
- content_list += '
' + list.attributes.name + '(current) ';
+ content_list += '
' + list.attributes.name + i18next.t('(current)') + ' ';
is_first_list = true;
} else {
content_list += '
' + list.attributes.name + ' ';
diff --git a/client/js/views/login_view.js b/client/js/views/login_view.js
index 479de4397..91b819462 100644
--- a/client/js/views/login_view.js
+++ b/client/js/views/login_view.js
@@ -65,7 +65,9 @@ App.LoginView = Backbone.View.extend({
auth_response.board_id = response.board_id;
auth_response.user.notify_count = response.user.notify_count;
auth_response.user.last_activity_id = response.user.last_activity_id;
+ auth_response.user.language = response.user.language;
window.sessionStorage.setItem('auth', JSON.stringify(auth_response));
+ i18next.changeLanguage(response.user.language);
api_token = response.access_token;
var links = JSON.parse(response.links);
window.sessionStorage.setItem('links', response.links);
@@ -78,17 +80,15 @@ App.LoginView = Backbone.View.extend({
this.headerView = new App.HeaderView({
model: model
});
- $('#content').html('');
$('.company').addClass('hide');
$('#header').html(this.headerView.el);
app.navigate('#/boards', {
trigger: true,
replace: true
});
- //self.flash('success', 'Wellcome ' + authuser.user.username);
} else {
$('input#inputPassword', target).val('');
- self.flash('danger', response.error);
+ self.flash('danger', i18next.t('Sorry, login failed. Either your username or password are incorrect or admin deactivated your account.'));
}
}
@@ -117,6 +117,8 @@ App.LoginView = Backbone.View.extend({
changeFavicon: function(count) {
if (!_.isUndefined(count) && count !== '0') {
favicon.badge(count);
+ } else {
+ favicon.badge(0);
}
}
});
diff --git a/client/js/views/modal_card_view.js b/client/js/views/modal_card_view.js
index 4f3d25fae..ebfe4349b 100644
--- a/client/js/views/modal_card_view.js
+++ b/client/js/views/modal_card_view.js
@@ -461,7 +461,8 @@ App.ModalCardView = Backbone.View.extend({
*/
showMemberSearch: function(e) {
var q = $(e.target).val();
- if (q !== '' && q === '@') {
+ var x = e.which || e.keyCode;
+ if (x === 50) {
var target = $('.js-show-members').parents('.dropdown:first');
target.addClass('open');
} else {
@@ -613,7 +614,10 @@ App.ModalCardView = Backbone.View.extend({
subscribed = '
';
}
var class_name = '';
- var text = _.escape(this.model.attributes.name) + ' in list ' + _.escape(this.model.list.attributes.name) + subscribed;
+ var text = i18next.t('%s in list %s %s', {
+ postProcess: 'sprintf',
+ sprintf: [_.escape(this.model.attributes.name), _.escape(this.model.list.attributes.name), subscribed]
+ });
if (this.model.attributes.is_archived === 1) {
class_name = ' label label-warning';
text = _.escape('This card is archived.');
@@ -632,8 +636,7 @@ App.ModalCardView = Backbone.View.extend({
autoUpload: true,
singleFileUploads: false,
formData: $('form.js-user-profile-edit').serialize(),
- dropZone: $('#dropzone' + self.model.id),
-
+ dropZone: $('#dropzone' + self.model.id)
});
var loader_id = '';
uploadManager.on('fileadd', function(file) {
@@ -727,11 +730,14 @@ App.ModalCardView = Backbone.View.extend({
this.renderLabelsCollection();
this.renderUsersCollection();
this.renderChecklistsCollection();
- var title = _.escape(this.model.attributes.name) + ' in list ' + _.escape(this.model.list.attributes.name) + subscribed;
+ var title = i18next.t('%s in list %s %s', {
+ postProcess: 'sprintf',
+ sprintf: [_.escape(this.model.attributes.name), _.escape(this.model.list.attributes.name), subscribed]
+ });
var class_name = '';
if (this.model.attributes.is_archived === 1) {
class_name = ' label label-warning';
- title = _.escape('This card is archived.');
+ title = i18next.t('This card is archived.');
}
this.$el.dockmodal({
initialState: initialState,
@@ -809,11 +815,14 @@ App.ModalCardView = Backbone.View.extend({
autoUpload: true,
singleFileUploads: false,
formData: $('form.js-user-profile-edit').serialize(),
- dropZone: $('#dropzone' + self.model.id),
-
+ dropZone: $('#dropzone' + self.model.id)
});
var loader_id = '';
uploadManager.on('fileadd', function(file) {
+ if (!file.attributes.data.name) {
+ var currentdate = new Date();
+ file.attributes.data.name = 'upload_' + (currentdate.getMonth() + 1) + '_' + currentdate.getDate() + '_' + currentdate.getFullYear() + '_at_' + ((currentdate.getHours() + 11) % 12 + 1) + '_' + currentdate.getMinutes() + '_' + currentdate.getSeconds() + '_' + ((currentdate.getHours() >= 12) ? 'PM' : 'AM') + '.' + file.attributes.data.type.split('/')[1];
+ }
loader_id = new Date().getTime();
$('.js-attachment-loader', $('#js-card-modal-' + self.model.id)).html('');
self.$('.js_card_image_upload').addClass('cssloader');
@@ -956,7 +965,7 @@ App.ModalCardView = Backbone.View.extend({
var board_id = this.model.attributes.board_id;
var uuid = new Date().getTime();
$(e.currentTarget).removeClass('js-add-card-vote');
- $('.panel-title', e.currentTarget).html('
Unvote');
+ $('.panel-title', e.currentTarget).html('
' + i18next.t('Unvote'));
var card_voter = new App.CardVoter();
card_voter.set('is_offline', true);
card_voter.set('card_id', parseInt(card_id));
@@ -1024,7 +1033,7 @@ App.ModalCardView = Backbone.View.extend({
});
var voter_id = voted_user.id;
$(e.currentTarget).removeClass('js-delete-card-vote').addClass('js-add-card-vote');
- $('.panel-title', e.currentTarget).html('
Vote');
+ $('.panel-title', e.currentTarget).html('
' + i18next.t('Vote'));
$('i.icon-ok', e.currentTarget).remove();
var card_voter = new App.CardVoter();
@@ -1991,7 +2000,7 @@ App.ModalCardView = Backbone.View.extend({
} else {
$(e.target).find('.error-msg').remove();
var self = this;
- $('.js-add-comment-response').html('');
+ $('.js-add-comment-response').html('');
var board_id = this.model.attributes.board_id;
var data = $(e.target).serializeObject();
var is_reply = $(e.target).hasClass('js-reply-form');
@@ -2086,7 +2095,7 @@ App.ModalCardView = Backbone.View.extend({
e.preventDefault();
if (!$.trim($('.js-inputComment').val()).length) {
$('.error-msg').remove();
- $('
Whitespace alone not allowed
').insertAfter('.js-inputComment');
+ $('
' + i18next.t('Whitespace alone not allowed') + '
').insertAfter('.js-inputComment');
} else {
$('.error-msg').remove();
var self = this;
@@ -2418,7 +2427,7 @@ App.ModalCardView = Backbone.View.extend({
is_first_list = false;
for (var i = 1; i <= list.attributes.card_count; i++) {
if (self.model.attributes.list_id == list.attributes.id && i == current_position) {
- content_position += '
' + i + '(current) ';
+ content_position += '
' + i + i18next.t('(current)') + ' ';
} else {
content_position += '
' + i + ' ';
}
@@ -2454,7 +2463,7 @@ App.ModalCardView = Backbone.View.extend({
var current_position = this.model.collection.indexOf(this.model) + 1;
for (var i = 1; i <= list.attributes.card_count; i++) {
if (self.model.attributes.list_id == list.attributes.id && i == current_position) {
- content_position += '
' + self.model.attributes.position + '(current) ';
+ content_position += '
' + self.model.attributes.position + i18next.t('(current)') + ' ';
} else {
content_position += '
' + i + ' ';
}
@@ -2642,7 +2651,7 @@ App.ModalCardView = Backbone.View.extend({
e.preventDefault();
var target = $(e.currentTarget);
var user_name = target.data('user-name');
- this.$el.find('.js-comment').val('@' + user_name + ' ' + this.$el.find('.js-comment').val());
+ this.$el.find('.js-comment').val(this.$el.find('.js-comment').val().replace('@' + $('.js-search-member').val(), '@' + user_name));
},
renderBoardUsers: function() {
var self = this;
diff --git a/client/js/views/modal_flickr_photo_view.js b/client/js/views/modal_flickr_photo_view.js
index 9609b546f..42009871b 100644
--- a/client/js/views/modal_flickr_photo_view.js
+++ b/client/js/views/modal_flickr_photo_view.js
@@ -93,7 +93,7 @@ App.ModalFlickrPhotoView = Backbone.View.extend({
Flickr.fetch({
cache: false,
success: function(photos, response) {
- $('.js-flickr-loader-and-more').html('
Load More ');
+ $('.js-flickr-loader-and-more').html('
' + i18next.t('Load More') + ' ');
$('.js-flickr-loader-and-more').show();
if (!_.isUndefined(photos.attributes.photos) && photos.attributes.photos !== null) {
var fl_photos = photos.attributes.photos.photo;
@@ -113,7 +113,7 @@ App.ModalFlickrPhotoView = Backbone.View.extend({
self.total_page = parseInt(photos.attributes.photos.pages);
self.page = parseInt(photos.attributes.photos.page);
if (self.page == 1) {
- $('.js-flickr-loader-and-more').html('
No Photo Found.... ');
+ $('.js-flickr-loader-and-more').html('
' + i18next.t('No record found') + '.... ');
$('.js-flickr-loader-and-more').show();
} else {
self.page = parseInt(photos.attributes.photos.page) + 1;
@@ -203,10 +203,18 @@ App.ModalFlickrPhotoView = Backbone.View.extend({
background_picture_url: image_path,
background_pattern_url: 'NULL'
};
- App.boards.get(this.model.id).set('background_name', title);
- App.boards.get(this.model.id).set('background_picture_url', image_path);
- App.boards.get(this.model.id).set('background_pattern_url', '');
- App.boards.get(this.model.id).set('background_color', '');
+ App.boards.get(this.model.id).set('background_name', title, {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_picture_url', image_path, {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_pattern_url', '', {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_color', '', {
+ silent: true
+ });
} else {
$('body').removeAttr('style').css({
@@ -215,10 +223,18 @@ App.ModalFlickrPhotoView = Backbone.View.extend({
this.model.set('background_name', title);
this.model.set('background_picture_url', '');
this.model.set('background_pattern_url', image_path);
- App.boards.get(this.model.id).set('background_name', title);
- App.boards.get(this.model.id).set('background_picture_url', '');
- App.boards.get(this.model.id).set('background_pattern_url', image_path);
- App.boards.get(this.model.id).set('background_color', '');
+ App.boards.get(this.model.id).set('background_name', title, {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_picture_url', '', {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_pattern_url', image_path, {
+ silent: true
+ });
+ App.boards.get(this.model.id).set('background_color', '', {
+ silent: true
+ });
image_path = 'http://farm' + farm + '.static.flickr.com/' + server + '/' + id + '_' + secret + '_XXXX.jpg';
data = {
background_name: title,
diff --git a/client/js/views/modal_music_view.js b/client/js/views/modal_music_view.js
index 469e2abdc..bc3b6e631 100644
--- a/client/js/views/modal_music_view.js
+++ b/client/js/views/modal_music_view.js
@@ -51,7 +51,7 @@ App.ModalMusicView = Backbone.View.extend({
patch: true,
success: function(model, response) {
var view = new Backbone.View();
- view.flash('success', 'Updated successfully.');
+ view.flash('success', i18next.t('Updated successfully.'));
$('#music-modal').modal('hide');
$('div.modal-backdrop').remove();
if (!_.isEmpty(music_name) && music_name != 'NULL') {
diff --git a/client/js/views/music_repeat_view.js b/client/js/views/music_repeat_view.js
index 10588cfa8..dd48b7f89 100644
--- a/client/js/views/music_repeat_view.js
+++ b/client/js/views/music_repeat_view.js
@@ -21,12 +21,12 @@ App.MusicRepeatView = Backbone.View.extend({
continueMusic: function(e) {
var temp = new App.MusicRepeatView();
var music_content = App.music.music_content;
- if (!_.isUndefined(App.music) && music_content !== undefined && music_content !== '' && music_content !== null) {
+ if (!_.isUndefined(App.music) && music_content !== undefined && music_content !== '' && music_content !== null && !navigator.userAgent.match(/Trident/)) {
App.music.inst.setTimbre({
wave: 'piano'
});
if (!_.isUndefined(authuser.user)) {
- if (!_.isUndefined(authuser.user.is_productivity_beats) && (authuser.user.is_productivity_beats === true || authuser.user.is_productivity_beats === 1)) {
+ if (parseInt(authuser.user.is_productivity_beats) === 1) {
App.music.inst.play(
music_content, temp.continueMusic
);
diff --git a/client/js/views/organization_add_view.js b/client/js/views/organization_add_view.js
index 08ce4c830..b240e5e30 100644
--- a/client/js/views/organization_add_view.js
+++ b/client/js/views/organization_add_view.js
@@ -65,7 +65,7 @@ App.OrganizationAddView = Backbone.View.extend({
}
});
} else {
- this.flash('Enter organization name', 'Organization name is empty');
+ this.flash(i18next.t('Enter organization name'), i18next.t('Organization name is empty'));
}
return false;
}
diff --git a/client/js/views/organization_delete_form_view.js b/client/js/views/organization_delete_form_view.js
index decced851..bd0e8a66a 100644
--- a/client/js/views/organization_delete_form_view.js
+++ b/client/js/views/organization_delete_form_view.js
@@ -61,7 +61,7 @@ App.OrganizationDeleteFormView = Backbone.View.extend({
target.parents('li.dropdown').removeClass('open');
this.model.url = api_url + 'organizations/' + this.model.id + '.json';
this.model.set('id', this.model.id);
- this.flash('success', 'Organization deleted successfully.');
+ this.flash('success', i18next.t('Organization deleted successfully.'));
auth_user_organizations.remove(self.model);
this.model.destroy({
success: function(model, response) {
diff --git a/client/js/views/organization_header_view.js b/client/js/views/organization_header_view.js
index c44feff6f..32e80ef42 100644
--- a/client/js/views/organization_header_view.js
+++ b/client/js/views/organization_header_view.js
@@ -79,7 +79,7 @@ App.OrganizationHeaderView = Backbone.View.extend({
editOrganization: function(e) {
if (!$.trim($('#inputOrganizationName').val()).length) {
$('.error-msg').remove();
- $('
Whitespace alone not allowed
').insertAfter('#inputOrganizationName');
+ $('
' + i18next.t('Whitespace alone not allowed') + '
').insertAfter('#inputOrganizationName');
return false;
} else {
$('.error-msg').remove();
@@ -111,7 +111,7 @@ App.OrganizationHeaderView = Backbone.View.extend({
organization.url = api_url + 'organizations/' + this.model.organization_id + '.json';
organization.set('id', this.model.organization_id);
organization.destroy();
- this.flash('success', 'Organization deleted successfully');
+ this.flash('success', i18next.t('Organization deleted successfully.'));
app.navigate('#/organizations', {
trigger: true,
replace: true
diff --git a/client/js/views/organization_view.js b/client/js/views/organization_view.js
index ac0ae5dd2..40d57bc3c 100644
--- a/client/js/views/organization_view.js
+++ b/client/js/views/organization_view.js
@@ -215,7 +215,7 @@ App.OrganizationsView = Backbone.View.extend({
$('#org-loader').addClass('cssloader');
var allowedExt = /(\.jpg|\.jpeg|\.bmp|\.gif|\.png)$/i;
if (!allowedExt.exec(file.attributes.data.name)) {
- _this.flash('danger', 'File extension not supported. It supports only jpg, png, bmp and gif.');
+ _this.flash('danger', i18next.t('File extension not supported. It supports only jpg, png, bmp and gif.'));
$('#org-loader').removeClass('cssloader');
}
});
@@ -295,7 +295,7 @@ App.OrganizationsView = Backbone.View.extend({
cache: false,
contentType: false,
error: function(e, s) {
- self.flash('danger', 'Unable to update. Please try again.');
+ self.flash('danger', i18next.t('Unable to update. Please try again.'));
},
success: function(model, response) {
$('#org-loader').removeClass('cssloader');
diff --git a/client/js/views/organizations_list_view.js b/client/js/views/organizations_list_view.js
index 1c9d9192d..1aa8acd44 100644
--- a/client/js/views/organizations_list_view.js
+++ b/client/js/views/organizations_list_view.js
@@ -74,7 +74,7 @@ App.OrganizationsListView = Backbone.View.extend({
var organization = new App.Organization();
organization.url = api_url + 'organizations/' + this.model.organization_id + '.json';
organization.set('id', this.model.organization_id);
- this.flash('success', 'Organization deleted successfully.');
+ this.flash('success', i18next.t('Organization deleted successfully.'));
organization.destroy({
success: function(model, response) {
app.navigate('#/', {
diff --git a/client/js/views/organizations_user_view.js b/client/js/views/organizations_user_view.js
index 304372cf5..0bae5c833 100644
--- a/client/js/views/organizations_user_view.js
+++ b/client/js/views/organizations_user_view.js
@@ -75,7 +75,10 @@ App.OrganizationsUserView = Backbone.View.extend({
clearMemberList: function(e) {
var self = this;
self.$('.js-organization-member-search-response').nextAll().remove();
- self.$('.js-organization-member-search-response').after('
Search for a person in Restyaboard by name or email address. ');
+ self.$('.js-organization-member-search-response').after('
' + i18next.t('Search for a person in %s by name or email address.', {
+ postProcess: 'sprintf',
+ sprintf: [SITE_NAME]
+ }) + ' ');
},
/**
* organizationUsersSearch()
@@ -161,7 +164,7 @@ App.OrganizationsUserView = Backbone.View.extend({
var organizations_user_id = target.data('organizations_user_id');
target.parents('li.dropdown').removeClass('open');
self.model.organizations_users.remove(self.model.organizations_users.get(parseInt(organizations_user_id)));
- self.flash('success', 'User removed from this organization');
+ self.flash('success', i18next.t('User removed from this organization'));
self.render();
var organizationsUser = new App.OrganizationsUser();
organizationsUser.url = api_url + 'organizations_users/' + organizations_user_id + '.json';
diff --git a/client/js/views/plugin_setting_view.js b/client/js/views/plugin_setting_view.js
new file mode 100644
index 000000000..c67eb7ea9
--- /dev/null
+++ b/client/js/views/plugin_setting_view.js
@@ -0,0 +1,64 @@
+/**
+ * @fileOverview This file has functions related to plugin settings view. This view calling from application view.
+ * Available Object:
+ * App.boards : this object contain all boards(Based on logged in user)
+ * this.model : undefined.
+ */
+if (typeof App == 'undefined') {
+ App = {};
+}
+App.PluginSettingsView = Backbone.View.extend({
+ /**
+ * Constructor
+ * initialize default values and actions
+ */
+ initialize: function(options) {
+ this.folder = options.folder;
+ this.render(options.plugin_settings);
+ },
+ template: JST['templates/plugin_setting'],
+ /**
+ * Events
+ * functions to fire on events (Mouse events, Keyboard Events, Frame/Object Events, Form Events, Drag Events, etc...)
+ */
+ events: {
+ 'submit form#js-plugin-setting-form': 'updatePlugin',
+ },
+ /**
+ * updatePlugin()
+ * @return false
+ */
+ updatePlugin: function(e) {
+ var target = $(e.currentTarget);
+ var data = target.serializeObject();
+ var self = this;
+ var plugin = new App.Plugin();
+ plugin.url = api_url + 'plugins/settings.json';
+ plugin.save(data, {
+ success: function(model, response) {
+ if (!_.isEmpty(response.success)) {
+ self.flash('success', i18next.t('Plugin updated successfully'));
+ } else {
+ self.flash('danger', i18next.t('Plugin not updated successfully.'));
+ }
+ }
+ });
+ return false;
+ },
+ /**
+ * render()
+ * populate the html to the dom
+ * @param NULL
+ * @return object
+ *
+ */
+ render: function(plugin_settings) {
+ this.$el.html(this.template({
+ plugin_settings: plugin_settings,
+ folder: this.folder
+ }));
+ $('.js-admin-plugin-menu').addClass('active');
+ $('.js-admin-activity-menu, .js-admin-user-menu, .js-admin-role-menu, .js-admin-setting-menu, .js-admin-board-menu, .js-admin-email-menu').removeClass('active');
+ return this;
+ }
+});
diff --git a/client/js/views/plugin_view.js b/client/js/views/plugin_view.js
new file mode 100644
index 000000000..77a11d2ef
--- /dev/null
+++ b/client/js/views/plugin_view.js
@@ -0,0 +1,72 @@
+/**
+ * @fileOverview This file has functions related to plugin template view. This view calling from application view.
+ * Available Object:
+ * App.boards : this object contain all boards(Based on logged in user)
+ * this.model : undefined.
+ */
+if (typeof App == 'undefined') {
+ App = {};
+}
+App.PluginsView = Backbone.View.extend({
+ /**
+ * Constructor
+ * initialize default values and actions
+ */
+ initialize: function() {
+ this.render();
+ },
+ template: JST['templates/plugin'],
+ /**
+ * Events
+ * functions to fire on events (Mouse events, Keyboard Events, Frame/Object Events, Form Events, Drag Events, etc...)
+ */
+ events: {
+ 'click .js-update-plugin': 'updatePlugin',
+ },
+ /**
+ * updatePlugin()
+ * @return false
+ */
+ updatePlugin: function(e) {
+ var target = $(e.currentTarget);
+ var data = {};
+ if (target.data('current-status') === true) {
+ data.enable = false;
+ } else {
+ data.enable = true;
+ }
+ data.folder = target.data('folder');
+ var self = this;
+ var plugin = new App.Plugin();
+ plugin.url = api_url + 'plugins/settings.json';
+ plugin.save(data, {
+ success: function(model, response) {
+ if (!_.isEmpty(response.success)) {
+ self.flash('success', i18next.t('Plugin updated successfully'));
+ app.navigate('#/plugins', {
+ trigger: true,
+ replace: true
+ });
+ } else {
+ self.flash('danger', i18next.t('Plugin not updated successfully.'));
+ }
+ }
+ });
+ return false;
+ },
+ /**
+ * render()
+ * populate the html to the dom
+ * @param NULL
+ * @return object
+ *
+ */
+ render: function() {
+ this.$el.html(this.template({
+ plugins: this.model,
+ }));
+ $('.js-admin-plugin-menu').addClass('active');
+ $('.js-admin-activity-menu, .js-admin-user-menu, .js-admin-role-menu, .js-admin-setting-menu, .js-admin-board-menu, .js-admin-email-menu').removeClass('active');
+ return this;
+ }
+});
diff --git a/client/js/views/qr_code_view.js b/client/js/views/qr_code_view.js
new file mode 100644
index 000000000..db2053bac
--- /dev/null
+++ b/client/js/views/qr_code_view.js
@@ -0,0 +1,42 @@
+/**
+ * @fileOverview This file has functions related to qr code view. This view calling from footer view.
+ * Available Object:
+ * App.boards : this object contain all boards(Based on logged in user)
+ * this.model : undefined.
+ */
+if (typeof App == 'undefined') {
+ App = {};
+}
+/**
+ * Qr Code View
+ * @class QrCodeView
+ * @constructor
+ * @extends Backbone.View
+ */
+App.QrCodeView = Backbone.View.extend({
+ template: JST['templates/qr_code'],
+ /**
+ * Constructor
+ * initialize default values and actions
+ */
+ initialize: function(options) {
+ this.render();
+ },
+ /**
+ * render()
+ * populate the html to the dom
+ * @param NULL
+ * @return object
+ *
+ */
+ render: function() {
+ this.$el.html(this.template()).attr('title', 'View in iOS App');
+ this.$el.dockmodal({
+ initialState: 'docked',
+ height: 300,
+ width: 400
+ });
+ this.showTooltip();
+ return this;
+ }
+});
diff --git a/client/js/views/register_view.js b/client/js/views/register_view.js
index b4017931d..26a0b8c21 100644
--- a/client/js/views/register_view.js
+++ b/client/js/views/register_view.js
@@ -48,11 +48,15 @@ App.RegisterView = Backbone.View.extend({
user.url = api_url + 'users/register.json';
user.save(data, {
success: function(model, response) {
- if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ if (response.error) {
+ if (response.error === 1) {
+ self.flash('danger', i18next.t('Email address already exist. Your registration process is not completed. Please, try again.'));
+ } else if (response.error === 2) {
+ self.flash('danger', i18next.t('Username already exists. Your registration process is not completed. Please, try again.'));
+ }
$('#inputPassword').val('');
} else {
- self.flash('success', 'You have successfully registered with our site and your activation mail has been sent to your mail inbox.');
+ self.flash('success', i18next.t('You have successfully registered with our site and your activation mail has been sent to your mail inbox.'));
target[0].reset();
}
}
diff --git a/client/js/views/setting_view.js b/client/js/views/setting_view.js
index 0790a9aab..408bd4c84 100644
--- a/client/js/views/setting_view.js
+++ b/client/js/views/setting_view.js
@@ -54,9 +54,9 @@ App.SettingView = Backbone.View.extend({
settingModel.save(data, {
success: function(model, response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
+ self.flash('success', i18next.t('Settings updated successfully.'));
} else {
- self.flash('danger', 'Settings not updated properly.');
+ self.flash('danger', i18next.t('Settings not updated properly.'));
}
}
});
diff --git a/client/js/views/show_copy_board_view.js b/client/js/views/show_copy_board_view.js
index 3d5e2733c..47e7dd996 100644
--- a/client/js/views/show_copy_board_view.js
+++ b/client/js/views/show_copy_board_view.js
@@ -65,10 +65,14 @@ App.ShowCopyBoardView = Backbone.View.extend({
board.url = api_url + 'boards/' + this.model.id + '/copy.json';
board.save(data, {
success: function(model, response) {
- app.navigate('#/board/' + board.get('id'), {
- trigger: true,
- replace: true,
- });
+ if (!_.isUndefined(board.get('id'))) {
+ app.navigate('#/board/' + board.get('id'), {
+ trigger: true,
+ replace: true,
+ });
+ } else {
+ self.flash('danger', i18next.t('Unable to copy the board.'));
+ }
}
});
return false;
diff --git a/client/js/views/user_activity_view.js b/client/js/views/user_activity_view.js
index 4477b343a..627b1d29b 100644
--- a/client/js/views/user_activity_view.js
+++ b/client/js/views/user_activity_view.js
@@ -74,7 +74,7 @@ App.UserActivityView = Backbone.View.extend({
this.model.save({}, {
patch: true,
success: function(model, response) {
- self.flash('danger', "Undo Succeed");
+ self.flash('danger', i18next.t('Undo Succeed'));
emojify.run();
}
});
diff --git a/client/js/views/user_index_container_view.js b/client/js/views/user_index_container_view.js
index 3f7baa0a1..6973eb039 100644
--- a/client/js/views/user_index_container_view.js
+++ b/client/js/views/user_index_container_view.js
@@ -21,6 +21,7 @@ App.UserIndexContainerView = Backbone.View.extend({
events: {
'change .js-more-action-user': 'usersMoreActions',
'click .js-sort': 'sortUser',
+ 'click .js-filter': 'filterUser',
},
/**
@@ -29,6 +30,8 @@ App.UserIndexContainerView = Backbone.View.extend({
*/
initialize: function(options) {
this.sortField = options.sortField;
+ this.filter_count = options.filter_count;
+ this.roles = options.roles;
this.sortDirection = options.sortDirection;
if (!_.isUndefined(this.model) && this.model !== null) {
this.model.showImage = this.showImage;
@@ -47,7 +50,8 @@ App.UserIndexContainerView = Backbone.View.extend({
*/
render: function() {
this.$el.html(this.template({
- user: this.model
+ filter_count: this.filter_count,
+ roles: this.roles
}));
if (!_.isUndefined(this.sortField)) {
this.renderUserCollection();
@@ -73,6 +77,55 @@ App.UserIndexContainerView = Backbone.View.extend({
});
return this;
},
+ /**
+ * filterUser()
+ * @param NULL
+ * @return object
+ *
+ */
+ filterUser: function(e) {
+ var _this = this;
+ _this.current_page = (!_.isUndefined(_this.current_page)) ? _this.current_page : 1;
+ _this.filterField = (!_.isUndefined(e)) ? $(e.currentTarget).data('filter') : _this.filterField;
+ var users = new App.UserCollection();
+ users.url = api_url + 'users.json?page=' + _this.current_page + '&filter=' + _this.filterField;
+ app.navigate('#/' + 'users?page=' + _this.current_page + '&filter=' + _this.filterField, {
+ trigger: false,
+ trigger_function: false,
+ });
+ $('.js-user-list').html('');
+ users.fetch({
+ cache: false,
+ abortPending: true,
+ success: function(users, response) {
+ if (users.length !== 0) {
+ users.each(function(user) {
+ $('.js-user-list').append(new App.UserIndex({
+ model: user
+ }).el);
+ });
+ } else {
+ $('.js-user-list').html('
No record found ');
+ }
+ $('.js-filter-list').children().removeClass('active');
+ $(e.currentTarget).parent().addClass('active');
+ $('.js-user-list').find('.timeago').timeago();
+ $('.pagination-boxes').unbind();
+ $('.pagination-boxes').pagination({
+ total_pages: response._metadata.noOfPages,
+ current_page: _this.current_page,
+ display_max: 4,
+ callback: function(event, page) {
+ event.preventDefault();
+ if (page) {
+ _this.current_page = page;
+ _this.filterUser();
+ }
+ }
+ });
+ }
+ });
+ },
/**
* sortUser()
* @param NULL
@@ -87,6 +140,10 @@ App.UserIndexContainerView = Backbone.View.extend({
var users = new App.UserCollection();
users.setSortField(_this.sortField, _this.sortDirection);
users.url = api_url + 'users.json?page=' + _this.current_page + '&sort=' + _this.sortField + '&direction=' + _this.sortDirection;
+ app.navigate('#/' + 'users?page=' + _this.current_page + '&sort=' + _this.sortField + '&direction=' + _this.sortDirection, {
+ trigger: false,
+ trigger_function: false,
+ });
if (!_.isUndefined(e)) {
if ($(e.currentTarget).data('direction') == 'desc') {
$(e.currentTarget).data('direction', 'asc');
@@ -142,10 +199,10 @@ App.UserIndexContainerView = Backbone.View.extend({
usersMoreActions: function(e) {
var self = this;
if (_.isUndefined($('.js-checkbox-list:checked').val())) {
- alert('Please select atleast one record!');
+ alert(i18next.t('Please select atleast one record!'));
return false;
} else {
- if (window.confirm('Are you sure you want to do this action?')) {
+ if (window.confirm(i18next.t('Are you sure you want to do this action?'))) {
var User = Backbone.Model.extend({});
var Users = Backbone.BatchCollection.extend({
model: User,
@@ -165,7 +222,7 @@ App.UserIndexContainerView = Backbone.View.extend({
users.save({
'success': function(response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
+ self.flash('success', i18next.t('Checked users are blocked successfully.'));
app.navigate('#/users', {
trigger: true,
});
diff --git a/client/js/views/user_index_view.js b/client/js/views/user_index_view.js
index 4e9669dea..3cb9d471a 100644
--- a/client/js/views/user_index_view.js
+++ b/client/js/views/user_index_view.js
@@ -171,7 +171,7 @@ App.UserIndex = Backbone.View.extend({
e.preventDefault();
this.$el.remove();
this.model.url = api_url + 'users/' + this.model.attributes.id + '.json';
- this.flash('success', 'User deleted successfully.');
+ this.flash('success', i18next.t('User deleted successfully.'));
this.model.destroy();
},
showUserActivities: function(e) {
diff --git a/client/js/views/user_view.js b/client/js/views/user_view.js
index ab06f217a..9aa8b0790 100644
--- a/client/js/views/user_view.js
+++ b/client/js/views/user_view.js
@@ -192,15 +192,19 @@ App.UserView = Backbone.View.extend({
cache: false,
contentType: false,
error: function(e, s) {
- self.flash('danger', 'Unable to update. Please try again.');
+ self.flash('danger', i18next.t('Unable to update. Please try again.'));
},
success: function(model, response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
- } else if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ self.flash('success', i18next.t('User Profile has been updated.'));
+ } else if (response.error) {
+ if (response.error === 1) {
+ self.flash('danger', i18next.t('File extension not supported. It supports only jpg, png, bmp and gif.'));
+ } else if (response.error === 2) {
+ self.flash('danger', i18next.t('Email address already exist. User Profile could not be updated. Please, try again.'));
+ }
} else {
- self.flash('danger', 'User Profile could not be updated. Please, try again.');
+ self.flash('danger', i18next.t('User Profile could not be updated. Please, try again.'));
}
if (!_.isUndefined(response.activity.profile_picture_path)) {
self.model.set('profile_picture_path', response.activity.profile_picture_path);
@@ -247,7 +251,10 @@ App.UserView = Backbone.View.extend({
}).el);
});
} else {
- self.$('#cards').html('No cards available.');
+ self.$('#cards').html(i18next.t('No %s available.', {
+ postProcess: 'sprintf',
+ sprintf: [i18next.t('cards')]
+ }));
}
$('#tab-loaded-content').load();
}
@@ -340,7 +347,7 @@ App.UserView = Backbone.View.extend({
$('#dropzone-cssloader').addClass('cssloader');
var ext = $('#js-user-profile-attachment').val().split('.').pop().toLowerCase();
if ($.inArray(ext, ['gif', 'png', 'jpg', 'jpeg']) == -1) {
- self.flash('danger', 'File extension not supported. It supports only jpg, png, bmp and gif.');
+ self.flash('danger', i18next.t('File extension not supported. It supports only jpg, png, bmp and gif.'));
$('#dropzone-cssloader').removeClass('cssloader');
return false;
} else {
@@ -356,8 +363,12 @@ App.UserView = Backbone.View.extend({
contentType: false,
success: function(model, response) {
$('#dropzone-cssloader').removeClass('cssloader');
- if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ if (response.error) {
+ if (response.error === 1) {
+ self.flash('danger', i18next.t('File extension not supported. It supports only jpg, png, bmp and gif.'));
+ } else if (response.error === 2) {
+ self.flash('danger', i18next.t('Email address already exist. User Profile could not be updated. Please, try again.'));
+ }
}
self.model.set('profile_picture_path', response.profile_picture_path);
var Auth = JSON.parse(window.sessionStorage.getItem('auth'));
diff --git a/client/js/views/users_activation_view.js b/client/js/views/users_activation_view.js
index ad9f0ed39..4ec3fd948 100644
--- a/client/js/views/users_activation_view.js
+++ b/client/js/views/users_activation_view.js
@@ -48,9 +48,9 @@ App.UseractivationView = Backbone.View.extend({
patch: true,
success: function(model, response) {
if (!_.isEmpty(response.success)) {
- self.flash('success', response.success);
+ self.flash('success', i18next.t('Your activation has been confirmed. You can now login to the site.'));
} else {
- self.flash('danger', response.error);
+ self.flash('danger', i18next.t('Invalid Activation URL'));
}
app.navigate('#/users/login', {
trigger: true,
diff --git a/client/js/views/users_change_password_view.js b/client/js/views/users_change_password_view.js
index 5976b2fc5..897829200 100644
--- a/client/js/views/users_change_password_view.js
+++ b/client/js/views/users_change_password_view.js
@@ -49,10 +49,16 @@ App.ChangepasswordView = Backbone.View.extend({
user.url = api_url + 'users/' + this.model.user_id + '/changepassword.json';
user.save(data, {
success: function(model, response) {
- if (!_.isEmpty(response.error)) {
- self.flash('danger', response.error);
+ if (response.error) {
+ if (parseInt(response.error) === 1) {
+ self.flash('danger', i18next.t('Your old password is incorrect, please try again.'));
+ } else if (parseInt(response.error) === 2) {
+ self.flash('danger', i18next.t('Unable to change password. Please try again.'));
+ } else if (parseInt(response.error) === 3) {
+ self.flash('danger', i18next.t('New and confirm password field must match, please try again.'));
+ }
} else {
- self.flash('success', 'Password has been changed successfully.');
+ self.flash('success', i18next.t('Password has been changed successfully.'));
app.navigate('#/users/logout', {
trigger: true,
replace: true
diff --git a/client/js/views/users_forgot_password_view.js b/client/js/views/users_forgot_password_view.js
index 4befb308e..e5eab53c1 100644
--- a/client/js/views/users_forgot_password_view.js
+++ b/client/js/views/users_forgot_password_view.js
@@ -54,9 +54,9 @@ App.ForgotpasswordView = Backbone.View.extend({
trigger: true,
replace: true
});
- self.flash('success', response.success);
+ self.flash('success', i18next.t('An email has been sent with your new password.'));
} else {
- self.flash('danger', response.error);
+ self.flash('danger', i18next.t('No record found.'));
}
}
});
diff --git a/client/locales/en/translation.json b/client/locales/en/translation.json
new file mode 100644
index 000000000..9936794af
--- /dev/null
+++ b/client/locales/en/translation.json
@@ -0,0 +1,427 @@
+{
+ "%s checklist completed out of %s": "%s checklist completed out of %s",
+ "%s in list %s %s": "%s in list %s %s",
+ "%s's Restyaboard | %s": "%s's Restyaboard | %s",
+ "(Owner, Member)": "(Owner, Member)",
+ "(current)": "(current)",
+ "(none)": "(none)",
+ "404 Page not found": "404 Page not found",
+ "A board is a collection of cards ordered in a list of lists. Use it to manage a project, track a collection, or organize anything.": "A board is a collection of cards ordered in a list of lists. Use it to manage a project, track a collection, or organize anything.",
+ "About": "About",
+ "About Me": "About Me",
+ "Actions": "Actions",
+ "Active": "Active",
+ "Activities": "Activities",
+ "Activity": "Activity",
+ "Add": "Add",
+ "Add Board or Organization": "Add Board or Organization",
+ "Add Card": "Add Card",
+ "Add Cards via Email": "Add Cards via Email",
+ "Add Checklist": "Add Checklist",
+ "Add Comment": "Add Comment",
+ "Add Emoji": "Add Emoji",
+ "Add Item": "Add Item",
+ "Add Member": "Add Member",
+ "Add User": "Add User",
+ "Add Vote": "Add Vote",
+ "Add a card": "Add a card",
+ "Add a list": "Add a list",
+ "Add an attachment": "Add an attachment",
+ "Add new Labels": "Add new Labels",
+ "Add...": "Add...",
+ "Added": "Added",
+ "Additional Settings": "Additional Settings",
+ "Admin": "Admin",
+ "Admin (%s)": "Admin (%s)",
+ "Admin Add User": "Admin Add User",
+ "Admin CP": "Admin CP",
+ "All": "All",
+ "All actions will be removed from the activity feed and you won\\'t be able to reopen the card. There is no undo. You can archive a card to remove it from the board and preserve the activity.": "All actions will be removed from the activity feed and you won\\'t be able to reopen the card. There is no undo. You can archive a card to remove it from the board and preserve the activity.",
+ "An email has been sent with your new password.": "An email has been sent with your new password.",
+ "An organization is a group of boards and members.": "An organization is a group of boards and members.",
+ "An organization is a group of boards and people. Use it to group boards in your company, team, or family.": "An organization is a group of boards and people. Use it to group boards in your company, team, or family.",
+ "Archive": "Archive",
+ "Archive All": "Archive All",
+ "Archive All Cards in this List": "Archive All Cards in this List",
+ "Archive This List": "Archive This List",
+ "Archived": "Archived",
+ "Archived Items": "Archived Items",
+ "Archived list send back to board": "Archived list send back to board",
+ "Are you sure you want to do this action": "Are you sure you want to do this action",
+ "Are you sure you want to do this action?": "Are you sure you want to do this action?",
+ "Attach From...": "Attach From...",
+ "Attach a Link": "Attach a Link",
+ "Attachment": "Attachment",
+ "Attachments": "Attachments",
+ "Available in AppStore": "Available in AppStore",
+ "Background Photo": "Background Photo",
+ "Below permissions can be changed:": "Below permissions can be changed:",
+ "Block": "Block",
+ "Blocked": "Blocked",
+ "Board": "Board",
+ "Board Count": "Board Count",
+ "Board Name": "Board Name",
+ "Board is closed": "Board is closed",
+ "Board not found": "Board not found",
+ "Boards": "Boards",
+ "Boards for": "Boards for",
+ "By": "By",
+ "Calendar": "Calendar",
+ "Can view and edit cards, remove members, and change settings for the board.": "Can view and edit cards, remove members, and change settings for the board.",
+ "Can view and edit cards. Can't change settings.": "Can view and edit cards. Can't change settings.",
+ "Can view, create and edit boards, and change settings for the board.": "Can view, create and edit boards, and change settings for the board.",
+ "Can view, create and edit org boards, and change settings for the organization.": "Can view, create and edit org boards, and change settings for the organization.",
+ "Can view, create, and edit org boards, but not change settings.": "Can view, create, and edit org boards, but not change settings.",
+ "Can view, create, and view members, but not change settings.": "Can view, create, and view members, but not change settings.",
+ "Cancel": "Cancel",
+ "Card": "Card",
+ "Card - %s on %s": "Card - %s on %s",
+ "Card Cover Images Enabled": "Card Cover Images Enabled",
+ "Card Name": "Card Name",
+ "Card Title": "Card Title",
+ "Cards": "Cards",
+ "Change": "Change",
+ "Change Background": "Change Background",
+ "Change Language": "Change Language",
+ "Change Password": "Change Password",
+ "Change Permission": "Change Permission",
+ "Change Visibility": "Change Visibility",
+ "Change background to board": "Change background to board",
+ "Change permissions": "Change permissions",
+ "Checked boards are closed successfully.": "Checked boards are closed successfully.",
+ "Checked users are blocked successfully.": "Checked users are blocked successfully.",
+ "Checklist": "Checklist",
+ "Checklist completed count": "Checklist completed count",
+ "Checklist pending count": "Checklist pending count",
+ "Checklists": "Checklists",
+ "Choose...": "Choose...",
+ "Click here to Reopen Board": "Click here to Reopen Board",
+ "Click to star this board. It will show up at top of your boards list.": "Click to star this board. It will show up at top of your boards list.",
+ "Close": "Close",
+ "Close board": "Close board",
+ "Closed": "Closed",
+ "Closed Boards": "Closed Boards",
+ "Coming soon.....": "Coming soon.....",
+ "Comment": "Comment",
+ "Comments": "Comments",
+ "Computer": "Computer",
+ "Convert to Card": "Convert to Card",
+ "Copy": "Copy",
+ "Copy Card": "Copy Card",
+ "Copy Items From": "Copy Items From",
+ "Copy List": "Copy List",
+ "Copy board": "Copy board",
+ "Count": "Count",
+ "Create": "Create",
+ "Create Board": "Create Board",
+ "Create List": "Create List",
+ "Create Organization": "Create Organization",
+ "Create card": "Create card",
+ "Created": "Created",
+ "Created by": "Created by",
+ "Currently, board owner, board member, organization owner and organization member roles are static with below permissions:": "Currently, board owner, board member, organization owner and organization member roles are static with below permissions:",
+ "Custom": "Custom",
+ "Dashboard": "Dashboard",
+ "Date": "Date",
+ "Delete": "Delete",
+ "Delete Attachment": "Delete Attachment",
+ "Delete Card": "Delete Card",
+ "Delete Checklist": "Delete Checklist",
+ "Delete Comment": "Delete Comment",
+ "Delete List": "Delete List",
+ "Delete Organization": "Delete Organization",
+ "Delete This Checklist": "Delete This Checklist",
+ "Delete User": "Delete User",
+ "Delete background photo": "Delete background photo",
+ "Delete this Checklist": "Delete this Checklist",
+ "Delete this List": "Delete this List",
+ "Deleting a checklist is permanent and there is no way to get it back.": "Deleting a checklist is permanent and there is no way to get it back.",
+ "Deleting a comment is forever. There is no undo.": "Deleting a comment is forever. There is no undo.",
+ "Deleting a item is permanent and there is no way to get it back.": "Deleting a item is permanent and there is no way to get it back.",
+ "Deleting an Organization is permanent. There is no undo.": "Deleting an Organization is permanent. There is no undo.",
+ "Deleting an attachment is permanent. There is no undo.": "Deleting an attachment is permanent. There is no undo.",
+ "Deleting an background photo. There is no undo.": "Deleting an background photo. There is no undo.",
+ "Deleting an organization is permanent. Are you sure you want to delete this organization? There is no undo. Boards with this organization won't be deleted. Your boards in this organization will appear in your personal boards list.": "Deleting an organization is permanent. Are you sure you want to delete this organization? There is no undo. Boards with this organization won't be deleted. Your boards in this organization will appear in your personal boards list.",
+ "Deleting an user is permanent. There is no undo.": "Deleting an user is permanent. There is no undo.",
+ "Description": "Description",
+ "Disabled": "Disabled",
+ "Download": "Download",
+ "Drop Files Here": "Drop Files Here",
+ "Drop files to upload": "Drop files to upload",
+ "Dropbox": "Dropbox",
+ "Due Date": "Due Date",
+ "Due in the next day": "Due in the next day",
+ "Due in the next month": "Due in the next month",
+ "Due in the next week": "Due in the next week",
+ "Edit": "Edit",
+ "Edit Card Info": "Edit Card Info",
+ "Email": "Email",
+ "Email Content": "Email Content",
+ "Email Template has been updated successfully.": "Email Template has been updated successfully.",
+ "Email Template not updated properly.": "Email Template not updated properly.",
+ "Email Templates": "Email Templates",
+ "Email address already exist. User Profile could not be updated. Please, try again.": "Email address already exist. User Profile could not be updated. Please, try again.",
+ "Email address already exist. Your registration process is not completed. Please, try again.": "Email address already exist. Your registration process is not completed. Please, try again.",
+ "Email for this card": "Email for this card",
+ "Email or Username": "Email or Username",
+ "Email or Username or LDAP Login": "Email or Username or LDAP Login",
+ "Email to board settings": "Email to board settings",
+ "Enable Card Cover Images": "Enable Card Cover Images",
+ "Enable Desktop Notification": "Enable Desktop Notification",
+ "Enabled": "Enabled",
+ "Enter a new Password": "Enter a new Password",
+ "Enter abc music notation. May choose from": "Enter abc music notation. May choose from",
+ "Enter organization name": "Enter organization name",
+ "Enter your email and we will send new password.": "Enter your email and we will send new password.",
+ "File extension not supported. It supports only jpg, png, bmp and gif.": "File extension not supported. It supports only jpg, png, bmp and gif.",
+ "Filter Cards": "Filter Cards",
+ "Flickr": "Flickr",
+ "Forgot your password": "Forgot your password",
+ "From": "From",
+ "Full Name": "Full Name",
+ "Gantt": "Gantt",
+ "Grid": "Grid",
+ "Guest": "Guest",
+ "ID": "ID",
+ "IP": "IP",
+ "Import Board from Trello": "Import Board from Trello",
+ "In this board": "In this board",
+ "Inactive": "Inactive",
+ "Info": "Info",
+ "Initials": "Initials",
+ "Instant Add Card": "Instant Add Card",
+ "Instantly, Send email notification every 5 minutes": "Instantly, Send email notification every 5 minutes",
+ "Invalid Activation URL": "Invalid Activation URL",
+ "Item Options": "Item Options",
+ "Join Now": "Join Now",
+ "Keep Cards": "Keep Cards",
+ "Keep...": "Keep...",
+ "LDAP": "LDAP",
+ "LDAP Login": "LDAP Login",
+ "LDAP configuration": "LDAP configuration",
+ "Labels": "Labels",
+ "Language changed successfully.": "Language changed successfully.",
+ "Last activity": "Last activity",
+ "Leave": "Leave",
+ "Leave from board": "Leave from board",
+ "Leave organization": "Leave organization",
+ "Link to this card": "Link to this card",
+ "List": "List",
+ "List Actions": "List Actions",
+ "List Name": "List Name",
+ "Load More": "Load More",
+ "Load more activities": "Load more activities",
+ "Loading...": "Loading...",
+ "Login": "Login",
+ "Login IP": "Login IP",
+ "Login Time": "Login Time",
+ "Logout": "Logout",
+ "Logout successfully.": "Logout successfully.",
+ "Member": "Member",
+ "Member %s": "Member %s",
+ "Member Activities": "Member Activities",
+ "Members": "Members",
+ "Mention a member": "Mention a member",
+ "More": "More",
+ "More Actions": "More Actions",
+ "More options share, print, export, and delete.": "More options share, print, export, and delete.",
+ "Move": "Move",
+ "Move All Cards in This List": "Move All Cards in This List",
+ "Move All Cards in this List": "Move All Cards in this List",
+ "Move Card": "Move Card",
+ "Move List": "Move List",
+ "My Boards": "My Boards",
+ "N/A": "N/A",
+ "Name": "Name",
+ "Never, Don't send email notifications": "Never, Don't send email notifications",
+ "New Board": "New Board",
+ "New Organization": "New Organization",
+ "New and confirm password field must match, please try again.": "New and confirm password field must match, please try again.",
+ "No %s available.": "No %s available.",
+ "No record found": "No record found",
+ "No record found.": "No record found.",
+ "None": "None",
+ "Normal": "Normal",
+ "Notifications": "Notifications",
+ "Old Password": "Old Password",
+ "Open": "Open",
+ "Options": "Options",
+ "Organization": "Organization",
+ "Organization %s": "Organization %s",
+ "Organization User": "Organization User",
+ "Organization deleted successfully.": "Organization deleted successfully.",
+ "Organization name is empty": "Organization name is empty",
+ "Organizations": "Organizations",
+ "Organizations Count": "Organizations Count",
+ "Overdue": "Overdue",
+ "Owner": "Owner",
+ "Owner %s": "Owner %s",
+ "Password": "Password",
+ "Password has been changed successfully.": "Password has been changed successfully.",
+ "Password. Minimum 6 characters and white space not allowed": "Password. Minimum 6 characters and white space not allowed",
+ "Paste any link here": "Paste any link here",
+ "Patterns and Textures": "Patterns and Textures",
+ "Periodically, Send email notification every 1 hour": "Periodically, Send email notification every 1 hour",
+ "Permission denied": "Permission denied",
+ "Photos": "Photos",
+ "Please Select": "Please Select",
+ "Please select atleast one record!": "Please select atleast one record!",
+ "Please select organization": "Please select organization",
+ "Plugin Settings": "Plugin Settings",
+ "Plugin not updated successfully.": "Plugin not updated successfully.",
+ "Plugin updated successfully": "Plugin updated successfully",
+ "Plugins": "Plugins",
+ "Position": "Position",
+ "Powered by": "Powered by",
+ "Private": "Private",
+ "Private %s": "Private %s",
+ "Productivity Beats": "Productivity Beats",
+ "Profile": "Profile",
+ "Public": "Public",
+ "Public %s": "Public %s",
+ "QR code": "QR code",
+ "Recent activity": "Recent activity",
+ "Register": "Register",
+ "Registered": "Registered",
+ "Remove": "Remove",
+ "Remove %s from %s Boards? The member will be removed from all cards on this board.": "Remove %s from %s Boards? The member will be removed from all cards on this board.",
+ "Remove Member": "Remove Member",
+ "Remove all access to the organization. The member will remain on all their boards in this organization.": "Remove all access to the organization. The member will remain on all their boards in this organization.",
+ "Remove all access to the organization. The member will remain on all their boards in this organization. They will receive a notification.": "Remove all access to the organization. The member will remain on all their boards in this organization. They will receive a notification.",
+ "Remove from board": "Remove from board",
+ "Remove from organization": "Remove from organization",
+ "Rename": "Rename",
+ "Rename Board": "Rename Board",
+ "Reopen": "Reopen",
+ "Reopen Board": "Reopen Board",
+ "Reply": "Reply",
+ "Reply To": "Reply To",
+ "Role": "Role",
+ "Role Settings": "Role Settings",
+ "Roles": "Roles",
+ "Save": "Save",
+ "Search": "Search",
+ "Search Card": "Search Card",
+ "Search Member": "Search Member",
+ "Search Members": "Search Members",
+ "Search for a card to copy": "Search for a card to copy",
+ "Search for a person in %s by name or email address.": "Search for a person in %s by name or email address.",
+ "Select": "Select",
+ "Select Board": "Select Board",
+ "Select List": "Select List",
+ "Select Template": "Select Template",
+ "Select Visibility": "Select Visibility",
+ "Send": "Send",
+ "Send to board": "Send to board",
+ "Set cover image to card": "Set cover image to card",
+ "Settings": "Settings",
+ "Settings not updated properly.": "Settings not updated properly.",
+ "Settings updated successfully.": "Settings updated successfully.",
+ "Share and more...": "Share and more...",
+ "Show Attachments": "Show Attachments",
+ "Single unified notifier app to track many Restyaboards. Available in AppStore.": "Single unified notifier app to track many Restyaboards. Available in AppStore.",
+ "Site is in offline": "Site is in offline",
+ "Sorry, login failed. Either your username or password are incorrect or admin deactivated your account.": "Sorry, login failed. Either your username or password are incorrect or admin deactivated your account.",
+ "Sort": "Sort",
+ "Star": "Star",
+ "Starred Boards": "Starred Boards",
+ "Subject": "Subject",
+ "Submit": "Submit",
+ "Subscribe": "Subscribe",
+ "Switch to Cards": "Switch to Cards",
+ "Switch to lists": "Switch to lists",
+ "Sync with Google Calendar": "Sync with Google Calendar",
+ "Syncing...": "Syncing...",
+ "Technologies and Components": "Technologies and Components",
+ "Template": "Template",
+ "The board must be added to an org to enable this.": "The board must be added to an org to enable this.",
+ "This board is private. Only people added to the board can view and edit it.": "This board is private. Only people added to the board can view and edit it.",
+ "This board is public. It's visible to anyone with the link and will show up in search engines like Google. Only people added to the board can edit.": "This board is public. It's visible to anyone with the link and will show up in search engines like Google. Only people added to the board can edit.",
+ "This board is visible to members of the organization. Only people added to the board can edit.": "This board is visible to members of the organization. Only people added to the board can edit.",
+ "This board may be private.": "This board may be private.",
+ "This board will be": "This board will be",
+ "This card is archived.": "This card is archived.",
+ "This organization is private. It's not indexed or visible to those outside the org.": "This organization is private. It's not indexed or visible to those outside the org.",
+ "This organization is public. It's visible to anyone with the link and will show up in search engines like Google. Only those invited to the org can add and edit org boards.": "This organization is public. It's visible to anyone with the link and will show up in search engines like Google. Only those invited to the org can add and edit org boards.",
+ "This will remove all the cards in this list from the board. To view archived cards and bring them back to the board, click \"Menu\" > \"Archived Items\".": "This will remove all the cards in this list from the board. To view archived cards and bring them back to the board, click \"Menu\" > \"Archived Items\".",
+ "This will remove list from the board. To view archived lists and bring them back to the board, click \"Settings\" > \"Archived Items\" > \"Switch to lists\".": "This will remove list from the board. To view archived lists and bring them back to the board, click \"Settings\" > \"Archived Items\" > \"Switch to lists\".",
+ "This will remove list from the board. You can't undo the list after delete.": "This will remove list from the board. You can't undo the list after delete.",
+ "Time": "Time",
+ "Tip: You can drag and drop files and links onto cards to upload them.": "Tip: You can drag and drop files and links onto cards to upload them.",
+ "Title": "Title",
+ "Toggle Dropdown": "Toggle Dropdown",
+ "Toggle navigation": "Toggle navigation",
+ "URL": "URL",
+ "Unable to change password. Please try again.": "Unable to change password. Please try again.",
+ "Unable to copy the board.": "Unable to copy the board.",
+ "Unable to import. please try again.": "Unable to import. please try again.",
+ "Unable to update. Please try again.": "Unable to update. Please try again.",
+ "Unblock": "Unblock",
+ "Unblocked": "Unblocked",
+ "Undo": "Undo",
+ "Undo Succeed": "Undo Succeed",
+ "Unstar": "Unstar",
+ "Unsubscribe": "Unsubscribe",
+ "Unvote": "Unvote",
+ "Update": "Update",
+ "Updated successfully.": "Updated successfully.",
+ "Upload Avatar": "Upload Avatar",
+ "Upload json file exported from Trello.": "Upload json file exported from Trello.",
+ "User": "User",
+ "User (%s)": "User (%s)",
+ "User Activation": "User Activation",
+ "User Profile could not be updated. Please, try again.": "User Profile could not be updated. Please, try again.",
+ "User Profile has been updated.": "User Profile has been updated.",
+ "User activities......": "User activities......",
+ "User added successfully.": "User added successfully.",
+ "User deleted successfully.": "User deleted successfully.",
+ "User removed from this organization": "User removed from this organization",
+ "Username": "Username",
+ "Username already exists. Your registration process is not completed. Please, try again.": "Username already exists. Your registration process is not completed. Please, try again.",
+ "Username. Minimum 6 characters": "Username. Minimum 6 characters",
+ "Users": "Users",
+ "Users Count": "Users Count",
+ "Version": "Version",
+ "View all activity": "View all activity",
+ "View in iOS App": "View in iOS App",
+ "View member's board activity": "View member's board activity",
+ "Visibility": "Visibility",
+ "Vote": "Vote",
+ "Voters": "Voters",
+ "Votes": "Votes",
+ "Website": "Website",
+ "Whitespace alone not allowed": "Whitespace alone not allowed",
+ "Write a comment": "Write a comment",
+ "You can reopen the board by clicking the \"Boards\" menu from the header, selecting \"View Closed Boards": "You can reopen the board by clicking the \"Boards\" menu from the header, selecting \"View Closed Boards",
+ "You can use search operators like @member, #label, is:archived, and has:attachments to refine your search.": "You can use search operators like @member, #label, is:archived, and has:attachments to refine your search.",
+ "You have successfully registered with our site and your activation mail has been sent to your mail inbox.": "You have successfully registered with our site and your activation mail has been sent to your mail inbox.",
+ "You may be able to view it by %s": "You may be able to view it by %s",
+ "Your activation has been confirmed. You can now login to the site.": "Your activation has been confirmed. You can now login to the site.",
+ "Your email address for this board": "Your email address for this board",
+ "Your emailed cards appear in...": "Your emailed cards appear in...",
+ "Your old password is incorrect, please try again.": "Your old password is incorrect, please try again.",
+ "abc Notation": "abc Notation",
+ "activities": "activities",
+ "attachments": "attachments",
+ "boards": "boards",
+ "cards": "cards",
+ "closed boards": "closed boards",
+ "emoji": "emoji",
+ "in list": "in list",
+ "lists": "lists",
+ "logging in.": "logging in.",
+ "members": "members",
+ "on": "on",
+ "organizations": "organizations",
+ "starred boards": "starred boards",
+ "users": "users",
+ "voters": "voters",
+ "{{count}} Attachment": "{{count}} Attachment",
+ "{{count}} Attachment_plural": "{{count}} Attachments",
+ "{{count}} Board": "{{count}} Board",
+ "{{count}} Board_plural": "{{count}} Boards",
+ "{{count}} Comment": "{{count}} Comment",
+ "{{count}} Comment_plural": "{{count}} Comments",
+ "{{count}} Vote": "{{count}} Vote",
+ "{{count}} Vote_plural": "{{count}} Votes"
+}
\ No newline at end of file
diff --git a/restyaboard.conf b/restyaboard.conf
index 4e87bed4a..0f442c932 100644
--- a/restyaboard.conf
+++ b/restyaboard.conf
@@ -18,8 +18,8 @@ server {
client_max_body_size 300M;
- rewrite ^/download/([0-9]*)/([a-zA-Z0-9_\.]*)$ /server/php/R/download.php?id=$1&hash=$2 last;
- rewrite ^/ical/([0-9]*)/([a-z0-9]*).ics$ /server/php/R/ical.php?id=$1&hash=$2 last;
+ rewrite ^/download/([0-9]*)/([a-zA-Z0-9_\.]*)$ /server/php/download.php?id=$1&hash=$2 last;
+ rewrite ^/ical/([0-9]*)/([a-z0-9]*).ics$ /server/php/ical.php?id=$1&hash=$2 last;
rewrite ^/api/(.*)$ /server/php/R/r.php?_url=$1&$args last;
location / {
@@ -40,7 +40,7 @@ server {
if (-f $request_filename) {
break;
}
- rewrite ^/img/([a-zA-Z_]*)/([a-zA-Z_]*)/([a-zA-Z0-9_\.]*)$ /server/php/R/image.php?size=$1&model=$2&filename=$3 last;
+ rewrite ^/img/([a-zA-Z_]*)/([a-zA-Z_]*)/([a-zA-Z0-9_\.]*)$ /server/php/image.php?size=$1&model=$2&filename=$3 last;
add_header Cache-Control public;
add_header Cache-Control must-revalidate;
expires 7d;
diff --git a/restyaboard.sh b/restyaboard.sh
index a09a4223a..f9a535254 100644
--- a/restyaboard.sh
+++ b/restyaboard.sh
@@ -45,17 +45,17 @@
echo "Setting up cron for every 5 minutes to send email notification to user, if the user chosen notification type as instant..."
if ([ "$OS_REQUIREMENT" = "Ubuntu" ] || [ "$OS_REQUIREMENT" = "Debian" ])
then
- echo "*/5 * * * * $dir/server/php/R/shell/instant_email_notification.sh" >> /var/spool/cron/crontabs/root
+ echo "*/5 * * * * $dir/server/php/shell/instant_email_notification.sh" >> /var/spool/cron/crontabs/root
else
- echo "*/5 * * * * $dir/server/php/R/shell/instant_email_notification.sh" >> /var/spool/cron/root
+ echo "*/5 * * * * $dir/server/php/shell/instant_email_notification.sh" >> /var/spool/cron/root
fi
echo "Setting up cron for every 1 hour to send email notification to user, if the user chosen notification type as periodic..."
if ([ "$OS_REQUIREMENT" = "Ubuntu" ] || [ "$OS_REQUIREMENT" = "Debian" ])
then
- echo "0 * * * * $dir/server/php/R/shell/periodic_email_notification.sh" >> /var/spool/cron/crontabs/root
+ echo "0 * * * * $dir/server/php/shell/periodic_email_notification.sh" >> /var/spool/cron/crontabs/root
else
- echo "0 * * * * $dir/server/php/R/shell/periodic_email_notification.sh" >> /var/spool/cron/root
+ echo "0 * * * * $dir/server/php/shell/periodic_email_notification.sh" >> /var/spool/cron/root
fi
echo "Updating SQL..."
@@ -241,7 +241,7 @@
chmod -R go+w "$dir/media"
chmod -R go+w "$dir/client/img"
chmod -R go+w "$dir/tmp/cache"
- chmod -R 0755 "$dir/server/php/R/shell/*.sh"
+ chmod -R 0755 "$dir/server/php/shell/*.sh"
psql -U postgres -c "\q"
sleep 1
@@ -256,20 +256,20 @@
fi
echo "Changing PostgreSQL database name, user and password..."
- sed -i "s/^.*'R_DB_NAME'.*$/define('R_DB_NAME', '${POSTGRES_DBNAME}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_USER'.*$/define('R_DB_USER', '${POSTGRES_DBUSER}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', '${POSTGRES_DBPASS}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', '${POSTGRES_DBHOST}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_PORT'.*$/define('R_DB_PORT', '${POSTGRES_DBPORT}');/g" "$dir/server/php/R/config.inc.php"
+ sed -i "s/^.*'R_DB_NAME'.*$/define('R_DB_NAME', '${POSTGRES_DBNAME}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_USER'.*$/define('R_DB_USER', '${POSTGRES_DBUSER}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', '${POSTGRES_DBPASS}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', '${POSTGRES_DBHOST}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_PORT'.*$/define('R_DB_PORT', '${POSTGRES_DBPORT}');/g" "$dir/server/php/config.inc.php"
echo "Setting up cron for every 5 minutes to update ElasticSearch indexing..."
- echo "*/5 * * * * $dir/server/php/R/shell/cron.sh" >> /var/spool/cron/crontabs/root
+ echo "*/5 * * * * $dir/server/php/shell/cron.sh" >> /var/spool/cron/crontabs/root
echo "Setting up cron for every 5 minutes to send email notification to user, if the user chosen notification type as instant..."
- echo "*/5 * * * * $dir/server/php/R/shell/instant_email_notification.sh" >> /var/spool/cron/crontabs/root
+ echo "*/5 * * * * $dir/server/php/shell/instant_email_notification.sh" >> /var/spool/cron/crontabs/root
echo "Setting up cron for every 1 hour to send email notification to user, if the user chosen notification type as periodic..."
- echo "0 * * * * $dir/server/php/R/shell/periodic_email_notification.sh" >> /var/spool/cron/crontabs/root
+ echo "0 * * * * $dir/server/php/shell/periodic_email_notification.sh" >> /var/spool/cron/crontabs/root
echo "Starting services..."
service cron restart
@@ -455,7 +455,7 @@
chmod -R go+w "$dir/media"
chmod -R go+w "$dir/client/img"
chmod -R go+w "$dir/tmp/cache"
- chmod -R 0755 "$dir/server/php/R/shell/*.sh"
+ chmod -R 0755 "$dir/server/php/shell/*.sh"
psql -U postgres -c "\q"
sleep 1
@@ -470,20 +470,20 @@
fi
echo "Changing PostgreSQL database name, user and password..."
- sed -i "s/^.*'R_DB_NAME'.*$/define('R_DB_NAME', '${POSTGRES_DBNAME}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_USER'.*$/define('R_DB_USER', '${POSTGRES_DBUSER}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', '${POSTGRES_DBPASS}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', '${POSTGRES_DBHOST}');/g" "$dir/server/php/R/config.inc.php"
- sed -i "s/^.*'R_DB_PORT'.*$/define('R_DB_PORT', '${POSTGRES_DBPORT}');/g" "$dir/server/php/R/config.inc.php"
+ sed -i "s/^.*'R_DB_NAME'.*$/define('R_DB_NAME', '${POSTGRES_DBNAME}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_USER'.*$/define('R_DB_USER', '${POSTGRES_DBUSER}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_PASSWORD'.*$/define('R_DB_PASSWORD', '${POSTGRES_DBPASS}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_HOST'.*$/define('R_DB_HOST', '${POSTGRES_DBHOST}');/g" "$dir/server/php/config.inc.php"
+ sed -i "s/^.*'R_DB_PORT'.*$/define('R_DB_PORT', '${POSTGRES_DBPORT}');/g" "$dir/server/php/config.inc.php"
echo "Setting up cron for every 5 minutes to update ElasticSearch indexing..."
- echo "*/5 * * * * $dir/server/php/R/shell/cron.sh" >> /var/spool/cron/root
+ echo "*/5 * * * * $dir/server/php/shell/cron.sh" >> /var/spool/cron/root
echo "Setting up cron for every 5 minutes to send email notification to user, if the user chosen notification type as instant..."
- echo "*/5 * * * * $dir/server/php/R/shell/instant_email_notification.sh" >> /var/spool/cron/root
+ echo "*/5 * * * * $dir/server/php/shell/instant_email_notification.sh" >> /var/spool/cron/root
echo "Setting up cron for every 1 hour to send email notification to user, if the user chosen notification type as periodic..."
- echo "0 * * * * $dir/server/php/R/shell/periodic_email_notification.sh" >> /var/spool/cron/root
+ echo "0 * * * * $dir/server/php/shell/periodic_email_notification.sh" >> /var/spool/cron/root
echo "Reset php-fpm (use unix socket mode)..."
sed -i "/listen = 127.0.0.1:9000/a listen = /var/run/php5-fpm.sock" /etc/php-fpm.d/www.conf
diff --git a/server/php/R/r.php b/server/php/R/r.php
index 3eb3149db..d369b17ca 100644
--- a/server/php/R/r.php
+++ b/server/php/R/r.php
@@ -20,10 +20,10 @@
$_server_domain_url = $_server_protocol . '://' . $_SERVER['HTTP_HOST']; // http://localhost
header('Access-Control-Allow-Origin: ' . $_server_domain_url);
header('Access-Control-Allow-Methods: *');
-require_once 'config.inc.php';
-require_once 'libs/vendors/finediff.php';
-require_once 'libs/core.php';
-require_once 'libs/vendors/OAuth2/Autoloader.php';
+require_once '../config.inc.php';
+require_once '../libs/vendors/finediff.php';
+require_once '../libs/core.php';
+require_once '../libs/vendors/OAuth2/Autoloader.php';
/**
* Common method to handle GET method
*
@@ -45,11 +45,23 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
$response['users'] = array();
$order_by = 'id';
$direction = 'desc';
+ $filter_condition = '';
if (!empty($r_resource_filters['sort'])) {
$order_by = $r_resource_filters['sort'];
$direction = $r_resource_filters['direction'];
+ } else if (!empty($r_resource_filters['filter'])) {
+ $filter_condition = 'WHERE ';
+ if ($r_resource_filters['filter'] == 'active') {
+ $filter_condition.= 'is_active = 1';
+ } else if ($r_resource_filters['filter'] == 'inactive') {
+ $filter_condition.= 'is_active = 0';
+ } else if ($r_resource_filters['filter'] == 'ldap') {
+ $filter_condition.= 'is_ldap = 1';
+ } else {
+ $filter_condition.= 'role_id = ' . $r_resource_filters['filter'];
+ }
}
- $sql = 'SELECT row_to_json(d) FROM (SELECT * FROM users_listing ul ORDER BY ' . $order_by . ' ' . $direction . ') as d ';
+ $sql = 'SELECT row_to_json(d) FROM (SELECT * FROM users_listing ul ' . $filter_condition . ' ORDER BY ' . $order_by . ' ' . $direction . ') as d ';
$c_sql = 'SELECT COUNT(*) FROM users_listing ul';
break;
@@ -89,8 +101,12 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
while ($row = pg_fetch_assoc($org_users)) {
$org_ids[] = $row['organization_id'];
}
- if (!empty($authUser) && $authUser['role_id'] == 1 && $authUser['id'] == $r_resource_vars['users']) {
- $condition = (!empty($r_resource_filters['last_activity_id'])) ? ' WHERE al.id > $1' : "";
+ if (!empty($authUser) && $authUser['role_id'] == 1 && $authUser['id'] == $r_resource_vars['users'] && empty($r_resource_filters['board_id'])) {
+ if (!empty($r_resource_filters['type']) && $r_resource_filters['type'] == 'profile') {
+ $condition = (!empty($r_resource_filters['last_activity_id'])) ? ' WHERE al.id < $1' : "";
+ } else {
+ $condition = (!empty($r_resource_filters['last_activity_id'])) ? ' WHERE al.id > $1' : "";
+ }
$sql = 'SELECT row_to_json(d) FROM (SELECT * FROM activities_listing al ' . $condition . ' ORDER BY id DESC LIMIT ' . PAGING_COUNT . ') as d';
$c_sql = 'SELECT COUNT(*) FROM activities_listing al' . $condition;
} else {
@@ -133,6 +149,8 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
$sql = 'SELECT row_to_json(d) FROM (SELECT u.id, u.username, u.profile_picture_path,u.initials, u.full_name FROM users u JOIN boards_users bu ON bu.user_id = u.id WHERE u.is_active = true AND u.is_email_confirmed = true AND ';
$sql.= 'bu.board_id = $1 AND';
array_push($pg_params, $r_resource_filters['board_id']);
+ } else if (!empty($r_resource_filters['filter'])) {
+ $sql = 'SELECT row_to_json(d) FROM (SELECT u.id, u.username, u.profile_picture_path,u.initials, u.full_name FROM users u WHERE ';
} else {
$sql = 'SELECT row_to_json(d) FROM (SELECT u.id, u.username, u.profile_picture_path,u.initials, u.full_name FROM users u WHERE u.is_active = true AND u.is_email_confirmed = true AND ';
}
@@ -302,9 +320,24 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
}
$order_by = 'name';
$direction = 'asc';
+ $filter_condition = '';
if (!empty($r_resource_filters['sort'])) {
$order_by = $r_resource_filters['sort'];
$direction = $r_resource_filters['direction'];
+ } else if (!empty($r_resource_filters['filter'])) {
+ $filter_condition = 'WHERE ';
+ if ($r_resource_filters['filter'] == 'open') {
+ $filter_condition.= 'is_closed = 0';
+ } else if ($r_resource_filters['filter'] == 'closed') {
+ $filter_condition.= 'is_closed = 1';
+ } else if ($r_resource_filters['filter'] == 'private') {
+ $filter_condition.= 'board_visibility = 0';
+ } else if ($r_resource_filters['filter'] == 'public') {
+ $filter_condition.= 'board_visibility = 1';
+ } else if ($r_resource_filters['filter'] == 'organization') {
+ $filter_condition.= 'board_visibility = 2';
+ }
+ $sql.= $filter_condition;
}
$sql.= ' ORDER BY ' . $order_by . ' ' . $direction . ') as d ';
if ($authUser['role_id'] != 1 && empty($board_ids)) {
@@ -597,10 +630,56 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
case '/settings':
$role_id = (empty($user['role_id'])) ? 3 : $user['role_id'];
- $s_sql = pg_query_params($db_lnk, 'SELECT name, value FROM settings WHERE name = \'SITE_NAME\' OR name = \'SITE_TIMEZONE\' OR name = \'DROPBOX_APPKEY\' OR name = \'LABEL_ICON\' OR name = \'FLICKR_API_KEY\' or name = \'LDAP_LOGIN_ENABLED\' or name = \'STANDARD_LOGIN_ENABLED\'', array());
+ $s_sql = pg_query_params($db_lnk, 'SELECT name, value FROM settings WHERE name = \'SITE_NAME\' OR name = \'SITE_TIMEZONE\' OR name = \'DROPBOX_APPKEY\' OR name = \'LABEL_ICON\' OR name = \'FLICKR_API_KEY\' or name = \'LDAP_LOGIN_ENABLED\' OR name = \'DEFAULT_LANGUAGE\' OR name = \'IMAP_EMAIL\' OR name = \'STANDARD_LOGIN_ENABLED\'', array());
while ($row = pg_fetch_assoc($s_sql)) {
$response[$row['name']] = $row['value'];
}
+ $files = glob(APP_PATH . '/client/plugins/*/plugin.json', GLOB_BRACE);
+ foreach ($files as $file) {
+ $content = file_get_contents($file);
+ $data = json_decode($content, true);
+ if ($data['enabled'] === true) {
+ if (!empty($data['settings'])) {
+ foreach ($data['settings'] as $key => $value) {
+ if ($value['is_public']) {
+ $value['name'] = $key;
+ $response['plugins']['settings'][] = $value;
+ }
+ }
+ }
+ foreach ($data['assets']['js'] as $jsfiles) {
+ $response['plugins']['js'][] = $jsfiles;
+ }
+ foreach ($data['assets']['css'] as $cssfiles) {
+ $response['plugins']['css'][] = $cssfiles;
+ }
+ }
+ }
+ break;
+
+ case '/plugins':
+ $files = glob(APP_PATH . '/client/plugins/*/plugin.json', GLOB_BRACE);
+ foreach ($files as $file) {
+ $folder = explode('/', $file);
+ $content = file_get_contents($file);
+ $data = json_decode($content, true);
+ $data['folder'] = $folder[count($folder) - 2];
+ $response[] = $data;
+ }
+ break;
+
+ case '/plugins/settings':
+ $content = file_get_contents(APP_PATH . '/client/plugins/' . $r_resource_filters['plugin'] . '/plugin.json');
+ $data = json_decode($content, true);
+ if (!empty($data['settings'])) {
+ foreach ($data['settings'] as $key => $value) {
+ $value['name'] = $key;
+ $value['folder'] = $r_resource_filters['plugin'];
+ $value['plugin_name'] = $data['name'];
+ $value['settings_description'] = $data['settings_description'];
+ $response[] = $value;
+ }
+ }
break;
default:
@@ -625,6 +704,66 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
);
$sql.= ' LIMIT ' . PAGING_COUNT . ' OFFSET ' . $start;
}
+ if ($r_resource_cmd == '/users') {
+ $filter_count = array();
+ $val_array = array(
+ true
+ );
+ $active_count = executeQuery('SELECT count(*) FROM users WHERE is_active = $1', $val_array);
+ $filter_count['active'] = $active_count['count'];
+ $val_array = array(
+ 0
+ );
+ $inactive_count = executeQuery('SELECT count(*) FROM users WHERE is_active = $1', $val_array);
+ $filter_count['inactive'] = $inactive_count['count'];
+ $val_array = array(
+ true
+ );
+ $ldap_count = executeQuery('SELECT count(*) FROM users WHERE is_ldap = $1', $val_array);
+ $filter_count['ldap'] = $ldap_count['count'];
+ $val_array = array();
+ $s_result = pg_query_params($db_lnk, 'SELECT * FROM roles', $val_array);
+ $roles = array();
+ $i = 0;
+ while ($row = pg_fetch_assoc($s_result)) {
+ $roles[$i]['id'] = $row['id'];
+ $roles[$i]['name'] = ucfirst($row['name']);
+ $val_array = array(
+ $row['id']
+ );
+ $user_count = executeQuery('SELECT count(*) FROM users WHERE role_id = $1', $val_array);
+ $roles[$i]['count'] = $user_count['count'];
+ $i++;
+ }
+ }
+ if ($r_resource_cmd == '/boards') {
+ $filter_count = array();
+ $val_array = array(
+ true
+ );
+ $closed_count = executeQuery('SELECT count(*) FROM boards WHERE is_closed = $1', $val_array);
+ $filter_count['closed'] = $closed_count['count'];
+ $val_array = array(
+ 0
+ );
+ $open_count = executeQuery('SELECT count(*) FROM boards WHERE is_closed = $1', $val_array);
+ $filter_count['open'] = $open_count['count'];
+ $val_array = array(
+ 0
+ );
+ $private_count = executeQuery('SELECT count(*) FROM boards WHERE board_visibility = $1', $val_array);
+ $filter_count['private'] = $private_count['count'];
+ $val_array = array(
+ 1
+ );
+ $public_count = executeQuery('SELECT count(*) FROM boards WHERE board_visibility = $1', $val_array);
+ $filter_count['public'] = $public_count['count'];
+ $val_array = array(
+ 2
+ );
+ $organization_count = executeQuery('SELECT count(*) FROM boards WHERE board_visibility = $1', $val_array);
+ $filter_count['organization'] = $organization_count['count'];
+ }
$arrayResponse = array(
'/users/?/cards',
'/users/?/activities',
@@ -804,6 +943,12 @@ function r_get($r_resource_cmd, $r_resource_vars, $r_resource_filters)
if (!empty($_metadata)) {
$data['_metadata'] = $_metadata;
}
+ if (!empty($_metadata) && !empty($filter_count)) {
+ $data['filter_count'] = $filter_count;
+ }
+ if (!empty($roles)) {
+ $data['roles'] = $roles;
+ }
echo json_encode($data);
pg_free_result($result);
} else {
@@ -969,9 +1114,9 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
} else {
$msg = '';
if ($user['email'] == $r_post['email']) {
- $msg = 'Email address already exists. Your registration process is not completed. Please, try again.';
+ $msg = 1;
} else if ($user['username'] == $r_post['username']) {
- $msg = 'Username already exists. Your registration process is not completed. Please, try again.';
+ $msg = 2;
}
$response = array(
'error' => $msg
@@ -997,9 +1142,9 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
} else {
$msg = '';
if ($user['email'] == $r_post['email']) {
- $msg = 'Email address already exist. Your registration process is not completed. Please, try again.';
+ $msg = 1;
} else if ($user['username'] == $r_post['username']) {
- $msg = 'Username address already exist. Your registration process is not completed. Please, try again.';
+ $msg = 2;
}
$response = array(
'error' => $msg
@@ -1128,17 +1273,17 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
}
} else {
$response = array(
- 'error' => 'Your old password is incorrect, please try again.'
+ 'error' => 1
);
}
} else {
$response = array(
- 'error' => 'Unable to change password. Please try again.'
+ 'error' => 2
);
}
} else {
$response = array(
- 'error' => 'New and confirm password field must match, please try again.'
+ 'error' => 3
);
}
break;
@@ -1185,7 +1330,7 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
pg_query_params($db_lnk, 'UPDATE users SET profile_picture_path = $1 WHERE id = $2', $qry_val_arr);
} else {
$no_error = false;
- $msg = 'File extension not supported. It supports only jpg, png, bmp and gif.';
+ $msg = 1;
}
} else {
if (!empty($_POST['email'])) {
@@ -1195,7 +1340,7 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
$user = executeQuery('SELECT * FROM users WHERE email = $1', $usr_val_arr);
if ($user['id'] != $r_resource_vars['users'] && $user['email'] == $_POST['email']) {
$no_error = false;
- $msg = 'Email address already exist. User Profile could not be updated. Please, try again.';
+ $msg = 2;
}
}
if ($no_error) {
@@ -1341,18 +1486,20 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
);
$result = pg_query_params($db_lnk, 'INSERT INTO ' . $table_name . ' (created, modified, board_id, user_id, is_starred) VALUES (now(), now(), $1, $2, true) RETURNING id', $qry_val_arr);
} else {
- if ($subcriber['is_starred'] == 1) {
+ if ($subcriber['is_starred'] == true) {
$qry_val_arr = array(
+ 0,
$r_resource_vars['boards'],
$authUser['id']
);
- $result = pg_query_params($db_lnk, 'UPDATE ' . $table_name . ' SET is_starred = false Where board_id = $1 and user_id = $2 RETURNING id', $qry_val_arr);
+ $result = pg_query_params($db_lnk, 'UPDATE ' . $table_name . ' SET is_starred = $1 Where board_id = $2 and user_id = $3 RETURNING id', $qry_val_arr);
} else {
$qry_val_arr = array(
+ 1,
$r_resource_vars['boards'],
$authUser['id']
);
- $result = pg_query_params($db_lnk, 'UPDATE ' . $table_name . ' SET is_starred = True Where board_id = $1 and user_id = $2 RETURNING id', $qry_val_arr);
+ $result = pg_query_params($db_lnk, 'UPDATE ' . $table_name . ' SET is_starred = $1 Where board_id = $2 and user_id = $3 RETURNING id', $qry_val_arr);
}
}
$star = pg_fetch_assoc($result);
@@ -1963,6 +2110,24 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
}
break;
+ case '/plugins/settings':
+ $folder_name = $r_post['folder'];
+ unset($r_post['folder']);
+ $content = file_get_contents(APP_PATH . '/client/plugins/' . $folder_name . '/plugin.json');
+ $plugin = json_decode($content, true);
+ if (isset($r_post['enable'])) {
+ $plugin['enabled'] = $r_post['enable'];
+ } else {
+ foreach ($r_post as $key => $val) {
+ $plugin['settings'][$key]['value'] = $val;
+ }
+ }
+ $fh = fopen(APP_PATH . '/client/plugins/' . $folder_name . '/plugin.json', 'w');
+ fwrite($fh, json_encode($plugin, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
+ fclose($fh);
+ $response['success'] = 'Plugin updated successfully';
+ break;
+
default:
header($_SERVER['SERVER_PROTOCOL'] . ' 501 Not Implemented', true, 501);
break;
@@ -2108,6 +2273,17 @@ function r_post($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_post)
}
$response['list']['cards'] = json_decode($response['list']['cards'], true);
$response['list']['lists_subscribers'] = json_decode($response['list']['lists_subscribers'], true);
+ $qry_val_arr = array(
+ $r_post['board_id']
+ );
+ $list_count = executeQuery('SELECT count(*) as count FROM lists WHERE board_id = $1', $qry_val_arr);
+ if ($list_count['count'] == 1) {
+ $qry_val_arr = array(
+ $r_post['board_id'],
+ $response['id']
+ );
+ $board_query = pg_query_params($db_lnk, 'UPDATE boards SET default_email_list_id = $2 WHERE id = $1', $qry_val_arr);
+ }
} else if ($r_resource_cmd == '/boards/?/lists/?/cards' || $r_resource_cmd == '/boards/?/lists/?/cards/?/checklists/?/items/?/convert_to_card') {
$qry_val_arr = array(
$r_post['list_id']
@@ -2957,8 +3133,9 @@ function r_put($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_put)
$username = pg_fetch_assoc($s_result);
$comment = '##USER_NAME## ' . $is_active . ' ' . $username['username'] . '';
$foreign_id['user_id'] = $r_resource_vars['users'];
- } else if (isset($r_put['last_activity_id'])) {
+ } else if (isset($r_put['last_activity_id']) || isset($r_put['language'])) {
$comment = '';
+ $response['success'] = 'Language changed successfully.';
}
$foreign_ids['user_id'] = $authUser['id'];
break;
@@ -2993,7 +3170,9 @@ function r_put($r_resource_cmd, $r_resource_vars, $r_resource_filters, $r_put)
'Public'
);
$foreign_ids['board_id'] = $r_resource_vars['boards'];
- if (isset($r_put['board_visibility'])) {
+ if (isset($r_put['default_email_list_id']) || isset($r_put['is_default_email_position_as_bottom'])) {
+ $comment = '';
+ } else if (isset($r_put['board_visibility'])) {
$comment = '##USER_NAME## changed visibility to ' . $board_visibility[$r_put['board_visibility']];
$activity_type = 'change_visibility';
} else if (!empty($r_put['is_closed'])) {
@@ -3847,7 +4026,7 @@ function r_delete($r_resource_cmd, $r_resource_vars, $r_resource_filters)
);
$response = executeQuery("SELECT user_id as username, expires FROM oauth_access_tokens WHERE client_id = $1 AND access_token = $2", $conditions);
$expires = strtotime($response['expires']);
- if (!empty($response['error']) || ($expires > 0 && $expires < time())) {
+ if (empty($response) || !empty($response['error']) || ($expires > 0 && $expires < time())) {
$response['error']['type'] = 'OAuth';
echo json_encode($response);
exit;
@@ -3886,6 +4065,16 @@ function r_delete($r_resource_cmd, $r_resource_vars, $r_resource_filters)
);
$role_links = executeQuery('SELECT * FROM role_links_listing WHERE id = $1', $qry_val_arr);
$response = array_merge($response, $role_links);
+ $files = glob(APP_PATH . '/client/locales/*/translation.json', GLOB_BRACE);
+ foreach ($files as $file) {
+ $folder = explode('/', $file);
+ $qry_val_arr = array(
+ $folder[count($folder) - 2]
+ );
+ $language = executeQuery('SELECT name FROM languages WHERE iso2 = $1', $qry_val_arr);
+ $response['languages'][$folder[count($folder) - 2]] = $language['name'];
+ }
+ $response['languages'] = json_encode($response['languages']);
echo json_encode($response);
exit;
}
diff --git a/server/php/R/shell/instant_email_notification.php b/server/php/R/shell/instant_email_notification.php
deleted file mode 100644
index d4443500b..000000000
--- a/server/php/R/shell/instant_email_notification.php
+++ /dev/null
@@ -1,164 +0,0 @@
-
- * @copyright 2014 Restya
- * @license http://restya.com/ Restya Licence
- * @link http://restya.com/
- */
-$app_path = dirname(dirname(__FILE__));
-require_once $app_path . '/config.inc.php';
-require_once $app_path . '/libs/core.php';
-global $_server_domain_url;
-if (file_exists(APP_PATH . '/tmp/cache/site_url_for_shell.php')) {
- include_once APP_PATH . '/tmp/cache/site_url_for_shell.php';
-}
-if ($db_lnk) {
- $qry_val_arr = array(
- 2
- );
- $users_result = pg_query_params($db_lnk, 'SELECT users.*, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT bs.board_id FROM board_subscribers bs WHERE bs.user_id = users.id) d) AS board_ids, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT ls.list_id, l.board_id FROM list_subscribers ls, lists l WHERE ls.user_id = users.id AND l.id = ls.list_id) d) AS list_ids,(SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT cs.card_id, c.list_id, c.board_id FROM card_subscribers cs, cards c WHERE cs.user_id = users.id AND c.id = cs.card_id) d) AS card_ids FROM users WHERE is_send_newsletter = $1', $qry_val_arr);
- while ($user = pg_fetch_assoc($users_result)) {
- $board_ids = $list_ids = $card_ids = array();
- $board_arr = (!empty($user['board_ids'])) ? array_filter(json_decode($user['board_ids'], true)) : '';
- $list_arr = (!empty($user['list_ids'])) ? array_filter(json_decode($user['list_ids'], true)) : '';
- $card_arr = (!empty($user['card_ids'])) ? array_filter(json_decode($user['card_ids'], true)) : '';
- if (!empty($board_arr)) {
- foreach ($board_arr as $boards) {
- $board_ids[] = $boards['board_id'];
- }
- }
- if (!empty($list_arr)) {
- foreach ($list_arr as $lists) {
- if (!in_array($lists['board_id'], $board_ids)) {
- $list_ids[] = $lists['list_id'];
- }
- }
- }
- if (!empty($card_arr)) {
- foreach ($card_arr as $cards) {
- if (!in_array($cards['board_id'], $board_ids) && !in_array($cards['list_id'], $list_ids)) {
- $card_ids[] = $cards['card_id'];
- }
- }
- }
- $mail_content = '';
- $activities_result = '';
- $notification_count = 0;
- if (!empty($board_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $board_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND board_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($list_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $list_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND list_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($card_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $card_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND card_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($mail_content)) {
- $qry_arr = array(
- max($activity_id) ,
- $user['id']
- );
- pg_query_params($db_lnk, 'UPDATE users SET last_email_notified_activity_id = $1 WHERE id = $2', $qry_arr);
- $emailFindReplace['##CONTENT##'] = $mail_content;
- $emailFindReplace['##NAME##'] = $user['full_name'];
- $emailFindReplace['##NOTIFICATION_COUNT##'] = $notification_count;
- $emailFindReplace['##SINCE##'] = date("h:i A (F j, Y)");
- $emailFindReplace['##USER_ID##'] = $user['id'];
- sendMail('email_notification', $emailFindReplace, $user['email']);
- }
- }
-}
diff --git a/server/php/R/shell/periodic_email_notification.php b/server/php/R/shell/periodic_email_notification.php
deleted file mode 100644
index d4443500b..000000000
--- a/server/php/R/shell/periodic_email_notification.php
+++ /dev/null
@@ -1,164 +0,0 @@
-
- * @copyright 2014 Restya
- * @license http://restya.com/ Restya Licence
- * @link http://restya.com/
- */
-$app_path = dirname(dirname(__FILE__));
-require_once $app_path . '/config.inc.php';
-require_once $app_path . '/libs/core.php';
-global $_server_domain_url;
-if (file_exists(APP_PATH . '/tmp/cache/site_url_for_shell.php')) {
- include_once APP_PATH . '/tmp/cache/site_url_for_shell.php';
-}
-if ($db_lnk) {
- $qry_val_arr = array(
- 2
- );
- $users_result = pg_query_params($db_lnk, 'SELECT users.*, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT bs.board_id FROM board_subscribers bs WHERE bs.user_id = users.id) d) AS board_ids, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT ls.list_id, l.board_id FROM list_subscribers ls, lists l WHERE ls.user_id = users.id AND l.id = ls.list_id) d) AS list_ids,(SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT cs.card_id, c.list_id, c.board_id FROM card_subscribers cs, cards c WHERE cs.user_id = users.id AND c.id = cs.card_id) d) AS card_ids FROM users WHERE is_send_newsletter = $1', $qry_val_arr);
- while ($user = pg_fetch_assoc($users_result)) {
- $board_ids = $list_ids = $card_ids = array();
- $board_arr = (!empty($user['board_ids'])) ? array_filter(json_decode($user['board_ids'], true)) : '';
- $list_arr = (!empty($user['list_ids'])) ? array_filter(json_decode($user['list_ids'], true)) : '';
- $card_arr = (!empty($user['card_ids'])) ? array_filter(json_decode($user['card_ids'], true)) : '';
- if (!empty($board_arr)) {
- foreach ($board_arr as $boards) {
- $board_ids[] = $boards['board_id'];
- }
- }
- if (!empty($list_arr)) {
- foreach ($list_arr as $lists) {
- if (!in_array($lists['board_id'], $board_ids)) {
- $list_ids[] = $lists['list_id'];
- }
- }
- }
- if (!empty($card_arr)) {
- foreach ($card_arr as $cards) {
- if (!in_array($cards['board_id'], $board_ids) && !in_array($cards['list_id'], $list_ids)) {
- $card_ids[] = $cards['card_id'];
- }
- }
- }
- $mail_content = '';
- $activities_result = '';
- $notification_count = 0;
- if (!empty($board_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $board_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND board_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($list_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $list_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND list_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($card_ids)) {
- $qry_arr = array(
- $user['last_email_notified_activity_id'],
- $user['id'],
- '{' . implode(',', $card_ids) . '}'
- );
- $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id = $2 AND card_id = ANY ($3) ORDER BY id DESC', $qry_arr);
- $i = 0;
- while ($activity = pg_fetch_assoc($activities_result)) {
- if (!empty($activity['profile_picture_path'])) {
- $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
- $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
- $user_avatar = '
';
- } else if (!empty($activity['initials'])) {
- $user_avatar = '
' . $activity['initials'] . ' ';
- }
- if (empty($i)) {
- $activity_id[] = $activity['id'];
- $i++;
- }
- if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
- $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
- $br = '
';
- } else {
- $activity['comment'].= ' on ##BOARD_NAME##';
- $br = '
';
- }
- $comment = findAndReplaceVariables($activity);
- $mail_content.= $user_avatar . $comment . $br;
- $notification_count++;
- }
- }
- if (!empty($mail_content)) {
- $qry_arr = array(
- max($activity_id) ,
- $user['id']
- );
- pg_query_params($db_lnk, 'UPDATE users SET last_email_notified_activity_id = $1 WHERE id = $2', $qry_arr);
- $emailFindReplace['##CONTENT##'] = $mail_content;
- $emailFindReplace['##NAME##'] = $user['full_name'];
- $emailFindReplace['##NOTIFICATION_COUNT##'] = $notification_count;
- $emailFindReplace['##SINCE##'] = date("h:i A (F j, Y)");
- $emailFindReplace['##USER_ID##'] = $user['id'];
- sendMail('email_notification', $emailFindReplace, $user['email']);
- }
- }
-}
diff --git a/server/php/R/config.inc.php b/server/php/config.inc.php
similarity index 92%
rename from server/php/R/config.inc.php
rename to server/php/config.inc.php
index 18924d4f6..7fd033ba0 100644
--- a/server/php/R/config.inc.php
+++ b/server/php/config.inc.php
@@ -15,7 +15,10 @@
define('R_DEBUG', false);
ini_set('display_errors', R_DEBUG);
define('R_API_VERSION', 1);
-define('APP_PATH', dirname(dirname(dirname(dirname(__FILE__)))));
+if (!defined('JSON_PRETTY_PRINT')) {
+ define('JSON_PRETTY_PRINT', 128);
+}
+define('APP_PATH', dirname(dirname(dirname(__FILE__))));
// While changing below oAuth credentials, have to update in oauth_clients table also.
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
define('OAUTH_CLIENTID', $_SERVER['PHP_AUTH_USER']);
@@ -42,7 +45,7 @@
fclose($fh);
}
$db_lnk = pg_connect('host=' . R_DB_HOST . ' port=' . R_DB_PORT . ' dbname=' . R_DB_NAME . ' user=' . R_DB_USER . ' password=' . R_DB_PASSWORD . ' options=--client_encoding=UTF8') or die('Database could not connect');
-$settings = pg_query_params($db_lnk, 'SELECT name, value FROM settings WHERE setting_category_id in (1,2,3) OR setting_category_parent_id in (1,2,3)', array());
+$settings = pg_query_params($db_lnk, 'SELECT name, value FROM settings WHERE setting_category_id in (1,2,3,10) OR setting_category_parent_id in (1,2,3)', array());
while ($setting = pg_fetch_assoc($settings)) {
if ($setting['name'] == 'LDAP_LOGIN_ENABLED' || $setting['name'] == 'STANDARD_LOGIN_ENABLED') {
$setting_array = array(
diff --git a/server/php/R/download.php b/server/php/download.php
similarity index 100%
rename from server/php/R/download.php
rename to server/php/download.php
diff --git a/server/php/R/ical.php b/server/php/ical.php
similarity index 93%
rename from server/php/R/ical.php
rename to server/php/ical.php
index 6de779c30..677981032 100644
--- a/server/php/R/ical.php
+++ b/server/php/ical.php
@@ -23,32 +23,34 @@
);
$result = pg_query_params($db_lnk, 'SELECT board.name, card.id, card.name as card_name, card.description, card.due_date FROM boards board LEFT JOIN cards card ON card.board_id = board.id WHERE card.is_archived = FALSE AND card.due_date IS NOT NULL AND board.id = $1', $val_array);
$count = pg_num_rows($result);
- $ical = 'BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//' . SITE_NAME . '//EN
-X-PUBLISHED-TTL:PT1H
-X-ORIGINAL-URL:http://' . $_SERVER['HTTP_HOST'] . '
-CALSCALE:GREGORIAN
+ $ical = 'BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//' . SITE_NAME . '//EN
+X-PUBLISHED-TTL:PT1H
+X-ORIGINAL-URL:http://' . $_SERVER['HTTP_HOST'] . '
+CALSCALE:GREGORIAN
METHOD:PUBLISH';
if ($count > 0) {
$event = '';
$board_name = '';
while ($row = pg_fetch_assoc($result)) {
$board_name = $row['name'];
- $event.= '
-BEGIN:VEVENT
-UID:' . $row['id'] . '
-DTSTART:' . date('Ymd\THis\Z', strtotime($row['due_date'])) . '
-DTEND:' . date('Ymd\THis\Z', strtotime($row['due_date'])) . '
-SUMMARY:' . $row['card_name'] . '
-URL:http://' . $_SERVER['HTTP_HOST'] . '/client/#/board/' . $_GET['id'] . '
-DESCRIPTION:' . $row['description'] . '
-END:VEVENT
-END:VCALENDAR';
+ $event.= '
+BEGIN:VEVENT
+UID:' . $row['id'] . '
+DTSTART:' . date('Ymd\THis\Z', strtotime($row['due_date'])) . '
+DTEND:' . date('Ymd\THis\Z', strtotime($row['due_date'])) . '
+SUMMARY:' . $row['card_name'] . '
+URL:http://' . $_SERVER['HTTP_HOST'] . '/client/#/board/' . $_GET['id'] . '
+DESCRIPTION:' . $row['description'] . '
+END:VEVENT
';
}
- $ical.= 'X-WR-CALNAME:' . $board_name . ' (via ' . SITE_NAME . ')';
+ $ical.= '
+X-WR-CALNAME:' . $board_name . ' (via ' . SITE_NAME . ')';
$ical.= $event;
}
+ $ical.= '
+END:VCALENDAR';
header('Content-type: text/calendar; charset=utf-8');
header('Content-Disposition: inline; filename=calendar.ics');
echo $ical;
diff --git a/server/php/R/image.php b/server/php/image.php
similarity index 100%
rename from server/php/R/image.php
rename to server/php/image.php
diff --git a/server/php/R/libs/core.php b/server/php/libs/core.php
similarity index 99%
rename from server/php/R/libs/core.php
rename to server/php/libs/core.php
index 65d569518..dbb893ae0 100644
--- a/server/php/R/libs/core.php
+++ b/server/php/libs/core.php
@@ -220,6 +220,9 @@ function curlExecute($url, $method = 'get', $post = array() , $format = 'plain')
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
}
$response = curl_exec($ch);
+ if ($format == 'token') {
+ return $response;
+ }
if ($format == 'image') {
$info = curl_getinfo($ch);
array_change_key_case($info);
@@ -534,10 +537,11 @@ function executeQuery($qry, $arr = array())
* @param string $template Email template name
* @param string $replace_content Email content replace array
* @param string $to To email address
+ * @param string $reply_to_mail Reply to email address
*
* @return void
*/
-function sendMail($template, $replace_content, $to)
+function sendMail($template, $replace_content, $to, $reply_to_mail = '')
{
global $r_debug, $db_lnk, $_server_domain_url;
if (file_exists(APP_PATH . '/tmp/cache/site_url_for_shell.php')) {
@@ -559,6 +563,9 @@ function sendMail($template, $replace_content, $to)
$subject = strtr($template['subject'], $emailFindReplace);
$from_email = strtr($template['from_email'], $emailFindReplace);
$headers = 'From:' . $from_email . "\r\n";
+ if (!empty($reply_to_mail)) {
+ $headers.= 'Reply-To:' . $reply_to_mail . "\r\n";
+ }
$headers.= "MIME-Version: 1.0\r\n";
$headers.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$headers.= "X-Mailer: Restyaboard (0.1.6; +http://restya.com/board)\r\n";
@@ -880,6 +887,7 @@ function getbindValues($table, $data, $expected_fields_arr = array())
*/
function importTrelloBoard($board = array())
{
+ set_time_limit(0);
global $r_debug, $db_lnk, $authUser, $_server_domain_url;
$users = array();
if (!empty($board)) {
diff --git a/server/php/R/libs/vendors/OAuth2/Autoloader.php b/server/php/libs/vendors/OAuth2/Autoloader.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Autoloader.php
rename to server/php/libs/vendors/OAuth2/Autoloader.php
diff --git a/server/php/R/libs/vendors/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php b/server/php/libs/vendors/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
rename to server/php/libs/vendors/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/ClientAssertionType/HttpBasic.php b/server/php/libs/vendors/OAuth2/ClientAssertionType/HttpBasic.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ClientAssertionType/HttpBasic.php
rename to server/php/libs/vendors/OAuth2/ClientAssertionType/HttpBasic.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/AuthorizeController.php b/server/php/libs/vendors/OAuth2/Controller/AuthorizeController.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/AuthorizeController.php
rename to server/php/libs/vendors/OAuth2/Controller/AuthorizeController.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/AuthorizeControllerInterface.php b/server/php/libs/vendors/OAuth2/Controller/AuthorizeControllerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/AuthorizeControllerInterface.php
rename to server/php/libs/vendors/OAuth2/Controller/AuthorizeControllerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/ResourceController.php b/server/php/libs/vendors/OAuth2/Controller/ResourceController.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/ResourceController.php
rename to server/php/libs/vendors/OAuth2/Controller/ResourceController.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/ResourceControllerInterface.php b/server/php/libs/vendors/OAuth2/Controller/ResourceControllerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/ResourceControllerInterface.php
rename to server/php/libs/vendors/OAuth2/Controller/ResourceControllerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/TokenController.php b/server/php/libs/vendors/OAuth2/Controller/TokenController.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/TokenController.php
rename to server/php/libs/vendors/OAuth2/Controller/TokenController.php
diff --git a/server/php/R/libs/vendors/OAuth2/Controller/TokenControllerInterface.php b/server/php/libs/vendors/OAuth2/Controller/TokenControllerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Controller/TokenControllerInterface.php
rename to server/php/libs/vendors/OAuth2/Controller/TokenControllerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Encryption/EncryptionInterface.php b/server/php/libs/vendors/OAuth2/Encryption/EncryptionInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Encryption/EncryptionInterface.php
rename to server/php/libs/vendors/OAuth2/Encryption/EncryptionInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Encryption/Jwt.php b/server/php/libs/vendors/OAuth2/Encryption/Jwt.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Encryption/Jwt.php
rename to server/php/libs/vendors/OAuth2/Encryption/Jwt.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/AuthorizationCode.php b/server/php/libs/vendors/OAuth2/GrantType/AuthorizationCode.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/AuthorizationCode.php
rename to server/php/libs/vendors/OAuth2/GrantType/AuthorizationCode.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/ClientCredentials.php b/server/php/libs/vendors/OAuth2/GrantType/ClientCredentials.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/ClientCredentials.php
rename to server/php/libs/vendors/OAuth2/GrantType/ClientCredentials.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/GrantTypeInterface.php b/server/php/libs/vendors/OAuth2/GrantType/GrantTypeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/GrantTypeInterface.php
rename to server/php/libs/vendors/OAuth2/GrantType/GrantTypeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/JwtBearer.php b/server/php/libs/vendors/OAuth2/GrantType/JwtBearer.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/JwtBearer.php
rename to server/php/libs/vendors/OAuth2/GrantType/JwtBearer.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/RefreshToken.php b/server/php/libs/vendors/OAuth2/GrantType/RefreshToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/RefreshToken.php
rename to server/php/libs/vendors/OAuth2/GrantType/RefreshToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/GrantType/UserCredentials.php b/server/php/libs/vendors/OAuth2/GrantType/UserCredentials.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/GrantType/UserCredentials.php
rename to server/php/libs/vendors/OAuth2/GrantType/UserCredentials.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Controller/AuthorizeController.php b/server/php/libs/vendors/OAuth2/OpenID/Controller/AuthorizeController.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Controller/AuthorizeController.php
rename to server/php/libs/vendors/OAuth2/OpenID/Controller/AuthorizeController.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php b/server/php/libs/vendors/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Controller/UserInfoController.php b/server/php/libs/vendors/OAuth2/OpenID/Controller/UserInfoController.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Controller/UserInfoController.php
rename to server/php/libs/vendors/OAuth2/OpenID/Controller/UserInfoController.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Controller/UserInfoControllerInterface.php b/server/php/libs/vendors/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/GrantType/AuthorizationCode.php b/server/php/libs/vendors/OAuth2/OpenID/GrantType/AuthorizationCode.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/GrantType/AuthorizationCode.php
rename to server/php/libs/vendors/OAuth2/OpenID/GrantType/AuthorizationCode.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCode.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCode.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCode.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCode.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/IdToken.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/IdToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/IdToken.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/IdToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/IdTokenInterface.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/IdTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/IdTokenInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/IdTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdToken.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdToken.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdTokenInterface.php b/server/php/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdTokenInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/ResponseType/TokenIdTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php b/server/php/libs/vendors/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/OpenID/Storage/UserClaimsInterface.php b/server/php/libs/vendors/OAuth2/OpenID/Storage/UserClaimsInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/OpenID/Storage/UserClaimsInterface.php
rename to server/php/libs/vendors/OAuth2/OpenID/Storage/UserClaimsInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Request.php b/server/php/libs/vendors/OAuth2/Request.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Request.php
rename to server/php/libs/vendors/OAuth2/Request.php
diff --git a/server/php/R/libs/vendors/OAuth2/RequestInterface.php b/server/php/libs/vendors/OAuth2/RequestInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/RequestInterface.php
rename to server/php/libs/vendors/OAuth2/RequestInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Response.php b/server/php/libs/vendors/OAuth2/Response.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Response.php
rename to server/php/libs/vendors/OAuth2/Response.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseInterface.php b/server/php/libs/vendors/OAuth2/ResponseInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseInterface.php
rename to server/php/libs/vendors/OAuth2/ResponseInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/AccessToken.php b/server/php/libs/vendors/OAuth2/ResponseType/AccessToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/AccessToken.php
rename to server/php/libs/vendors/OAuth2/ResponseType/AccessToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/AccessTokenInterface.php b/server/php/libs/vendors/OAuth2/ResponseType/AccessTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/AccessTokenInterface.php
rename to server/php/libs/vendors/OAuth2/ResponseType/AccessTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/AuthorizationCode.php b/server/php/libs/vendors/OAuth2/ResponseType/AuthorizationCode.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/AuthorizationCode.php
rename to server/php/libs/vendors/OAuth2/ResponseType/AuthorizationCode.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/AuthorizationCodeInterface.php b/server/php/libs/vendors/OAuth2/ResponseType/AuthorizationCodeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/AuthorizationCodeInterface.php
rename to server/php/libs/vendors/OAuth2/ResponseType/AuthorizationCodeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/CryptoToken.php b/server/php/libs/vendors/OAuth2/ResponseType/CryptoToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/CryptoToken.php
rename to server/php/libs/vendors/OAuth2/ResponseType/CryptoToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/ResponseType/ResponseTypeInterface.php b/server/php/libs/vendors/OAuth2/ResponseType/ResponseTypeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ResponseType/ResponseTypeInterface.php
rename to server/php/libs/vendors/OAuth2/ResponseType/ResponseTypeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Scope.php b/server/php/libs/vendors/OAuth2/Scope.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Scope.php
rename to server/php/libs/vendors/OAuth2/Scope.php
diff --git a/server/php/R/libs/vendors/OAuth2/ScopeInterface.php b/server/php/libs/vendors/OAuth2/ScopeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/ScopeInterface.php
rename to server/php/libs/vendors/OAuth2/ScopeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Server.php b/server/php/libs/vendors/OAuth2/Server.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Server.php
rename to server/php/libs/vendors/OAuth2/Server.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/AccessTokenInterface.php b/server/php/libs/vendors/OAuth2/Storage/AccessTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/AccessTokenInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/AccessTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/AuthorizationCodeInterface.php b/server/php/libs/vendors/OAuth2/Storage/AuthorizationCodeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/AuthorizationCodeInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/AuthorizationCodeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/Cassandra.php b/server/php/libs/vendors/OAuth2/Storage/Cassandra.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/Cassandra.php
rename to server/php/libs/vendors/OAuth2/Storage/Cassandra.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/ClientCredentialsInterface.php b/server/php/libs/vendors/OAuth2/Storage/ClientCredentialsInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/ClientCredentialsInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/ClientCredentialsInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/ClientInterface.php b/server/php/libs/vendors/OAuth2/Storage/ClientInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/ClientInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/ClientInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/CryptoToken.php b/server/php/libs/vendors/OAuth2/Storage/CryptoToken.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/CryptoToken.php
rename to server/php/libs/vendors/OAuth2/Storage/CryptoToken.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/CryptoTokenInterface.php b/server/php/libs/vendors/OAuth2/Storage/CryptoTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/CryptoTokenInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/CryptoTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/JwtBearerInterface.php b/server/php/libs/vendors/OAuth2/Storage/JwtBearerInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/JwtBearerInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/JwtBearerInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/Memory.php b/server/php/libs/vendors/OAuth2/Storage/Memory.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/Memory.php
rename to server/php/libs/vendors/OAuth2/Storage/Memory.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/Mongo.php b/server/php/libs/vendors/OAuth2/Storage/Mongo.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/Mongo.php
rename to server/php/libs/vendors/OAuth2/Storage/Mongo.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/Pdo.php b/server/php/libs/vendors/OAuth2/Storage/Pdo.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/Pdo.php
rename to server/php/libs/vendors/OAuth2/Storage/Pdo.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/PublicKeyInterface.php b/server/php/libs/vendors/OAuth2/Storage/PublicKeyInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/PublicKeyInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/PublicKeyInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/Redis.php b/server/php/libs/vendors/OAuth2/Storage/Redis.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/Redis.php
rename to server/php/libs/vendors/OAuth2/Storage/Redis.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/RefreshTokenInterface.php b/server/php/libs/vendors/OAuth2/Storage/RefreshTokenInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/RefreshTokenInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/RefreshTokenInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/ScopeInterface.php b/server/php/libs/vendors/OAuth2/Storage/ScopeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/ScopeInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/ScopeInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/Storage/UserCredentialsInterface.php b/server/php/libs/vendors/OAuth2/Storage/UserCredentialsInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/Storage/UserCredentialsInterface.php
rename to server/php/libs/vendors/OAuth2/Storage/UserCredentialsInterface.php
diff --git a/server/php/R/libs/vendors/OAuth2/TokenType/Bearer.php b/server/php/libs/vendors/OAuth2/TokenType/Bearer.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/TokenType/Bearer.php
rename to server/php/libs/vendors/OAuth2/TokenType/Bearer.php
diff --git a/server/php/R/libs/vendors/OAuth2/TokenType/Mac.php b/server/php/libs/vendors/OAuth2/TokenType/Mac.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/TokenType/Mac.php
rename to server/php/libs/vendors/OAuth2/TokenType/Mac.php
diff --git a/server/php/R/libs/vendors/OAuth2/TokenType/TokenTypeInterface.php b/server/php/libs/vendors/OAuth2/TokenType/TokenTypeInterface.php
similarity index 100%
rename from server/php/R/libs/vendors/OAuth2/TokenType/TokenTypeInterface.php
rename to server/php/libs/vendors/OAuth2/TokenType/TokenTypeInterface.php
diff --git a/server/php/R/libs/vendors/finediff.php b/server/php/libs/vendors/finediff.php
similarity index 100%
rename from server/php/R/libs/vendors/finediff.php
rename to server/php/libs/vendors/finediff.php
diff --git a/server/php/oauth_callback.php b/server/php/oauth_callback.php
new file mode 100644
index 000000000..88aee7351
--- /dev/null
+++ b/server/php/oauth_callback.php
@@ -0,0 +1,28 @@
+
+ * @copyright 2014 Restya
+ * @license http://restya.com/ Restya Licence
+ * @link http://restya.com/
+ */
+require_once 'config.inc.php';
+require_once 'libs/core.php';
+if (!empty($_GET['plugin'])) {
+ $content = file_get_contents(APP_PATH . DIRECTORY_SEPARATOR . 'client' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $_GET['plugin'] . DIRECTORY_SEPARATOR . 'plugin.json');
+ $data = json_decode($content, true);
+ $post_data = array(
+ 'client_id' => $data['settings'][$_GET['plugin'] . '_client_id']['value'],
+ 'client_secret' => $data['settings'][$_GET['plugin'] . '_client_secret']['value'],
+ 'code' => $_GET['code']
+ );
+ $response = doPost($data['settings'][$_GET['plugin'] . '_oauth_token_url']['value'], $post_data, 'token');
+ parse_str($response);
+ echo (!empty($access_token)) ? $access_token : 'failed';
+}
diff --git a/server/php/R/shell/cron.php b/server/php/shell/cron.php
similarity index 100%
rename from server/php/R/shell/cron.php
rename to server/php/shell/cron.php
diff --git a/server/php/R/shell/cron.sh b/server/php/shell/cron.sh
similarity index 100%
rename from server/php/R/shell/cron.sh
rename to server/php/shell/cron.sh
diff --git a/server/php/shell/imap.php b/server/php/shell/imap.php
new file mode 100644
index 000000000..6a441d313
--- /dev/null
+++ b/server/php/shell/imap.php
@@ -0,0 +1,198 @@
+
+ * @copyright 2014 Restya
+ * @license http://restya.com/ Restya Licence
+ * @link http://restya.com/
+ */
+$app_path = dirname(dirname(__FILE__));
+require_once $app_path . '/config.inc.php';
+// Check is imap extension loaded
+if (!extension_loaded('imap')) {
+ echo 'IMAP PHP extension not available on this server. Bounced email functions will not work.';
+ exit;
+}
+// Connect imap server
+$connection = imap_open('{' . IMAP_HOST . ':' . IMAP_PORT . '/imap/ssl/novalidate-cert/notls}INBOX', IMAP_EMAIL, IMAP_EMAIL_PASSWORD);
+if (!$connection) {
+ return;
+}
+$message_count = imap_num_msg($connection);
+for ($counter = 1; $counter <= $message_count; $counter++) {
+ // Fetch email header
+ $header = imap_header($connection, $counter);
+ // Fetch email body
+ $body = imap_fetchbody($connection, $counter, 1.1);
+ $mail = explode('+', $header->to[0]->mailbox);
+ // Email format for board - board+##board_id##+hash@restya.com
+ // Email format for card - board+##board_id##+##card_id##+hash@restya.com
+ // Check to email address contains atleast one "+" symbol
+ if (count($mail) > 1) {
+ $board_id = $mail[1];
+ $card_id = '';
+ $hash = $mail[2];
+ if (count($mail) > 3) {
+ $card_id = $mail[2];
+ $hash = $mail[3];
+ }
+ // Check email hash with generated hash
+ if ($hash == md5(SECURITYSALT . $board_id . $card_id . SITE_NAME)) {
+ $condition = array(
+ $board_id
+ );
+ // Check from email is a member/owner in board
+ $board_query = pg_query_params($db_lnk, 'SELECT default_email_list_id, is_default_email_position_as_bottom, user_id FROM boards_users_listing WHERE board_id = $1', $condition);
+ $board = pg_fetch_assoc($board_query);
+ if (!empty($board)) {
+ // To email address is for board then insert the email as new card
+ if (empty($card_id)) {
+ $str = 'coalesce(MAX(position), 0)';
+ if (empty($board['is_default_email_position_as_bottom'])) {
+ $str = 'coalesce(MIN(position), 0)';
+ }
+ $list_id = $board['default_email_list_id'];
+ $val_arr = array(
+ $board_id,
+ $list_id
+ );
+ // Select minimum/maximum card position based on email to board settings
+ $card_query = pg_query_params('SELECT ' . $str . ' as position FROM cards WHERE board_id = $1 AND list_id = $2', $val_arr);
+ $card = pg_fetch_assoc($card_query);
+ $position = empty($card['position']) ? 1 : (!empty($board['is_default_email_position_as_bottom'])) ? $card['position'] + 1 : $card['position'];
+ $val_arr = array(
+ $board_id,
+ $list_id,
+ $header->subject,
+ $body,
+ $position,
+ $board['user_id']
+ );
+ // Insert card in default list id and position as selected in email to board settings
+ $card_query = pg_query_params($db_lnk, 'INSERT INTO cards (created, modified, board_id, list_id, name, description, position, user_id) VALUES (now(), now(), $1, $2, $3, $4, $5, $6) RETURNING id', $val_arr);
+ $card = pg_fetch_assoc($card_query);
+ $card_id = $card['id'];
+ } else {
+ // To email address is for specific card then insert the email as card comment
+ $val_arr = array(
+ $card_id
+ );
+ // Fetching list_id to update in card comment
+ $card_query = pg_query_params('SELECT list_id FROM cards WHERE id = $1', $val_arr);
+ $card = pg_fetch_assoc($card_query);
+ $list_id = $card['list_id'];
+ $val_arr = array(
+ $card_id,
+ $board['user_id'],
+ $list_id,
+ $board_id,
+ 'add_comment',
+ $body
+ );
+ // Insert email content as comment in respective card
+ pg_query_params($db_lnk, 'INSERT INTO activities (created, modified, card_id, user_id, list_id, board_id, type, comment) VALUES (now(), now(), $1, $2, $3, $4, $5, $6)', $val_arr);
+ }
+ // Fetching email structure to get the attachments
+ $structure = imap_fetchstructure($connection, $header->Msgno);
+ $attachments = array();
+ if (isset($structure->parts) && count($structure->parts)) {
+ $i = 0;
+ $file_attachments = false;
+ foreach ($structure->parts as $partno0 => $p) {
+ $attachments[$i] = array(
+ 'is_attachment' => false,
+ 'filename' => '',
+ 'name' => '',
+ 'attachment' => '',
+ );
+ if (isset($structure->parts[$i]->bytes)) {
+ $attachments[$i]['filesize'] = $structure->parts[$i]->bytes;
+ }
+ //### Tmobile & metropcs
+ if (preg_match('/parts[$i]->id) && preg_match('/>/i', $structure->parts[$i]->id)) {
+ foreach ($structure->parts[$i]->parameters as $param) {
+ if (strtolower($param->attribute) == 'name') {
+ $attachments[$i]['is_attachment'] = true;
+ $attachments[$i]['name'] = $param->value;
+ $attachments[$i]['filename'] = $param->value;
+ }
+ }
+ }
+ // Setting attachment filename
+ if ($structure->parts[$i]->ifdparameters) {
+ foreach ($structure->parts[$i]->dparameters as $object) {
+ if (strtolower($object->attribute) == 'filename') {
+ if (!preg_match('/tmobile/i', strtolower($object->value)) && !preg_match('/dottedline/i', strtolower($object->value))) {
+ $attachments[$i]['is_attachment'] = true;
+ $attachments[$i]['filename'] = $object->value;
+ }
+ }
+ }
+ }
+ // Setting attachment name
+ if ($structure->parts[$i]->ifparameters) {
+ foreach ($structure->parts[$i]->parameters as $object) {
+ if (strtolower($object->attribute) == 'name') {
+ $attachments[$i]['is_attachment'] = true;
+ $attachments[$i]['name'] = $object->value;
+ }
+ }
+ }
+ // Decoding the attachment content based on encoding format
+ if ($attachments[$i]['is_attachment']) {
+ $attachments[$i]['attachment'] = imap_fetchbody($connection, $header->Msgno, $i + 1);
+ if ($structure->parts[$i]->encoding == 3) { // 3 = BASE64
+ $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
+ } elseif ($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
+ $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
+ }
+ }
+ if ($attachments[$i]['is_attachment'] === true) {
+ // Generating filename with time to avoid duplicate filename for same card
+ $file_attachments = true;
+ $filename = date('Y_m_d', time()) . '_at_' . date('H_i_s', time()) . '_' . $attachments[$i]['filename'];
+ $save_path = 'media' . DIRECTORY_SEPARATOR . 'Card' . DIRECTORY_SEPARATOR . $card_id;
+ $mediadir = APP_PATH . DIRECTORY_SEPARATOR . $save_path;
+ if (!file_exists($mediadir)) {
+ mkdir($mediadir, 0777, true);
+ }
+ // Saving attachment content in file
+ $fh = fopen($mediadir . DIRECTORY_SEPARATOR . $filename, 'x+');
+ fputs($fh, $attachments[$i]['attachment']);
+ fclose($fh);
+ $val_arr = array(
+ $card_id,
+ $filename,
+ $save_path . '/' . $filename,
+ $list_id,
+ $board_id,
+ strtolower('image/' . $structure->parts[1]->subtype)
+ );
+ // Inserting attachments for the card
+ pg_query_params($db_lnk, 'INSERT INTO card_attachments (created, modified, card_id, name, path, list_id , board_id, mimetype) VALUES (now(), now(), $1, $2, $3, $4, $5, $6)', $val_arr);
+ }
+ $i++;
+ }
+ if (empty($file_attachments)) {
+ $body = imap_fetchbody($connection, $counter, 1);
+ $val_arr = array(
+ $body,
+ $card_id
+ );
+ $card_query = pg_query_params('UPDATE cards SET description = $1 WHERE id = $2', $val_arr);
+ }
+ }
+ }
+ }
+ }
+ // Deleting the email
+ imap_delete($connection, trim($header->Msgno));
+}
+// Closing the imap connection
+imap_expunge($connection);
diff --git a/server/php/shell/imap.sh b/server/php/shell/imap.sh
new file mode 100644
index 000000000..fafb17da2
--- /dev/null
+++ b/server/php/shell/imap.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# lock logic for semaphore - http://mywiki.wooledge.org/BashFAQ/045
+path=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P )
+lockdir="${path}/imap_sh.lock"
+echo >&2 "$(date '+%Y-%m-%d %H:%M:%S') #################################################"
+if mkdir "$lockdir"
+ then # directory did not exist, but was created successfully
+ echo >&2 "successfully acquired lock: $lockdir"
+
+##########################################################################################################
+
+# -----------------------------------------------------------------
+# RESTYABOARD --->
+# ==========
+php ${path}/imap.php
+
+##########################################################################################################
+ rmdir "$lockdir"
+ else
+ echo >&2 "cannot acquire lock, giving up on $lockdir"
+ exit 0
+ fi
\ No newline at end of file
diff --git a/server/php/shell/instant_email_notification.php b/server/php/shell/instant_email_notification.php
new file mode 100644
index 000000000..145e1d1e5
--- /dev/null
+++ b/server/php/shell/instant_email_notification.php
@@ -0,0 +1,334 @@
+
+ * @copyright 2014 Restya
+ * @license http://restya.com/ Restya Licence
+ * @link http://restya.com/
+ */
+$app_path = dirname(dirname(__FILE__));
+require_once $app_path . '/config.inc.php';
+require_once $app_path . '/libs/vendors/finediff.php';
+require_once $app_path . '/libs/core.php';
+global $_server_domain_url;
+if (file_exists(APP_PATH . '/tmp/cache/site_url_for_shell.php')) {
+ include_once APP_PATH . '/tmp/cache/site_url_for_shell.php';
+}
+if ($db_lnk) {
+ $qry_val_arr = array(
+ 2
+ );
+ $users_result = pg_query_params($db_lnk, 'SELECT users.id, users.email, users.full_name, users.last_email_notified_activity_id, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT bs.board_id FROM board_subscribers bs WHERE bs.user_id = users.id) d) AS board_ids, (SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT ls.list_id, l.board_id FROM list_subscribers ls, lists l WHERE ls.user_id = users.id AND l.id = ls.list_id) d) AS list_ids,(SELECT array_to_json(array_agg(row_to_json(d))) FROM (SELECT cs.card_id, c.list_id, c.board_id FROM card_subscribers cs, cards c WHERE cs.user_id = users.id AND c.id = cs.card_id) d) AS card_ids FROM users WHERE is_send_newsletter = $1', $qry_val_arr);
+ while ($user = pg_fetch_assoc($users_result)) {
+ $board_ids = $list_ids = $card_ids = array();
+ $board_arr = (!empty($user['board_ids'])) ? array_filter(json_decode($user['board_ids'], true)) : '';
+ $list_arr = (!empty($user['list_ids'])) ? array_filter(json_decode($user['list_ids'], true)) : '';
+ $card_arr = (!empty($user['card_ids'])) ? array_filter(json_decode($user['card_ids'], true)) : '';
+ if (!empty($board_arr)) {
+ foreach ($board_arr as $boards) {
+ $board_ids[] = $boards['board_id'];
+ }
+ }
+ if (!empty($list_arr)) {
+ foreach ($list_arr as $lists) {
+ if (!in_array($lists['board_id'], $board_ids)) {
+ $list_ids[] = $lists['list_id'];
+ }
+ }
+ }
+ if (!empty($card_arr)) {
+ foreach ($card_arr as $cards) {
+ if (!in_array($cards['board_id'], $board_ids) && !in_array($cards['list_id'], $list_ids)) {
+ $card_ids[] = $cards['card_id'];
+ }
+ }
+ }
+ $mail_content = '';
+ $activities_result = '';
+ $notification_count = 0;
+ $reply_to_mail = '';
+ if (!empty($board_ids)) {
+ $qry_arr = array(
+ $user['last_email_notified_activity_id'],
+ $user['id'],
+ '{' . implode(',', $board_ids) . '}'
+ );
+ $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id != $2 AND board_id = ANY ($3) ORDER BY id DESC', $qry_arr);
+ $i = 0;
+ $tmp_card_id = '';
+ while ($activity = pg_fetch_assoc($activities_result)) {
+ if (!empty($activity['profile_picture_path'])) {
+ $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
+ $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
+ $user_avatar = '
' . "\n";
+ } else if (!empty($activity['initials'])) {
+ $user_avatar = '
' . $activity['initials'] . ' ' . "\n";
+ }
+ if (empty($i)) {
+ $activity_id[] = $activity['id'];
+ $i++;
+ }
+ if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
+ $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
' . $activity['comment'] . '
';
+ $br = '
';
+ } else {
+ $activity['comment'].= ' on ##BOARD_NAME##';
+ $br = '
';
+ }
+ if (!empty($activity['card_id'])) {
+ $imap_email = split("@", IMAP_EMAIL);
+ $board_email = $imap_email[0] . '+' . $activity['board_id'] . '+' . $activity['card_id'] . '+' . md5(SECURITYSALT . $activity['board_id'] . $activity['card_id'] . SITE_NAME) . '@' . $imap_email[1];
+ $qry_arr = array(
+ $activity['card_id']
+ );
+ $card = pg_query_params($db_lnk, 'SELECT * FROM cards WHERE id = $1', $qry_arr);
+ $card = pg_fetch_assoc($card);
+ $mail_to = 'mailto:' . $board_email . '?subject=RE:' . $card['name'];
+ if (empty($tmp_card_id) || $tmp_card_id == $activity['card_id']) {
+ $reply_to_mail = $board_email;
+ } else {
+ $reply_to_mail = '';
+ }
+ $tmp_card_id = $activity['card_id'];
+ $reply_to = '
' . "\n";
+ }
+ if (!empty($activity['revisions']) && trim($activity['revisions']) !== '') {
+ $revisions = unserialize($activity['revisions']);
+ $activity['revisions'] = $revisions;
+ unset($dif);
+ if (!empty($revisions['new_value'])) {
+ foreach ($revisions['new_value'] as $key => $value) {
+ if ($key != 'is_archived' && $key != 'is_deleted' && $key != 'created' && $key != 'modified' && $key != 'is_offline' && $key != 'uuid' && $key != 'to_date' && $key != 'temp_id' && $activity['type'] != 'moved_card_checklist_item' && $activity['type'] != 'add_card_desc' && $activity['type'] != 'add_card_duedate' && $activity['type'] != 'delete_card_duedate' && $activity['type'] != 'add_background' && $activity['type'] != 'change_background' && $activity['type'] != 'change_visibility' && $activity['type'] != 'change_card_position') {
+ $old_val = (isset($revisions['old_value'][$key]) && $revisions['old_value'][$key] != null && $revisions['old_value'][$key] != 'null') ? $revisions['old_value'][$key] : '';
+ $new_val = (isset($revisions['new_value'][$key]) && $revisions['new_value'][$key] != null && $revisions['new_value'][$key] != 'null') ? $revisions['new_value'][$key] : '';
+ $dif[] = nl2br(getRevisiondifference($old_val, $new_val));
+ }
+ if ($activity['type'] == 'add_card_desc' || $activity['type'] == 'add_card_desc' || $activity['type'] == ' edit_card_duedate' || $activity['type'] == 'add_background' || $activity['type'] == 'change_background' || $activity['type'] == 'change_visibility') {
+ $dif[] = $revisions['new_value'][$key];
+ }
+ }
+ } else if (!empty($revisions['old_value']) && isset($activity['type']) && $activity['type'] == 'delete_card_comment') {
+ $dif[] = nl2br(getRevisiondifference($revisions['old_value'], ''));
+ }
+ if (isset($dif)) {
+ $activity['difference'] = $dif;
+ }
+ if (!empty($activity['difference'][0])) {
+ $search = array(
+ '
';
+ }
+ }
+ $comment = findAndReplaceVariables($activity);
+ $mail_content.= '
' . "\n";
+ $mail_content.= $br . "\n";
+ $notification_count++;
+ }
+ }
+ if (!empty($list_ids)) {
+ $qry_arr = array(
+ $user['last_email_notified_activity_id'],
+ $user['id'],
+ '{' . implode(',', $list_ids) . '}'
+ );
+ $activities_result = pg_query_params($db_lnk, 'SELECT * FROM activities_listing WHERE id > $1 AND user_id != $2 AND list_id = ANY ($3) ORDER BY id DESC', $qry_arr);
+ $i = 0;
+ $tmp_card_id = '';
+ while ($activity = pg_fetch_assoc($activities_result)) {
+ if (!empty($activity['profile_picture_path'])) {
+ $hash = md5(SECURITYSALT . 'User' . $activity['user_id'] . 'png' . 'small_thumb' . SITE_NAME);
+ $profile_picture_path = $_server_domain_url . '/img/small_thumb/User/' . $activity['user_id'] . '.' . $hash . '.png';
+ $user_avatar = '
' . "\n";
+ } else if (!empty($activity['initials'])) {
+ $user_avatar = '
' . "\n";
+ }
+ if (empty($i)) {
+ $activity_id[] = $activity['id'];
+ $i++;
+ }
+ if ($activity['type'] == 'add_comment' || $activity['type'] == 'edit_comment') {
+ $activity['comment'] = '##USER_NAME## commented to the card ##CARD_NAME## on ##BOARD_NAME##
';
+ } else {
+ $activity['comment'].= ' on ##BOARD_NAME##';
+ $br = '
';
+ }
+ if (!empty($activity['card_id'])) {
+ $imap_email = split("@", IMAP_EMAIL);
+ $board_email = $imap_email[0] . '+' . $activity['board_id'] . '+' . $activity['card_id'] . '+' . md5(SECURITYSALT . $activity['board_id'] . $activity['card_id'] . SITE_NAME) . '@' . $imap_email[1];
+ $qry_arr = array(
+ $activity['card_id']
+ );
+ $card = pg_query_params($db_lnk, 'SELECT * FROM cards WHERE id = $1', $qry_arr);
+ $card = pg_fetch_assoc($card);
+ $mail_to = 'mailto:' . $board_email . '?subject=RE:' . $card['name'];
+ if (empty($tmp_card_id) || $tmp_card_id == $activity['card_id']) {
+ $reply_to_mail = $board_email;
+ } else {
+ $reply_to_mail = '';
+ }
+ $tmp_card_id = $activity['card_id'];
+ $reply_to = '
' . "\n";
+ }
+ if (!empty($activity['revisions']) && trim($activity['revisions']) !== '') {
+ $revisions = unserialize($activity['revisions']);
+ $activity['revisions'] = $revisions;
+ unset($dif);
+ if (!empty($revisions['new_value'])) {
+ foreach ($revisions['new_value'] as $key => $value) {
+ if ($key != 'is_archived' && $key != 'is_deleted' && $key != 'created' && $key != 'modified' && $key != 'is_offline' && $key != 'uuid' && $key != 'to_date' && $key != 'temp_id' && $activity['type'] != 'moved_card_checklist_item' && $activity['type'] != 'add_card_desc' && $activity['type'] != 'add_card_duedate' && $activity['type'] != 'delete_card_duedate' && $activity['type'] != 'add_background' && $activity['type'] != 'change_background' && $activity['type'] != 'change_visibility') {
+ $old_val = (isset($revisions['old_value'][$key]) && $revisions['old_value'][$key] != null && $revisions['old_value'][$key] != 'null') ? $revisions['old_value'][$key] : '';
+ $new_val = (isset($revisions['new_value'][$key]) && $revisions['new_value'][$key] != null && $revisions['new_value'][$key] != 'null') ? $revisions['new_value'][$key] : '';
+ $dif[] = nl2br(getRevisiondifference($old_val, $new_val));
+ }
+ if ($activity['type'] == 'add_card_desc' || $activity['type'] == 'add_card_desc' || $activity['type'] == ' edit_card_duedate' || $activity['type'] == 'add_background' || $activity['type'] == 'change_background' || $activity['type'] == 'change_visibility') {
+ $dif[] = $revisions['new_value'][$key];
+ }
+ }
+ } else if (!empty($revisions['old_value']) && isset($activity['type']) && $activity['type'] == 'delete_card_comment') {
+ $dif[] = nl2br(getRevisiondifference($revisions['old_value'], ''));
+ }
+ if (isset($dif)) {
+ $activity['difference'] = $dif;
+ }
+ if (!empty($activity['difference'][0])) {
+ $search = array(
+ '