How can I connect users and courses using Moodle database? - moodle

I was doing a small project with Moodle, and I have a little query a more advanced.
I would like to be able to create a course by means of a SQL query in the Moodle DB and to be able to link it to an existing user in Moodle.
Has anyone ever done something like this and can you give me your opinion suggestion?
I am using Moodle version 3.10 dev
Thanks a lot.

What don’t you want to use the moodle api will be easy and best way to get what you need done.
You just need to make 2 api calls create course and enroll user .

You need to use moodle APIs or native functions in order to create courses or users. In this case SQL is not a common practice and need to be avoided.
Instead, you may need to use core functions, API etc. In example:
#create a course
$course = create_course($data, $editoroptions = NULL);
#or get course if it already exists
$course = get_course($courseid);
#enrol student
$enrol_manual = enrol_get_plugin('manual');
$enrolinstances = enrol_get_instances($course->id, true);
foreach($enrolinstances as $instance) {
#enrol user
$enrol_manual->enrol_user($instance, $studentid);
break;
}
Check these guides as well:
https://docs.moodle.org/dev/Enrolment_API
https://docs.moodle.org/dev/Core_APIs
https://docs.moodle.org/dev/Access_API

Related

How to handle creating schema/tables on the fly for a multi-tenant web app

Problem
I'm building a web app, where each user needs to have segregated data (due to confidentiality), but with exactly the same data structures/tables.
Looking around I think this concept is called multi-tenants? And it seems as though a good solution is 1 schema per tenant.
I think sqlalchemy 1.1 implemented some support for this with
session.connection(execution_options={
"schema_translate_map": {"per_user": "account_one"}})
However this seems to assume the schema and tables are already created.
I'm not sure how many tenants I'm going to have, so I need to create the schema, and the tables within them, on the fly, when the user's account is created.
Solution
What I've come up with feels like a bit of a hack, which is why I'm posting here to see if there's a better solution.
To create schemas on the fly I'm using
if not engine.dialect.has_schema(engine, user.name):
engine.execute(sqlalchemy.schema.CreateSchema(user.name))
And then directly afterwards I'm creating the tables using
table = TableModel()
table.__table__.schema = user.name
table.__table__.create(db.session.bind)
With TableModel defined as
class TableModel(Base):
__tablename__ = 'users'
__table_args__ = {'schema': 'public'}
id = db.Column(
db.Integer,
primary_key=True
)
...
I'm not too sure why to inherit from Base vs db.Model - db.Model seems to automatically create the table in public, which I want to avoid.
Bonus question
Once the schema are created, if, down the line, I need to add tables to all the schema - what's the best way to manage that? Does flask-migrations natively handle that?
Thanks!
If anyone sees this in the future, this solution seems to broadly work, however I've recently run into a problem.
This line
table.__table__.schema = user.name
seems to create some odd behaviour where the value of user.name seems to persist in order areas of the app, so if you switch user, the table from the previous user is incorrectly queried.
I'm not totally sure why this happens, and still investigating how to fix it.

Strapi: Initialize / populate database

When I deploy Strapi to a new server, I want to create and populate the database tables (PostgreSQL), particularly categories. How do I access production config, and create tables and category entries?
A hint on how-to approach this, would be much appreciated!
I know this is an old question, but i recently came upon the same issue.
Basically you should create the collections first, which result in the creation of models. Of course you also could create the models manually.
In the recent documentation you find a section about a bootstrap function.
docs bootstrap
The function is called at the start of the server.
The docs list the following use cases:
Here are some use cases:
Create an admin user if there isn't one.
Fill the database with some necessary data.
Load some environment variables.
The bootstrap function can be synchronous or asynchronous.
A great example can be found in the Plugin strapi-plugin-users-permissions
You can implement a new service or overwrite a function of an existing plugin.
the function initialize is implemented here async initialize
and called in the bootstrap function here
await ...initialize()
The initialize function is used to populate the database with the two roles
Authenticated and Public.
Hope that helps whoever stumbles upon this question.

SugarCRM Querying Database

In SugarCRM, using SOAP API, imagining i have lots of accounts populated in the database, and i want to find the account that has 'phone_work' = '00352254856987'. How can i make a query to accomplish that? It would be something like this:?
$query = "phone_work = '${myPhone}'";
For what i have tried, it seems the compiler finds an error in the XML document, which means the query is not well executed. What is the best way to do this kind of queries?
I'm using magento and creating a module to connect to sugar, so it is PHP
It turned out the field 'phone_work' is wrong. You can access at: http://apidocs.sugarcrm.com/schema/6.3.0/pro/tables/accounts.html and get all the fields related to that module. In the module 'Accounts', the field name is called 'office phone', but in the database, the name is 'phone_office'. Because the query is for the database, we need to use database field names.
Could you post the error that you get? Take also a look at the sugarcrm.log and maybe increase the logging level to see if the sql that gets created from your query is wrong.
By the way I switched to REST Json to get rid of soap related problems.

How to inspect every query going to DB from Zend Framework

I have a complex reporting application that allows clients to login and view reports for their client data. There are several sections of the application where there are database calls, using various controllers. I need to make sure that client A doesn't get client B's information via header manipulation.
The system authenticates, and assignes them a clientID and roleID. If your roleID >1, that means you work for the company hosting the data, and you can see all client info. I want to create a catch-all that basically works like this:
if($roleID > 1) {
...send query to database
}else {
if(...does this query select a record with clientID other than my $auth->clientID){
do not execute query
}else {
execute query
}
}
The problem is, I want this to run for every query that goes to the server... how can I place this code as a "roadblock" between the application and the DB? I already use Zend_Profiler to look at queries, so I know it is somehow possible, but cannot discern this from the Profiler code...
I can always write an authentication function and pass selected queries that way, but this catch-all would be easier to implement across all of the calls and would be future proof. Any help is appreciated.
it's application design fault.
you shoud use 'service architecture' - the only one entry point for queries would be a service. and any checks inside it.
If this is something you want run on every query, I'd suggest extending Zend_Db_Select and overwrite either the query() or assemble() functions to add in your logic. You'll also want to add a way for it to be aware of your $auth object.
Another option is to extend your database adapter so you can intercept the queries directly. IMO, you should try and do this at the application level though.
Depending on your database server, you can put a trace on the DB side.
Here's an example for Oracle:
http://orafaq.com/wiki/SQL_Trace

What is the difference between the QueryParser and the API?

On step 3 of this tutorial the author writes:
I personally would use the QueryParser when the search string is supplied by the user, and I’d use directly the API when the query is generated by your code.
Are there any benefits of using one over the other or is it just personal preference?
It's like the link says, if you want to allow users to enter custom searches as text string (i.e Name:matt, Age:[10 TO 80] use the QueryParser.
However if you only need to allow pre-defined queries, you can create them directly in your code.
So it depends what sort of queries you are using and how they are made, by the user, pre-defined etc