MOODLE. Problem with definition user role for course - mysql

I'm trying make solution by Using MOODLE create users and enroll them in courses via SQL
Add user - done
Add user to course - done
But user without role into course. No roles in role column.
'googleoauth2' as auth value for login with social network API. It's work.
The problem is remains If I change 'auth' value to 'manual'.
Into database all records as in queries.
Help, please.
UPD: sorry, I need to change enlorID to courseID in instanceid field...
Code:
async function test(){
var query = `INSERT INTO mdl_user (auth, confirmed, username, password, firstname, lastname, email, mnethostid)
VALUES ('googleoauth2', 1, '${pseudo}', 'not cached', '${name}',
'${secondname}', '${email}', 1);`;
var insertOutput = await getMysqlQuery(query);
var userId = insertOutput.results.insertId;
var courseRecords = await getMysqlQuery("SELECT id FROM mdl_course WHERE idnumber=\"" + shortname + "\"");
if(courseRecords.length < 1)
throw 'Course not found';
var courseId = courseRecords.results[0].id;
var enrolRecords = await getMysqlQuery(`SELECT id FROM mdl_enrol WHERE courseid=${courseId} AND enrol='manual';`);
if(enrolRecords.length < 1)
throw 'Enrol not found';
var enrolId = enrolRecords.results[0].id;
var contextRecords = await getMysqlQuery(`SELECT id FROM mdl_context WHERE contextlevel=50 AND instanceid=${courseId};`);
if(contextRecords.length < 1)
throw 'Context not found';
var now = (new Date()).getTime() / 1000 ;
var contextId = contextRecords.results[0].id;
await getMysqlQuery(`INSERT INTO mdl_user_enrolments (status, enrolid, userid,
timestart, timeend, timecreated, timemodified) VALUES
(0, ${enrolId}, ${userId}, '${now}', '${now + 60*60*24*2}', '${now}', '${now}')`);
await getMysqlQuery(`INSERT INTO mdl_role_assignments
(roleid, contextid, userid, timemodified)
VALUES (5, ${contextId}, '${userId}', '${now}');`);
}

It looks like you are using JavaScript. I have a solution to enroll the student in course with a role in PHP programming language as below.
$plugin = enrol_get_plugin('manual');
$course = $DB->get_record('course', array('id' => $courseid)); // Get course object by courseid
$instance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
if (empty($instance)) {
// Only add an enrol instance to the course if non-existent.
$enrolid = $plugin->add_instance($course);
$instance = $DB->get_record('enrol', array('id' => $enrolid));
}
// Take care of timestart/timeend in course settings.
$timestart = time();
// Remove time part from the timestamp and keep only the date part.
$timestart = make_timestamp(date('Y', $timestart), date('m', $timestart), date('d', $timestart), 0, 0, 0);
if ($instance->enrolperiod) {
$timeend = $timestart + $instance->enrolperiod;
} else {
$timeend = 0;
}
// Enrol the user with this plugin instance.
$plugin->enrol_user($instance, $user->id, $roleid); // This will enroll user in course with roleid you provided.

Related

Nodejs Mysql Select Count nested loop insert query

I am new in nodejs and mysql.
I am have an array of objects that i get from post and want to insert it to mysql database.
If the data already exist then run the update query to database.
The problem is Insert query not loop the entire array. it just insert the last entry of Array. Here my code:
Array Data:
bukukasData
[{transactionid: '562018965521',
tanggal: '2018-06-05',
kodeakun: 0, item: 'Saldo',
debit: 100000, credit: 0,
saldo: 100000},
{transactionid:'562018595664',
tanggal:'2018-06-05',
kodeakun: 0,
item: 'Test Data',
debit: 0,
credit: 5000,
saldo:95000}]
NodeJS Query
app.post('/api/addbukukas', function(req, res) {
let bukukasData = req.body.bukukasData;
var status = '';
for (var i = 0; i < bukukasData.length; i++) {
var transactionid = req.body.bukukasData[i].transactionid;
var kodeakun = req.body.bukukasData[i].kodeakun;
var item = req.body.bukukasData[i].item;
var debit = req.body.bukukasData[i].debit;
var credit = req.body.bukukasData[i].credit;
var saldo = req.body.bukukasData[i].saldo;
var tanggal = req.body.bukukasData[i].tanggal;
db.query('SELECT COUNT (*) AS rowCount FROM bukukas WHERE transactionid = ?', [req.body.bukukasData[i].transactionid], function(error, result) {
var rows = result[0].rowCount;
if (rows > 0) {
db.query('UPDATE bukukas SET transactionid=?, kodeakun=?, tanggal=?, item=?, debit=?, credit=?, saldo=? WHERE transactionid = ?', [transactionid, kodeakun, tanggal, item, debit, credit, saldo, transactionid],
function(err, result) {
if (err) {
status = 'Update Gagal';
} else {
status = 'Update Success';
}
})
} else {
db.query('INSERT INTO bukukas (transactionid, kodeakun, tanggal, item, debit, credit, saldo) VALUES (?,?,?,?,?,?,?)', [transactionid, kodeakun, tanggal, item, debit, credit, saldo], function(err, insertresult) {
if (err) {
status = 'Insert Gagal';
} else {
status = "insertresult";
}
})
}
})
}
console.log(status);
return res.json({ status: status });
});
With this code the only data that getting inserted to database just the last data in array. How can i insert all the data in Array to database?
Thanks
Use let instead of var. That will avoid this problem.
The source of this problem is, that in JavaScript the for-loop loops through the variable i and starts bukukasData.length times the db query. The parameter is given as reference. Since the loop iterates very fast, the first sql statement ist started with i set to the last value and all db-statements are executed with i set to bukukasData.length. let was introduced to JavaScript to fix problems like this. With let it will create a copy of the variable in the background.

Node JS Parse Error in MySQL Syntax

In the following code, I am trying to query the database based on three parameters (search type, search term, operator that connects different search types in one query). As you can see, I gave it two search types along with their terms so that the query will be like search where the author is WayneRooney AND the tag is UCL. Later, it might have more than two search types such as search based on author x, author y, mention z, and tag a.
var search = ['Author','Tag'];
var term = ['WayneRooney','UCL'];
var operator = 'AND';
var queryString = "select Tweet.ID, Tweet.Label, Tweet.TDate, Tweet.RetweetID, User.Name, User.ScreenName from Tweet, User where";
for(var i in search){
if(search.indexOf(search[i]) != 0){
queryString += operator;
}
if(search[i] == 'Author')
{
queryString += "Tweet.UserID IN (select ID from User where ScreenName = '"+ term[i] +"') AND User.ID IN (select ID from User where ScreenName = '"+ term[i] +"')";
}
else if(search[i] == 'Mention')
{
queryString += "select Tweet.ID, Tweet.Label, Tweet.TDate, User.ScreenName, User.Name, Tweet.RetweetID from Tweet, User where Tweet.ID IN (select TweetID from TweetMention where UserID IN (select ID from User where ScreenName = '"+ term[i] +"')) AND User.ID = Tweet.UserID";
}
else if(search[i] == 'Tag')
{
queryString += "select Tweet.ID, Tweet.Label, Tweet.TDate, User.Name, User.ScreenName, Tweet.RetweetID from Tweet, User where Tweet.ID IN (select TweetID from TweetHashs where HashID IN (select ID from Hashtag where Label = '"+ term[i] +"')) AND User.ID = Tweet.UserID";
}
};
var query = connection.query(queryString, function(err, rows) {
if (err) {
throw (err);
}
console.log(rows);
//res.write(JSON.stringify(rows));
var tweet = JSON.parse(JSON.stringify(rows));
var queries_made = 0;
var queries_success = 0;
The error that I got is:
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.UserID IN (select ID from User where ScreenName = 'WayneRooney') AND User.ID IN'at line 1
I tried to figure out what the problem is but I couldn't.
You're missing prepended spaces when appending to your queryString, otherwise you get run-on keywords like: whereTweet.UserID IN ... or ANDTweet.UserID IN ....

Join and Union with Entity Framework

I have two tables (clients and emails), one with customer's data, including a main email address, and another one with additional email addresses.
I need to validate the user from one of their many email addresses, no matter if it is on clients or emails table. I've come up with this SQL sentence which works fine:
set #email = 'client#domain.com';
select c1.credits > 0 as Allowed, c1.Email as MainEmail from
customers c1 inner join (select ClientId, Email FROM customers WHERE
Email=#email union all select ClientId, Email FROM emails WHERE Email=#email) e1
on c1.ClientId = e1.ClientId;
How to write this query in LINQ to Entities with method-based syntax?
If i understand correctly,
Customer may or may not have the email (Additional) in emails table.
Also, Customer have more than one additional emails entry in emails table. Like below
List<Customer> customers = new List<Customer>
{
new Customer { ClientId = 1, Email = "client1#domain.com", Credits = 2 },
new Customer { ClientId = 2, Email = "client2#domain.com", Credits = 1 },
new Customer { ClientId = 3, Email = "client3#domain.com", Credits = 1 },
};
List<Emails> emails = new List<Emails>
{
new Emails { ClientId = 1, Email = "client1-2#domain.com" },
new Emails { ClientId = 1, Email = "client1-3#domain.com" },
new Emails { ClientId = 2, Email = "client2-1#domain.com" },
};
In that case, Use the below query to get it done,
var result = from c in customers
let _emails = emails.Where(e => c.ClientId == e.ClientId).Select(t => t.Email)
where c.Email == "client3#domain.com" || _emails.Contains("client3#domain.com")
select new
{
Allowed = c.Credits > 0,
MainEmail = c.Email
};
I hope it helps you.

How to write Linq-To-SQL statment which is equal to my following TSQL?

TSQL:-
Update table1
Set Name = 'John',
Address = null
where
ID = 1
LINQ-TO-SQL
var tab = db.Table1.Single(s => s.ID == 3);
tab.Name = DateTime.Now;
tab.Address = null;
db.SubmitChanges();
There isn't a single LINQ to SQL statement for updates. You have to retrieve the object, modify it, then save the changes (code assumes a single row since you have a specific Id):
var entity = context.Table1.Single(t => t.Id == 1);
entity.Name = "John";
entity.Address = "Toronto";
context.SubmitChanges();
using (var dataContext = new MyEntities())
{
var contact = Contacts.Single (c => c.ContactID == 1);
contact.FirstName = 'John';
contact.Address= 'Toronto';
dataContext.SaveChanges();
}

LINQ join and group

How to expand this query:
public Dictionary<int, List<TasksInDeal>> FindAllCreatedTasks()
{
return (from taskInDeal in db.TasksInDeals
where taskInDeal.Date > DateTime.Now && taskInDeal.Date < DateTime.Now.AddDays(7)
group taskInDeal by taskInDeal.CreatedByUserID
into groupedDemoClasses
select groupedDemoClasses).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
}
into something like this:
public Dictionary<int, List<TaskForNotification>> FindAllCreatedTasks()
{
return (from taskInDeal in db.TasksInDeals
join user in db.Users on taskInDeal.CreatedByUserID equals user.UserID
where taskInDeal.Date > DateTime.Now && taskInDeal.Date < DateTime.Now.AddDays(7)
group taskInDeal by taskInDeal.CreatedByUserID
into groupedDemoClasses
select new TaskForNotification
{
Email = user.Email,
TaskInDealField1 = taskInDeal.TaskInDealField1,
TaskInDealField2 = taskInDeal.TaskInDealField2,
TaskInDealField3 = taskInDeal.TaskInDealField3,
...
}
).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
}
So, to first query I need to join email from other table.
// do the date logic up front, not in the database.
DateTime now = DateTime.Now
DateTime weekFromNow = now.AddDays(7);
// pull the joined rows out of the database.
var rows =
(
from taskInDeal in db.TasksInDeals
where taskInDeal.Date > now && taskInDeal.Date < weekFromNow
join user in db.Users
on taskInDeal.CreatedByUserID equals user.UserID
select new {TaskInDeal = taskInDeal, UserEmail = user.Email}
).ToList();
// shape the rows in memory
Dictionary<int, List<TaskForNotification>> result =
(
from row in rows
let taskForNotification = new TaskForNotification
{
Email = row.UserEmail,
TaskInDealField1 = row.TaskInDeal.TaskInDealField1,
TaskInDealField2 = row.TaskInDeal.TaskInDealField2,
TaskInDealField3 = row.TaskInDeal.TaskInDealField3,
...
}
group taskForNotification by row.TaskInDeal.CreatedByUserID
// without an "into", group by ends the query.
).ToDictionary(g => g.Key, g => g.ToList());
When you group, bear this in mind. Groups in SQL have only keys and aggregates. Groups in LINQ have keys, aggregates and elements! If you ask the database for groups, and then ask for the elements - SQL couldn't provide you with those elements in a single query. You'll wind up automatically repeatedly re-querying using the group's key as a filter.