<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ink-ru</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ink-ru"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Ink-ru"/>
	<updated>2026-04-17T13:12:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Development:Developer_FAQ&amp;diff=29788</id>
		<title>Development:Developer FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Development:Developer_FAQ&amp;diff=29788"/>
		<updated>2010-04-21T18:12:14Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* See also */ Interwiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Help for new coders==&lt;br /&gt;
&lt;br /&gt;
===Where can I start?===&lt;br /&gt;
&lt;br /&gt;
* [[Development:Finding your way into the Moodle code]]&lt;br /&gt;
* [http://dev.moodle.org/ Moodle Developer Courses]&lt;br /&gt;
&lt;br /&gt;
===Where can &amp;quot;newbies&amp;quot; to Moodle get help?===&lt;br /&gt;
&lt;br /&gt;
The [http://moodle.org/mod/forum/view.php?f=33 General developer forum]! Feel free to ask any question, no matter how basic or advanced. Many people ask different levels of question every day, and the community is generally welcoming and quick to respond.&lt;br /&gt;
&lt;br /&gt;
===How do I create a patch?===&lt;br /&gt;
&lt;br /&gt;
See [[Development:How to create a patch]].&lt;br /&gt;
&lt;br /&gt;
===Is there any information on creating a new module or plugin?===&lt;br /&gt;
&lt;br /&gt;
See [[Development:NEWMODULE Documentation]], [[Development:Blocks]] and [[Development:Authentication plugins]], or the [[Development:Developer_documentation#Make_a_new_plugin|full list of plugin types]].&lt;br /&gt;
&lt;br /&gt;
Also have a look at the [http://dev.moodle.org/ Moodle Developer Courses].&lt;br /&gt;
&lt;br /&gt;
===Is there any information on backup and restore?===&lt;br /&gt;
&lt;br /&gt;
See [[Development:Backup]].&lt;br /&gt;
&lt;br /&gt;
==I can&#039;t use one of the available plug-in points to make my change. What alternative is there?==&lt;br /&gt;
&lt;br /&gt;
See [[Development:Local customisation]].&lt;br /&gt;
&lt;br /&gt;
==Moodle&#039;s database==&lt;br /&gt;
&lt;br /&gt;
===Where can I see a schema for the structure of the Moodle database?===&lt;br /&gt;
&lt;br /&gt;
[[Development:Database_schema_introduction]] gives a high level overview of the database schema.&lt;br /&gt;
&lt;br /&gt;
Because of Moodle&#039;s modular nature, there is no single, detailed representation of the full database schema. Instead, the tables for each part of Moodle are defined in a database-neutral XML format, see [[Database_FAQ#XMLDB| XMLDB]], in each part of Moodle. Look for files called install.xml in folders called db throughout the code. Alternatively, from Moodle 2.0 onwards, go to Administration -&amp;gt; Development -&amp;gt; XMLDB editor, and use the [Doc] links to see automatically generated documentation built form the comments in the install.xml files.&lt;br /&gt;
&lt;br /&gt;
See also [[Database FAQ]].&lt;br /&gt;
&lt;br /&gt;
==How to get/set information when writing new Moodle code==&lt;br /&gt;
&lt;br /&gt;
===How do I find out the currently-logged-on user?===&lt;br /&gt;
&lt;br /&gt;
The global object $USER, which contains the numeric $USER-&amp;gt;id among other things.&lt;br /&gt;
&lt;br /&gt;
===How do I find out the current course?===&lt;br /&gt;
The global object $COURSE, which contains the numeric $COURSE-&amp;gt;id&lt;br /&gt;
&lt;br /&gt;
===How do I insert/retrieve records in the database, without creating my own database connections?===&lt;br /&gt;
&lt;br /&gt;
Always use the &amp;quot;datalib&amp;quot; functions, such as insert_record() or get_record(). Since Moodle 1.7 these are found in lib/dmllib.php. Using these functions helps with database abstraction (e.g. running on either MySQL or Postgres) as well as maintaining a single database connection. Moodle uses ADODB for database abstraction.&lt;br /&gt;
&lt;br /&gt;
See [http://xref.moodle.org/nav.html?lib/datalib.php.html /lib/datalib.php] for higher level functions and [http://xref.moodle.org/nav.html?lib/dmllib.php.html /lib/dmllib.php] for lower level functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Look at [http://phpdocs.moodle.org/19/moodlecore/_lib---datalib.php.html  the documentation for datalib.php] for the list of functions and details of use.&lt;br /&gt;
&lt;br /&gt;
===How do I get/set configuration settings?===&lt;br /&gt;
&lt;br /&gt;
To get config values you would typically access the global $CFG object directly, which is automatically created by the core Moodle scripts. To set these &amp;quot;main&amp;quot; config values use set_config($name, $value). The values are stored in the Moodle &amp;quot;config&amp;quot; database table, but these functions take care of cacheing on your behalf, so you should always use these rather than fetching the records directly.&lt;br /&gt;
&lt;br /&gt;
There is also a second table of config settings specifically for plugins (&amp;quot;config_plugin&amp;quot;). These are not automatically loaded into the $CFG object, so to fetch these you would use get_config($plugin, $name). To set them use set_config($name, $value, $plugin).&lt;br /&gt;
&lt;br /&gt;
On top of those global configuration values, individual blocks may also have configuration &amp;quot;object&amp;quot; associated with it (the data is serialized and stored in the &amp;quot;block_instance&amp;quot; table). Within blocks, this data is automatically loaded into the &amp;lt;tt&amp;gt;config&amp;lt;/tt&amp;gt; attribute of the block.&lt;br /&gt;
&lt;br /&gt;
==What is &#039;HEAD&#039;?==&lt;br /&gt;
&lt;br /&gt;
HEAD is version control jargon for the latest version, so at the moment it means Moodle 2.0 dev version. (After the Moodle 2.0 stable branch is made, HEAD will mean 2.1 dev). Look for example, at the links at the top of http://cvs.moodle.org/moodle/README.txt?view=log&amp;amp;pathrev=MOODLE_19_STABLE You can get it from http://download.moodle.org/ and install it if you want to play.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Contributed code FAQ]]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?f=33 General developer forum]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=55719 How does date / time in DB convert to real Date / Time?] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category: Developer]]&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[es:FAQ Desarrollador]]&lt;br /&gt;
[[fr:FAQ de développement]]&lt;br /&gt;
[[pl:Developer FAQ]]&lt;br /&gt;
[[ru:Development:Developer FAQ]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Developer_FAQ&amp;diff=3375</id>
		<title>Developer FAQ</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Developer_FAQ&amp;diff=3375"/>
		<updated>2010-04-21T18:12:14Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* See also */ Interwiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Help for new coders==&lt;br /&gt;
&lt;br /&gt;
===Where can I start?===&lt;br /&gt;
&lt;br /&gt;
* [[Finding your way into the Moodle code]]&lt;br /&gt;
* [http://dev.moodle.org/ Moodle Developer Courses]&lt;br /&gt;
&lt;br /&gt;
===Where can &amp;quot;newbies&amp;quot; to Moodle get help?===&lt;br /&gt;
&lt;br /&gt;
The [http://moodle.org/mod/forum/view.php?f=33 General developer forum]! Feel free to ask any question, no matter how basic or advanced. Many people ask different levels of question every day, and the community is generally welcoming and quick to respond.&lt;br /&gt;
&lt;br /&gt;
===How do I create a patch?===&lt;br /&gt;
&lt;br /&gt;
See [[How to create a patch]].&lt;br /&gt;
&lt;br /&gt;
===Is there any information on creating a new module or plugin?===&lt;br /&gt;
&lt;br /&gt;
See [[NEWMODULE Documentation]], [[Blocks]] and [[Authentication plugins]], or the [[Developer_documentation#Make_a_new_plugin|full list of plugin types]].&lt;br /&gt;
&lt;br /&gt;
Also have a look at the [http://dev.moodle.org/ Moodle Developer Courses].&lt;br /&gt;
&lt;br /&gt;
===Is there any information on backup and restore?===&lt;br /&gt;
&lt;br /&gt;
See [[Backup]].&lt;br /&gt;
&lt;br /&gt;
==I can&#039;t use one of the available plug-in points to make my change. What alternative is there?==&lt;br /&gt;
&lt;br /&gt;
See [[Local customisation]].&lt;br /&gt;
&lt;br /&gt;
==Moodle&#039;s database==&lt;br /&gt;
&lt;br /&gt;
===Where can I see a schema for the structure of the Moodle database?===&lt;br /&gt;
&lt;br /&gt;
[[Database_schema_introduction]] gives a high level overview of the database schema.&lt;br /&gt;
&lt;br /&gt;
Because of Moodle&#039;s modular nature, there is no single, detailed representation of the full database schema. Instead, the tables for each part of Moodle are defined in a database-neutral XML format, see [[Database_FAQ#XMLDB| XMLDB]], in each part of Moodle. Look for files called install.xml in folders called db throughout the code. Alternatively, from Moodle 2.0 onwards, go to Administration -&amp;gt; Development -&amp;gt; XMLDB editor, and use the [Doc] links to see automatically generated documentation built form the comments in the install.xml files.&lt;br /&gt;
&lt;br /&gt;
See also [[Database FAQ]].&lt;br /&gt;
&lt;br /&gt;
==How to get/set information when writing new Moodle code==&lt;br /&gt;
&lt;br /&gt;
===How do I find out the currently-logged-on user?===&lt;br /&gt;
&lt;br /&gt;
The global object $USER, which contains the numeric $USER-&amp;gt;id among other things.&lt;br /&gt;
&lt;br /&gt;
===How do I find out the current course?===&lt;br /&gt;
The global object $COURSE, which contains the numeric $COURSE-&amp;gt;id&lt;br /&gt;
&lt;br /&gt;
===How do I insert/retrieve records in the database, without creating my own database connections?===&lt;br /&gt;
&lt;br /&gt;
Always use the &amp;quot;datalib&amp;quot; functions, such as insert_record() or get_record(). Since Moodle 1.7 these are found in lib/dmllib.php. Using these functions helps with database abstraction (e.g. running on either MySQL or Postgres) as well as maintaining a single database connection. Moodle uses ADODB for database abstraction.&lt;br /&gt;
&lt;br /&gt;
See [http://xref.moodle.org/nav.html?lib/datalib.php.html /lib/datalib.php] for higher level functions and [http://xref.moodle.org/nav.html?lib/dmllib.php.html /lib/dmllib.php] for lower level functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Look at [http://phpdocs.moodle.org/19/moodlecore/_lib---datalib.php.html  the documentation for datalib.php] for the list of functions and details of use.&lt;br /&gt;
&lt;br /&gt;
===How do I get/set configuration settings?===&lt;br /&gt;
&lt;br /&gt;
To get config values you would typically access the global $CFG object directly, which is automatically created by the core Moodle scripts. To set these &amp;quot;main&amp;quot; config values use set_config($name, $value). The values are stored in the Moodle &amp;quot;config&amp;quot; database table, but these functions take care of cacheing on your behalf, so you should always use these rather than fetching the records directly.&lt;br /&gt;
&lt;br /&gt;
There is also a second table of config settings specifically for plugins (&amp;quot;config_plugin&amp;quot;). These are not automatically loaded into the $CFG object, so to fetch these you would use get_config($plugin, $name). To set them use set_config($name, $value, $plugin).&lt;br /&gt;
&lt;br /&gt;
On top of those global configuration values, individual blocks may also have configuration &amp;quot;object&amp;quot; associated with it (the data is serialized and stored in the &amp;quot;block_instance&amp;quot; table). Within blocks, this data is automatically loaded into the &amp;lt;tt&amp;gt;config&amp;lt;/tt&amp;gt; attribute of the block.&lt;br /&gt;
&lt;br /&gt;
==What is &#039;HEAD&#039;?==&lt;br /&gt;
&lt;br /&gt;
HEAD is version control jargon for the latest version, so at the moment it means Moodle 2.0 dev version. (After the Moodle 2.0 stable branch is made, HEAD will mean 2.1 dev). Look for example, at the links at the top of http://cvs.moodle.org/moodle/README.txt?view=log&amp;amp;pathrev=MOODLE_19_STABLE You can get it from http://download.moodle.org/ and install it if you want to play.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Contributed code FAQ]]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?f=33 General developer forum]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/discuss.php?d=55719 How does date / time in DB convert to real Date / Time?] forum discussion&lt;br /&gt;
&lt;br /&gt;
[[Category: Developer]]&lt;br /&gt;
[[Category: FAQ]]&lt;br /&gt;
&lt;br /&gt;
[[es:FAQ Desarrollador]]&lt;br /&gt;
[[fr:FAQ de développement]]&lt;br /&gt;
[[pl:Developer FAQ]]&lt;br /&gt;
[[ru:Development:Developer FAQ]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=852</id>
		<title>Authentication API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=852"/>
		<updated>2010-04-21T18:10:54Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* USER INFORMATION AND SYNCRONIZATION */ Intrewiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Moodle authentication interface==&lt;br /&gt;
&lt;br /&gt;
Authentication API This file describes Moodle interface functions to authentication modules. (This page is incomplete , I&#039;ll update it after I have phpdoc commented auth/ldap/lib.php)&lt;br /&gt;
&lt;br /&gt;
Most of functions are from ldap-authentication module and are not implemented (yet?) on other modules. Please feel free to extend other modules to support same features or roll your own module.&lt;br /&gt;
&lt;br /&gt;
Some of new function are still tested and are not documented here yet.&lt;br /&gt;
&lt;br /&gt;
==Authentication functions==&lt;br /&gt;
&lt;br /&gt;
Basic functions to authenticate users with external db&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mandatory:===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_login ($username, $password)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Authenticate username, password with userdatabase.&lt;br /&gt;
&lt;br /&gt;
Returns: true if the username and password work and false if they don&#039;t&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Optional:===&lt;br /&gt;
&lt;br /&gt;
Following functions are optional , but if present they extend module usability with Moodle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userinfo($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Query other userinformation from database.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
User information in array &#039;&#039;(name =&amp;gt; value, ...)&#039;&#039; or &#039;&#039;false&#039;&#039; in case of error. Function honors update-flags so if&lt;br /&gt;
&amp;lt;code&amp;gt;$CFG-&amp;gt;auth_user_(atribute)_updatelocal&amp;lt;/code&amp;gt;&lt;br /&gt;
is present, it will return value only if flag is true.&lt;br /&gt;
&lt;br /&gt;
===COURSE CREATING===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_iscreator($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
should user have rights to create courses&lt;br /&gt;
&lt;br /&gt;
Returns: True if user has rights to create cources otherwise false&lt;br /&gt;
&lt;br /&gt;
===USER CREATION===&lt;br /&gt;
&lt;br /&gt;
Functions that enable user creation, activation and deactivation from moodle to external database&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_exists ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Checks if given username exists on external db&lt;br /&gt;
&lt;br /&gt;
Returns: true if given usernname exist or false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_create ($userobject,$plainpass)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Creates new user to external db. User should be created in inactive stage until confirmed by email.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_activate ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
activate new user after email-address is confirmed&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_disable ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
deactivate user in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
=== USER INFORMATION AND SYNCRONIZATION ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userlist ()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get list of usernames in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: All usernames in array or false on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_users($filter=&#039;*&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get ALL USEROBJECTS FROM EXTERNAL DB.&lt;br /&gt;
&lt;br /&gt;
Returns: Array of all users as objects from external db &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication API]]&lt;br /&gt;
&lt;br /&gt;
[[ru:Development:API Аутентификации]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Overview&amp;diff=7041</id>
		<title>Overview</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Overview&amp;diff=7041"/>
		<updated>2010-04-21T18:08:08Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* See also */ Interwiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A lot of people ask how the development of Moodle operates.  This page should give you a working overview that should help in understanding a lot of other developer documentation.&lt;br /&gt;
&lt;br /&gt;
==The key players==&lt;br /&gt;
&lt;br /&gt;
;Martin Dougiamas: Martin is the lead developer of Moodle. Generally he tries to facilitate democracy and meritocracy but occasionally has to make executive decisions on things.&lt;br /&gt;
&lt;br /&gt;
;Moodle HQ: The mostly-Australian team of developers who are directly funded by the Moodle project to work full-time on core developments.  Developers include Martin Dougiamas (moodler), Eloy Lafuente (stronk7), Petr Skoda (skodak), Mathieu Petit-Clair (scyrma), Nicolas Connault, Donsheng Cai, Jérôme Mouneyrac, Helen Foster (wildgirl) and occasionally Jamie Pratt (jamiesensei). Pictures of everyone can be found here: http://moodle.com/hq/.&lt;br /&gt;
&lt;br /&gt;
;Catalyst: The team of developers working for Moodle clients via Catalyst Ltd in New Zealand, resulting in a lot of core development.  Developers include Martin Langhoff, Penny Leach (mjollnir), Matt Clarkson, and Donal McMullan.&lt;br /&gt;
&lt;br /&gt;
;Open University: The team of developers working on Moodle implementations at Open University in the UK.  Developers include Tim Hunt, Sam Marshall, Nick Freear, Thanh Le and Jenny Gray.&lt;br /&gt;
&lt;br /&gt;
There are many other people contributing to Moodle in many ways, these are just the main groups currently working on core development.  See [http://moodle.org/cvs the full list of people with write access to Moodle]&lt;br /&gt;
&lt;br /&gt;
==Moodle versions==&lt;br /&gt;
&lt;br /&gt;
Moodle major releases occur roughly 6 months or more apart, on no fixed schedule.  Each major release increments the version number by 0.1.  Minor releases (no new features, just fixes) on each stable branch can occur at any time, whenever enough bug fixes have been made to justify them.  The full details can be seen in the [[Release notes]].&lt;br /&gt;
&lt;br /&gt;
The current development version is always on the trunk of CVS (i.e. HEAD), while stable branches are split off for every major version (e.g. MOODLE_18_STABLE).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How we develop the Roadmap==&lt;br /&gt;
&lt;br /&gt;
The [[Roadmap]] lists the features being developed for the next version.  This list is derived mostly from the issues with large numbers of votes in the Moodle [[Tracker]], so please vote for what you want!  Other influences include general discussion and feature requests at Moodle Moots and in the Moodle forums.&lt;br /&gt;
&lt;br /&gt;
==Release cycles==&lt;br /&gt;
&lt;br /&gt;
Generally a cycle works like this:&lt;br /&gt;
;Rapid Development:Long period of several months adding code to the HEAD version of Moodle.  At the same time, all fixes that don&#039;t involve database changes or radical core changes are backported to the last two or three stable branches.&lt;br /&gt;
;Head Freeze:At some point Martin Dougiamas declares a freeze on new work for a while to stabilise the core.  All database changes and all major core changes need to have explicit permission from Martin.  All developers should be wrapping up work on new features and fixing bugs in new code.  This period may be 1 or 2 weeks.&lt;br /&gt;
;Beta period:Once the HEAD version becomes fairly stable, Martin declares a BETA version and this point is marked on HEAD as MOODLE_XX_BETA (e.g. MOODLE_19_BETA).  Install packages are generated daily from the latest version for wider testing and feedback via the tracker.  The freeze continues, testing and bug fixing continues.  This testing period may be anywhere from 2 to 6 weeks.&lt;br /&gt;
;Major release:When the core code passes all the testing we can throw at it, the MOODLE_XX_BETA flag is moved up to mark the current point as a branch point, and a new stable branch named MOODLE_XX_STABLE is created.  Packages are created, and the release is announced.&lt;br /&gt;
&lt;br /&gt;
Then it all starts again!&lt;br /&gt;
&lt;br /&gt;
==Quality control==&lt;br /&gt;
&lt;br /&gt;
Issue tracking is an important part of a continuous quality control process. It involves reporting of problems (bugs), ideas for improvement and new features. Unlike most proprietary software programs, Moodle issue reporting and tracking information is open to everyone. Moodle&#039;s issue tracking system is called the [[Tracker]].&lt;br /&gt;
&lt;br /&gt;
All Moodle users are encouraged to be active participants when it comes to testing. Anyone with a Tracker user account can create, view, comment on, vote, and watch bugs.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
&lt;br /&gt;
Testers are responsible for verifying the accuracy of changes made by developers. Testers choose which bugs they want to test, according to their area of expertise, and use the QA Assignee field to identify themselves as the tester.&lt;br /&gt;
&lt;br /&gt;
If the bug passes testing, then the tester changes the status of the bug from &#039;resolved&#039; to &#039;closed&#039;. If the bug fails testing, or if the fix is incomplete, then the tester reopens the bug.&lt;br /&gt;
&lt;br /&gt;
A Moodle release will be deemed ready when all &amp;quot;blocker&amp;quot; bugs fixed for a particular version have been closed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Weekly Code Review===&lt;br /&gt;
&lt;br /&gt;
Every Tuesday (all time zones), testers and core developers stop developing new code and focus on reviewing changes made to the stable releases in the past week (both at a code level and an interface level).&lt;br /&gt;
&lt;br /&gt;
This process is intended to improve the quality of the latest download packages and to catch any new bugs that might have been created while fixing old ones.&lt;br /&gt;
&lt;br /&gt;
The latest stable packages are tagged as MOODLE_19_WEEKLY (these tags are updated after the weekly review is over).&lt;br /&gt;
&lt;br /&gt;
See [[Weekly Code Review]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Coding Standards==&lt;br /&gt;
&lt;br /&gt;
The full [[Coding|Coding Guide]] gives all the details, but here are some of the major things  your code needs to hit:&lt;br /&gt;
&lt;br /&gt;
===XMLDB===&lt;br /&gt;
&lt;br /&gt;
All our database schema are created using the XML &#039;&#039;install.php&#039;&#039; files, and upgraded using database-agnostic commands in &#039;&#039;upgrade.php&#039;&#039; files.  Any version of any part of Moodle can be smoothly upgraded to any later version in this fashion (on a wide variety of supported databases).&lt;br /&gt;
&lt;br /&gt;
===XHTML===&lt;br /&gt;
&lt;br /&gt;
All output from Moodle must be compliant with XHTML Strict 1.0, and also compliant with all common accessibility guidelines (such as W3C WAG).  &lt;br /&gt;
&lt;br /&gt;
===Forms===&lt;br /&gt;
&lt;br /&gt;
All forms should use the Moodleforms library if possible.  This results in a standardised accessible output that designers can style consistently and well.&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&lt;br /&gt;
All parameters should be checked using require_param() and optional_param() which will safely clean all incoming data for use and provide defaults to your code.  Moodleforms will do this automatically for you.&lt;br /&gt;
&lt;br /&gt;
===Output===&lt;br /&gt;
&lt;br /&gt;
All textual output should be output using the format_text or format_string functions.  This will ensure that text is cleaned and filtered appropriately.&lt;br /&gt;
&lt;br /&gt;
===Access===&lt;br /&gt;
&lt;br /&gt;
All permissions-checking should use the &amp;quot;Access library&amp;quot; to check against current capabilities.  The most common function you&#039;ll use is has_capability() which checks the permissions of the current user in an efficient way to see if they are allowed to do this specific operation.   Do not check for specific roles in your code (e.g. teacher/student) as that will make your code useless.&lt;br /&gt;
&lt;br /&gt;
===Other core libraries===&lt;br /&gt;
&lt;br /&gt;
The other major libraries you should get familiar with are:&lt;br /&gt;
# &#039;&#039;moodlelib.php&#039;&#039; - a useful bin of all kinds of useful functions and constants&lt;br /&gt;
# &#039;&#039;datalib.php&#039;&#039; - all the functions you need to interface with the database &lt;br /&gt;
# &#039;&#039;weblib.php&#039;&#039; - all the functions you&#039;ll need to create and output XHTML &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Plugins===&lt;br /&gt;
&lt;br /&gt;
Moodle has about 22 different types of plugins last time I counted.  Plugins can generally be self-contained in a single directory containing scripts, images, stylesheets and language files all in one package that can be dropped into the Moodle script directory in the right place.  After that the admin just needs to visit the admin page to install them.&lt;br /&gt;
&lt;br /&gt;
Most plugins work in one of two ways, they either provide a &#039;&#039;lib.php&#039;&#039; filled with common functions and some scripts with standard names, or they subclass a proto-plugin and override a few method functions to achieve their goals.  &lt;br /&gt;
&lt;br /&gt;
The best way to learn is to pick an example from the core code that is similar to what you want to do and start playing with it.   There are also some template plugins to help get you started.&lt;br /&gt;
&lt;br /&gt;
==Development processes==&lt;br /&gt;
Not all Moodle development happens exactly like this, but it really should. :-)&lt;br /&gt;
&lt;br /&gt;
===Major Development===&lt;br /&gt;
A major development is a significant piece of new code, adding new functionality to Moodle.&lt;br /&gt;
&lt;br /&gt;
====Make sure it&#039;s a good idea====&lt;br /&gt;
Firstly, you should look at the roadmap and talk the idea over with some Moodle developers to see if someone else is working on it already and whether others think the general idea has merit.  Use the forums if you wish, or whatever means you have.  If you have a client, you may need to work with them to work out what they REALLY want (perhaps it isn&#039;t actually a new development for Moodle).&lt;br /&gt;
&lt;br /&gt;
====Create a specification in Moodle Docs====&lt;br /&gt;
Start a new page in the Moodle Docs wiki, similar to [[Grades]].  Your page should outline the database table design, the GUI, the hows and whys etc.  Include as much detail as you need (even mock screenshots) but try to keep it clear and logically organised.&lt;br /&gt;
&lt;br /&gt;
====Seek and absorb community feedback====&lt;br /&gt;
Post about the new page in the appropriate forums on [http://moodle.org/course/view.php?id=5 Using Moodle] to help draw attention to it and to stimulate some discussion around your development.  The more feedback you have the better, especially if it includes a wide variety of users (developers, teachers, students etc).&lt;br /&gt;
&lt;br /&gt;
Edit your page in response to the feedback, or invite people to do so themselves.  try to evolve the specification into something that all users are happy with.   Sometimes it&#039;s worth working harder to find the &amp;quot;best&amp;quot; way to do something without adding Yet Another Option.&lt;br /&gt;
&lt;br /&gt;
====Set up tasks in the Moodle Tracker====&lt;br /&gt;
Once the specification has settled down, it&#039;s time to start work.  Create a new task for yourself in the Moodle Tracker, and add sub-tasks in roughly chronological order for all the different parts of the job.   This not only helps you keep track of where you are, but allows the community to &amp;quot;watch you&amp;quot; develop and to help you where they can.  If there are different people working on different parts, you can assign subtasks to different people.  It&#039;s really very convenient to use once you get the hang of it.&lt;br /&gt;
&lt;br /&gt;
====Use CVS and link commits to Tracker====&lt;br /&gt;
If possible, develop the code in an open code repository (and preferably Moodle CVS!).  If you need CVS write access to the core code or the contrib repository, use the &amp;quot;Apply for CVS Access&amp;quot; tab on http://moodle.org/cvs. Gaining access to the main core code is quite difficult, but we are generally very free with access to the contrib area.&lt;br /&gt;
&lt;br /&gt;
Every time you make a commit, include a detailed message about the new code and always include a Moodle Tracker bug number (e.g. MDL-7777).  This will ensure that the Moodle Tracker is able to detect your commit and attach it to the relevant bug report.&lt;br /&gt;
&lt;br /&gt;
====Comment on milestones in forums and tracker====&lt;br /&gt;
If you hit a major milestone, or want testers to try something, feel free to post about it in the relevant forum on Using Moodle.  The more people you can attract to look and try out your code the better it will be, trust me.&lt;br /&gt;
&lt;br /&gt;
====Respond to bug reports====&lt;br /&gt;
Of course you need to listen to your users (well, most of them :-)).  Encourage people to file bugs, and fix them.  If you need help setting up a project category in the Tracker contact support@moodle.com.  This will ensure that all your bugs are easy to find and to track.&lt;br /&gt;
&lt;br /&gt;
===Minor Development=== &lt;br /&gt;
&lt;br /&gt;
For smaller modules, fixes, improvements and other issues.&lt;br /&gt;
&lt;br /&gt;
====Create a new issue in the tracker====&lt;br /&gt;
&lt;br /&gt;
You should definitely create an issue in the tracker to describe your development and to act as a focus point for all discussion.  You can reference the bug number from forum discussions and in commit messages etc.  This way everyone can easily find out exactly what they are talking about.&lt;br /&gt;
&lt;br /&gt;
====Attach a patch====&lt;br /&gt;
&lt;br /&gt;
If you have some code, please attach it to the tracker issue, or if it&#039;s on your own site then link to it from the tracker issue.  Don&#039;t attach code in the Moodle forums ... it will &amp;quot;rot&amp;quot; quickly there and just clogs up moodle.org with useless old code.&lt;br /&gt;
&lt;br /&gt;
====Promote the patch====&lt;br /&gt;
&lt;br /&gt;
By all means draw attention to your work in the Moodle forums (mentioning the bug number) or email developers directly to help make them aware of it.  You can also add developers as &amp;quot;watchers&amp;quot; to the tracker issue if you want, this means they will get email for every change on the issue.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Finding your way into the Moodle code]]&lt;br /&gt;
* [[Working with the Community]]&lt;br /&gt;
* [[Guidelines for contributed code]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Overview]]&lt;br /&gt;
[[Category:Quality Assurance|Overview]]&lt;br /&gt;
[[Category:Processes|Overview]]&lt;br /&gt;
&lt;br /&gt;
[[ru:Development:Краткий обзор]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=File_API_internals&amp;diff=8294</id>
		<title>File API internals</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=File_API_internals&amp;diff=8294"/>
		<updated>2010-04-21T18:06:08Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* See also */ Interwiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
This specification has now largely been implemented in Moodle 2.0. Inevitably, in the implementation, some details may have changed. If in doubt, read the code. (Then come back and correct this page ;-))&lt;br /&gt;
&lt;br /&gt;
The implementation of this specification is being tracked at MDL-14589.&lt;br /&gt;
&lt;br /&gt;
Please see [[Using the file API]] if you just want to know how to use the File API in your code, rather than how it works internally.&lt;br /&gt;
&lt;br /&gt;
==Objectives==&lt;br /&gt;
&lt;br /&gt;
The goals of these changes are to: &lt;br /&gt;
&lt;br /&gt;
* allow files to be stored within Moodle, as part of the content (as we do now).&lt;br /&gt;
* use a consistent and simple approach for all file handling throughout Moodle.&lt;br /&gt;
* give modules control over which users can access a file, using capabilities and other local rules.&lt;br /&gt;
* make it easy to determine which parts of Moodle use which files, to simplify operations like backup and restore.&lt;br /&gt;
* track where files originally came from.&lt;br /&gt;
* avoid redundant storage, when the same file is used twice.&lt;br /&gt;
* fully support Unicode file names, irrespective of the capabilities of the underlying file system.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The File API is a set of core interfaces to allow the rest of Moodle to:&lt;br /&gt;
# store files, and&lt;br /&gt;
# display files to users.&lt;br /&gt;
It applies only to files that are part of the Moodle site&#039;s content. It is not used for internal files, such as those in the following subdirectories of dataroot: temp, lang, cache, environment, filter, search, sessions, upgradelogs, ...&lt;br /&gt;
&lt;br /&gt;
The API can be subdivided into the following parts:&lt;br /&gt;
; Serving files&lt;br /&gt;
: Lets users accessing a Moodle site get the files (file.php, draftfile.php, pluginfile.php, userfile.php, etc.)&lt;br /&gt;
:* Serve the files on request&lt;br /&gt;
:* with appropriate security checks&lt;br /&gt;
; File API internals&lt;br /&gt;
: Stores the files on disc, with metadata in associated database tables.&lt;br /&gt;
:* Content-addressed storage.&lt;br /&gt;
; File management API&lt;br /&gt;
: Allows code to manipulate the stored files (lib/filelib.php)&lt;br /&gt;
:* find information about stored files.&lt;br /&gt;
:* print links to files.&lt;br /&gt;
:* move/rename/copy/delete/etc.&lt;br /&gt;
:* keep a file synchronised with an external repository.&lt;br /&gt;
; File management user interface&lt;br /&gt;
: Provides the interface for (lib/form/file.php, filemanager.php, filepicker.php and files/index.php, draftfiles.php)&lt;br /&gt;
:* Form elements allowing users to select a file using the Repository API, and have it stored within Moodle.&lt;br /&gt;
:* UI for users to manage their files, replacing the old course files UI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Serving files ==&lt;br /&gt;
&lt;br /&gt;
TODO revise this section.&lt;br /&gt;
&lt;br /&gt;
Deals with serving of files - browser requests file, Moodle sends it back. We have three main files. It is important to setup slasharguments on server (file.php/some/thing/xxx.jpg), any content that relies on relative links can not work without it (scorm, uploaded html pages, etc.).&lt;br /&gt;
&lt;br /&gt;
=== file.php ===&lt;br /&gt;
&lt;br /&gt;
Serves course files.&lt;br /&gt;
&lt;br /&gt;
Implements basic file access. Ideally only images and files linked from course sections should be there, no XSS protection required - we expect javascript, sw, etc. there, no way to make it &amp;quot;secure&amp;quot;. The access control is not critical any more if we move most of the files into modules&lt;br /&gt;
&lt;br /&gt;
The file name and parameter structure is critical for backwards compatibility of existing course content.&lt;br /&gt;
&lt;br /&gt;
 /file.php/courseid/dir/dir/filename.ext&lt;br /&gt;
&lt;br /&gt;
Internally the files would be stored in &amp;lt;code&amp;gt;array(&#039;contextid&#039;=&amp;gt;$coursecontextid, &#039;filearea&#039;=&amp;gt;&#039;coursefiles&#039;, &#039;itemid&#039;=&amp;gt;0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== pluginfile.php ===&lt;br /&gt;
&lt;br /&gt;
(aka modfile.php)&lt;br /&gt;
Sends module, block, question files.&lt;br /&gt;
* modules decide about access control&lt;br /&gt;
* optional XSS protection - student submitted files must not be served with normal headers, we have to force download instead; ideally there should be second wwwroot for serving of untrusted files&lt;br /&gt;
* only internal links to selected areas are supported - you can link images in summary area, but not the assignment submissions&lt;br /&gt;
&lt;br /&gt;
Absolute file links need to be rewritten if html editing allowed in module. The links are stored internally as relative links. Before editing or display the internal link representation is converted to absolute links using simple str_replace() @@thipluginlink/summary@@/image.jpg --&amp;gt; /pluginfile.php/assignmentcontextid/intro/image.jpg, it is converted back to internal links before saving.&lt;br /&gt;
&lt;br /&gt;
::Can the distinct file areas supported by one plugin be declared somehow in order add some information about them? For example, I think it can be interesting to declare:&lt;br /&gt;
::* assignment_summary:&lt;br /&gt;
::** relpath=&#039;intro&#039;&lt;br /&gt;
::** userdata=false&lt;br /&gt;
::** anotherproperty=anothervalue&lt;br /&gt;
::* assignment_submission:&lt;br /&gt;
::** relpath=&#039;submission/@@USERID@@&#039;&lt;br /&gt;
::** userdata=false&lt;br /&gt;
::** anotherproperty=anothervalue&lt;br /&gt;
::* and so on...&lt;br /&gt;
::And then, when the editor &amp;quot;receives&amp;quot; one &amp;quot;assignment_summary&amp;quot; areaname, if knows what to show and so on? Also that info could be useful to know, in backup &amp;amp; restore if some fileareas have to be processed or no (userdata=false). Or also, when reconstructing the links (str_replace() above). And will cause to have a well defined list of fileareas by module, instead of coding them in a free way (prone to errors). [[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 16:35, 28 June 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
::Something like this will be part of file management API, hardcoding this in file storage would make it less flexible imo [[User:Skodak|Skodak]]&lt;br /&gt;
&lt;br /&gt;
::Yup, yup. Storage doesn&#039;t know anything but get/put files (nothing else). It&#039;s part of management, absolutely. [[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 11:21, 29 June 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/contextid/areaname/arbitrary/params/or/dirs/filename.ext&lt;br /&gt;
&lt;br /&gt;
pluginfile.php detects the type of plugin from context table, fetches basic info (like $course or $cm if appropriate) and calls plugin function (or later method) which does the access control and finally sends the file to user. &#039;&#039;areaname&#039;&#039; separates files by type and divides the context into several subtrees - for example &#039;&#039;summary&#039;&#039; files (images used in module intros), post attachments, etc.&lt;br /&gt;
&lt;br /&gt;
==== Assignment example ====&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/assignmentcontextid/intro/someimage.jpg&lt;br /&gt;
 /pluginfile.php/assignmentcontextid/submission/submissionid/attachmentname.ext&lt;br /&gt;
 /pluginfile.php/assignmentcontextid/extra/allsubmissionfiles.zip&lt;br /&gt;
&lt;br /&gt;
::Uhm... all those files together? What&#039;s going to differentiate the &amp;quot;submission&amp;quot; path in the example above from the &amp;quot;summary&amp;quot; path? Is it supposed that the editor, or the filemanager won&#039;t allow , for example to pick-up one file from the &amp;quot;submission&amp;quot; area to be used in the summary of one assignment and only the &amp;quot;summary&amp;quot; area will be showed? That means multiple file managers by context and it&#039;s against the clean &amp;quot;one file manager per context&amp;quot; agreed below [[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 21:28, 26 June 2008 (CDT)&lt;br /&gt;
::Yes Eloy, the different areas (summary, submission) etc. have different uses, different access control. There are two types of file manager - the two pane file manager which lists all contexts+areas user may access, and minimalistic manager in html editor which shows only subset of areas from current plugin (because you can not link anything else).&lt;br /&gt;
&lt;br /&gt;
====scorm example====&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/scormcontextid/intro/someimage.jpg&lt;br /&gt;
 /pluginfile.php/scormcontextid/content/revisionnumber/dir/somescormfile.js&lt;br /&gt;
&lt;br /&gt;
The revision counter is incremented when any file changes in order to prevent caching problems. The lifetime should be adjustable in module settings.&lt;br /&gt;
&lt;br /&gt;
====quiz example====&lt;br /&gt;
&lt;br /&gt;
 pluginfile.php/quizcontextid/intro/niceimage.jpg&lt;br /&gt;
 pluginfile.php/quizcontextid/report/type/export.ods&lt;br /&gt;
&lt;br /&gt;
====questions example====&lt;br /&gt;
&lt;br /&gt;
 pluginfile.php/SYSCONTEXTID/question/questionid/file.jpg&lt;br /&gt;
&lt;br /&gt;
====blog example====&lt;br /&gt;
Blog entries or notes in general do not have context id (because they live in system context, SYSCONTEXTID below is the id of system context).&lt;br /&gt;
The note attachments are always served with XSS protection on, ideally we should use separate wwwroot for this. Access control can be hardcoded.&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/SYSCONTEXTID/blog_attachment/blogentryid/attachmentname.ext&lt;br /&gt;
&lt;br /&gt;
Internally stored in &amp;lt;code&amp;gt;array(&#039;contextid&#039;=&amp;gt;SYSCONTEXTID, &#039;filearea&#039;=&amp;gt;&#039;blog_attachment&#039;, &#039;itemid&#039;=&amp;gt;$blogentryid)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/SYSCONTEXTID/blog_post/blogentryid/embeddedimage.ext&lt;br /&gt;
&lt;br /&gt;
Internally stored in &amp;lt;code&amp;gt;array(&#039;contextid&#039;=&amp;gt;SYSCONTEXTID, &#039;filearea&#039;=&amp;gt;&#039;blog_post&#039;, &#039;itemid&#039;=&amp;gt;$blogentryid)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====backup example====&lt;br /&gt;
It would be nice to have some special protection of backup files - new capabilities for backup file download, upload. Backups contain a lot of personal info, we could block restoring of backups from other sites too.&lt;br /&gt;
&lt;br /&gt;
 /pluginfile.php/coursecontextid/backup/backupfile.zip&lt;br /&gt;
&lt;br /&gt;
Internally stored in &amp;lt;code&amp;gt;array(&#039;contextid&#039;=&amp;gt;$coursecontextid, &#039;filearea&#039;=&amp;gt;&#039;backup&#039;, &#039;itemid&#039;=&amp;gt;0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===userfile.php===&lt;br /&gt;
Personal file storage, intended as an online storage of work in progress like assignments before the submission.&lt;br /&gt;
* read/write own files only for now&lt;br /&gt;
* option to share with others later&lt;br /&gt;
* personal &amp;quot;websites&amp;quot; will not be supported (security)&lt;br /&gt;
&lt;br /&gt;
 /userfile.php/userid/dir/dir/filename.ext&lt;br /&gt;
&lt;br /&gt;
===rssfile.php===&lt;br /&gt;
Replaces rss/file.php which is kept only for backwards compatibility.&lt;br /&gt;
RSS files should not require sessions/cookies, URLs should contain some sort of security token/key.&lt;br /&gt;
Internally the files may be stored in database or together with other files.&lt;br /&gt;
Performance improvements - we should support both Etag (cool) and Last-Modified (more used), when we receive If-None-Match/If-Modified-Since =&amp;gt; 304 &lt;br /&gt;
&lt;br /&gt;
 /rssfile.php/contextid/any/parameters/module/wants/rss.xml&lt;br /&gt;
 /rssfile.php/SYSCONTEXTID/blog/userid/rss.xml&lt;br /&gt;
&lt;br /&gt;
Again modules and plugins decide what gets sent to user.&lt;br /&gt;
&lt;br /&gt;
=== Temporary files ===&lt;br /&gt;
Temporary files are usually used during the lifetime of one script only.&lt;br /&gt;
uses:&lt;br /&gt;
* exports&lt;br /&gt;
* imports&lt;br /&gt;
* zipping/unzipping&lt;br /&gt;
* processing by executable files (latex, mimetex)&lt;br /&gt;
&lt;br /&gt;
Ideally these files should never use utf-8 (which is a major problem for zipping at the moment).&lt;br /&gt;
Proposed new sha1 based file storage is not suitable both for performance and technical reasons.&lt;br /&gt;
&lt;br /&gt;
=== Legacy file storage and serving ===&lt;br /&gt;
Going to use good-old separate directories in $CFG-&amp;gt;dataroot.&lt;br /&gt;
&lt;br /&gt;
file serving and storage:&lt;br /&gt;
# user avatars - user/pix.php&lt;br /&gt;
# group avatars - user/pixgroup.php&lt;br /&gt;
# tex, algebra - filter/tex/* and filter/algebra/*&lt;br /&gt;
# rss cache (?full rss rewrite soon?) - backwards compatibility only rss/file.php&lt;br /&gt;
&lt;br /&gt;
only storage:&lt;br /&gt;
#sessions&lt;br /&gt;
&lt;br /&gt;
== File API internals ==&lt;br /&gt;
&lt;br /&gt;
=== File storage on disk ===&lt;br /&gt;
&lt;br /&gt;
Files are stored in $CFG-&amp;gt;dataroot (also known as moodledata) in the filedir subfolder.&lt;br /&gt;
&lt;br /&gt;
Files are stored according to the SHA1 hash of their content. This means each file with particular contents is stored once, irrespective of how many times it is included in different places, even if it is referred to by different names. (This idea comes from the git version control system.) To relate a file on disc to a user-comprehensible path or filename, you need to use the file database tables. See the next section.&lt;br /&gt;
&lt;br /&gt;
Suppose a file has SHA1 hash 081371cb102fa559e81993fddc230c79205232ce. Then it will be stored in on disc as moodledata/filedir/08/13/71/081371cb102fa559e81993fddc230c79205232ce.&lt;br /&gt;
&lt;br /&gt;
If you were wondering, in PHP, SHA1 hashes can be computed with either the [http://php.net/sha1 sha1] or [http://php.net/sha1_file sha1_file] functions.&lt;br /&gt;
&lt;br /&gt;
The information in this section should be considered completely internal to the file API. Other parts of the Moodle code should manipulate files using the higher level functions of the file API. For example, they should refer to files by file id in the file table, not the SHA1 hash.&lt;br /&gt;
&lt;br /&gt;
=== Files database tables ===&lt;br /&gt;
&lt;br /&gt;
==== Table: files ====&lt;br /&gt;
&lt;br /&gt;
This table contains one entry for each usage of a file. Enough information is kept here so that the file can be fully identified and retrieved again if necessary.&lt;br /&gt;
&lt;br /&gt;
If, for example, the same image is used in a user&#039;s profile, and a forum post, then there will be two rows in this table, one for each use of the file, and Moodle will treat the two as separate files, even though the file is only stored once on disc.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
| int(10)  &lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this file.&lt;br /&gt;
|-&lt;br /&gt;
| contenthash&lt;br /&gt;
| varchar(40)&lt;br /&gt;
|  &lt;br /&gt;
| The sha1 hash of content.&lt;br /&gt;
|-&lt;br /&gt;
| pathnamehash&lt;br /&gt;
| varchar(40)&lt;br /&gt;
| &lt;br /&gt;
| The sha1 hash of contextid+filearea+itemid+filepath+filename - prevents file duplicates and allows fast lookup&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;contextid&#039;&#039;&#039; &lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The context id defined in context table - identifies the instance of plugin owning the file.&lt;br /&gt;
|-&lt;br /&gt;
| filearea&lt;br /&gt;
| varchar(50)&lt;br /&gt;
|&lt;br /&gt;
| Like &amp;quot;submissions&amp;quot;, &amp;quot;intro&amp;quot; and &amp;quot;content&amp;quot; (images and swf linked from summaries), etc.; &amp;quot;blogs&amp;quot; and &amp;quot;userfiles&amp;quot; are special case that live at the system context.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;itemid&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| Some plugin specific item id (eg. forum post, blog entry or assignment submission or user id for user files)&lt;br /&gt;
|-&lt;br /&gt;
| filepath&lt;br /&gt;
| text&lt;br /&gt;
| &lt;br /&gt;
| relative path to file from module content root, useful in Scorm and Resource mod - most of the mods do not need this&lt;br /&gt;
|-&lt;br /&gt;
| filename&lt;br /&gt;
| varchar(255)&lt;br /&gt;
| &lt;br /&gt;
| The full Unicode name of this file (case sensitive)&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;filesize&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| size of file - bytes&lt;br /&gt;
|-&lt;br /&gt;
| mimetype&lt;br /&gt;
| varchar(100)&lt;br /&gt;
| NULL&lt;br /&gt;
| type of file&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;userid&#039;&#039;&#039;&lt;br /&gt;
| int(10)  &lt;br /&gt;
| NULL&lt;br /&gt;
| Optional - general user id field - meaning depending on plugin&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;timecreated&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The time this file was created&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;timemodified&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The last time the file was last modified&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Indexes:&lt;br /&gt;
* non-unique index on (contextid, filearea, itemid)&lt;br /&gt;
* non-unique index on (contenthash)&lt;br /&gt;
* unique index on (pathnamehash).&lt;br /&gt;
&lt;br /&gt;
The plugin type does not need to be specified because it can be derived from the context. Items like blog that do not have their own context will use their own file area inside a suitable context. In this case, the user context.&lt;br /&gt;
&lt;br /&gt;
Entries with filename = &#039;.&#039; represent directories. Directory entries like this are created automatically when a file is added within them.&lt;br /&gt;
&lt;br /&gt;
Note: &#039;files&#039; plural used even thought that goes against the [[Database|coding guidelines]] because &#039;file&#039; is a reserved word.&lt;br /&gt;
&lt;br /&gt;
==== Table: files_metadata ====&lt;br /&gt;
&lt;br /&gt;
This table contains extra metadata about files.  Repositories could provide this, or it could be manually edited in the local copy.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
| int(10)  &lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fileid&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| Foreign key, references files.id&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;name&#039;&#039;&#039;&lt;br /&gt;
| varchar(255)&lt;br /&gt;
| &lt;br /&gt;
| The name of the metadata field&lt;br /&gt;
|-&lt;br /&gt;
| value&lt;br /&gt;
| text&lt;br /&gt;
| &lt;br /&gt;
| The value of this metadata field&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: this is not implemented yet.&lt;br /&gt;
&lt;br /&gt;
==== Table: files_sync ====&lt;br /&gt;
&lt;br /&gt;
This table contains information on how to synchronise data with repositories. Data would be synchronised from cron.php or on demand from file manager. The sync would be one way only (repository -&amp;gt; local file).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Type &lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
| int(10)  &lt;br /&gt;
| auto-incrementing &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;fileid&#039;&#039;&#039; &lt;br /&gt;
| int(10)&lt;br /&gt;
|  &lt;br /&gt;
| Foreign key, references files.id&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;repositoryid&#039;&#039;&#039;&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The repository instance this is associated with, see [[Repository_API]]&lt;br /&gt;
|-&lt;br /&gt;
| updates&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| Specifies the update schedule (0 = none, 1 = on demand, other = some period in seconds)&lt;br /&gt;
|-&lt;br /&gt;
| repositorypath&lt;br /&gt;
| text&lt;br /&gt;
| &lt;br /&gt;
| The full path to the original file on the repository&lt;br /&gt;
|-&lt;br /&gt;
| timeimportfirst&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The first time this file was imported into Moodle&lt;br /&gt;
|-&lt;br /&gt;
| timeimportlast&lt;br /&gt;
| int(10)&lt;br /&gt;
| &lt;br /&gt;
| The most recent time that this file was imported into Moodle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: this is not implemented yet. It may end up being implemented within the Repository API istead. That is, this table may end up being called repository_sync.&lt;br /&gt;
&lt;br /&gt;
==== Table: files_cleanup ====&lt;br /&gt;
&lt;br /&gt;
This table contains candidates for deletion from the file pool. Files are not deleted immediately because there may be multiple references to the same file. Therefore, it is better for performance to simply add a row to this table, and later, on cron, clean the files off disc if they are really no longer used. Also, batch deletion on cron makes it easier to avoid concurrency issues when one user deletes what was the last reference to the file as another user adds a new reference. (The cron cleanup code should be doing appropriate locking.)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;id&#039;&#039;&#039; &lt;br /&gt;
| int(10)  &lt;br /&gt;
| auto-incrementing &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| contenthash&lt;br /&gt;
| varchar(40)&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Implementation of basic operations===&lt;br /&gt;
&lt;br /&gt;
This is just an overview. See the external API description below for how to do this from client code.&lt;br /&gt;
&lt;br /&gt;
====Storing a file====&lt;br /&gt;
&lt;br /&gt;
# Calculate the SHA1 hash of the file contents.&lt;br /&gt;
# Check if a file with this SHA1 hash already exists on disc. If not, store the file there.&lt;br /&gt;
# Remove this SHA1 hash from list of deleted files, if present.&lt;br /&gt;
# Add the record for this file to the files table.&lt;br /&gt;
&lt;br /&gt;
====Reading a file====&lt;br /&gt;
&lt;br /&gt;
# Fetch the record (which includes the SHA1 hash) for the file you want from the files table.&lt;br /&gt;
# Retrieve the contents using the SHA1 hash.&lt;br /&gt;
&lt;br /&gt;
====Deleting a file====&lt;br /&gt;
&lt;br /&gt;
# Store the SHA1 hash of the file being deleted in the files_cleanup table.&lt;br /&gt;
# Delete the record from the files table.&lt;br /&gt;
# Later, admin/cron.php will actually delete the file from disc if it is no longer used (with proper table locking to prevent race conditions when adding/deleting files simultaneously).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing and management API ==&lt;br /&gt;
&lt;br /&gt;
This is what other parts of Moodle use to access and manage files. The code is in lib/file/.&lt;br /&gt;
&lt;br /&gt;
These section documents both the public facing parts of this code, and also the inner workings. Hopefully it makes it sufficiently clear which is which. For more information, see the API documentation in the code, and [[Using_the_file_API]].&lt;br /&gt;
&lt;br /&gt;
TODO write the rest of this section.&lt;br /&gt;
&lt;br /&gt;
=== lib/filelib.php ===&lt;br /&gt;
&lt;br /&gt;
Including this file includes all of the other library files.&lt;br /&gt;
&lt;br /&gt;
=== Class: file_browser ===&lt;br /&gt;
&lt;br /&gt;
=== Class: file_info and subclasses ===&lt;br /&gt;
&lt;br /&gt;
=== Class: file_storage ===&lt;br /&gt;
&lt;br /&gt;
=== Class: stored_file ===&lt;br /&gt;
&lt;br /&gt;
=== File exceptions===&lt;br /&gt;
&lt;br /&gt;
== File management user-interface ==&lt;br /&gt;
&lt;br /&gt;
=== File manager ===&lt;br /&gt;
&lt;br /&gt;
All the contexts, file areas and files now form a single huge tree structure, although each user only has access to certain parts of that tree. The file manager (files/index.php) allow users to brows this tree, and manage files within it, according to the level of permissions they have.&lt;br /&gt;
&lt;br /&gt;
Single pane file manager is hard to implement without drag &amp;amp; drop which is notoriously problematic in web based applications. I propose to implement a two pane commander-style file manager. Two pane manager allows you to easily copy/move files between two different contexts (ex: courses).&lt;br /&gt;
&lt;br /&gt;
File manager must not interact directly with filesystem API, instead each module should return traversable tree of files and directories with both real and localised names (localised names are needed for dirs like backupdata).&lt;br /&gt;
&lt;br /&gt;
This code will be in file/.&lt;br /&gt;
&lt;br /&gt;
=== Formslib field types ===&lt;br /&gt;
&lt;br /&gt;
This code will be in lib/form/&lt;br /&gt;
&lt;br /&gt;
* Upload single files.&lt;br /&gt;
* Upload multiple files to a files area.&lt;br /&gt;
* HTML editor (see next)&lt;br /&gt;
&lt;br /&gt;
=== Integration with the HTML editor ===&lt;br /&gt;
&lt;br /&gt;
Each instance of the HTML editor will be told to store related files in a particular file area.&lt;br /&gt;
&lt;br /&gt;
During editing, files will be stored in a draft files area. Then when the form is submitted they will be (automatically) moved into the real file area.&lt;br /&gt;
&lt;br /&gt;
Files will be selected using the repository file picker.&lt;br /&gt;
&lt;br /&gt;
=== Local files repository plugin ===&lt;br /&gt;
&lt;br /&gt;
Allows users to see an browse files they already have access to within this Moodle, for inclusion in the page currently being edited.&lt;br /&gt;
&lt;br /&gt;
This code will be in repository/local/&lt;br /&gt;
&lt;br /&gt;
== Backwards compatibility ==&lt;br /&gt;
&lt;br /&gt;
=== Content backwards compatibility ===&lt;br /&gt;
&lt;br /&gt;
This should be preserved as much as possible. This will involve rewriting links in content during the upgrade to 2.0. &lt;br /&gt;
&lt;br /&gt;
Some new features (like resource sharing - if implemented) may not work with existing data that still uses files from course files area.&lt;br /&gt;
&lt;br /&gt;
There might be a breakage of links due to special characters stripping in uploaded files which will not match the links in uploaded html files any more. This should not be very common I hope.&lt;br /&gt;
&lt;br /&gt;
===Code backwards compatibility===&lt;br /&gt;
&lt;br /&gt;
Other Moodle code (for example plugins) will have to be converted to the new APIs. See [[Using_the_file_API]] for guidance.&lt;br /&gt;
&lt;br /&gt;
It is not possible to provide backwards-compatibility here. For example, the old $CFG-&amp;gt;dataroot/$courseid/ will no longer exist, and there is no way to emulate that, so we won&#039;t try.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Upgrade and migration ==&lt;br /&gt;
&lt;br /&gt;
When a site is upgraded to Moodle 2.0, all the files in moodledata will have to be migrated. This is going to be a pain, like DML/DDL was :-(&lt;br /&gt;
&lt;br /&gt;
The upgrade process should be interruptible (like the Unicode upgrade was) so it can be stopped/restarted any time.&lt;br /&gt;
&lt;br /&gt;
=== Migration of content ===&lt;br /&gt;
&lt;br /&gt;
* resources - move files to new resource content file area; can be done automatically for pdf, image resources; definitely not accurate for uploaded web pages&lt;br /&gt;
* questions - image file moved to new area, image tag appended to questions&lt;br /&gt;
* moddata files - the easiest part, just move to new storage&lt;br /&gt;
* coursefiles - there might be many outdated files :-( :-(&lt;br /&gt;
* rss feeds links in readers - will be broken, the new security related code would break it anyway&lt;br /&gt;
&lt;br /&gt;
=== Moving files to files table and file pool ===&lt;br /&gt;
&lt;br /&gt;
The migration process must be interruptable because it might take a very long time. The files would be moved from old location, the restarting would be straightforward.&lt;br /&gt;
&lt;br /&gt;
Proposed stages:&lt;br /&gt;
#migration of all course files except moddata - finish marked by some $CFG-&amp;gt;files_migrated=true; - this step breaks the old file manager and html editor integration&lt;br /&gt;
#migration of blog attachments&lt;br /&gt;
#migration of question files&lt;br /&gt;
#migration of moddata files - each module is responsible to copy data from converted coursefiles or directly from moddata which is not converted automatically&lt;br /&gt;
&lt;br /&gt;
Some people use symbolic links in coursefiles - we must make sure that those will be copied to new storage in both places, though they can not be linked any more - anybody wanting to have content synced will need to move the files to some repository and set up the sync again.&lt;br /&gt;
&lt;br /&gt;
::Talked about a double task here, when migrating course files to module areas:&lt;br /&gt;
::# Parse html files to detect all the dependencies and move them together.&lt;br /&gt;
::# Fallback in pluginfile.php so, if something isn&#039;t found in module filearea, search for it in course filearea, copying it and finally, serving it.&lt;br /&gt;
&lt;br /&gt;
:: Also we talked about the possibility of add a new setting to resource in order to define if it should work against old coursefiles or new autocontained file areas. Migrated resources will point to old coursefiles while new ones will enforce autocontained file areas.&lt;br /&gt;
&lt;br /&gt;
:: it seems that only resource files will be really complex (because allow arbitrary HTML inclusion). The rest (labels, intros... doesn&#039;t) and should be easier to parse.&lt;br /&gt;
&lt;br /&gt;
::[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 19:00, 29 June 2008 (CDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parts of Moodle that need to be modified ==&lt;br /&gt;
&lt;br /&gt;
Of course, all parts of Moodle that use files need to be changed. See MDL-14589 for a more detailed list.&lt;br /&gt;
&lt;br /&gt;
=== Any form where the user can upload files ===&lt;br /&gt;
&lt;br /&gt;
=== Any from containing a HTML editor ===&lt;br /&gt;
&lt;br /&gt;
Since users can embed images etc. there.&lt;br /&gt;
&lt;br /&gt;
=== Backup/restore ===&lt;br /&gt;
&lt;br /&gt;
File handling in backups needs to be fully rewritten - list of files in xml + pool of sha1 named files with contents. This solves the utf-8 trouble here, yay!!&lt;br /&gt;
&lt;br /&gt;
=== Antivirus scanning ===&lt;br /&gt;
&lt;br /&gt;
== Issues that need to be resolved ==&lt;br /&gt;
&lt;br /&gt;
=== Unicode support in zip format ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;This has now been solved by using the built in zip in PHP 5.2.8.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zip format is an old standard for compressing files. It was created long before Unicode existed, and Unicode support was only recently added. There are several ways used for encoding of non-ASCII characters in path names, but unfortunately it is not very standardised. Most Windows packers use DOS encoding.&lt;br /&gt;
&lt;br /&gt;
Client software:&lt;br /&gt;
* Windows built-in compression - bundled with Windows, non-standard DOS encoding only&lt;br /&gt;
* WinZip - shareware, Unicode option (since v11.2)&lt;br /&gt;
* TotalCommander - shareware, single byte(DOS) encoding only&lt;br /&gt;
* 7-Zip - free, Unicode or DOS encoding depending on characters used in file name (since v4.58beta)&lt;br /&gt;
* Info-ZIP - free, uses some weird character set conversions&lt;br /&gt;
&lt;br /&gt;
PHP extraction:&lt;br /&gt;
* Info-ZIP binary execution - no Unicode support at all, mangles character sets in file names (depends on OS, see docs), files must be copied to temp directory before compression and after extraction&lt;br /&gt;
* PclZip PHP library - reads single byte encoded names only, problems with random problems and higher memory usage.&lt;br /&gt;
* Zip PHP extension - reads single byte encoded names only, 64bit operating system can not open/create archives with more than 500 files (depends on sum of lengths of all filenames and directories, to be fixed in PHP 5.3 and external PECL library, no PHP 5.2.x backport planned!), adding of files is limited by number of free file handles (around 1000 - depends on OS and other PHP code, workaround is to close and reopen archive)&lt;br /&gt;
&lt;br /&gt;
Large file support:&lt;br /&gt;
PHP running under 32bit operating systems does not support files &amp;gt;2GB (do not expect fix before PHP 6). This might be a potential problem for larger backups.&lt;br /&gt;
&lt;br /&gt;
Tar Alternative:&lt;br /&gt;
* tar with gzip compression - easy to implement in PHP + zlib extension (PclTar, Tar from PEAR or custom code)&lt;br /&gt;
* no problem with unicode in *nix, Windows again expects DOS encoding :-(&lt;br /&gt;
* seems suitable for backup/restore - yay!&lt;br /&gt;
&lt;br /&gt;
Roadmap:&lt;br /&gt;
# add zip processing class that fully hides the underlying library&lt;br /&gt;
# use single byte encoding &amp;quot;garbage in/garbage out&amp;quot; approach for encoding of files in zip archives; add new &#039;zipencoding&#039; string into lang packs (ex: cp852 DOS charset for Czech locale) and use it during extraction, we might support true unicode later when PHP Zip extension does that&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Possible future ideas ==&lt;br /&gt;
&lt;br /&gt;
=== Files maintenance report ===&lt;br /&gt;
&lt;br /&gt;
This would do deep validation of the files on disc. It would:&lt;br /&gt;
* Report when there is a row in the files table, but the corresponding file is missing from the file system.&lt;br /&gt;
* Report files that still exist on disc, even though no references remain.&lt;br /&gt;
* Report orphaned files.&lt;br /&gt;
* Report total disc space usage by context (as much as is possible with content-addressible file storage).&lt;br /&gt;
* Verify that the SHA1 hash of the contents of each file matches the file name.&lt;br /&gt;
&lt;br /&gt;
In addition, it might offer options to fix these problems, where possible.&lt;br /&gt;
&lt;br /&gt;
=== Support quotas per user, course, etc. ===&lt;br /&gt;
&lt;br /&gt;
People want this.&lt;br /&gt;
&lt;br /&gt;
If we have implemented the above report, it would then just be a matter of adding the interface hooks to stop people uploading more files once the quota has been reached.&lt;br /&gt;
&lt;br /&gt;
(We could also divide the file size by number of instances that are using it, this might be considered more accurate in some scenarios.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Using the file API]]&lt;br /&gt;
* [[Repository API]]&lt;br /&gt;
* [[Portfolio API]]&lt;br /&gt;
* [[Resource module file API migration]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
&lt;br /&gt;
[[ja:開発:ファイルAPI]]&lt;br /&gt;
[[ru:Development:File_API]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12356</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12356"/>
		<updated>2010-04-21T17:16:04Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* $this-&amp;gt;version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
{{main|Development:Blocks}}&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12355</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12355"/>
		<updated>2010-04-21T17:15:37Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* _self_test() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
{{main|Development:Blocks}}&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12354</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12354"/>
		<updated>2010-04-21T17:15:14Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* name() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
{{main|Development:Blocks}}&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12353</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12353"/>
		<updated>2010-04-21T17:14:39Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* specialization() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
{{main|Development:Blocks}}&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2780</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2780"/>
		<updated>2010-04-21T16:52:16Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou ([mailto:pj@moodle.org pj@moodle.org])&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks/Appendix_B| Appendix B]]).&lt;br /&gt;
&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a &#039;&#039;&#039;reference&#039;&#039;&#039; text should refer to [[Blocks/Appendix_A| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. &lt;br /&gt;
&lt;br /&gt;
Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class block_simplehtml extends block_base {&lt;br /&gt;
  function init() {&lt;br /&gt;
    $this-&amp;gt;title   = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
    $this-&amp;gt;version = 2004111200;&lt;br /&gt;
  }&lt;br /&gt;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| init()]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
  function get_content() {&lt;br /&gt;
    if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
      return $this-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;content         =  new stdClass;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&gt;
&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
    $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;text = &#039;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks/Appendix_A#init.28.29|init()]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks/Appendix_A#specialization.28.29| specialization()]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. &lt;br /&gt;
&lt;br /&gt;
However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| hide_header()]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. &lt;br /&gt;
&lt;br /&gt;
For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) &lt;br /&gt;
             echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
   &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean FALSE) it displays the box as pre-checked (reflecting the current status). &lt;br /&gt;
&lt;br /&gt;
Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behavior: save all variables as $CFG properties&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
  }else {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
&lt;br /&gt;
===String me up ===&lt;br /&gt;
&lt;br /&gt;
Now that we have a working config_global with saved values we want to be able to read the values from it. The simplest way to do this is to assign the config setting to a string and then use the string as we would any other. IE;&lt;br /&gt;
&lt;br /&gt;
$string = $CFG-&amp;gt;configsetting;&lt;br /&gt;
&lt;br /&gt;
You can check all the configuration settings available to a module by displaying them all with;&lt;br /&gt;
&lt;br /&gt;
print_object($CFG);  &lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  // Clean the data if we have to&lt;br /&gt;
  global $CFG;&lt;br /&gt;
  if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
    $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // And now forward to the default implementation defined in the parent class&lt;br /&gt;
  return parent::instance_config_save($data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. &lt;br /&gt;
&lt;br /&gt;
The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
In order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // The preferred value is in pixels&lt;br /&gt;
  return 200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;div&amp;amp;gt; or &amp;amp;lt;table&amp;amp;gt; elements, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we&#039;ll see below).&lt;br /&gt;
&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
    &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). &lt;br /&gt;
&lt;br /&gt;
And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
===and some other useful examples too:===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
    return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    $attrs = parent::html_attributes();&lt;br /&gt;
    // Add your own attributes here, e.g.&lt;br /&gt;
    // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
    return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
&lt;br /&gt;
# The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
# The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
# Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to TRUE, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== Responding to Cron ==&lt;br /&gt;
&lt;br /&gt;
It is possible to have your block respond to the cron process. That is have a method that is run at regular intervals regardless of user interaction. There are two parts to this. Firstly you need to define a new function within your block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
    mtrace( &amp;quot;Hey, my cron script is running&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // do something&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then within your init function you will need to set the (minimum) execution interval for your cron function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this&amp;gt;cron = 300;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will set the minimum interval to 5 minutes. However, the function can only be called as frequently as cron has been set to run in the Moodle installation. Remember that if you change any values in the init function you &#039;&#039;&#039;must&#039;&#039;&#039; bump the version number and visit the Notifications page otherwise they will be ignored.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
The block cron is designed to call the cron script for that block &#039;&#039;&#039;type&#039;&#039;&#039; only. That is, cron does not care about individual instances of blocks. Inside your cron function although $this is defined it has almost nothing in it (only title, content type, version and cron fields are populated). If you need to execute cron for individual instances it is your own responsibility to iterate over them in the block&#039;s cron function. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
&lt;br /&gt;
    // get the block type from the name&lt;br /&gt;
    $blocktype = get_record( &#039;block&#039;, &#039;name&#039;, &#039;my_block_name&#039; );&lt;br /&gt;
&lt;br /&gt;
    // get the instances of the block&lt;br /&gt;
    $instances = get_records( &#039;block_instance&#039;,&#039;blockid&#039;,$blocktype-&amp;gt;id );&lt;br /&gt;
&lt;br /&gt;
    // iterate over the instances&lt;br /&gt;
    foreach ($instances as $instance) {&lt;br /&gt;
&lt;br /&gt;
        // recreate block object&lt;br /&gt;
        $block = block_instance( &#039;my_block_name&#039;, $instance );&lt;br /&gt;
&lt;br /&gt;
        // $block is now the equivalent of $this in &#039;normal&#039; block&lt;br /&gt;
        // usage, e.g.&lt;br /&gt;
        $someconfigitem = $block-&amp;gt;config-&amp;gt;item2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;my_block_name&#039; will coincide with the name of the directory the block is stored in.&lt;br /&gt;
&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function get_content() {&lt;br /&gt;
  if ($this-&amp;gt;content !== null) {&lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content         = new stdClass;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
  // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
  return $this-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Database support ==&lt;br /&gt;
In case you need to have a database table that holds some specific information that is used with your block. you will need to create a sub folder &#039;&#039;&#039;db&#039;&#039;&#039; and have an &#039;&#039;&#039;install.xml&#039;&#039;&#039; file with the table schema setup.&lt;br /&gt;
&lt;br /&gt;
To create the install.xml file, use the [[XMLDB editor]]. See [[Database_FAQ#XMLDB|Database FAQ &amp;gt; XMLDB]] for further details.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [http://dev.moodle.org/mod/resource/view.php?id=48 Unit 7 of the Introduction to Moodle Programming course] is a follow up to this course. (But you should follow the forum discussions of that course closely as there are still some bugs and inconsistencies.)&lt;br /&gt;
* A [http://cvs.moodle.org/contrib/plugins/blocks/NEWBLOCK/ NEWBLOCK template] you can all use to start you own block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック]]&lt;br /&gt;
[[ru:Development:Blocks]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2779</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2779"/>
		<updated>2010-04-21T16:51:03Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou ([mailto:pj@moodle.org|pj@moodle.org])&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks/Appendix_B| Appendix B]]).&lt;br /&gt;
&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a &#039;&#039;&#039;reference&#039;&#039;&#039; text should refer to [[Blocks/Appendix_A| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. &lt;br /&gt;
&lt;br /&gt;
Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class block_simplehtml extends block_base {&lt;br /&gt;
  function init() {&lt;br /&gt;
    $this-&amp;gt;title   = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
    $this-&amp;gt;version = 2004111200;&lt;br /&gt;
  }&lt;br /&gt;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| init()]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
  function get_content() {&lt;br /&gt;
    if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
      return $this-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;content         =  new stdClass;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&gt;
&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
    $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;text = &#039;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks/Appendix_A#init.28.29|init()]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks/Appendix_A#specialization.28.29| specialization()]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. &lt;br /&gt;
&lt;br /&gt;
However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| hide_header()]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. &lt;br /&gt;
&lt;br /&gt;
For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) &lt;br /&gt;
             echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
   &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean FALSE) it displays the box as pre-checked (reflecting the current status). &lt;br /&gt;
&lt;br /&gt;
Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behavior: save all variables as $CFG properties&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
  }else {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
&lt;br /&gt;
===String me up ===&lt;br /&gt;
&lt;br /&gt;
Now that we have a working config_global with saved values we want to be able to read the values from it. The simplest way to do this is to assign the config setting to a string and then use the string as we would any other. IE;&lt;br /&gt;
&lt;br /&gt;
$string = $CFG-&amp;gt;configsetting;&lt;br /&gt;
&lt;br /&gt;
You can check all the configuration settings available to a module by displaying them all with;&lt;br /&gt;
&lt;br /&gt;
print_object($CFG);  &lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  // Clean the data if we have to&lt;br /&gt;
  global $CFG;&lt;br /&gt;
  if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
    $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // And now forward to the default implementation defined in the parent class&lt;br /&gt;
  return parent::instance_config_save($data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. &lt;br /&gt;
&lt;br /&gt;
The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
In order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // The preferred value is in pixels&lt;br /&gt;
  return 200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;div&amp;amp;gt; or &amp;amp;lt;table&amp;amp;gt; elements, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we&#039;ll see below).&lt;br /&gt;
&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
    &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). &lt;br /&gt;
&lt;br /&gt;
And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
===and some other useful examples too:===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
    return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    $attrs = parent::html_attributes();&lt;br /&gt;
    // Add your own attributes here, e.g.&lt;br /&gt;
    // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
    return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
&lt;br /&gt;
# The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
# The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
# Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to TRUE, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== Responding to Cron ==&lt;br /&gt;
&lt;br /&gt;
It is possible to have your block respond to the cron process. That is have a method that is run at regular intervals regardless of user interaction. There are two parts to this. Firstly you need to define a new function within your block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
    mtrace( &amp;quot;Hey, my cron script is running&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // do something&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then within your init function you will need to set the (minimum) execution interval for your cron function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this&amp;gt;cron = 300;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will set the minimum interval to 5 minutes. However, the function can only be called as frequently as cron has been set to run in the Moodle installation. Remember that if you change any values in the init function you &#039;&#039;&#039;must&#039;&#039;&#039; bump the version number and visit the Notifications page otherwise they will be ignored.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
The block cron is designed to call the cron script for that block &#039;&#039;&#039;type&#039;&#039;&#039; only. That is, cron does not care about individual instances of blocks. Inside your cron function although $this is defined it has almost nothing in it (only title, content type, version and cron fields are populated). If you need to execute cron for individual instances it is your own responsibility to iterate over them in the block&#039;s cron function. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
&lt;br /&gt;
    // get the block type from the name&lt;br /&gt;
    $blocktype = get_record( &#039;block&#039;, &#039;name&#039;, &#039;my_block_name&#039; );&lt;br /&gt;
&lt;br /&gt;
    // get the instances of the block&lt;br /&gt;
    $instances = get_records( &#039;block_instance&#039;,&#039;blockid&#039;,$blocktype-&amp;gt;id );&lt;br /&gt;
&lt;br /&gt;
    // iterate over the instances&lt;br /&gt;
    foreach ($instances as $instance) {&lt;br /&gt;
&lt;br /&gt;
        // recreate block object&lt;br /&gt;
        $block = block_instance( &#039;my_block_name&#039;, $instance );&lt;br /&gt;
&lt;br /&gt;
        // $block is now the equivalent of $this in &#039;normal&#039; block&lt;br /&gt;
        // usage, e.g.&lt;br /&gt;
        $someconfigitem = $block-&amp;gt;config-&amp;gt;item2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;my_block_name&#039; will coincide with the name of the directory the block is stored in.&lt;br /&gt;
&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function get_content() {&lt;br /&gt;
  if ($this-&amp;gt;content !== null) {&lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content         = new stdClass;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
  // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
  return $this-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== Database support ==&lt;br /&gt;
In case you need to have a database table that holds some specific information that is used with your block. you will need to create a sub folder &#039;&#039;&#039;db&#039;&#039;&#039; and have an &#039;&#039;&#039;install.xml&#039;&#039;&#039; file with the table schema setup.&lt;br /&gt;
&lt;br /&gt;
To create the install.xml file, use the [[XMLDB editor]]. See [[Database_FAQ#XMLDB|Database FAQ &amp;gt; XMLDB]] for further details.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [http://dev.moodle.org/mod/resource/view.php?id=48 Unit 7 of the Introduction to Moodle Programming course] is a follow up to this course. (But you should follow the forum discussions of that course closely as there are still some bugs and inconsistencies.)&lt;br /&gt;
* A [http://cvs.moodle.org/contrib/plugins/blocks/NEWBLOCK/ NEWBLOCK template] you can all use to start you own block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック]]&lt;br /&gt;
[[ru:Development:Blocks]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2778</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2778"/>
		<updated>2010-04-21T16:47:12Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Configure That Out */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou (pj@moodle.org)&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks/Appendix_B| Appendix B]]).&lt;br /&gt;
&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a &#039;&#039;&#039;reference&#039;&#039;&#039; text should refer to [[Blocks/Appendix_A| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. &lt;br /&gt;
&lt;br /&gt;
Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class block_simplehtml extends block_base {&lt;br /&gt;
  function init() {&lt;br /&gt;
    $this-&amp;gt;title   = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
    $this-&amp;gt;version = 2004111200;&lt;br /&gt;
  }&lt;br /&gt;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| init()]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
  function get_content() {&lt;br /&gt;
    if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
      return $this-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;content         =  new stdClass;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
{{Top}}&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&gt;
&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
    $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;text = &#039;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks/Appendix_A#init.28.29|init()]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks/Appendix_A#specialization.28.29| specialization()]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. &lt;br /&gt;
&lt;br /&gt;
However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| hide_header()]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. &lt;br /&gt;
&lt;br /&gt;
For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) &lt;br /&gt;
             echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
   &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean FALSE) it displays the box as pre-checked (reflecting the current status). &lt;br /&gt;
&lt;br /&gt;
Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behavior: save all variables as $CFG properties&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
  }else {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
&lt;br /&gt;
===String me up ===&lt;br /&gt;
&lt;br /&gt;
Now that we have a working config_global with saved values we want to be able to read the values from it. The simplest way to do this is to assign the config setting to a string and then use the string as we would any other. IE;&lt;br /&gt;
&lt;br /&gt;
$string = $CFG-&amp;gt;configsetting;&lt;br /&gt;
&lt;br /&gt;
You can check all the configuration settings available to a module by displaying them all with;&lt;br /&gt;
&lt;br /&gt;
print_object($CFG);  &lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  // Clean the data if we have to&lt;br /&gt;
  global $CFG;&lt;br /&gt;
  if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
    $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // And now forward to the default implementation defined in the parent class&lt;br /&gt;
  return parent::instance_config_save($data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. &lt;br /&gt;
&lt;br /&gt;
The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
In order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // The preferred value is in pixels&lt;br /&gt;
  return 200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;div&amp;amp;gt; or &amp;amp;lt;table&amp;amp;gt; elements, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we&#039;ll see below).&lt;br /&gt;
&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
    &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). &lt;br /&gt;
&lt;br /&gt;
And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
===and some other useful examples too:===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
    return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    $attrs = parent::html_attributes();&lt;br /&gt;
    // Add your own attributes here, e.g.&lt;br /&gt;
    // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
    return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
&lt;br /&gt;
# The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
# The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
# Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to TRUE, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== Responding to Cron ==&lt;br /&gt;
&lt;br /&gt;
It is possible to have your block respond to the cron process. That is have a method that is run at regular intervals regardless of user interaction. There are two parts to this. Firstly you need to define a new function within your block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
    mtrace( &amp;quot;Hey, my cron script is running&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // do something&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then within your init function you will need to set the (minimum) execution interval for your cron function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this&amp;gt;cron = 300;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will set the minimum interval to 5 minutes. However, the function can only be called as frequently as cron has been set to run in the Moodle installation. Remember that if you change any values in the init function you &#039;&#039;&#039;must&#039;&#039;&#039; bump the version number and visit the Notifications page otherwise they will be ignored.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
The block cron is designed to call the cron script for that block &#039;&#039;&#039;type&#039;&#039;&#039; only. That is, cron does not care about individual instances of blocks. Inside your cron function although $this is defined it has almost nothing in it (only title, content type, version and cron fields are populated). If you need to execute cron for individual instances it is your own responsibility to iterate over them in the block&#039;s cron function. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
&lt;br /&gt;
    // get the block type from the name&lt;br /&gt;
    $blocktype = get_record( &#039;block&#039;, &#039;name&#039;, &#039;my_block_name&#039; );&lt;br /&gt;
&lt;br /&gt;
    // get the instances of the block&lt;br /&gt;
    $instances = get_records( &#039;block_instance&#039;,&#039;blockid&#039;,$blocktype-&amp;gt;id );&lt;br /&gt;
&lt;br /&gt;
    // iterate over the instances&lt;br /&gt;
    foreach ($instances as $instance) {&lt;br /&gt;
&lt;br /&gt;
        // recreate block object&lt;br /&gt;
        $block = block_instance( &#039;my_block_name&#039;, $instance );&lt;br /&gt;
&lt;br /&gt;
        // $block is now the equivalent of $this in &#039;normal&#039; block&lt;br /&gt;
        // usage, e.g.&lt;br /&gt;
        $someconfigitem = $block-&amp;gt;config-&amp;gt;item2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;my_block_name&#039; will coincide with the name of the directory the block is stored in.&lt;br /&gt;
&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function get_content() {&lt;br /&gt;
  if ($this-&amp;gt;content !== null) {&lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content         = new stdClass;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
  // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
  return $this-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== Database support ==&lt;br /&gt;
In case you need to have a database table that holds some specific information that is used with your block. you will need to create a sub folder &#039;&#039;&#039;db&#039;&#039;&#039; and have an &#039;&#039;&#039;install.xml&#039;&#039;&#039; file with the table schema setup.&lt;br /&gt;
&lt;br /&gt;
To create the install.xml file, use the [[XMLDB editor]]. See [[Database_FAQ#XMLDB|Database FAQ &amp;gt; XMLDB]] for further details.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [http://dev.moodle.org/mod/resource/view.php?id=48 Unit 7 of the Introduction to Moodle Programming course] is a follow up to this course. (But you should follow the forum discussions of that course closely as there are still some bugs and inconsistencies.)&lt;br /&gt;
* A [http://cvs.moodle.org/contrib/plugins/blocks/NEWBLOCK/ NEWBLOCK template] you can all use to start you own block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック]]&lt;br /&gt;
[[ru:Development:Blocks]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12352</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12352"/>
		<updated>2010-04-21T16:42:49Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Appendix A: block_base Reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
{{main|Development:Blocks}}&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12351</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12351"/>
		<updated>2010-04-21T15:58:16Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* BLOCK_TYPE_TEXT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;br /&gt;
[[ru:Development:Blocks/Appendix_A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12350</id>
		<title>Blocks/Appendix A</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks/Appendix_A&amp;diff=12350"/>
		<updated>2010-04-21T11:51:38Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Appendix A: block_base Reference */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Appendix A: &#039;&#039;block_base&#039;&#039; Reference ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories:&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_you_can_freely_use_and_override:|those you may use and override in your block]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_but_may_want_to_use:|those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use]];&lt;br /&gt;
:#[[Blocks/Appendix_A#Methods_which_you_should_not_override_and_not_use_at_all:|those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden]].&lt;br /&gt;
In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
== Methods you can freely use and override: ==&lt;br /&gt;
&lt;br /&gt;
=== after_install() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function after_install() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is designed to be overridden by block subclasses, and allows you to specify a set of tasks to be executed after the block is installed.  For example, you may wish to store the date on which the block was installed.  However, each database type has its own way of getting the current date, and when using XMLDB to install your block, these operations are also unsupported. So the best way to complete such a task while maintaining database abstraction is to use XMLDB to install the block, and then use the after_install() method to perform the insertion before the block is used.&lt;br /&gt;
&lt;br /&gt;
Please note that after_install() is called once per block, not once per instance.&lt;br /&gt;
&lt;br /&gt;
=== applicable_formats() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;all&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;mod&#039; =&amp;gt; false,&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
&lt;br /&gt;
=== before_delete() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function before_delete() {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.7 and later&lt;br /&gt;
&lt;br /&gt;
This method is called when an administrator removes a block from the Moodle installation, immediately before the relevant database tables are deleted.  It allows block authors to perform any necessary cleanup - removing temporary files and so on - before the block is deleted.&lt;br /&gt;
&lt;br /&gt;
=== config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_print() {&lt;br /&gt;
  // Default behavior: print the config_global.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
  &lt;br /&gt;
  print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
  include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
  print_simple_box_end();&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
&lt;br /&gt;
* If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
* The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behaviour: save all variables as $CFG properties&lt;br /&gt;
  // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== get_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content() {&lt;br /&gt;
  // This should be implemented by the derived class.&lt;br /&gt;
  return NULL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
&lt;br /&gt;
=== has_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function has_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
&lt;br /&gt;
=== hide_header() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  //Default, false--&amp;gt; the header is shown&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
&lt;br /&gt;
=== html_attributes() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
  return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  $attrs = parent::html_attributes();&lt;br /&gt;
  // Add your own attributes here, e.g.&lt;br /&gt;
  // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
  return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== init() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function init() {&lt;br /&gt;
  $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
  $this-&amp;gt;version = 2004111200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_config() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
&lt;br /&gt;
=== instance_allow_multiple() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  // Are you going to allow multiple instances of each block?&lt;br /&gt;
  // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
  return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
&lt;br /&gt;
=== instance_config_print() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_print() {&lt;br /&gt;
  // Default behavior: print the config_instance.html file&lt;br /&gt;
  // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
  if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
    return FALSE;&lt;br /&gt;
  }&lt;br /&gt;
  global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
  if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
    print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
    include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
    print_simple_box_end();&lt;br /&gt;
   } else {&lt;br /&gt;
     notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
        str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
   }&lt;br /&gt;
   return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
&lt;br /&gt;
=== preferred_width() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
  return 180;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
&lt;br /&gt;
=== refresh_content() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function refresh_content() {&lt;br /&gt;
  // Nothing special here, depends on content()&lt;br /&gt;
  $this-&amp;gt;content = NULL;&lt;br /&gt;
  return $this-&amp;gt;get_content();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
&lt;br /&gt;
=== specialization() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // Just to make sure that this method exists.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_content_type() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_content_type() {&lt;br /&gt;
  return $this-&amp;gt;content_type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_title() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function get_title() {&lt;br /&gt;
  return $this-&amp;gt;title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== get_version() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;function get_version() {&lt;br /&gt;
  return $this-&amp;gt;version;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== instance_config_commit() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_commit() {&lt;br /&gt;
  return set_field(&#039;block_instance&#039;,&#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)), &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
&lt;br /&gt;
=== is_empty() ===&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function is_empty() {&lt;br /&gt;
  $this-&amp;gt;get_content();&lt;br /&gt;
  return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
&lt;br /&gt;
=== name() ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function name() {&lt;br /&gt;
  static $myname;&lt;br /&gt;
  if ($myname === NULL) {&lt;br /&gt;
    $myname = strtolower(get_class($this));&lt;br /&gt;
    $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
  }&lt;br /&gt;
  return $myname;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Available in Moodle 1.5 and later&lt;br /&gt;
&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
&lt;br /&gt;
== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ==&lt;br /&gt;
&lt;br /&gt;
=== _add_edit_controls() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _load_instance() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_block() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _print_shadow() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
=== _self_test() ===&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
== Class variables: ==&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;config ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content ===&lt;br /&gt;
&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. &lt;br /&gt;
&lt;br /&gt;
Specifically:&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;text&#039;&#039;&#039; This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
* If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;items&#039;&#039;&#039; This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;icons&#039;&#039;&#039; This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
# &#039;&#039;&#039;footer&#039;&#039;&#039; This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;content_type === &lt;br /&gt;
&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;instance === &lt;br /&gt;
&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;title === &lt;br /&gt;
&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
  // for use. We can now change the title to whatever we want.&lt;br /&gt;
  $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lot of blocks seem to use &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;blockname&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to set the title of the block (and then put a more specific title inside the language file).&lt;br /&gt;
&lt;br /&gt;
If there is no proper language string, the title of the block will then be set to &#039;&#039;blockname&#039;&#039;. If there is another block with the same generic title, then an error will show up: Naming conflict.&lt;br /&gt;
&lt;br /&gt;
To avoid this error on installations with missing language strings, use a more specific name when calling the language string...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, ... );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way all blocks will show up with a unique title in the admin area, even if people have not yet succeeded in placing language files in the correct location&lt;br /&gt;
&lt;br /&gt;
=== $this-&amp;gt;version === &lt;br /&gt;
&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
== Named constants: ==&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_LIST ===&lt;br /&gt;
&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
=== BLOCK_TYPE_TEXT ===&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック/付録A]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2777</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2777"/>
		<updated>2010-04-20T18:05:31Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Eye Candy */ div&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou (pj@moodle.org)&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks/Appendix_B| Appendix B]]).&lt;br /&gt;
&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a &#039;&#039;&#039;reference&#039;&#039;&#039; text should refer to [[Blocks/Appendix_A| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. &lt;br /&gt;
&lt;br /&gt;
Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class block_simplehtml extends block_base {&lt;br /&gt;
  function init() {&lt;br /&gt;
    $this-&amp;gt;title   = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
    $this-&amp;gt;version = 2004111200;&lt;br /&gt;
  }&lt;br /&gt;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| init()]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
  function get_content() {&lt;br /&gt;
    if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
      return $this-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;content         =  new stdClass;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&gt;
&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
    $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;text = &#039;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks/Appendix_A#init.28.29|init()]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks/Appendix_A#specialization.28.29| specialization()]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. &lt;br /&gt;
&lt;br /&gt;
However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| hide_header()]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. &lt;br /&gt;
&lt;br /&gt;
For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) &lt;br /&gt;
             echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
   &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean FALSE) it displays the box as pre-checked (reflecting the current status). &lt;br /&gt;
&lt;br /&gt;
Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behavior: save all variables as $CFG properties&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
  }else {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
&lt;br /&gt;
===String me up ===&lt;br /&gt;
&lt;br /&gt;
Now that we have a working config_global with saved values we want to be able to read the values from it. The simplest way to do this is to assign the config setting to a string and then use the string as we would any other. IE;&lt;br /&gt;
&lt;br /&gt;
$string = $CFG-&amp;gt;configsetting;&lt;br /&gt;
&lt;br /&gt;
You can check all the configuration settings available to a module by displaying them all with;&lt;br /&gt;
&lt;br /&gt;
print_object($CFG);  &lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  // Clean the data if we have to&lt;br /&gt;
  global $CFG;&lt;br /&gt;
  if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
    $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // And now forward to the default implementation defined in the parent class&lt;br /&gt;
  return parent::instance_config_save($data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. &lt;br /&gt;
&lt;br /&gt;
The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
In order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // The preferred value is in pixels&lt;br /&gt;
  return 200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;div&amp;amp;gt; or &amp;amp;lt;table&amp;amp;gt; elements, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we&#039;ll see below).&lt;br /&gt;
&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
    &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). &lt;br /&gt;
&lt;br /&gt;
And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
===and some other useful examples too:===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
    return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    $attrs = parent::html_attributes();&lt;br /&gt;
    // Add your own attributes here, e.g.&lt;br /&gt;
    // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
    return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
&lt;br /&gt;
# The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
# The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
# Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to TRUE, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== Responding to Cron ==&lt;br /&gt;
&lt;br /&gt;
It is possible to have your block respond to the cron process. That is have a method that is run at regular intervals regardless of user interaction. There are two parts to this. Firstly you need to define a new function within your block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
    mtrace( &amp;quot;Hey, my cron script is running&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // do something&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then within your init function you will need to set the (minimum) execution interval for your cron function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this&amp;gt;cron = 300;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will set the minimum interval to 5 minutes. However, the function can only be called as frequently as cron has been set to run in the Moodle installation. Remember that if you change any values in the init function you &#039;&#039;&#039;must&#039;&#039;&#039; bump the version number and visit the Notifications page otherwise they will be ignored.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
The block cron is designed to call the cron script for that block &#039;&#039;&#039;type&#039;&#039;&#039; only. That is, cron does not care about individual instances of blocks. Inside your cron function although $this is defined it has almost nothing in it (only title, content type, version and cron fields are populated). If you need to execute cron for individual instances it is your own responsibility to iterate over them in the block&#039;s cron function. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
&lt;br /&gt;
    // get the block type from the name&lt;br /&gt;
    $blocktype = get_record( &#039;block&#039;, &#039;name&#039;, &#039;my_block_name&#039; );&lt;br /&gt;
&lt;br /&gt;
    // get the instances of the block&lt;br /&gt;
    $instances = get_records( &#039;block_instance&#039;,&#039;blockid&#039;,$blocktype-&amp;gt;id );&lt;br /&gt;
&lt;br /&gt;
    // iterate over the instances&lt;br /&gt;
    foreach ($instances as $instance) {&lt;br /&gt;
&lt;br /&gt;
        // recreate block object&lt;br /&gt;
        $block = block_instance( &#039;my_block_name&#039;, $instance );&lt;br /&gt;
&lt;br /&gt;
        // $block is now the equivalent of $this in &#039;normal&#039; block&lt;br /&gt;
        // usage, e.g.&lt;br /&gt;
        $someconfigitem = $block-&amp;gt;config-&amp;gt;item2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;my_block_name&#039; will coincide with the name of the directory the block is stored in.&lt;br /&gt;
&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function get_content() {&lt;br /&gt;
  if ($this-&amp;gt;content !== null) {&lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content         = new stdClass;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
  // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
  return $this-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== Database support ==&lt;br /&gt;
In case you need to have a database table that holds some specific information that is used with your block. you will need to create a sub folder &#039;&#039;&#039;db&#039;&#039;&#039; and have an &#039;&#039;&#039;install.xml&#039;&#039;&#039; file with the table schema setup.&lt;br /&gt;
&lt;br /&gt;
To create the install.xml file, use the [[XMLDB editor]]. See [[Database_FAQ#XMLDB|Database FAQ &amp;gt; XMLDB]] for further details.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [http://dev.moodle.org/mod/resource/view.php?id=48 Unit 7 of the Introduction to Moodle Programming course] is a follow up to this course. (But you should follow the forum discussions of that course closely as there are still some bugs and inconsistencies.)&lt;br /&gt;
* A [http://cvs.moodle.org/contrib/plugins/blocks/NEWBLOCK/ NEWBLOCK template] you can all use to start you own block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック]]&lt;br /&gt;
[[ru:Development:Blocks]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2776</id>
		<title>Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Blocks&amp;diff=2776"/>
		<updated>2010-04-19T19:05:47Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Appendices */  interwiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou (pj@moodle.org)&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks/Appendix_B| Appendix B]]).&lt;br /&gt;
&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. &lt;br /&gt;
&lt;br /&gt;
Experienced developers and those who just want a &#039;&#039;&#039;reference&#039;&#039;&#039; text should refer to [[Blocks/Appendix_A| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. &lt;br /&gt;
&lt;br /&gt;
Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &#039;&#039;/blocks/simplehtml/&#039;&#039; and creating a file named &#039;&#039;/blocks/simplehtml/&#039;&#039;&#039;&#039;&#039;block_simplehtml.php&#039;&#039;&#039; which will hold our code. We then begin coding the block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
class block_simplehtml extends block_base {&lt;br /&gt;
  function init() {&lt;br /&gt;
    $this-&amp;gt;title   = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
    $this-&amp;gt;version = 2004111200;&lt;br /&gt;
  }&lt;br /&gt;
  // The PHP tag and the curly bracket for the class definition &lt;br /&gt;
  // will only be closed after there is another function added in the next section.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
&lt;br /&gt;
Our class is then given a small method: [[Blocks/Appendix_A#init.28.29| init()]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Etitle| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks#Eye_Candy| how to disable the title&#039;s display]].&lt;br /&gt;
&lt;br /&gt;
[[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. &lt;br /&gt;
&lt;br /&gt;
In our example, this is certainly the case so we just set [[Blocks/Appendix_A#.24this-.3Eversion| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039;&amp;lt;br /&amp;gt; &lt;br /&gt;
Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
  function get_content() {&lt;br /&gt;
    if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
      return $this-&amp;gt;content;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;content         =  new stdClass;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
    $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
}   // Here&#039;s the closing curly bracket for the class definition&lt;br /&gt;
    // and here&#039;s the closing PHP tag from the section above.&lt;br /&gt;
?&amp;gt;  &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it (Click &amp;quot;Notifications&amp;quot; under the Site Administration Block) and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&#039;&#039;&#039;config_instance.html&#039;&#039;&#039;&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
       &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &#039;&#039;&#039;config_instance.html&#039;&#039;&#039; file as instance configuration data. &lt;br /&gt;
&lt;br /&gt;
We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29| init()]].&lt;br /&gt;
&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks/Appendix_A| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in its configuration data. To do that, find this snippet in &#039;&#039;/blocks/simplehtml/block_simplehtml.php&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and change it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text   = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&lt;br /&gt;
    &amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/p&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
&lt;br /&gt;
That&#039;s not too weird, if we think back a bit. Do you remember that [[Blocks/Appendix_A#init.28.29|init()]] method, where we set [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] is definitely not the same as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;title&#039;&#039;&#039; (to Moodle, at least). What we need is a way to update [[Blocks/Appendix_A#.24this-.3Etitle|$this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks/Appendix_A#.24this-.3Econfig| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks/Appendix_A#init.28.29|init()]]! So what can we do?&lt;br /&gt;
&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function specialization() {&lt;br /&gt;
  if(!empty($this-&amp;gt;config-&amp;gt;title)){&lt;br /&gt;
    $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
  }else{&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;title = &#039;Some title ...&#039;;&lt;br /&gt;
  }&lt;br /&gt;
  if(empty($this-&amp;gt;config-&amp;gt;text)){&lt;br /&gt;
    $this-&amp;gt;config-&amp;gt;text = &#039;Some text ...&#039;;&lt;br /&gt;
  }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks/Appendix_A#specialization.28.29| specialization()]] method?&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks/Appendix_A#init.28.29|init()]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks/Appendix_A#specialization.28.29| specialization()]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. &lt;br /&gt;
&lt;br /&gt;
However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;). Moodle performs this check by calling the block&#039;s [[Blocks/Appendix_A#is_empty.28.29| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks/Appendix_A#hide_header.28.29| hide_header()]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_allow_multiple() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks/Appendix_A#instance_allow_multiple.28.29| instance_allow_multiple()]] method, the method [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] that was already defined became obsolete. &lt;br /&gt;
&lt;br /&gt;
Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks/Appendix_A#instance_allow_config.28.29| instance_allow_config()]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. &lt;br /&gt;
&lt;br /&gt;
For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function has_config() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
[[Development_talk:Blocks|TODO: New settings.php method]] &lt;br /&gt;
: Just to note that general documentation about admin settings is at [[Admin_settings#Individual_settings]]. In the absence of documentation, you can look at blocks/course_list, blocks/online_users and blocks/rss_client. They all use a settings.php file.--[[User:Tim Hunt|Tim Hunt]] 19:38, 28 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) &lt;br /&gt;
             echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
   &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean FALSE) it displays the box as pre-checked (reflecting the current status). &lt;br /&gt;
&lt;br /&gt;
Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
&lt;br /&gt;
To round our bag of tricks up, notice that the use of &#039;&#039;if(!empty($CFG-&amp;gt;block_simplehtml_strict))&#039;&#039; in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable &#039;&#039;&#039;$CFG-&amp;gt;block_simplehtml_strict&#039;&#039;&#039; will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== config_save() ===&lt;br /&gt;
&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks/Appendix_A#config_save.28.29| config_save()]], the default implementation of which is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  // Default behavior: save all variables as $CFG properties&lt;br /&gt;
  foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
    set_config($name, $value);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function config_save($data) {&lt;br /&gt;
  if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
  }else {&lt;br /&gt;
    set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
  }&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
&lt;br /&gt;
===String me up ===&lt;br /&gt;
&lt;br /&gt;
Now that we have a working config_global with saved values we want to be able to read the values from it. The simplest way to do this is to assign the config setting to a string and then use the string as we would any other. IE;&lt;br /&gt;
&lt;br /&gt;
$string = $CFG-&amp;gt;configsetting;&lt;br /&gt;
&lt;br /&gt;
You can check all the configuration settings available to a module by displaying them all with;&lt;br /&gt;
&lt;br /&gt;
print_object($CFG);  &lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
=== instance_config_save() ===&lt;br /&gt;
&lt;br /&gt;
Much as we did just before with overriding [[Blocks/Appendix_A#config_save.28.29| config_save()]], what is needed here is overriding the method [[Blocks/Appendix_A#instance_config_save.28.29| instance_config_save()]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  $data = stripslashes_recursive($data);&lt;br /&gt;
  $this-&amp;gt;config = $data;&lt;br /&gt;
  return set_field(&#039;block_instance&#039;, &lt;br /&gt;
                   &#039;configdata&#039;,&lt;br /&gt;
                    base64_encode(serialize($data)),&lt;br /&gt;
                   &#039;id&#039;, &lt;br /&gt;
                   $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function instance_config_save($data) {&lt;br /&gt;
  // Clean the data if we have to&lt;br /&gt;
  global $CFG;&lt;br /&gt;
  if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
    $data-&amp;gt;text = strip_tags($data-&amp;gt;text);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // And now forward to the default implementation defined in the parent class&lt;br /&gt;
  return parent::instance_config_save($data);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. &lt;br /&gt;
&lt;br /&gt;
The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
&lt;br /&gt;
=== Exercise === &lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory exercise for the reader: &lt;br /&gt;
In order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. &lt;br /&gt;
(Hint: Do that in the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method.)&lt;br /&gt;
&lt;br /&gt;
=== UPDATING: === &lt;br /&gt;
Prior to version 1.5, the file &#039;&#039;config_global.html&#039;&#039; was named simply &#039;&#039;config.html&#039;&#039;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function hide_header() {&lt;br /&gt;
  return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks/Appendix_A#init.28.29| init()]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks/Appendix_A#init.28.29| init()]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function preferred_width() {&lt;br /&gt;
  // The preferred value is in pixels&lt;br /&gt;
  return 200;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;table&amp;amp;gt; element, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we&#039;ll see below).&lt;br /&gt;
&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
  return array(&lt;br /&gt;
    &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
    &#039;onmouseover&#039; =&amp;gt; &amp;quot;alert(&#039;Mouseover on our block!&#039;);&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). &lt;br /&gt;
&lt;br /&gt;
And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks/Appendix_A#name.28.29| name()]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
===and some other useful examples too:===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
    return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function html_attributes() {&lt;br /&gt;
    $attrs = parent::html_attributes();&lt;br /&gt;
    // Add your own attributes here, e.g.&lt;br /&gt;
    // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
    return $attrs;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
&lt;br /&gt;
# The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
# The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
# Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
# The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
# The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
# The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to TRUE, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
    &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function applicable_formats() {&lt;br /&gt;
  return array(&lt;br /&gt;
           &#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
          &#039;course-view&#039; =&amp;gt; true, &lt;br /&gt;
   &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &lt;br /&gt;
             &#039;mod-quiz&#039; =&amp;gt; false&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; &amp;lt;br /&amp;gt;&lt;br /&gt;
Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks/Appendix_B| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
&lt;br /&gt;
== Responding to Cron ==&lt;br /&gt;
&lt;br /&gt;
It is possible to have your block respond to the cron process. That is have a method that is run at regular intervals regardless of user interaction. There are two parts to this. Firstly you need to define a new function within your block class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
    mtrace( &amp;quot;Hey, my cron script is running&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
    // do something&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then within your init function you will need to set the (minimum) execution interval for your cron function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $this&amp;gt;cron = 300;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Will set the minimum interval to 5 minutes. However, the function can only be called as frequently as cron has been set to run in the Moodle installation. Remember that if you change any values in the init function you &#039;&#039;&#039;must&#039;&#039;&#039; bump the version number and visit the Notifications page otherwise they will be ignored.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
The block cron is designed to call the cron script for that block &#039;&#039;&#039;type&#039;&#039;&#039; only. That is, cron does not care about individual instances of blocks. Inside your cron function although $this is defined it has almost nothing in it (only title, content type, version and cron fields are populated). If you need to execute cron for individual instances it is your own responsibility to iterate over them in the block&#039;s cron function. Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
function cron() {&lt;br /&gt;
&lt;br /&gt;
    // get the block type from the name&lt;br /&gt;
    $blocktype = get_record( &#039;block&#039;, &#039;name&#039;, &#039;my_block_name&#039; );&lt;br /&gt;
&lt;br /&gt;
    // get the instances of the block&lt;br /&gt;
    $instances = get_records( &#039;block_instance&#039;,&#039;blockid&#039;,$blocktype-&amp;gt;id );&lt;br /&gt;
&lt;br /&gt;
    // iterate over the instances&lt;br /&gt;
    foreach ($instances as $instance) {&lt;br /&gt;
&lt;br /&gt;
        // recreate block object&lt;br /&gt;
        $block = block_instance( &#039;my_block_name&#039;, $instance );&lt;br /&gt;
&lt;br /&gt;
        // $block is now the equivalent of $this in &#039;normal&#039; block&lt;br /&gt;
        // usage, e.g.&lt;br /&gt;
        $someconfigitem = $block-&amp;gt;config-&amp;gt;item2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;my_block_name&#039; will coincide with the name of the directory the block is stored in.&lt;br /&gt;
&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
&lt;br /&gt;
As we have seen so far, blocks use two properties of [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]]: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&lt;br /&gt;
&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method to construct the [[Blocks/Appendix_A#.24this-.3Econtent| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt; &lt;br /&gt;
function get_content() {&lt;br /&gt;
  if ($this-&amp;gt;content !== null) {&lt;br /&gt;
    return $this-&amp;gt;content;&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content         = new stdClass;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons  = array();&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
  $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; class=&amp;quot;icon&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
  // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
  return $this-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks/Appendix_A#get_content.28.29| get_content()]] method. Adding the mandatory [[Blocks/Appendix_A#init.28.29| init()]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
[[#top|Back to top of page]]&lt;br /&gt;
&lt;br /&gt;
== Database support ==&lt;br /&gt;
In case you need to have a database table that holds some specific information that is used with your block. you will need to create a sub folder &#039;&#039;&#039;db&#039;&#039;&#039; and have an &#039;&#039;&#039;install.xml&#039;&#039;&#039; file with the table schema setup.&lt;br /&gt;
&lt;br /&gt;
To create the install.xml file, use the [[XMLDB editor]]. See [[Database_FAQ#XMLDB|Database FAQ &amp;gt; XMLDB]] for further details.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [http://dev.moodle.org/mod/resource/view.php?id=48 Unit 7 of the Introduction to Moodle Programming course] is a follow up to this course. (But you should follow the forum discussions of that course closely as there are still some bugs and inconsistencies.)&lt;br /&gt;
* A [http://cvs.moodle.org/contrib/plugins/blocks/NEWBLOCK/ NEWBLOCK template] you can all use to start you own block.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Appendices ==&lt;br /&gt;
&lt;br /&gt;
The appendices have been moved to separate pages:&lt;br /&gt;
&lt;br /&gt;
* Appendix A: [[Blocks/Appendix A|&#039;&#039;block_base&#039;&#039; Reference]] &lt;br /&gt;
* Appendix B: [[Blocks/Appendix B|Differences in the Blocks API for Moodle Versions prior to 1.5]]&lt;br /&gt;
* Appendix C: [[Blocks/Appendix C|Creating Database Tables for Blocks (prior to 1.7)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;br /&gt;
[[ja:開発:ブロック]]&lt;br /&gt;
[[ru:Development:Blocks]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=851</id>
		<title>Authentication API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=851"/>
		<updated>2010-04-10T20:37:56Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* Optional: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Moodle authentication interface==&lt;br /&gt;
&lt;br /&gt;
Authentication API This file describes Moodle interface functions to authentication modules. (This page is incomplete , I&#039;ll update it after I have phpdoc commented auth/ldap/lib.php)&lt;br /&gt;
&lt;br /&gt;
Most of functions are from ldap-authentication module and are not implemented (yet?) on other modules. Please feel free to extend other modules to support same features or roll your own module.&lt;br /&gt;
&lt;br /&gt;
Some of new function are still tested and are not documented here yet.&lt;br /&gt;
&lt;br /&gt;
==Authentication functions==&lt;br /&gt;
&lt;br /&gt;
Basic functions to authenticate users with external db&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mandatory:===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_login ($username, $password)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Authenticate username, password with userdatabase.&lt;br /&gt;
&lt;br /&gt;
Returns: true if the username and password work and false if they don&#039;t&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Optional:===&lt;br /&gt;
&lt;br /&gt;
Following functions are optional , but if present they extend module usability with Moodle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userinfo($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Query other userinformation from database.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
User information in array &#039;&#039;(name =&amp;gt; value, ...)&#039;&#039; or &#039;&#039;false&#039;&#039; in case of error. Function honors update-flags so if&lt;br /&gt;
&amp;lt;code&amp;gt;$CFG-&amp;gt;auth_user_(atribute)_updatelocal&amp;lt;/code&amp;gt;&lt;br /&gt;
is present, it will return value only if flag is true.&lt;br /&gt;
&lt;br /&gt;
===COURSE CREATING===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_iscreator($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
should user have rights to create courses&lt;br /&gt;
&lt;br /&gt;
Returns: True if user has rights to create cources otherwise false&lt;br /&gt;
&lt;br /&gt;
===USER CREATION===&lt;br /&gt;
&lt;br /&gt;
Functions that enable user creation, activation and deactivation from moodle to external database&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_exists ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Checks if given username exists on external db&lt;br /&gt;
&lt;br /&gt;
Returns: true if given usernname exist or false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_create ($userobject,$plainpass)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Creates new user to external db. User should be created in inactive stage until confirmed by email.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_activate ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
activate new user after email-address is confirmed&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_disable ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
deactivate user in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
=== USER INFORMATION AND SYNCRONIZATION ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userlist ()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get list of usernames in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: All usernames in array or false on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_users($filter=&#039;*&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get ALL USEROBJECTS FROM EXTERNAL DB.&lt;br /&gt;
&lt;br /&gt;
Returns: Array of all users as objects from external db &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication API]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=850</id>
		<title>Authentication API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=850"/>
		<updated>2010-04-10T20:23:02Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* USER CREATION */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Moodle authentication interface==&lt;br /&gt;
&lt;br /&gt;
Authentication API This file describes Moodle interface functions to authentication modules. (This page is incomplete , I&#039;ll update it after I have phpdoc commented auth/ldap/lib.php)&lt;br /&gt;
&lt;br /&gt;
Most of functions are from ldap-authentication module and are not implemented (yet?) on other modules. Please feel free to extend other modules to support same features or roll your own module.&lt;br /&gt;
&lt;br /&gt;
Some of new function are still tested and are not documented here yet.&lt;br /&gt;
&lt;br /&gt;
==Authentication functions==&lt;br /&gt;
&lt;br /&gt;
Basic functions to authenticate users with external db&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mandatory:===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_login ($username, $password)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Authenticate username, password with userdatabase.&lt;br /&gt;
&lt;br /&gt;
Returns: true if the username and password work and false if they don&#039;t&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Optional:===&lt;br /&gt;
&lt;br /&gt;
Following functions are optional , but if present they extend module usability with Moodle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userinfo($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Query other userinformation from database.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
User information in array ( name =&amp;gt; value, .... or false in case of error Function honors update-flags so if&lt;br /&gt;
$CFG-&amp;gt;auth_user_(atribute)_updatelocal&lt;br /&gt;
is present, it will return value only if flag is true.&lt;br /&gt;
&lt;br /&gt;
===COURSE CREATING===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_iscreator($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
should user have rights to create courses&lt;br /&gt;
&lt;br /&gt;
Returns: True if user has rights to create cources otherwise false&lt;br /&gt;
&lt;br /&gt;
===USER CREATION===&lt;br /&gt;
&lt;br /&gt;
Functions that enable user creation, activation and deactivation from moodle to external database&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_exists ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Checks if given username exists on external db&lt;br /&gt;
&lt;br /&gt;
Returns: true if given usernname exist or false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_create ($userobject,$plainpass)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Creates new user to external db. User should be created in inactive stage until confirmed by email.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_activate ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
activate new user after email-address is confirmed&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_disable ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
deactivate user in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
=== USER INFORMATION AND SYNCRONIZATION ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userlist ()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get list of usernames in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: All usernames in array or false on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_users($filter=&#039;*&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get ALL USEROBJECTS FROM EXTERNAL DB.&lt;br /&gt;
&lt;br /&gt;
Returns: Array of all users as objects from external db &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication API]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=849</id>
		<title>Authentication API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Authentication_API&amp;diff=849"/>
		<updated>2010-04-10T20:14:56Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: /* USER CREATION */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Moodle authentication interface==&lt;br /&gt;
&lt;br /&gt;
Authentication API This file describes Moodle interface functions to authentication modules. (This page is incomplete , I&#039;ll update it after I have phpdoc commented auth/ldap/lib.php)&lt;br /&gt;
&lt;br /&gt;
Most of functions are from ldap-authentication module and are not implemented (yet?) on other modules. Please feel free to extend other modules to support same features or roll your own module.&lt;br /&gt;
&lt;br /&gt;
Some of new function are still tested and are not documented here yet.&lt;br /&gt;
&lt;br /&gt;
==Authentication functions==&lt;br /&gt;
&lt;br /&gt;
Basic functions to authenticate users with external db&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Mandatory:===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_login ($username, $password)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Authenticate username, password with userdatabase.&lt;br /&gt;
&lt;br /&gt;
Returns: true if the username and password work and false if they don&#039;t&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Optional:===&lt;br /&gt;
&lt;br /&gt;
Following functions are optional , but if present they extend module usability with Moodle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userinfo($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Query other userinformation from database.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
&lt;br /&gt;
User information in array ( name =&amp;gt; value, .... or false in case of error Function honors update-flags so if&lt;br /&gt;
$CFG-&amp;gt;auth_user_(atribute)_updatelocal&lt;br /&gt;
is present, it will return value only if flag is true.&lt;br /&gt;
&lt;br /&gt;
===COURSE CREATING===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_iscreator($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
should user have rights to create courses&lt;br /&gt;
&lt;br /&gt;
Returns: True if user has rights to create cources otherwise false&lt;br /&gt;
&lt;br /&gt;
===USER CREATION===&lt;br /&gt;
&lt;br /&gt;
Functions that enable user creation, activation and deactivation from moodle to external database&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_exists ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Checks if given username exists on external db&lt;br /&gt;
&lt;br /&gt;
Returns: true if given usernname exist or false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_create ($userobject,$plainpass)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Creates new user to external db. User should be created in inactive stage until confirmed by email.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_activate ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
activate new user after email-address is confirmed&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_user_disable ($username)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
deactivate user in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: True on success otherwise false&lt;br /&gt;
&lt;br /&gt;
USER INFORMATION AND SYNCRONIZATION&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_userlist ()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get list of usernames in external db.&lt;br /&gt;
&lt;br /&gt;
Returns: All usernames in array or false on error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;auth_get_users($filter=&#039;*&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get ALL USEROBJECTS FROM EXTERNAL DB.&lt;br /&gt;
&lt;br /&gt;
Returns: Array of all users as objects from external db &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication API]]&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:%D0%AE%D1%80%D0%B8%D0%B9_%D0%92%D0%B0%D1%81%D0%B8%D0%BD&amp;diff=22356</id>
		<title>User:Юрий Васин</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:%D0%AE%D1%80%D0%B8%D0%B9_%D0%92%D0%B0%D1%81%D0%B8%D0%BD&amp;diff=22356"/>
		<updated>2010-04-09T12:44:12Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visit my main page in Moodle writing in russian language [[:ru:Участник:Юрий_Васин|User:Юрий Васин]] or [http://en.wikipedia.org/wiki/User:Inc_ru my page in Wikipedia].&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:%D0%AE%D1%80%D0%B8%D0%B9_%D0%92%D0%B0%D1%81%D0%B8%D0%BD&amp;diff=22355</id>
		<title>User:Юрий Васин</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:%D0%AE%D1%80%D0%B8%D0%B9_%D0%92%D0%B0%D1%81%D0%B8%D0%BD&amp;diff=22355"/>
		<updated>2010-04-09T12:43:06Z</updated>

		<summary type="html">&lt;p&gt;Ink-ru: New page: Visit my main page in Moodle writing in russian language :ru:Участник:Юрий_Васин or [http://en.wikipedia.org/wiki/User:Inc_ru my page in Wikipedia].&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Visit my main page in Moodle writing in russian language [[:ru:Участник:Юрий_Васин]] or [http://en.wikipedia.org/wiki/User:Inc_ru my page in Wikipedia].&lt;/div&gt;</summary>
		<author><name>Ink-ru</name></author>
	</entry>
</feed>