Creating Moodle plugin - php

I want to control actions, which user doing in test(click on answer, finish test and other)? Is it possible?
I think, that for this task need to create plugin? Am i right?
And dear community, can you help me some material - how develop plugin? Maybe can recomend some sites ot articles? Cause now I don`t understand this process.
For example, I know that plugin need to install in Moodle? But where create plugin before installing? In moodle also? But how export created in Moodle plugin to installing package?
For me very important question - how create installation package with plugin, that other users can install it.
Sorry for a lot question, and thanks for help.

These are the developer docs - https://docs.moodle.org/dev/Main_Page
Depends which plugin you need to develop - https://docs.moodle.org/dev/Plugin_types
If its part of a course then you will need to develop an activity module - https://docs.moodle.org/dev/Activity_modules
Or if not, then you will probably want a local plugin - https://docs.moodle.org/dev/Local_plugins
UPDATE:
Use a local plugin and respond to one of the quiz events.
https://docs.moodle.org/dev/Event_2#Event_observers
This is an overview:
Create a local plugin - https://docs.moodle.org/dev/Local_plugins
Then in local/yourpluginname/db/events/php have something like
defined('MOODLE_INTERNAL') || die();
$observers = array(
array(
'eventname' => '\mod_quiz\event\attempt_submitted',
'includefile' => '/local/yourpluginname/locallib.php',
'callback' => 'local_yourpluginname_attempt_submitted',
'internal' => false
),
);
This will respond to the attempt_submitted event when a user submits a quiz. I'm guessing this is the event that you will need to use. If not, then there are others here /mod/quiz/classes/event/
Then in /local/yourpluginname/locallib.php have something like
/**
* Handle the quiz_attempt_submitted event.
*
* #global moodle_database $DB
* #param mod_quiz\event\attempt_submitted $event
* #return boolean
*/
function local_yourpluginname_attempt_submitted(mod_quiz\event\attempt_submitted $event) {
global $DB;
$course = $DB->get_record('course', array('id' => $event->courseid));
$attempt = $event->get_record_snapshot('quiz_attempts', $event->objectid);
$quiz = $event->get_record_snapshot('quiz', $attempt->quiz);
$cm = get_coursemodule_from_id('quiz', $event->get_context()->instanceid, $event->courseid);
if (!($course && $quiz && $cm && $attempt)) {
// Something has been deleted since the event was raised. Therefore, the
// event is no longer relevant.
return true;
}
// Your code here to send the data to an external server.
return true;
}
That should get you started.

Related

Creating and matching the user created in Laravel in firebase

I have a Laravel 8 project. Users are applying to be a creator from another web project, and we approve these applications from the project I am currently having problems with. In other words, the project we are talking about is an admin panel. Let me tell you what I want to do now. We approve the applications coming here with the create button in the admin panel and create the creator. However, this creator does not currently occur on Firebase. I also want this creator to be rendered in Firebase as well. I did some research and found something like Firebase Admin SDK for PHP. As far as I understand, I can perform this operation with the help of this SDK.
Then I went and wrote my codes to the create function inside the CreatorController, where the content of this Create Button is written. Here is my code that I wrote.
CreatorController.php-create function
public function create(Request $request){
$application = null;
$subscriber = null;
if($request->application_id!=null){
$application = CreatorApplicationForm::findorfail($request->application_id);
$subscriber = User::where([['email','=',$application->email],['role_id','=',4]])->get()->first();
}
return view('admin.creators.create',['application' => $application,'subscriber' => $subscriber]);
if(isset($_POST['create-btn'])){
$displayName = $_POST['name'];
$email = $_POST['email'];
$userProperties = [
'displayName' => $displayName,
'email' => $email,
];
$createdUser = $auth->createUser($userProperties);
}
}
I wrote the last if block in the function, the previous ones were already written.
Later, when I showed this to a friend, he said it wouldn't work for me. He said you wrote it in classical PHP form and told me to adapt it to Laravel. Also, I guess I need to sync the newly created user to the subscribers in the first if block.
Frankly, I'm a little confused. How can I solve this problem?

Updating data after backend action TYPO3 11.5

Working on Typo3 11.5.13
I'm trying to update some data on my pages table after a be_user changed something.
I read something about setting hooks for that purpose but I can't seem to find a good explanation as to how hooks actually function within Typo3 and how to configure one, especially for my purpose.
As far as I can see, this problem I have should be quickly solved but the complexity of the typo3 doc is hindering my progress again. Maybe you can explain how I can accomplish my goal.
Simply put: A backend user is supposed to choose a date in a datepicker and some dateinterval in the settings of a page. After saving(Or even after picking both values) I would like to update the "Next time happening" field the user can see but not change to be updated to the given date plus the dateinterval chosen.
If you have some sort of idea please share it with me.
Generally hooks are not that good documented. Modern Events are easier to find and better commented. However, if I get your use case right, using DataHandler Hooks are they way to go. That mean, every place which are using the DataHandler to save data are then covered. The backend form engine are using DataHandler.
Basic information about hooks in the core documentation:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Events/Hooks/Index.html
How to identify or find hooks, events, signalslots (depending on TYPO3 version):
https://usetypo3.com/signals-and-hooks-in-typo3.html
https://daniel-siepmann.de/posts/migrated/how-to-find-hooks-in-typo3.html
Introduction or "DataHandler" explained:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Typo3CoreEngine/Database/Index.html
Basicly, DataHandler has two main kind of processings:
Data manipulations -> process_datamap()
Actions (move,delete, copy, translate) -> process_cmdmap()
For DataHandler, you register a class only for datamap and/or processmap, not for a concrete hook itself.
// <your-ext>/Classes/Hooks/MyDataHandlerHooks.php
namespace <Vendor>\<YourExt>\Hooks;
class MyDataHandlerHooks {}
// <your-ext>/ext_localconf.php
// -> for cmdmap hooks
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass']['yourextname']
= \Vendor\YourExt\Hooks\MyDataHandlerHooks::class;
// -> for datamap hooks
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['yourextname']
= \Vendor\YourExt\Hooks\MyDataHandlerHooks::class;
You need to register your class only for these kind of hooks you want to consume. And you do not have to implement all hooks.
Hooks can be looked up in \TYPO3\CMS\Core\DataHandling\DataHandler (as hooks are normally searched.
Next step would be to find the proper hook for your use case, and simply add that hook method to your class. Naming the hooks are not chooseable for DataHandler hooks.
TYPO3 Core tests contains a test fixture class for DataHandler hooks - which is not complete, but contains at least the most common ones (along with the needed method signatures) since 8.x:
https://github.com/TYPO3/typo3/blob/main/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/Fixtures/HookFixture.php
So you may have to look into the version for your core version to get a feeling how the signature should look for that core version.
Generally I would guess one of these two:
processDatamap_postProcessFieldArray(): Hook with prepared field array, and you can simple add your new stuff to write or update it and it will be saved. Good if you need to change the record directly.
processDatamap_afterDatabaseOperations(): Hook after record has been changed. This is a good startpoint if you need to do other things after saving a record.
Given your usecase, I would tip on the first one, so here a example implementation (in the class and registering as datamap hook as explained above):
// <your-ext>/Classes/Hooks/MyDataHandlerHooks.php
namespace <Vendor>\<YourExt>\Hooks;
class MyDataHandlerHooks {
/**
* #param string|int $id
*/
public function processDatamap_postProcessFieldArray(
string $status, // Status of the current operation, 'new' or 'update'
string $table, // The table currently processing data for
$id, // The record uid currently processing data for,
// [integer] or [string] (like 'NEW...')
array &$fieldArray, // The field array of a record, cleaned to only
// 'to-be-changed' values. Needs to be &$fieldArray to be considered reference.
DataHandler $dataHandler
): void
{
// $fieldArray may be stripped down to only the real fields which
// needs to be updated, mainly for $status === 'update'. So if you
// need to be sure to have correct data you may have to retrieve
// the record to get the current value, if not provided as with new
// value.
if ($table === 'be_users'
&& $status === 'update'
&& array_key_exists('target_field_name', $fieldArray)
) {
$valueToReactTo = $fieldArray['target_field_name'];
if ($valueToReactTo === 'some-check-value') {
// needs not to be there
$fieldArray['update-field'] = 'my-custom-value';
}
}
}
}

Drupal 7: hook_entity_insert($entity, $type)

I'm a noob junior so I apologise in advance if this is a very basic question and if it has been asked a gazillion times before.
I am basically trying to run another function when a user registers. After some googling I came upon: hook_entity_insert($entity, $type) from (https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_entity_insert/7.x) now, even though there are code examples it does not tell me where to put the code, how to get the data that is submitted etc...
Which file do I put the sample code to test. The sample code provided is:
function hook_entity_insert($entity, $type) {
// Insert the new entity into a fictional table of all entities.
$info = entity_get_info($type);
list($id) = entity_extract_ids($type, $entity);
db_insert('example_entity')
->fields(array(
'type' => $type,
'id' => $id,
'created' => REQUEST_TIME,
'updated' => REQUEST_TIME,
))
->execute();
}
First you should understand the hook system in Drupal. For Drupal 7 this page is a good start. It gives you a quick overview and understanding of the concept.
Understanding the hook system for Drupal modules
There is a specific hook that 'fires' after an user is inserted, named hook_user_insert
You don't need to use hook_entity_insert. In your custom module use below hook
when user registers.
function yourModuleName_form_user_register_alter(&$form, &$form_state) {
// Add your own function to the array of validation callbacks
$form['#validate'][] = 'yourModuleName_user_register_validate';
}
Refer
Hook into Drupal registration and validate user info against business logic
If you want to run a function after the user has registered, use hook_user_insert (or, if this needs to be run every time a user is changed, hook_user_presave).
In general: Hooks in drupal are functions that comply with a specific naming scheme. In the places where a hook is executed (i.e., on user registration), Drupal searches for all modules that contain a function where the function name consists of the module's (machine) name, followed by the hook name. For hook user insert, you would need to implement a module (or place your code in a module you already implemented), see documentation here. Supposing your module is called "custom_module", you then implement a function like so:
function custom_module_user_insert(&$edit, $account, $category) {
//Do what you wanted to do here
}
Hope this helps

Drupal completion hooks (og)

Drupal 7.12/organic groups 7.x-1.3
Does anyone know how I can do a quick cURL hit against a site with a few POST vars like group ID, group name, etc. when a user creates a group successfully?
I have no idea how the hooks system works in this case.
An organic group is defined as an Entity in Drupal 7, and as such you can implement hook_entity_insert in a custom module to react to a successful group creation:
function MYMODULE_entity_insert($entity, $type) {
if ($type == 'group') {
$group_id = $entity->gid;
// Install the Devel module and run the following code to get a full
// breakdown of what's available in the $entity object
dpm($entity);
// Perform your cURL here
}
}
Hope that helps

Can you Create your Own Hook in Drupal?

Is it possible to create your own hook in a Drupal module for other Drupal modules to consume? If not, is there a mechanism in Drupal for third party developers to provide hooks? If everything's been a no so far, where in the core are the list of hooks implemented?
As I understand things, Drupal modules work on a event like system called hooks. When you create a new module, you create functions that implement a hook. For example, there's a hook_delete hook. If you implement a function in your module
function mymodule_delete($node)
{
}
this function will be called whenever a node is deleted.
What I want to know is, is there a way or me, as a third party module developer, to create my own hooks. Say, something like hook_alanskickbutthook so that other module developers could subscribe to this hook.
If this is possible, how do you do it? I've looked around the official docs and haven't found much there, and I still get a little dizzy when I start poking around the Drupal source code (I understand recursion, but don't spend enough time thinking about recursive problems). Full solutions are welcome, but I'm happy to just be pointed in the right direction.
Module_invoke_all() is your ticket to creating your own hooks:
see the API:
http://api.drupal.org/api/drupal/includes--module.inc/function/module_invoke_all
and then look at this great writeup:
http://web.archive.org/web/20101227170201/http://himerus.com/blog/himerus/creating-hooks-your-drupal-modules
(edit: was at http://himerus.com/blog/himerus/creating-hooks-your-drupal-modules but this is now gone)
Once you've made your hook, it can be called in another module using:
/**
* Implementation of hook_myhookname()
*/
function THISMODULENAME_myhookname(args){
//do stuff
}
For example, say you wanted to create hook_my_custom_goodness() for others to use. Then just place code like this in your module at the point where you want the hook to happen:
$variables['msg'] = 'foo';
// Make sure at least one module implements our hook.
if (sizeof(module_implements('my_custom_goodness')) > 0) {
// Call modules that implement the hook, and let them change $variables.
$variables = module_invoke_all('my_custom_goodness', $variables);
}
drupal_set_message($variables['msg']); // Will display 'bar' instead.
Now, if anybody wanted to use your hook, then they could do so in their own module like this:
/**
* Implements hook_my_custom_goodness().
*/
function SOME_OTHER_MODULE_my_custom_goodness($variables) {
$variables['msg'] = 'bar';
return $variables;
}
There is a more complete explanation here:
http://tylerfrankenstein.com/code/drupal-create-custom-hook-for-other-modules
You need to implement two hooks 1. hook_token_info() & 2. hook_tokens() in your module file Below i have given code to create my custom token "query-param-all" and used that token in views- Textarea field.....
/**
* Implements hook_token_info().
*/
function mycustom_token_info() {
$type = [
'name' => ('Custom Token'),
'description' => ('Tokens for custom things.'),
];
$node['query-param-all'] = [
'name' => ("Get all URL query string"),
'description' => ('Get all URL query string'),
];
return [
'types' => ['customtoken' => $type],
'tokens' => ['customtoken' => $node],
];
}
/**
* Implements hook_tokens().
*/
function mycustom_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
//print '<pre>'; print_r($data);exit;
$current_path = \Drupal::request()->query->all();
$query_param = '';
if( count($current_path) > 0) {
$amper = '';
$query_param = '?';
foreach($current_path as $key => $value){
$query_param .= $amper.$key.'='.$value;
$amper = '&';
}
}
if ($type == 'customtoken') {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'query-param-all':
$replacements[$original] = $query_param;
break;
}
}
}
return $replacements;
}
If i recall... http://api.drupal.org/api/drupal/modules--node--node.api.php/function/hook_delete/7
does ths help? been a while since I messed with Drupal.
To create/offer custom Drupal hook, you must implement in a ways such that calling the hook with module_invoke or module_invoke_all does not make any conflicts with other module hooks. The name of the hook should be unique and it should offer all/specific feature in such a general way that it doesn't require any type of adjustments with code. All the configuration must go on admin pages and should store those configurations in a separate table or any existing tables create by Drupal or modules on which your modules depends. The hook should be easy to implment by other modules and it should not be much complex to implement. When you create custom hooks, your module(s) act(s) as API provider.
For Drupal 6 & 7, drupal_alter() is probably the best option.
As stated in the module_invoke_all() documentation,
All arguments are passed by value. Use drupal_alter() if you need to
pass arguments by reference.
In Drupal 8, use ModuleHandler::alter.
Passes alterable variables to specific hook_TYPE_alter()
implementations.

Categories