<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: hribeir0</title>
    <description>The latest articles on Forem by hribeir0 (@hribeir0).</description>
    <link>https://forem.com/hribeir0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F927278%2F553d611d-4102-4a9c-9857-2a0a8d75fc8b.png</url>
      <title>Forem: hribeir0</title>
      <link>https://forem.com/hribeir0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hribeir0"/>
    <language>en</language>
    <item>
      <title>Moodle: from (auto) registration to teacher in no time (no one else involved)</title>
      <dc:creator>hribeir0</dc:creator>
      <pubDate>Fri, 09 Jun 2023 18:12:15 +0000</pubDate>
      <link>https://forem.com/hribeir0/moodle-from-auto-registration-to-teacher-in-no-time-no-one-else-involved-534a</link>
      <guid>https://forem.com/hribeir0/moodle-from-auto-registration-to-teacher-in-no-time-no-one-else-involved-534a</guid>
      <description>&lt;p&gt;For a special Moodle instance, I needed to allow a new user to be an editing teacher in a course, actually, in several courses if needed. At the same time, this should apply to some users only, meaning not everyone would have the same rights.&lt;/p&gt;

&lt;p&gt;Nothing unusual except for the fact that no manager or admin should intervene in the process.&lt;/p&gt;

&lt;p&gt;I immediately thought about the &lt;a href="https://docs.moodle.org/402/en/Adding_a_new_course#Course_requests"&gt;course request feature&lt;/a&gt; which I didn't know very well besides it exists. Luckily there's also a small plugin to allow &lt;a href="https://moodle.org/plugins/tool_courseautoapprove"&gt;course requests to be automatically approved&lt;/a&gt; by &lt;a href="https://github.com/mudrd8mz"&gt;David Mudrák&lt;/a&gt; himself- it's a simple &lt;a href="https://github.com/mudrd8mz/moodle-tool_courseautoapprove/blob/master/classes/task/approve_course_requests_task.php"&gt;Moodle's scheduled task&lt;/a&gt;. Exactly what I needed!&lt;/p&gt;

&lt;p&gt;With the auto-approval requirement taken care of, it was only a matter of thinking about the workflow. So, anyone can register on the site but only some users should be able to request courses. This meant &lt;strong&gt;I had to add a user custom field to differentiate users upfront&lt;/strong&gt; and ask for this information in the registering process. As an example, the field can be named "Position" and the options "Manager", "Officer" and "Assistant". Let's assume only managers should be allowed to request courses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f4bPpnhJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jczxk2sgihnemq6vskl9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f4bPpnhJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jczxk2sgihnemq6vskl9.png" alt="Custom Field example" width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step was to use the &lt;a href="https://moodle.org/plugins/local_cohortauto"&gt;Auto Cohort plugin&lt;/a&gt; to gather all users of a given position on its cohort. It's a great plugin by Catalyst that gives me peace of mind. After that, we need to use another plugin to assign cohort users a specific system role. Once again HQ member maintains an excellent solution: &lt;a href="https://moodle.org/plugins/local_cohortrole"&gt;Cohort role synchronization&lt;/a&gt;. This simply loads cohorts members and assigns them a given system role, in my case the course requester role! Finally, the workflow is complete.&lt;/p&gt;

&lt;p&gt;So when a user autoregister having the position of "Manager" is added to the manager cohort, and then, since is a member of that cohort, is assigned the system context course requester role.&lt;/p&gt;

&lt;p&gt;In my case, there were additional requirements that I won't address here, but lead me to develop an alternative course request system, mostly because I needed to validate the requests against some rules, and because I needed a new request form. Of course, I wouldn't change Moodle core, so I developed a new local plugin, with new tables, tasks, and events (more on that in my next post).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I wanted to share is that by mixing Moodle Core's own functionalities and 2 trustful plugins, one can dismiss managers or admins&lt;/strong&gt; (for the process of registration and enrolment!!)&lt;/p&gt;

</description>
      <category>moodle</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>training</category>
    </item>
    <item>
      <title>Extending Moodle forms</title>
      <dc:creator>hribeir0</dc:creator>
      <pubDate>Thu, 27 Apr 2023 10:51:43 +0000</pubDate>
      <link>https://forem.com/hribeir0/extending-moodle-forms-12i7</link>
      <guid>https://forem.com/hribeir0/extending-moodle-forms-12i7</guid>
      <description>&lt;p&gt;While not possible on every forms, most of the existing moodle forms are extendable whether by extending classes or by using callbacks - which in Wordpress are known by &lt;em&gt;hooks.&lt;/em&gt; Also, Moodle forms are based on &lt;a href="https://pear.php.net/manual/en/package.html.html-quickform.introduction.php"&gt;PEAR's QuickForm API&lt;/a&gt; so that can be useful information. I learned that recently (well all my dev work on Moodle &lt;em&gt;is&lt;/em&gt; recent) when needed to add 2 new form fields on different contexts: in the new user auto-registration form and also when editing or adding an assignment activity.&lt;/p&gt;

&lt;p&gt;I started by checking if any of the &lt;a href="https://docs.moodle.org/dev/Callbacks"&gt;existing callbacks&lt;/a&gt; could help me with this and I was able to find &lt;code&gt;_type_myplugin_extend_signup_form()&lt;/code&gt; and &lt;code&gt;type_myplugin_coursemodule_standard_elements()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending Sign-up form
&lt;/h2&gt;

&lt;p&gt;The first one would allow me to add an extra field in the registration form. Simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;theme_stream_extend_signup_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Inject a static element of the word 'injected'&lt;/span&gt;
    &lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;div class="alert alert-primary" role="alert"&amp;gt;
        This is a primary alert—check it out!
         &amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'static'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'injectedstatic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is great! It works and adds a new static element identified by an id generated based on 'injectedstatic' as a last item on my sign up form. But it makes sense to have the warning before the relevant field, so how can I move my static element before, let's say the email field? JS could be used to move that item, but what horrendous hack would that be... Moodle should have a way right?&lt;/p&gt;

&lt;p&gt;I'll give you &lt;code&gt;insertElementBefore()&lt;/code&gt; Like you can imagine, this adds a form element before an existing one (if you want to move it around you would need to remove it before).&lt;/p&gt;

&lt;p&gt;However, you also need to create it before inserting it so your code should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;theme_stream_extend_signup_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Inject a static element of the word 'injected'&lt;/span&gt;
    &lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;div class="alert alert-primary" role="alert"&amp;gt;
        This is a primary alert—check it out!
         &amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$warning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'static'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'warning'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insertElementBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$warning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, it is important to note that if you want to add a new field to your sign-up form, the best approach would be to create a custom profile field and make it available in the sign-up process/page. No code and 100% functional - custom profiles will be placed last on the form, but using the callback you can &lt;code&gt;removeElement()&lt;/code&gt; and &lt;code&gt;insertElementBefore()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insertElementBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;removeElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'country'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extending Mod Assign form
&lt;/h2&gt;

&lt;p&gt;Imagine that I want to add a warning when people add or edit an assignment. The form fiddling is pretty much done the same way, so the only difference is that we need to check if this form belongs to mod_assign or not because &lt;code&gt;type_myplugin_coursemodule_standard_elements()&lt;/code&gt; is called on every mod.&lt;/p&gt;

&lt;p&gt;For that, we do &lt;code&gt;$cm = $formwrapper-&amp;gt;get_current();&lt;/code&gt; to get current form information and with a simple if we check &lt;code&gt;if ($cm-&amp;gt;modulename == 'assign') {}&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;The final code could be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;type_myplugin_coursemodule_standard_elements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;moodleform_mod&lt;/span&gt; &lt;span class="nv"&gt;$formwrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;MoodleQuickForm&lt;/span&gt; &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$cm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$formwrapper&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_current&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Skip right away.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;$cm&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;modulename&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'assign'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cm&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;modulename&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'assign'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nv"&gt;$html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;p&amp;gt;my extra info&amp;lt;/p&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'static'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'extraelement'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$mform&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insertElementBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'teamsubmission'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>moodle</category>
      <category>php</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
