
In this video we go through the moodle set up guide to install moodle on a clean ubuntu 18.04. We configure the apache2 'document root' to look at the directory where we have our moodle code. We also install mysql and configure moodle to be able to talk to the database using moodle's config.php file. Similar steps should work on mac.
https://docs.moodle.org/38/en/Step-by-step_Installation_Guide_for_Ubuntu
https://support.rackspace.com/how-to/install-mysql-server-on-the-ubuntu-operating-system/
If you want to use windows, I would recommend you try to follow the windows set up guide:
You can try: https://docs.moodle.org/39/en/Manual_install_on_Windows_7_with_Apache_and_MySQL
There is even some one click installers that might work for you: https://docs.moodle.org/39/en/Complete_install_packages_for_Windows
You can also use Xampp which creates apache, php, mariadb (basically mysql) automatically as well https://www.apachefriends.org/download.html . Then you just need to put moodle into the root folder of the web server.
Message me if you have trouble setting up moodle so we can get coding!
https://moodletips.org
Often we want to just browse through data in the database and in those situations it can be easier to have a program that lets us use the database almost like an excel spreadsheet rather than through just the CLI.
We also can directly update fields and change schema without writing sql, letting the phpmyadmin program write that for us.
https://moodletips.org
Phpstorm has a built in GUI like phpmyadmin so that's what I'll use instead of setting that up.
Here I show you how to use this functionality of phpstorm and connect it to our database.
https://www.jetbrains.com/resources/eap/
https://moodletips.org
In our local dev environment, there is no need to have our admin user/password credentials to be complicated and hard to remember. However, we won't be able to update it using moodle's UI or core functions because moodle will say our simple password is invalid. In this tutorial we hash a simple string 'admin', and directly insert that into the database as the admin password.
https://moodletips.org
We have different programs working together when we're building a moodle server. Here I give a quick overview of what those are and how they work together.
SQL database
server - apache/nginx
config.php file in moodle
PHP running on the server
sitedata folder - writable by the web server user
moodle code - not writable by the web server user (usually).
I just wanted to show a bit of the codebase to start so we get familiar with it. Of course, when you first download moodle it's just this huge pile of php. How can we ever learn it? But I wanted to explain that since it's so modular (after all, that's what the M in moodle stands for) we can mentally compartmentalise huge chunks of the code away. We don't need to care about all of it at once, just like we can use a function but not look into the internals of it.
Here I wanted to get our feet wet by showing you how changing a setting in the front end UI affects our database in the backend. As developers we should be aware of what is happening when we click a check box and how to see that change reflected in the database.
After this video we get a feel for the whole process taking place from end to end.
Here I show how the internal code structure and api's make it easy to do something in the code that is reflected in the real site. What I mean is that we added one line of code and that created a nice looking setting already, it was very easy. I also wanted to explain that we shouldn't be 'hacking' in core moodle code. It's better to extend moodle with plugins. The whole point of moodle is that it's extendible and has thousands of cool plugins to add the functionality you want.
This is an optional quick video showing how moodle has thought of some common use cases, eg. we can customise a language string without having to go in and write any code. It goes to show that there are a few ways to achieve the same thing as we have to decide what's the right way. Changing a lang string might be something we want to do like this in the UI, or we could change it in code, and knowing about all the ways is always going to be helpful.
Here we set up the basic boilerplate code in our new block plugin. This is the code that will allow our plugin to be recognised by moodle and communicate to it.
This video is a bit of a mess since we're copying in code from the core html block and deleting stuff we don't need. It goes to show that there is quite a bit of boilerplate code needed to get started making a plugin. We need the basic file structure there so that the rest of the core moodle codebase will recognise our plugin and they can work together.
If you want you can get this code from here: https://github.com/kristian-94/moodle-block_testblock
We see this line of code everywhere so I just wanted to make a quick video explaining that here. It's also super useful to know how the url is always pointing us to each php file and it can help us to figure out where to start looking in the codebase. Each url points to a php file that is just echoing some html to the page. But for other internal files, we want to prevent any access to them unless we come from moodle internally.
We use the moodle 'create test course' functionality to automatically make a course, with a user, and populate it with a little bit of content.
I also show how to see this in the database as well.
Here we're getting our hands dirty: grabbing data from the DB and displaying and manipulating it is a foundational aspect of moodle programming. I also show how that data is stored and how we can update it directly in the database and see that change reflected in our live site.
We add a setting to our block here and then read that in the code and use it to change the behaviour. We display a list of courses instead of users when it's enabled. We use the core moodle function get_config() to read in the config from our block. We don't want to have to do a direct DB query for something like that.
Here we follow the moodle tutorial found at https://docs.moodle.org/dev/Creating_a_theme_based_on_boost
We create a child theme with the initial boilerplate code that we need, and install it into our local moodle site.
You can find the code here: https://github.com/kristian-94/moodle-theme_kristian
Here we continue with setting up our custom theme https://docs.moodle.org/dev/Creating_a_theme_based_on_boost
We create a settings page and apply custom css to our moodle site.
Here we override a template in our custom theme. We change the output behaviour of the core moodle course overview block. https://docs.moodle.org/dev/Templates#How_to_I_override_a_template_in_my_theme.3F
Templates vs renderers
It's important to remember that this is different to overriding a renderer. For templates, in PHP we write code that calculates, queries the database, and provides data to a template (called template context). A template takes that data and outputs it within normal html. This means it's easy to override and change the display without changing or looking at php code. A renderer does the same job as templates but the PHP code itself outputs the html as a big string. The disadvantage is that to change any part of the render even just a html tag it's usually necessary to override the whole rendering function including the PHP logic.
https://www.patreon.com/moodletips
Here we override a core course renderer function to customise the display of course modules in our custom theme. You can follow along in any theme and override the function in the same way.
Docs used: https://docs.moodle.org/dev/Overriding_a_renderer
Here we take a look at a new series of videos which will all be dedicated to building up a new plugin. This will let us get deeper into moodle than we have before and explore more powerful features and tips for developers.
Here, we create a new plugin, and use the install.xml file to let moodle insert a couple of new database tables that we can use. We then display a hard coded notification, that will be dynamic by the end of the course.
Moodle docs used in this video: https://docs.moodle.org/dev/Notifications
Here we create a new page and use a mustache template to output dynamic content calculated over in PHP. We send those to the template to display nicely in html.
Moodle docs:
https://docs.moodle.org/39/en/Context#Roles_and_contexts
https://docs.moodle.org/dev/Templates
Here we create a new form. This is a class that extends the core moodleform class. We then instantiate it in a new 'edit' page.
Moodle docs: https://docs.moodle.org/dev/Form_API
Here we handle the form submission and store the data in our custom database tables that we created earlier.
Moodle docs: https://docs.moodle.org/dev/Form_API
Here we read in data from our custom tables to display a dynamic notification to the end user. We can create a new message with different type and content by submitting the form again.
Moodle docs: https://docs.moodle.org/dev/Callbacks
Here we build a more complex SQL query. We get messages that are not read by our current user, or not read by any user. We use this query to decide in the before_footer hook whether to display any message to the end user.
In this video we do some quick tidy ups to the code to improve it in terms of style and formatting.
The idea here is that we could continue from the first setup video, the initial install of moodle.
It will be good for us to have unit tests set up so that we can integrate them into our custom plugin. Getting tests going is super useful to the development process as we'll see.
Our SQL doesn't always return the right messages. We haven't tested the code properly, so we missed this issue earlier. In this video I show a quick way that the error can manifest.
It's not a coding error like an exception, but an error in behaviour. We haven't defined exactly what the behaviour and logic should be so this error wasn't caught. We need tests to explicitly set out what the SQL in this case is supposed to do.
In this lecture we get unit tests set up for our plugin and write our first test, to assert that we can create messages properly.
To do this, we've had to abstract away the message management into its own class, so that we can call the database operations individually from the test. This architecture will help our plugin as we continue to make changes.
In this lecture we first write a test to assert the new behaviour that we want, and then fix the code so the test passes.
In this lecture we implement namespaces in our local_message plugin. This allows us to avoid nasty errors with classes not being found, as well as avoid having to provide exact paths to php files and include them directly.
Dev docs used: https://docs.moodle.org/dev/Automatic_class_loading
Get the code at https://github.com/kristian-94/moodle-local_message
In this video we implement the ability to update existing messages. To do this we need to add a hidden element to the form, and pre-fill it with the existing message data.
We also fix up the styling of the message list, showing how we can use bootstrap css in moodle. We use a URL param to know which message we're editing.
https://getbootstrap.com/docs/4.0/components/card/
Get the code at https://github.com/kristian-94/moodle-local_message
Here I demo what we're going to build in this section. It is a simple modal popup + delete message via an external function. There is a few different parts to implementing this though.
Here we create a basic delete button in the manage.php page, where we display the list of messages.
Here we create a basic javascript file, and inject it into the moodle manage.php page.
Before moodle will recognise our javascript, we have to minify it. For this we use a 3rd party tool called grunt. Here we install it and test it out.
Here we create a basic modal that will popup to confirm if we really want to delete a message.
Moodle can be used by external systems via web services. This is also the same way moodle is used internally by Ajax requests, and between plugins.
Think of an external function as a plugin's API. It is a way for other places in moodle, external systems, or javascript, to interface with your plugin.
https://docs.moodle.org/dev/Adding_a_web_service_to_a_plugin#Quick_start
https://docs.moodle.org/dev/Web_service_API_functions
https://docs.moodle.org/dev/AMD_Modal
Here we use the external function that we've created in our modal save action, from the javascript.
Here we implement a basic loading spinner and show some feedback to the user that the message is being deleted, while the request is being processed by moodle.
We need to be able to view the manage messages page from somewhere! Here we use a settings.php file to put a link into the admin settings menu so that admins can access it.
Here we add a settings page to moodle in our plugin. We create a setting that lets us disable the plugin.
We don't want guests to be able to add messages and view the manage.php page. We want to kick them out to the login screen.
https://docs.moodle.org/311/en/Roles_and_permissions
Here we add a capability local/message:managemessages to our plugin and put that into our moodle site. We make it so that we must have this capability to create, edit, delete messages.
In this course, you will learn the basics of moodle. The official documentation is pretty hard to follow and I take us through the most important parts of it.
This course will greatly accelerate your initial learning phase with Moodle, with real tips and tricks I use having worked in the Moodle developer industry for over 3 years.
You will learn how to:
Install Moodle, apache, mysql, PHP
Use the command line to run moodle scripts
Use SQL to alter data directly
Learn the Moodle directory/plugin structure
Create a block plugin, with settings to alter its behaviour
Create a custom theme based off boost, with custom css
Learn about overriding templates and creating our own templates
Learn how to override a renderer
Create a local plugin to display dynamic notifications to the user
Create new moodle pages
Create custom forms that users can submit. Process and store that data in custom database tables.
Create a web service (external function to interface with our plugin) that can delete messages using AJAX requests.
Create a modal popup confirm dialogue window
Create a new capability and add it to a role
I also go into depth about each action taken and include explanations of various parts of the codebase.
If that sounds useful, I look forward to seeing you around in the course!
Feel free to drop comments/questions and I will do my best to help you out.
All the code is available on Github and links will be shown throughout the course.