<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/38/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolasconnault</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/38/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolasconnault"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/Special:Contributions/Nicolasconnault"/>
	<updated>2026-04-18T05:42:58Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=User:Nicolas_Connault&amp;diff=73828</id>
		<title>User:Nicolas Connault</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=User:Nicolas_Connault&amp;diff=73828"/>
		<updated>2010-07-11T11:21:46Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Removing all content from page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=User:Nicolas_Connault&amp;diff=64701</id>
		<title>User:Nicolas Connault</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=User:Nicolas_Connault&amp;diff=64701"/>
		<updated>2009-10-26T22:31:42Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Contact Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Contact Details==&lt;br /&gt;
 ICQ: 826611&lt;br /&gt;
 Yahoo : nicolasconnault&lt;br /&gt;
 AIM: NikoZeta&lt;br /&gt;
 Skype: nicolasconnault&lt;br /&gt;
 Email: nicolasconnault@gmail.com&lt;br /&gt;
 Cell: 0435423748&lt;br /&gt;
&lt;br /&gt;
==First steps towards Moodle==&lt;br /&gt;
Born in 1978 in France, I have 4 brothers and 1 sister. At age 19, I spent 2 years on a mission in England for the [http://www.mormon.org Church of Jesus Christ of Latter-Day Saints]. There I learned much about human nature and saw much misery and suffering, mostly caused by dysfunctional relationships between people, especially in families. I decided I would study psychology and become a family counselor, to help alleviate the hurt I saw all around me.&lt;br /&gt;
&lt;br /&gt;
I returned home to France in 2000, and shortly thereafter met my wife Anne-Marie while chatting on ICQ. We discovered we had similar interests, beliefs and values, and within 2 weeks (!?) I proposed to her over the Internet. I hadn&#039;t yet seen a picture of her. To me, physical appearance was not a concern.&lt;br /&gt;
&lt;br /&gt;
She came over to France 6 (long!) months later, and we were married in France (civilly) and in England (for eternity in the Temple). A few months later we moved to England for a job which did not work out as expected, following which we moved to Western Australia in 2001.&lt;br /&gt;
&lt;br /&gt;
==University and Self-teaching==&lt;br /&gt;
There I started taking interest in Web Development as a hobby (I had already built a couple of static websites as a youth), and used the many resources available online to teach myself LAMP/WAMP development. When I started my psychology degree (externally at Edith Cowan University), I chose a minor in professional computing, which included Object-Oriented programming, Database design and Web Development, but these added little to the knowledge I had already gained through learning online. The vibrant PHP community was the greatest source of learning for me.&lt;br /&gt;
&lt;br /&gt;
A few years ago I undertook my first serious open source project with two other friends, Christopher Vance and Vickie Comrie (both from the USA). The project was a PHP auction framework, along the lines of Ebay but much more simple, which could be implemented by small companies wanting an auction system. It was a voluntary project for a fairly large american charity. This project hasn&#039;t been maintained for years, and I would probably cringe if I looked at the source code now, but the skills I learned while working on it have proven invaluable.&lt;br /&gt;
&lt;br /&gt;
The code for the auction project attracted the attention of a small web development company, Triangle Solutions, who contracted me immediately on a part-time basis, later to become full-time. During the 1.5 years I worked for Triangle, I contributed to many different projects, but the most important was PHP Support Tickets, an application originally written in horrible spaghetti PHP which I was asked to upgrade. My decision was to rewrite it using Object-Oriented principles, of which I knew enough to improve the application at the time. Unfortunately I did not have the time resources available to devote enough time on this project, which greatly hindered its development. I still think it has great potential, but I would certainly refactor it if I had the opportunity to work on it again.&lt;br /&gt;
&lt;br /&gt;
==Beginnings at Moodle HQ==&lt;br /&gt;
In December 2006, I applied for the developer position at Moodle HQ in Perth, and was hired on a full-time basis. I started out doing mainly bug-squashing for version 1.8, but was also made responsible for unit testing, an area which had been greatly neglected until then. As soon as 1.8 was stable and released, I started working on the new gradebook internals for 1.9, together with Yu Zhang, Martin Dougiamas and Petr Skoda.&lt;br /&gt;
&lt;br /&gt;
==Other programming interests==&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
One last note on development: I have recently taken great interest in the Ruby language, although that interest started much earlier than the current Ruby on Rails craze. I find the language extremely elegant, intuitive and fun to write in. It enables me to be much more creative than with PHP or Java. I also enjoy the Rails framework, although it certainly isn&#039;t as easy to learn as some people would have you believe. I am currently working on a real estate application (sales and rentals) written on that platform. You can see the front-end for one of my clients at [http://www.glenmarrealty.com.au Glenmar Realty].&lt;br /&gt;
&lt;br /&gt;
=== Test-Driven Development (TDD) ===&lt;br /&gt;
Since my early days with Object-Oriented languages, I have been a strong proponent of unit testing, and a keen supporter of the Test-Driven Development approach. Unfortunately it is not always easy to adopt such methodology when working on a project like Moodle, with much legacy and non-OO code. The approach was successfully used when developing the new gradebook for Moodle 1.9, although it could have used better. &lt;br /&gt;
&lt;br /&gt;
In the last 6 months I have given 3 presentations on the subject of Unit Testing. One was at the [http://elearning.lse.ac.uk/blogs/clt/?p=251 2007 UK Moodle Moot], and the other two were given at two different branches of the BCS, [http://nottmderby.bcs.org/events08-feb.htm Derby-Nottingham] and [http://www.herts.bcs.org/past.htm Hertfordshire]. [http://moodlemoot.org/file.php/4/moddata/assignment/1/438/presentation.ppt My slides] are available at these sites, but there are minor differences between them, since I try to improve my presentation each time.&lt;br /&gt;
&lt;br /&gt;
==Psychology==&lt;br /&gt;
On the topic of psychology: during my external studies, I became more and more disillusioned with the traditional counseling practice. I felt that, although the intentions of most professional psychologists were noble, their skills were often exercised within an ideological framework of manufactured needs. This meant that often, their contributions to the well-being of the human race were more imagined than real.&lt;br /&gt;
&lt;br /&gt;
My interests diverged towards community development, group processes, interpersonal relationships, child development and the learning process. I became aware that people tended to get better emotionally when they had a strong support network, and that non-professional assistance in the form of support groups was often more effective than prohibitory and extensive therapy sessions.&lt;br /&gt;
&lt;br /&gt;
I also became more and more disenchanted with the educational practices of the universities in Australia. They seemed to be based on ancient traditions and to ignore the very principles they were teaching. I especially abhorred the lecture medium of teaching, which was one reason why I chose to study externally. However I did a few units on campus and was glad to see some tutors trying to change their delivery methods to something more informal and participative. Overall I was extremely disappointed in the appalling quality of external teaching. It was extremely difficult to connect with other students, and you only got help if you persistently sought for it. Feedback was as rare (and precious) as gold. BlackBoard was inadequate in many ways, and most tutors didn&#039;t even use it. The drop-out rates from external courses was so great that it was very difficult to extract that figure from university staff. I wouldn&#039;t be surprised if only around 10% of all external students across all Australian universities actually stuck to their entire course, not to mention those who stay but fail.&lt;br /&gt;
&lt;br /&gt;
My project for the honours degree (which I have delayed for next year) was to compare the teaching methods of a German university with those of Edith Cowan University, and to compare the measurable results. The project for my doctorate was to develop an online, open source software suite that would enable external students to connect with each other as a vibrant community, in order to facilitate self-motivated learning and participation. This was a major factor in me accepting the job with Moodle, which represented exactly what I had in mind.&lt;br /&gt;
&lt;br /&gt;
Well, this is a rather lengthy description, but those that have read all of it now know a lot about me, and will be better able to understand the person behind the posts and the code.&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64612</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64612"/>
		<updated>2009-10-22T23:44:22Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* External blogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
Before 2.0 there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this could lead to serious performance and usability issues on large sites, and was turning the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
This simplification means that sites using the old BLOG_GROUP_LEVEL and BLOG_COURSE_LEVEL and values of $CFG-&amp;gt;bloglevel have to perform an special upgrade which copies all the site&#039;s blog entries into a special &amp;quot;blog-type&amp;quot; forum in each course in which the blog entry&#039;s author is enrolled, then disables blogging at site level.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with an activity module.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can specify external blogs which publish an RSS/ATOM feed. This feed is then checked periodically through a cron task, and entries are copied into the user&#039;s blog in Moodle, as read-only entries.&lt;br /&gt;
&lt;br /&gt;
This synchronisation checks if external entries have been modified or deleted since the last sync, and updates the Moodle entries accordingly.&lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;Filter tags&amp;quot; and &amp;quot;Automatic tags&amp;quot;:&lt;br /&gt;
*Filter tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog. An external entry will be selected if it has at least one of the filter tags. (Tags are called &amp;quot;categories&amp;quot; in RSS feeds)&lt;br /&gt;
*Automatic tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
===Upgrade from &amp;quot;Users can only see blogs for people who share a course&amp;quot;===&lt;br /&gt;
&lt;br /&gt;
This mode was always a slightly quirky and uncomfortable hack.  It was mostly useful for sites with very distinct courses and users, such as those where each course consists of the employees from a separate company, and My Moodle was used to hide the companies from each other.  However, for the general case, the main problem is that you see ALL blog entries from those people, not just ones that are about your courses.  &lt;br /&gt;
&lt;br /&gt;
This mode has no direct equivalent in Moodle 2.0 because we have resolved not to emulate &amp;quot;course-like&amp;quot; modes within a system that is at system level, and outside the courses.  This helps understanding of the blog system, simplifies the implementation and improves performance.  &lt;br /&gt;
&lt;br /&gt;
However some people may be using that mode so we do need to provide an upgrade path for them.&lt;br /&gt;
&lt;br /&gt;
Informationally, the idea of just seeing all the blogs from people who are in your course is the same as a course forum. &lt;br /&gt;
&lt;br /&gt;
So a possible upgrade would be to do this:&lt;br /&gt;
 If the mode is set to &amp;quot;Users can only see blogs for people who share a course&amp;quot; then&lt;br /&gt;
   Set the new mode to &amp;quot;Users can only see their own blog&amp;quot;&lt;br /&gt;
   Foreach user who has a blog &lt;br /&gt;
     Foreach course that user is enrolled in &lt;br /&gt;
        If a &amp;quot;Course blogs (recovered)&amp;quot; forum doesn&#039;t exist yet in the course (section 0) then create one&lt;br /&gt;
        Foreach blog entry that the user created &lt;br /&gt;
           Create a new discussion from the blog post with the same dates, attachments etc&lt;br /&gt;
&lt;br /&gt;
This way no data is lost.  The teachers can choose to delete the whole forum if they choose to.  The original blog entries should not be touched.&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| failedlastsync&lt;br /&gt;
| int(1)&lt;br /&gt;
|&lt;br /&gt;
| Whether or not the last synchronisation failed&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64577</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64577"/>
		<updated>2009-10-22T08:56:15Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* blog_external */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
Before 2.0 there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this could lead to serious performance and usability issues on large sites, and was turning the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
This simplification means that sites using the old BLOG_GROUP_LEVEL and BLOG_COURSE_LEVEL and values of $CFG-&amp;gt;bloglevel have to perform an special upgrade which copies all the site&#039;s blog entries into a special &amp;quot;blog-type&amp;quot; forum in each course in which the blog entry&#039;s author is enrolled, then disables blogging at site level.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with an activity module.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
===Upgrade from &amp;quot;Users can only see blogs for people who share a course&amp;quot;===&lt;br /&gt;
&lt;br /&gt;
This mode was always a slightly quirky and uncomfortable hack.  It was mostly useful for sites with very distinct courses and users, such as those where each course consists of the employees from a separate company, and My Moodle was used to hide the companies from each other.  However, for the general case, the main problem is that you see ALL blog entries from those people, not just ones that are about your courses.  &lt;br /&gt;
&lt;br /&gt;
This mode has no direct equivalent in Moodle 2.0 because we have resolved not to emulate &amp;quot;course-like&amp;quot; modes within a system that is at system level, and outside the courses.  This helps understanding of the blog system, simplifies the implementation and improves performance.  &lt;br /&gt;
&lt;br /&gt;
However some people may be using that mode so we do need to provide an upgrade path for them.&lt;br /&gt;
&lt;br /&gt;
Informationally, the idea of just seeing all the blogs from people who are in your course is the same as a course forum. &lt;br /&gt;
&lt;br /&gt;
So a possible upgrade would be to do this:&lt;br /&gt;
 If the mode is set to &amp;quot;Users can only see blogs for people who share a course&amp;quot; then&lt;br /&gt;
   Set the new mode to &amp;quot;Users can only see their own blog&amp;quot;&lt;br /&gt;
   Foreach user who has a blog &lt;br /&gt;
     Foreach course that user is enrolled in &lt;br /&gt;
        If a &amp;quot;Course blogs (recovered)&amp;quot; forum doesn&#039;t exist yet in the course (section 0) then create one&lt;br /&gt;
        Foreach blog entry that the user created &lt;br /&gt;
           Create a new discussion from the blog post with the same dates, attachments etc&lt;br /&gt;
&lt;br /&gt;
This way no data is lost.  The teachers can choose to delete the whole forum if they choose to.  The original blog entries should not be touched.&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| failedlastsync&lt;br /&gt;
| int(1)&lt;br /&gt;
|&lt;br /&gt;
| Whether or not the last synchronisation failed&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64576</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64576"/>
		<updated>2009-10-22T08:52:04Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* blog_external */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
Before 2.0 there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this could lead to serious performance and usability issues on large sites, and was turning the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
This simplification means that sites using the old BLOG_GROUP_LEVEL and BLOG_COURSE_LEVEL and values of $CFG-&amp;gt;bloglevel have to perform an special upgrade which copies all the site&#039;s blog entries into a special &amp;quot;blog-type&amp;quot; forum in each course in which the blog entry&#039;s author is enrolled, then disables blogging at site level.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with an activity module.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
===Upgrade from &amp;quot;Users can only see blogs for people who share a course&amp;quot;===&lt;br /&gt;
&lt;br /&gt;
This mode was always a slightly quirky and uncomfortable hack.  It was mostly useful for sites with very distinct courses and users, such as those where each course consists of the employees from a separate company, and My Moodle was used to hide the companies from each other.  However, for the general case, the main problem is that you see ALL blog entries from those people, not just ones that are about your courses.  &lt;br /&gt;
&lt;br /&gt;
This mode has no direct equivalent in Moodle 2.0 because we have resolved not to emulate &amp;quot;course-like&amp;quot; modes within a system that is at system level, and outside the courses.  This helps understanding of the blog system, simplifies the implementation and improves performance.  &lt;br /&gt;
&lt;br /&gt;
However some people may be using that mode so we do need to provide an upgrade path for them.&lt;br /&gt;
&lt;br /&gt;
Informationally, the idea of just seeing all the blogs from people who are in your course is the same as a course forum. &lt;br /&gt;
&lt;br /&gt;
So a possible upgrade would be to do this:&lt;br /&gt;
 If the mode is set to &amp;quot;Users can only see blogs for people who share a course&amp;quot; then&lt;br /&gt;
   Set the new mode to &amp;quot;Users can only see their own blog&amp;quot;&lt;br /&gt;
   Foreach user who has a blog &lt;br /&gt;
     Foreach course that user is enrolled in &lt;br /&gt;
        If a &amp;quot;Course blogs (recovered)&amp;quot; forum doesn&#039;t exist yet in the course (section 0) then create one&lt;br /&gt;
        Foreach blog entry that the user created &lt;br /&gt;
           Create a new discussion from the blog post with the same dates, attachments etc&lt;br /&gt;
&lt;br /&gt;
This way no data is lost.  The teachers can choose to delete the whole forum if they choose to.  The original blog entries should not be touched.&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| validationresult&lt;br /&gt;
| int(1)&lt;br /&gt;
|&lt;br /&gt;
| A cached boolean of the last Feed validation test&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64418</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64418"/>
		<updated>2009-10-15T03:02:29Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Who can view blog entries? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
Before 2.0 there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this could lead to serious performance and usability issues on large sites, and was turning the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
This simplification means that sites using the old BLOG_GROUP_LEVEL and BLOG_COURSE_LEVEL and values of $CFG-&amp;gt;bloglevel have to perform an special upgrade which copies all the site&#039;s blog entries into a special &amp;quot;blog-type&amp;quot; forum in each course in which the blog entry&#039;s author is enrolled, then disables blogging at site level.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with an activity module.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
===Upgrade from &amp;quot;Users can only see blogs for people who share a course&amp;quot;===&lt;br /&gt;
&lt;br /&gt;
This mode was always a slightly quirky and uncomfortable hack.  It was mostly useful for sites with very distinct courses and users, such as those where each course consists of the employees from a separate company, and My Moodle was used to hide the companies from each other.  However, for the general case, the main problem is that you see ALL blog entries from those people, not just ones that are about your courses.  &lt;br /&gt;
&lt;br /&gt;
This mode has no direct equivalent in Moodle 2.0 because we have resolved not to emulate &amp;quot;course-like&amp;quot; modes within a system that is at system level, and outside the courses.  This helps understanding of the blog system, simplifies the implementation and improves performance.  &lt;br /&gt;
&lt;br /&gt;
However some people may be using that mode so we do need to provide an upgrade path for them.&lt;br /&gt;
&lt;br /&gt;
Informationally, the idea of just seeing all the blogs from people who are in your course is the same as a course forum. &lt;br /&gt;
&lt;br /&gt;
So a possible upgrade would be to do this:&lt;br /&gt;
 If the mode is set to &amp;quot;Users can only see blogs for people who share a course&amp;quot; then&lt;br /&gt;
   Set the new mode to &amp;quot;Users can only see their own blog&amp;quot;&lt;br /&gt;
   Foreach user who has a blog &lt;br /&gt;
     Foreach course that user is enrolled in &lt;br /&gt;
        If a &amp;quot;Course blogs (recovered)&amp;quot; forum doesn&#039;t exist yet in the course (section 0) then create one&lt;br /&gt;
        Foreach blog entry that the user created &lt;br /&gt;
           Create a new discussion from the blog post with the same dates, attachments etc&lt;br /&gt;
&lt;br /&gt;
This way no data is lost.  The teachers can choose to delete the whole forum if they choose to.  The original blog entries should not be touched.&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64417</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=64417"/>
		<updated>2009-10-15T02:45:30Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Associations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with an activity module.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
===Upgrade from &amp;quot;Users can only see blogs for people who share a course&amp;quot;===&lt;br /&gt;
&lt;br /&gt;
This mode was always a slightly quirky and uncomfortable hack.  It was mostly useful for sites with very distinct courses and users, such as those where each course consists of the employees from a separate company, and My Moodle was used to hide the companies from each other.  However, for the general case, the main problem is that you see ALL blog entries from those people, not just ones that are about your courses.  &lt;br /&gt;
&lt;br /&gt;
This mode has no direct equivalent in Moodle 2.0 because we have resolved not to emulate &amp;quot;course-like&amp;quot; modes within a system that is at system level, and outside the courses.  This helps understanding of the blog system, simplifies the implementation and improves performance.  &lt;br /&gt;
&lt;br /&gt;
However some people may be using that mode so we do need to provide an upgrade path for them.&lt;br /&gt;
&lt;br /&gt;
Informationally, the idea of just seeing all the blogs from people who are in your course is the same as a course forum. &lt;br /&gt;
&lt;br /&gt;
So a possible upgrade would be to do this:&lt;br /&gt;
 If the mode is set to &amp;quot;Users can only see blogs for people who share a course&amp;quot; then&lt;br /&gt;
   Set the new mode to &amp;quot;Users can only see their own blog&amp;quot;&lt;br /&gt;
   Foreach user who has a blog &lt;br /&gt;
     Foreach course that user is enrolled in &lt;br /&gt;
        If a &amp;quot;Course blogs (recovered)&amp;quot; forum doesn&#039;t exist yet in the course (section 0) then create one&lt;br /&gt;
        Foreach blog entry that the user created &lt;br /&gt;
           Create a new discussion from the blog post with the same dates, attachments etc&lt;br /&gt;
&lt;br /&gt;
This way no data is lost.  The teachers can choose to delete the whole forum if they choose to.  The original blog entries should not be touched.&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63672</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63672"/>
		<updated>2009-09-30T07:12:00Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Search blog entries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:search&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63671</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63671"/>
		<updated>2009-09-30T07:00:56Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Who can view blog entries? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:view&lt;br /&gt;
*moodle/blog:viewdrafts&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63670</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63670"/>
		<updated>2009-09-30T07:00:03Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* External blogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
Capabilities:&lt;br /&gt;
*moodle/blog:manageexternal&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63669</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63669"/>
		<updated>2009-09-30T06:59:11Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Associations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
Capabilities: &lt;br /&gt;
*moodle/blog:associatecourse&lt;br /&gt;
*moodle/blog:associatemodule&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63563</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63563"/>
		<updated>2009-09-25T08:48:49Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Add section on gotchas&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;filetypes&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;filetypes&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;filetypes:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/file/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES, &#039;filearea&#039; =&amp;gt; &#039;glossary_entry&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, filearea, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot; : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php.&lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Handling submitted data ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
=== Gotchas ===&lt;br /&gt;
A few things to keep in mind:&lt;br /&gt;
* Make sure that you instantiate the moodle form before any call to $OUTPUT-&amp;gt;header()&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63562</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63562"/>
		<updated>2009-09-25T08:35:10Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Preparing your options */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;filetypes&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;filetypes&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;filetypes:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/file/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES, &#039;filearea&#039; =&amp;gt; &#039;glossary_entry&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, filearea, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot; : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php.&lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Handling submitted data ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63559</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63559"/>
		<updated>2009-09-25T07:42:02Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Submitted data handling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;filetypes&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;filetypes&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;filetypes:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/file/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES, &#039;filearea&#039; =&amp;gt; &#039;glossary_entry&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, filearea, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot; : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php. &lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Handling submitted data ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63558</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63558"/>
		<updated>2009-09-25T07:38:14Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Element preparation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;filetypes&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;filetypes&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;filetypes:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/file/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES, &#039;filearea&#039; =&amp;gt; &#039;glossary_entry&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, filearea, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot; : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php. &lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
*# You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Submitted data handling ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63557</id>
		<title>Development:Using the File API in Moodle forms</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API_in_Moodle_forms&amp;diff=63557"/>
		<updated>2009-09-25T07:37:02Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Adding a conversion tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to get files from users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 all files are stored in a central database accessible via the [[Development:File API|File API]], and every file is associated with a &amp;quot;file area&amp;quot; in Moodle, such as a particular module.&lt;br /&gt;
&lt;br /&gt;
A common use case is to provide a form (using Moodle&#039;s [[Development:lib/formslib.php|Forms API]]) which allows users to upload or import files as attachments or media embedded into HTML.&lt;br /&gt;
&lt;br /&gt;
Normally this works like this:&lt;br /&gt;
# User starts creation or re-edits an existing item in Moodle (eg forum post, resource, glossary entry etc)&lt;br /&gt;
# User presses some sort of button to browse for new files to attach or embed&lt;br /&gt;
# User sees our &amp;quot;Choose file...&amp;quot; dialog, which contains one or more repository instances. &lt;br /&gt;
# User chooses a file, the [[Development:Repository API|Repository API]] takes care of copying the file into a &amp;quot;draft file area&amp;quot; within Moodle&lt;br /&gt;
# File appears in the text or as an attachment in the form.&lt;br /&gt;
# When the user hits save, the [[Development:File API|File API]] is invoked to move the file from the draft file area into a permanent file area associated with that data &lt;br /&gt;
&lt;br /&gt;
This document shows you exactly how to use Moodle forms to interact with users in a standard and secure way.&lt;br /&gt;
&lt;br /&gt;
If you just want to write code to manipulate Moodle files internally (without user input) then see [[Development:Using_the_File_API]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form elements== &lt;br /&gt;
&lt;br /&gt;
In Moodle 2.0 there are three file-related form elements for interacting with users:&lt;br /&gt;
&lt;br /&gt;
# filemanager - the way to attach one or more files as a set&lt;br /&gt;
# editor - the way to specify a textarea with a HTML editor, and all the handling of images and movies within that HTML&lt;br /&gt;
# filepicker - a way to specify one file for the case when you want to process the file and throw it away &lt;br /&gt;
&lt;br /&gt;
In Moodle 1.9 there were two other types which are now &#039;&#039;&#039;deprecated&#039;&#039;&#039; (they work, but please do not use these anymore)&lt;br /&gt;
# file - used to just allow a normal file upload from the desktop only.&lt;br /&gt;
# htmleditor - this old method of embedding a HTML editor in a textarea is not able to support repositories etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===filepicker===&lt;br /&gt;
&lt;br /&gt;
File picker (&#039;&#039;filepicker&#039;&#039;) is a direct replacement of the older &#039;&#039;file&#039;&#039; formslib element. &lt;br /&gt;
&lt;br /&gt;
It is intended for situations when you want the user to upload &#039;&#039;&#039;one&#039;&#039;&#039; file so you can process it and delete it, such as when you are importing data from a CSV file.&lt;br /&gt;
&lt;br /&gt;
==== Using the filepicker element ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filepicker&#039;, &#039;userfile&#039;, get_string(&#039;file&#039;), null, array(&#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;filetypes&#039; =&amp;gt; &#039;*&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Obtain the chosen file ====&lt;br /&gt;
&lt;br /&gt;
The API for getting file contents is exactly the same as for &#039;&#039;file&#039;&#039; element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$content = $mform-&amp;gt;get_file_content(&#039;userfile&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== filemanager ===&lt;br /&gt;
&lt;br /&gt;
The File Manager element improves on file picker by allowing you to manage more than one file.  It is expected that the files will be stored permanently for future use (such as forum and glossary attachments).&lt;br /&gt;
&lt;br /&gt;
==== Add file manager element ====&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachments&#039;, get_string(&#039;attachment&#039;, &#039;moodle&#039;), null,&lt;br /&gt;
                    array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50, &#039;filetypes&#039; =&amp;gt; array(&#039;document&#039;) ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the fields for filemanager:&lt;br /&gt;
&lt;br /&gt;
;&#039;filemanager&#039;:This is a filemanager element :)&lt;br /&gt;
;elementname:The unique name of the element in the form&lt;br /&gt;
;elementlabel:The label string that users see &lt;br /&gt;
;attributes:(leave it as null)&lt;br /&gt;
;options: an array of further options for the filepicker (see below)&lt;br /&gt;
&lt;br /&gt;
The options array can contain:&lt;br /&gt;
&lt;br /&gt;
;subdirs:(Default 0) Are subdirectories allowed?  (true or false)&lt;br /&gt;
;maxbytes:(Default 0) Restricts the total size of all the files.&lt;br /&gt;
;maxfiles:(Default -1) Restricts the total number of files.&lt;br /&gt;
;filetypes:(Default *) You can specify what file types are accepted by filemanager.  All current file types are listed in this file: [http://cvs.moodle.org/moodle/lib/file/file_types.mm moodle/lib/file/file_types.mm].  This is a [http://freemind.sourceforge.net/wiki/index.php/Main_Page freemind] file: if it is edited the changes will be immediately reflected in Moodle.  Example usage:  &#039;&#039;&#039;array(&#039;audio&#039;, &#039;video&#039;, &#039;documents&#039;)&#039;&#039;&#039;, you can include file extensions as well, for example: &#039;&#039;&#039;array(&#039;*.txt&#039;, &#039;*.jpg&#039;, &#039;audio&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Load existing files into draft area ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
    $entry = new object();&lt;br /&gt;
    $entry-&amp;gt;id = null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftitemid = file_get_submitted_draft_itemid(&#039;attachments&#039;);&lt;br /&gt;
file_prepare_draft_area($draftitemid, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
$entry-&amp;gt;attachments = $draftitemid;&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Store updated set of files ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // ... store or update $entry&lt;br /&gt;
    file_save_draft_area_files($data-&amp;gt;attachments, $context-&amp;gt;id, &#039;glossary_attachment&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039; =&amp;gt; 0, &#039;maxbytes&#039; =&amp;gt; $maxbytes, &#039;maxfiles&#039; =&amp;gt; 50));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===editor===&lt;br /&gt;
There are two way for using of editor element in code, the first one is easier but expects some standardized fields. The second method is more low level.&lt;br /&gt;
&lt;br /&gt;
====Simple use====&lt;br /&gt;
# name database fields: &#039;&#039;textfield&#039;&#039;, &#039;&#039;textfieldformat&#039;&#039; (and &#039;&#039;textfieldtrust&#039;&#039; if required)&lt;br /&gt;
# create options array &amp;lt;code php&amp;gt;$textfieldoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;true, &#039;maxfiles&#039;=&amp;gt;$maxfiles, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&amp;lt;/code&amp;gt;&lt;br /&gt;
# add editor &#039;&#039;textfield_editor&#039;&#039; to moodle form, pass options through custom data in form constructor, set $data-&amp;gt;id to null if data not exist yet &amp;lt;code php&amp;gt;$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;textfield_editor&#039;, get_string(&#039;fieldname&#039;, &#039;somemodule&#039;), null, $textfieldoptions);&amp;lt;/code&amp;gt;&lt;br /&gt;
# prepare data &amp;lt;code php&amp;gt;$data = file_prepare_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
# get submitted data and after inserting/updating of data &amp;lt;code php&amp;gt;$data = file_postupdate_standard_editor($data, &#039;textfield&#039;, $textfieldoptions, $context, &#039;somemodule_somearea&#039;, $data-&amp;gt;id);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Real world examples are in mod/glossary/edit.php and mod/glossary/comment.php&lt;br /&gt;
&lt;br /&gt;
====Low level use====&lt;br /&gt;
&lt;br /&gt;
When using editor element you  need to preprocess and postprocess the data:&lt;br /&gt;
# detect if form was already submitted (usually means draft is area already exists) - &#039;&#039;file_get_submitted_draft_itemid()&#039;&#039;&lt;br /&gt;
# prepare draft file area, temporary storage of all files attached to the text - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# convert encoded relative links to absolute links - &#039;&#039;file_prepare_draft_area()&#039;&#039;&lt;br /&gt;
# create form and set current data&lt;br /&gt;
# after submission the changed files must be merged back into original area - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
# absolute links have to be replaced by relative links - &#039;&#039;file_save_draft_area_files()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=====Replace old htmleditor with editor=====&lt;br /&gt;
&lt;br /&gt;
The file picker has been integrated with with TinyMCE to make the editor element. This new element should support all types on editors and should be able to switch them on-the-fly. Instances of the old htmleditor element in your forms should be replaced by the new editor element, this may need adding of new format and trusttext columns. For example:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;entry&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null,&lt;br /&gt;
        array(&#039;maxfiles&#039; =&amp;gt; EDITOR_UNLIMITED_FILES, &#039;filearea&#039; =&amp;gt; &#039;glossary_entry&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The editor element can take following options: maxfiles, maxbytes, filearea, subdirs and changeformat. Please note that the embedded files is optional feature and is not expected be used everywhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: the editor element now includes text format option. You should no longer use the separate format element type.&lt;br /&gt;
&lt;br /&gt;
=====Prepare current data - text and files=====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if (empty($entry-&amp;gt;id)) {&lt;br /&gt;
  $entry = new object();&lt;br /&gt;
  $entry-&amp;gt;id = null;&lt;br /&gt;
  $entry-&amp;gt;definition = &#039;&#039;;&lt;br /&gt;
  $entry-&amp;gt;format = FORMAT_HTML;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$draftid_editor = file_get_submitted_draft_itemid(&#039;entry&#039;);&lt;br /&gt;
$currenttext = file_prepare_draft_area($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $entry-&amp;gt;definition);&lt;br /&gt;
$entry-&amp;gt;entry = array(&#039;text&#039;=&amp;gt;$currenttext, &#039;format&#039;=&amp;gt;$entry-&amp;gt;format, &#039;itemid&#039;=&amp;gt;$draftid_editor);&lt;br /&gt;
&lt;br /&gt;
$mform-&amp;gt;set_data($entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are multiple files, they will share the same itemid.&lt;br /&gt;
&lt;br /&gt;
=====Obtain text, format and save draft files=====&lt;br /&gt;
&lt;br /&gt;
To retrieve editor content, you need to use following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($fromform = $mform-&amp;gt;get_data()) {&lt;br /&gt;
    // content of editor&lt;br /&gt;
    $messagetext = $fromform-&amp;gt;entry[&#039;text&#039;];&lt;br /&gt;
    // format of content&lt;br /&gt;
    $messageformat  = $fromform-&amp;gt;entry[&#039;format&#039;];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a user selects a file using the file picker, the file is initially stored in a draft file area, and a URL is inserted into the HTML in the editor that lets the person editing the content (but no one else) see the file.&lt;br /&gt;
&lt;br /&gt;
When the user submits the form, we then need to save the draft files to the correct place in permanent storage. (Just like you have to call $DB-&amp;gt;update_record(&#039;tablename&#039;, $data); to have the other parts of the form submission stored correctly.)&lt;br /&gt;
&lt;br /&gt;
The save_files_from_draft_area function and replace absolute links with internal relative links do:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_save_draft_area_files($draftid_editor, $context-&amp;gt;id, &#039;glossary_entry&#039;, $entry-&amp;gt;id, array(&#039;subdirs&#039;=&amp;gt;true), $messagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $context-&amp;gt;id, &#039;proper_file_area&#039; and $entry-&amp;gt;id : correspond to the contextid, filearea and itemid columns in the [[Development:File_API#Table:_files|files table]].&lt;br /&gt;
; $messagetext : this is the message text. As the files are saved to the real file area, the URLs in this content are rewritten.&lt;br /&gt;
&lt;br /&gt;
All URLs in content that point to files managed to the File API are converted to a form that starts &#039;@@PLUGINFILE@@/&#039; before the content is stored in the database. That is what we mean by rewriting.&lt;br /&gt;
&lt;br /&gt;
== File serving==&lt;br /&gt;
&lt;br /&gt;
=== Convert internal relative links to absolute links ===&lt;br /&gt;
&lt;br /&gt;
Before text content is displayed to the user, any URLs in the &#039;@@PLUGINFILE@@/&#039; form in the content need to be rewritten to the real URL where the user can access the files. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$messagetext = file_rewrite_pluginfile_urls($messagetext, &#039;pluginfile.php&#039;,&lt;br /&gt;
        &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
; $messagetext : is the content containing the @@PLUGINFILE@@ URLs from the database.&lt;br /&gt;
; &#039;pluginfile.php&#039; : there are a number of different scripts that can serve files with different permissions checks. You need to specify which one to use.&lt;br /&gt;
; &amp;quot;$context-&amp;gt;id/proper_file_area/$itemid/&amp;quot; : uniquely identifies the file area, as before.&lt;br /&gt;
&lt;br /&gt;
=== Implement file serving access control ===&lt;br /&gt;
&lt;br /&gt;
Attachments and embedded images should have the same access control like the text itself, in majority of cases these files are served using pluginfile.php. Access control is defined in &#039;&#039;module/lib.php&#039;&#039; file in function &#039;&#039;module_pluginfile()&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== File browsing support ==&lt;br /&gt;
Only owner of each file area is allowed to use low level File API function to access files, other parts of Moodle should use file browsing API.&lt;br /&gt;
&lt;br /&gt;
Activities may specify browsing support in own module/lib.php file by implementing functions module_get_file_areas() and module_get_file_info().&lt;br /&gt;
&lt;br /&gt;
== Upgrading your code ==&lt;br /&gt;
Here I will attempt to describe some simple steps you can take to upgrade your file-handling form elements from pre-2.0 code to 2.0. We will use the example of glossary, since it has been used above.&lt;br /&gt;
&lt;br /&gt;
=== Preparing your options ===&lt;br /&gt;
Unless you are happy with the defaults, you will need to define an array of options for each file-handling form element. You could define it at different places, but it&#039;s best to put it in one place and make the array(s) available to other files if they need it. In the majority of cases, this will be in a file like edit.php&lt;br /&gt;
&lt;br /&gt;
Previous code in mod/glossary/edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform =&amp;amp; new mod_glossary_entry_form(null, compact(&#039;cm&#039;, &#039;glossary&#039;, &#039;hook&#039;, &#039;mode&#039;, &#039;e&#039;, &#039;context&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$maxbytes = $course-&amp;gt;maxbytes; // Could also use $CFG-&amp;gt;maxbytes if you are not coding within a course context&lt;br /&gt;
$definitionoptions = array(&#039;trusttext&#039;=&amp;gt;true, &#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes, &#039;trusttext&#039;=&amp;gt;true, &#039;context&#039;=&amp;gt;$context);&lt;br /&gt;
$attachmentoptions = array(&#039;subdirs&#039;=&amp;gt;false, &#039;maxfiles&#039;=&amp;gt;99, &#039;maxbytes&#039;=&amp;gt;$maxbytes);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the data being passed to the form constructor have changed also, but this is not part of the file API changes, I just include them to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
These options are for the htmleditor (definition field) and the filemanager (attachment field). They are used by a file called edit_form.php. &lt;br /&gt;
&lt;br /&gt;
=== Element preparation ===&lt;br /&gt;
Before we look at this, however, we need to &amp;quot;prepare&amp;quot; the elements so that they can correctly display existing embedded images and attached files when you are editing a record instead of just creating one. So, let&#039;s take the code we&#039;ve got so far in edit.php and add to it:&lt;br /&gt;
&lt;br /&gt;
Currently upgraded code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code with element preparation:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$entry = file_prepare_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_prepare_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$mform = new mod_glossary_entry_form(null, array(&lt;br /&gt;
        &#039;current&#039;=&amp;gt;$entry, &lt;br /&gt;
        &#039;cm&#039;=&amp;gt;$cm, &lt;br /&gt;
        &#039;glossary&#039;=&amp;gt;$glossary,&lt;br /&gt;
        &#039;definitionoptions&#039;=&amp;gt;$definitionoptions, &lt;br /&gt;
        &#039;attachmentoptions&#039;=&amp;gt;$attachmentoptions));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* $entry in this case is simply a stdClass object which may either represent a new glossary entry or an existing one.&lt;br /&gt;
* $entry-&amp;gt;id must be the unique identifier for the current object. If we are creating a new entry, it will be null, but in all cases it must be defined.&lt;br /&gt;
* These two functions (file_prepare_standard_editor and file_prepare_standard_filemanager) are shortcuts functions that take care of some of the tedious setting up for you, but they make a couple of assumptions:&lt;br /&gt;
## You &#039;&#039;&#039;must&#039;&#039;&#039; name the form element as {element}_editor or {element}_filemanager (see next section)&lt;br /&gt;
## You &#039;&#039;&#039;must&#039;&#039;&#039; have at least the following fields in the database: {element} and {element}summary, as described earlier in this documentation&lt;br /&gt;
&lt;br /&gt;
We can now look at the upgrades needed in the form definition file.&lt;br /&gt;
&lt;br /&gt;
=== Form definition ===&lt;br /&gt;
Previous code in mod/glossary/edit_form.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;definition&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), array(&#039;rows&#039;=&amp;gt;20));&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;definition&#039;, array(&#039;writing&#039;, &#039;richtext&#039;), false, &#039;editorhelpbutton&#039;);&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;format&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment&#039;, array(&#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$definitionoptions = $this-&amp;gt;_customdata[&#039;definitionoptions&#039;];&lt;br /&gt;
$attachmentoptions = $this-&amp;gt;_customdata[&#039;attachmentoptions&#039;];&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;editor&#039;, &#039;definition_editor&#039;, get_string(&#039;definition&#039;, &#039;glossary&#039;), null, $definitionoptions);&lt;br /&gt;
$mform-&amp;gt;setType(&#039;definition_editor&#039;, PARAM_RAW);&lt;br /&gt;
$mform-&amp;gt;addRule(&#039;definition_editor&#039;, get_string(&#039;required&#039;), &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
// a bit further...&lt;br /&gt;
$mform-&amp;gt;addElement(&#039;filemanager&#039;, &#039;attachment_filemanager&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), null, $attachmentoptions);&lt;br /&gt;
$mform-&amp;gt;setHelpButton(&#039;attachment_filemanager&#039;, array(&#039;attachment2&#039;, get_string(&#039;attachment&#039;, &#039;glossary&#039;), &#039;glossary&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The format element and the help button are no longer required for the HTML editor element&lt;br /&gt;
* The name of the form element needs to be changed by adding &#039;_editor&#039; or &#039;_manager&#039; to the original name. This is a naming convention that is used by a couple of functions we will look at shortly&lt;br /&gt;
&lt;br /&gt;
=== Submitted data handling ===&lt;br /&gt;
The final step is to handle the submitted data properly, i.e. retrieve the files and save them to disk, associating them with the record we have just created (a glossary entry in our example). This happens in edit.php:&lt;br /&gt;
&lt;br /&gt;
Previous code in edit.php:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// Section that updates an entry:&lt;br /&gt;
$todb-&amp;gt;id = $e;&lt;br /&gt;
$dir = glossary_file_area_name($todb);&lt;br /&gt;
if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
    $todb-&amp;gt;attachment = $newfilename;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Section that adds an entry:&lt;br /&gt;
if ($todb-&amp;gt;id = insert_record(&amp;quot;glossary_entries&amp;quot;, $todb)) {&lt;br /&gt;
    $e = $todb-&amp;gt;id;&lt;br /&gt;
    $dir = glossary_file_area_name($todb);&lt;br /&gt;
    if ($mform-&amp;gt;save_files($dir) and $newfilename = $mform-&amp;gt;get_new_filename()) {&lt;br /&gt;
        set_field(&amp;quot;glossary_entries&amp;quot;, &amp;quot;attachment&amp;quot;, $newfilename, &amp;quot;id&amp;quot;, $todb-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// $todb was renamed to $entry, and the code was refactored &lt;br /&gt;
// so that the file-handling code is only used once for either an add or an update action.&lt;br /&gt;
// If an entry is being added, $DB-&amp;gt;insert() has already been called, so we have a valid $entry-&amp;gt;id&lt;br /&gt;
$entry = file_postupdate_standard_editor($entry, &#039;definition&#039;, $definitionoptions, $context, &#039;glossary_entry&#039;, $entry-&amp;gt;id);&lt;br /&gt;
$entry = file_postupdate_standard_filemanager($entry, &#039;attachment&#039;, $attachmentoptions, $context, &#039;glossary_attachment&#039;, $entry-&amp;gt;id);&lt;br /&gt;
// store the updated value values&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;glossary_entries&#039;, $entry);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Things to note:&lt;br /&gt;
* If you are adding a new record, you will still need to call update_record after calling the file_postupdate* functions&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]]&lt;br /&gt;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* MDL-14589 - File API Meta issue&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Repositories]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API&amp;diff=63555</id>
		<title>Development:Using the File API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Using_the_File_API&amp;diff=63555"/>
		<updated>2009-09-25T06:34:57Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Putting link to more useful doc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
The File API is for managing all the files stored by Moodle. If you are interested in how the file API works internally, see [[Development:File API]]. The page is just about what you need to know to use the file API. Related is the [[Development:Repository API]], which lets users get files into Moodle.&lt;br /&gt;
&lt;br /&gt;
If you are looking for an explanation on how to upgrade pre-2.0 code to using the file API, you most likely need to read [[Development:Using_the_File_API_in_Moodle_forms|Using the File API in Moodle forms]].&lt;br /&gt;
&lt;br /&gt;
==File areas==&lt;br /&gt;
&lt;br /&gt;
Files are conceptually stored in &#039;&#039;&#039;file areas&#039;&#039;&#039;. A file area is uniquely identified by:&lt;br /&gt;
* A context id.&lt;br /&gt;
* A file area type, for example &#039;course_intro&#039; or &#039;forum_post&#039;.&lt;br /&gt;
* A unique itemid. Normally, the itemid relates to something depending on the file area type. For example, for a &#039;course_intro&#039; file area, the itemid is is the course id. For forum post, it is the post id.&lt;br /&gt;
&lt;br /&gt;
File areas are not listed separately anywhere, they are stored implicitly in the files table. Please note that each subsystem is allowed to access only own file areas, for example core code must not access module or block files directly.&lt;br /&gt;
&lt;br /&gt;
===Naming file areas===&lt;br /&gt;
&lt;br /&gt;
It is important that file areas are named consistently so we do not get name collisions, and so the names are easy to understand. Please follow the following guidelines:&lt;br /&gt;
&lt;br /&gt;
====start of the name====&lt;br /&gt;
&lt;br /&gt;
If the file area belongs to a plugin, please use the plugin name as the start of the file area name.&lt;br /&gt;
&lt;br /&gt;
This is the same plugin name that you would use for get_string calls. Some examples:&lt;br /&gt;
* All file areas that belong to the forum modules should have a name beginning with &#039;forum&#039;. For example &#039;forum_post&#039;, &#039;forum_intro&#039;.&lt;br /&gt;
* A file area belonging to the HTML block would start &#039;block_html_&#039;.&lt;br /&gt;
* A file area belonging to a question type would start &#039;qtype_myqtype_&#039;, except this is probably not necessary, because question type images should probably be stored in the core &#039;question_text&#039; file area.&lt;br /&gt;
* If the file area is used by a local hack, the file area name should start &#039;local_&#039;.&lt;br /&gt;
&lt;br /&gt;
If the file area belongs to core code, the file area name should start with a prefix that indicates what part of Moodle it belongs to.&lt;br /&gt;
&lt;br /&gt;
But try to avoid clashing with prefixes that a plugin might use. Some examples:&lt;br /&gt;
* &#039;course_intro&#039;&lt;br /&gt;
* &#039;question_text&#039;&lt;br /&gt;
* &#039;user_draft&#039; (although draft file areas are a special case).&lt;br /&gt;
&lt;br /&gt;
====rest of the name====&lt;br /&gt;
&lt;br /&gt;
Like naming variables or functions, try to find a name that is short, but says exactly what the file area is for.&lt;br /&gt;
&lt;br /&gt;
If possible use the name of the file area to give a clue as to which database table the itemid relates to. For example:&lt;br /&gt;
&lt;br /&gt;
* For the &#039;forum_post&#039; file area, the itemid links to forum_post.id.&lt;br /&gt;
* For &#039;question_text&#039; file area, the itemid links to question.id. (Would it be permissible to call this file area just question?)&lt;br /&gt;
&lt;br /&gt;
==Serving files to users==&lt;br /&gt;
&lt;br /&gt;
You must refer to the file with a URL that includes a file-serving script, often pluginfile.php. For example&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$url = $CFG-&amp;gt;wwwroot/pluginfile.php/$contextid/$filearea/$itemid/file/path.ext;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Often you get these URLs generated automatically for you using the function file_rewrite_pluginfile_urls.&lt;br /&gt;
&lt;br /&gt;
==Getting files from the user==&lt;br /&gt;
&lt;br /&gt;
* See [[Development:Using_the_File_API_in_Moodle_forms|Using the File API in Moodle forms]]&lt;br /&gt;
==Examples==&lt;br /&gt;
Please note that in reality developers outside of core will not deal with file api directly in majority of cases, instead use formslib elements which are doing all this automatically.&lt;br /&gt;
&lt;br /&gt;
===Browsing files===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$browser = get_file_browser();&lt;br /&gt;
$context = get_system_context();&lt;br /&gt;
&lt;br /&gt;
$filearea = null;&lt;br /&gt;
$itemid   = null;&lt;br /&gt;
$filename = null;&lt;br /&gt;
if ($fileinfo = $browser-&amp;gt;get_file_info($context, $filearea, $itemid, &#039;/&#039;, $filename)) {&lt;br /&gt;
    // build a Breadcrumb trail&lt;br /&gt;
    $level = $fileinfo-&amp;gt;get_parent();&lt;br /&gt;
    while ($level) {&lt;br /&gt;
        $params = base64_encode(serialize($level-&amp;gt;get_params()));&lt;br /&gt;
        $path[] = array(&#039;name&#039;=&amp;gt;$level-&amp;gt;get_visible_name(), &#039;path&#039;=&amp;gt;$params);&lt;br /&gt;
        $level = $level-&amp;gt;get_parent();&lt;br /&gt;
    }&lt;br /&gt;
    $path = array_reverse($path);&lt;br /&gt;
    $children = $fileinfo-&amp;gt;get_children();&lt;br /&gt;
    foreach ($children as $child) {&lt;br /&gt;
        if ($child-&amp;gt;is_directory()) {&lt;br /&gt;
            echo $child-&amp;gt;get_visible_name();&lt;br /&gt;
            // display contextid, itemid, filepath and filename&lt;br /&gt;
            var_dump($child-&amp;gt;get_params());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===Moving files around===&lt;br /&gt;
&lt;br /&gt;
For example, if you have just built a file at the path&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $from_zip_file = $CFG-&amp;gt;dataroot . &#039;/temp/backup/&#039; . $preferences-&amp;gt;backup_unique_code .&lt;br /&gt;
         &#039;/&#039; . $preferences-&amp;gt;backup_name;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
And you want to move it into the course_backup file area, do&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $context = get_context_instance(CONTEXT_COURSE, $preferences-&amp;gt;backup_course);&lt;br /&gt;
 $fs = get_file_storage();&lt;br /&gt;
 $file_record = array(&#039;contextid&#039;=&amp;gt;$context-&amp;gt;id, &#039;filearea&#039;=&amp;gt;&#039;course_backup&#039;,&lt;br /&gt;
         &#039;itemid&#039;=&amp;gt;0, &#039;filepath&#039;=&amp;gt;&#039;/&#039;, &#039;filename&#039;=&amp;gt;$preferences-&amp;gt;backup_name,&lt;br /&gt;
         &#039;timecreated&#039;=&amp;gt;time(), &#039;timemodified&#039;=&amp;gt;time());&lt;br /&gt;
 $fs-&amp;gt;create_file_from_pathname($file_record, $from_zip_file);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===Create a copy of stored file===&lt;br /&gt;
If you need to create a copy of stored file (actually, it add a new record in database):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$context  = get_context_instance_by_id($contextid);&lt;br /&gt;
$file_info = $browser-&amp;gt;get_file_info($context, $filearea, $fileitemid, $filepath, $filename);&lt;br /&gt;
// copy this file to draft area&lt;br /&gt;
$file_info-&amp;gt;copy_to_storage($user_context-&amp;gt;id, &#039;user_draft&#039;, $newitemid, &#039;/&#039;, $title);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List area files ===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$fs = get_file_storage();&lt;br /&gt;
$files = $fs-&amp;gt;get_area_files($contextid, &#039;user_draft&#039;);&lt;br /&gt;
foreach ($files as $f) {&lt;br /&gt;
    // $f is an instance of stored_file&lt;br /&gt;
    echo $f-&amp;gt;get_filename();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:File API]] how the File API works internally.&lt;br /&gt;
* [[Roadmap|Moodle 2.0 roadmap]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Files]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:File_API&amp;diff=63553</id>
		<title>Development:File API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:File_API&amp;diff=63553"/>
		<updated>2009-09-25T06:15:55Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Updated name of fileareas&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 [[Development: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 [[Development: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 [[Development: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 [[Development: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 [[Development: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;
* [[Development:Using the file API]]&lt;br /&gt;
* [[Development:Repository API]]&lt;br /&gt;
* [[Development:Portfolio API]]&lt;br /&gt;
* [[Development: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;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63526</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63526"/>
		<updated>2009-09-24T09:21:41Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists all functions that have been deprecated between 1.9 and 2.0, with instructions on how to upgrade your code. A count of remaining function calls in core is kept next to each function name.&lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
Note: $nocurr has been dropped. Current page number is never displayed as a link&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63525</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63525"/>
		<updated>2009-09-24T09:20:33Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* General notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
Note: $nocurr has been dropped. Current page number is never displayed as a link&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Outputting_HTML_in_2.0&amp;diff=63524</id>
		<title>Development:Outputting HTML in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Outputting_HTML_in_2.0&amp;diff=63524"/>
		<updated>2009-09-24T09:19:56Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Development:Outputting HTML in 2.0 moved to Development:Deprecated functions in 2.0: Expanding the use of this page for all deprecated functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Development:Deprecated functions in 2.0]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63523</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=63523"/>
		<updated>2009-09-24T09:19:56Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Development:Outputting HTML in 2.0 moved to Development:Deprecated functions in 2.0: Expanding the use of this page for all deprecated functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
Note: $nocurr has been dropped. Current page number is never displayed as a link&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development_talk:Blog_2.0&amp;diff=63521</id>
		<title>Development talk:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development_talk:Blog_2.0&amp;diff=63521"/>
		<updated>2009-09-24T08:44:25Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Some questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Some questions ===&lt;br /&gt;
&lt;br /&gt;
* about the &amp;quot;who can view&amp;quot;/&amp;quot;externl blogs&amp;quot;/&amp;quot;associations&amp;quot; things... is going to be some capability like:&lt;br /&gt;
** viewblogentries&lt;br /&gt;
** viewdraftblogentries&lt;br /&gt;
** fetchexternalblogs&lt;br /&gt;
** searchblogentries&lt;br /&gt;
** associateblogentries&lt;br /&gt;
:Yes to the above [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Also, are &amp;quot;fetched&amp;quot; and manual blog entries differentiated in any way?&lt;br /&gt;
:In the database, entries that have been copied from an external blog will have a value in the post.uniquehash field. Also, you will be able to automatically tag an external blog&#039;s entries with one or more tags [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Finally, both tags and associations are going to be published in the RSS Feeds? &lt;br /&gt;
:I don&#039;t see why not, maybe that could be optional [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Is it going to be possible to get RSS Feeds by tag or association?&lt;br /&gt;
:Yes [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Atom_(standard) ATOM] (import from external blog feeds / publish local feeds)&lt;br /&gt;
:Not sure, can you explain? [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* When blog entries are displayed for say, course XX, will also &amp;quot;child&amp;quot; entries be displayed (activity-associated).&lt;br /&gt;
:Yes, whenever an entry is associated with an activity, it is also automatically associated with the course. [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
::&amp;quot;automatically associated&amp;quot; stands for: association record created automatically or rely in accesslib (nested contexts) abilities?&lt;br /&gt;
* If association is disabled in one site (or user if the capability exists), which will be the behaviour of the blocks?&lt;br /&gt;
:Instead of searching for entries associated with the course, it will just show all blog entries (for the site). The links in the blog_menu will be simplified accordingly. [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
--[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 08:45, 22 September 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===More questions===&lt;br /&gt;
&#039;&#039;&#039;Who can view blog entries&#039;&#039;&#039; - the description is not correct, there were more access levels, we can not just remove them - please explain the differences and propose upgrade routes. The descriptions have to contain all relevant capabilities and their use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Associations&#039;&#039;&#039; - just the context id does not seem to be granular enough, we use are+itemid elsewhere because it allows you to specify the exact forum discussion or post for example. Another problem is should we allow association with context you are not enrolled in? Please include all relevant capabilities too. &#039;&#039;blogid&#039;&#039; in blog_assoc table links which column and table? Should it be called postid?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;External blogs&#039;&#039;&#039; I would not call it import, maybe better &amp;quot;sync with external blog&amp;quot;. I suppose that it might be good to have a tag name in the blog description. There could be also separate option for synchronisation of external tags. Hmm, we could also fetch posts with some tags only. We do not need tags in order to distinguish external feeds - they have the hash there. The problem I see is if you accidentally add some ext blog and then you want to delete it - we do not know from which feed it was added (I suppose one user may have multiple ext blogs linked). Again include all caps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Atom&#039;&#039;&#039; what is it &#039;&#039;atom write&#039;&#039; support?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attachments&#039;&#039;&#039; we need embedded images too.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Problems&#039;&#039;&#039;&lt;br /&gt;
* different access control compared to 1.9&lt;br /&gt;
* RSS feeds when posts are not accessible without login need some form of protection&lt;br /&gt;
&lt;br /&gt;
[[User:Petr Škoda (škoďák)|Petr Škoda (škoďák)]] 21:13, 22 September 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development_talk:Blog_2.0&amp;diff=63420</id>
		<title>Development talk:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development_talk:Blog_2.0&amp;diff=63420"/>
		<updated>2009-09-22T08:56:05Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Some questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Some questions ===&lt;br /&gt;
&lt;br /&gt;
* about the &amp;quot;who can view&amp;quot;/&amp;quot;externl blogs&amp;quot;/&amp;quot;associations&amp;quot; things... is going to be some capability like:&lt;br /&gt;
** viewblogentries&lt;br /&gt;
** viewdraftblogentries&lt;br /&gt;
** fetchexternalblogs&lt;br /&gt;
** searchblogentries&lt;br /&gt;
** associateblogentries&lt;br /&gt;
:Yes to the above [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Also, are &amp;quot;fetched&amp;quot; and manual blog entries differentiated in any way?&lt;br /&gt;
:In the database, entries that have been copied from an external blog will have a value in the post.uniquehash field. Also, you will be able to automatically tag an external blog&#039;s entries with one or more tags [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Finally, both tags and associations are going to be published in the RSS Feeds? &lt;br /&gt;
:I don&#039;t see why not, maybe that could be optional [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* Is it going to be possible to get RSS Feeds by tag or association?&lt;br /&gt;
:Yes [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* ATOM (read/write)?&lt;br /&gt;
:Yes [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* When blog entries are displayed for say, course XX, will also &amp;quot;child&amp;quot; entries be displayed (activity-associated).&lt;br /&gt;
:Yes, whenever an entry is associated with an activity, it is also automatically associated with the course. [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
* If association is disabled in one site (or user if the capability exists), which will be the behaviour of the blocks?&lt;br /&gt;
:Instead of searching for entries associated with the course, it will just show all blog entries (for the site). The links in the blog_menu will be simplified accordingly. [[User:Nicolas Connault|Nicolas Connault]] 08:56, 22 September 2009 (UTC)&lt;br /&gt;
--[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 08:45, 22 September 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63418</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63418"/>
		<updated>2009-09-22T08:46:15Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See MDL-19676)&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: MDL-14408&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: MDL-19683&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19686&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19687&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19744&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-8776&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: MDL-19688&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63413</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63413"/>
		<updated>2009-09-22T08:08:51Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: http://moodle.org/mod/forum/discuss.php?d=133348&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676 this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63410</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63410"/>
		<updated>2009-09-22T08:01:59Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Upgrade process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676 this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
The only task required by the upgrade process is to install the new DB tables.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63409</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63409"/>
		<updated>2009-09-22T08:00:14Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* DB Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676 this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_association&lt;br /&gt;
&lt;br /&gt;
=== blog_external ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this external blog.&lt;br /&gt;
|-&lt;br /&gt;
| userid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The owner of the external blog&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| char(255)&lt;br /&gt;
|&lt;br /&gt;
| A descriptive name for the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| A long description of the external blog. Automatically fetched during initial import, can be overridden.&lt;br /&gt;
|-&lt;br /&gt;
| url&lt;br /&gt;
| text(small)&lt;br /&gt;
|&lt;br /&gt;
| The URL to the external blog (e.g. http://moodle.org/rss.xml)&lt;br /&gt;
|-&lt;br /&gt;
| timemodified&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| timefetched&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The last time the entries from this external blog were fetched by Moodle.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== blog_association ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Type&lt;br /&gt;
! Default&lt;br /&gt;
! Info&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| int(10)&lt;br /&gt;
| auto-incrementing&lt;br /&gt;
| The unique ID for this blog entry&amp;lt;-&amp;gt;contextid association.&lt;br /&gt;
|-&lt;br /&gt;
| contextid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The context id defined in context table - identifies the instance of the course or plugin associated with the blog entry.&lt;br /&gt;
|-&lt;br /&gt;
| blogid&lt;br /&gt;
| int(10)&lt;br /&gt;
|&lt;br /&gt;
| The id of the blog entry (from the post table) being associated with a course or module instance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63323</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63323"/>
		<updated>2009-09-21T06:52:31Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Who can view blog entries? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676 this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_associations&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63322</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63322"/>
		<updated>2009-09-21T06:52:12Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Who can view blog entries? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676 |this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_associations&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63321</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63321"/>
		<updated>2009-09-21T06:48:14Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* DB Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676|this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
2 new tables need to be added: blog_external and blog_associations&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63320</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63320"/>
		<updated>2009-09-21T06:29:09Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public. (See [http://tracker.moodle.org/browse/MDL-19676|this tracker issue])&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-14408]&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19683]&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19686]&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19687]&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19744]&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-8776]&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
Tracker issue: [http://tracker.moodle.org/browse/MDL-19688]&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63319</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63319"/>
		<updated>2009-09-21T06:24:43Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Other links and resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== Other links and resources ==&lt;br /&gt;
*[[Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63318</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63318"/>
		<updated>2009-09-21T06:24:21Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Other links and resources&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;br /&gt;
&lt;br /&gt;
== Other links and resources ==&lt;br /&gt;
*[[https://docs.moodle.org/en/Development:Blogs|Early wishlist]]&lt;br /&gt;
*[[https://docs.moodle.org/en/Student_projects/Blog_improvements|2008 GSoC project addressing some of these improvements]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63317</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63317"/>
		<updated>2009-09-21T06:20:48Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. &lt;br /&gt;
&lt;br /&gt;
These external blogs are a user preference, and two types of tags can be added to each of them: &amp;quot;External tags&amp;quot; and &amp;quot;Moodle tags&amp;quot;:&lt;br /&gt;
*External tags are used to filter the external blog entries that get copied into Moodle. They must match the tags used by that external blog.&lt;br /&gt;
*Moodle tags are automatically added to each blog entry copied into Moodle from an external blog that uses such tags. This makes it easier to distinguish which of a user&#039;s blog entries come from an external blog.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63316</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63316"/>
		<updated>2009-09-21T06:16:08Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
=== New &amp;quot;Recent blog entries&amp;quot; block ===&lt;br /&gt;
This block can be configured to display the last N blog entries, filtered by context. For example, if you are viewing an assignment activity, this block would display the last N blog entries that are associated with that assignment.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63315</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63315"/>
		<updated>2009-09-21T06:14:13Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table, in which the associations are recorded.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The [[Development:File_API|new file manager]] must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
The new [[Development:Comments_2.0|Comments API]] makes it possible for anyone having the correct capability to comment on blog entries.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63314</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63314"/>
		<updated>2009-09-21T06:08:30Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
This requires the creation of a new table.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can import blog entries into Moodle from external blogs. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting. This requires the creation of a new DB table.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
=== File attachments ===&lt;br /&gt;
The new file manager must be implemented to allow for multiple file attachments per blog entry.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63313</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63313"/>
		<updated>2009-09-21T06:04:46Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can enter URLs to other blog to make it possible to import this blog&#039;s entries into the user&#039;s blog in Moodle. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting.&lt;br /&gt;
&lt;br /&gt;
=== Search blog entries ===&lt;br /&gt;
It is now possible to search blog entries using a search box. The results maintain the current context, so that if you are viewing a list of blog entries for a particular user, entering a term in the search box will return only the blog entries for that user that match the search term. The search term also appears in the navigation breadcrumbs.&lt;br /&gt;
&lt;br /&gt;
=== Contextual blog menu ===&lt;br /&gt;
Previously, the &amp;quot;blog menu&amp;quot; block was the same on every page on which it appeared. In 2.0 it changes depending on which page you are. For example, if you are on course/view.php, it will include a link to blog entries associated with that course. Also, the link for adding a new entry will include the courseid, making the course association automatically pre-selected in the blog entry edit form.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63312</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63312"/>
		<updated>2009-09-21T05:59:42Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Description of improvements */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
=== Who can view blog entries? ===&lt;br /&gt;
Blog entries are either in draft mode (only the author can view it), or in public mode. In public mode, everyone on the entire site can view the blog entry. &lt;br /&gt;
&lt;br /&gt;
At one stage in 2.0 development there was an attempt to restrict who can view certain blog entries, based on course enrolment and capabilities. However, after extensive discussion and feasibility testing it became clear that this would lead to serious performance and usability issues, and would turn the blog into something more akin to a forum. It was thus decided to make all blogs public.&lt;br /&gt;
&lt;br /&gt;
An admin setting can allow for blog entries to be accessible by non-logged-in users, for the purpose of publishing and RSS feed aggregation.&lt;br /&gt;
&lt;br /&gt;
=== Associations ===&lt;br /&gt;
A blog entry can optionally be associated with a course. This makes it possible for a user to blog &amp;quot;about&amp;quot; that course. All blog entries associated in that way can be viewed on a page like blog/index.php?courseid=3. This type of filtering of blog entries does not take into account course enrolments.&lt;br /&gt;
&lt;br /&gt;
Additionally, blog entries can be associated with activity modules, in which case the blog entry is automatically associated with the module&#039;s course.&lt;br /&gt;
&lt;br /&gt;
=== Improved navigation ===&lt;br /&gt;
Before 2.0, the navigation for any listing of blog entries was either &amp;quot;Site &amp;gt; User &amp;gt; Blogs&amp;quot; (for a user&#039;s blog entries) or &amp;quot;Site &amp;gt; Blogs&amp;quot; for the whole site&#039;s blog entries, optionally filtered by tag. With the new association features, we need a better way to display what type of blog listing we are looking at, based on the parameters passed to blog/index.php. The navigation should also reflect additional filters such as tag and search.&lt;br /&gt;
&lt;br /&gt;
=== External blogs ===&lt;br /&gt;
A user can enter URLs to other blog to make it possible to import this blog&#039;s entries into the user&#039;s blog in Moodle. The external blog&#039;s entries are copied into Moodle when the external blog URL is entered, and a cron task periodically checks these external blogs to copy new entries not yet entered in Moodle. The period of time between checks can be adjusted as an admin setting.&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63307</id>
		<title>Development:Blog 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Blog_2.0&amp;diff=63307"/>
		<updated>2009-09-21T03:45:00Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: New page: {{Work in progress}}{{Moodle 2.0}}  * &amp;#039;&amp;#039;&amp;#039;PROJECT STATE: Coding&amp;#039;&amp;#039;&amp;#039; * &amp;#039;&amp;#039;&amp;#039;MAIN TRACKER ISSUE&amp;#039;&amp;#039;&amp;#039;: MDL-19676 Blog 2.0 improvements * &amp;#039;&amp;#039;&amp;#039;DISCUSSION AND COMMENTS&amp;#039;&amp;#039;&amp;#039;: Link to forum discussion will...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PROJECT STATE: Coding&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAIN TRACKER ISSUE&#039;&#039;&#039;: MDL-19676 Blog 2.0 improvements&lt;br /&gt;
* &#039;&#039;&#039;DISCUSSION AND COMMENTS&#039;&#039;&#039;: Link to forum discussion will appear here&lt;br /&gt;
&lt;br /&gt;
== Description of improvements ==&lt;br /&gt;
&lt;br /&gt;
== Potential problems and limitations ==&lt;br /&gt;
&lt;br /&gt;
== DB Structure ==&lt;br /&gt;
&lt;br /&gt;
== Upgrade process ==&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Grade_aggregation&amp;diff=62283</id>
		<title>Grade aggregation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Grade_aggregation&amp;diff=62283"/>
		<updated>2009-09-01T07:23:19Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* Weighted mean */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Grades}}The aggregation dropdown menu lets you choose the aggregation strategy that will be used to calculate each participant&#039;s overall grade for a [[Grade categories|grade category]]. The different options are explained below.&lt;br /&gt;
&lt;br /&gt;
The grades are first converted to percentage values (interval from 0 to 1), then aggregated using one of the strategies below and finally converted to the associated category item&#039;s range (between Minimum grade and Maximum grade).&lt;br /&gt;
&lt;br /&gt;
Important: An empty grade is simply a missing gradebook entry, and could mean different things. For example, it could be a participant who hasn&#039;t yet submitted an assignment, an assignment submission not yet graded by the teacher, or a grade that has been manually deleted by the gradebook administrator. Caution in interpreting these &amp;quot;empty grades&amp;quot; is thus advised.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mean of grades ==&lt;br /&gt;
The sum of all grades divided by the total number of grades.&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10, category max 100:&lt;br /&gt;
    (0.7 + 0.25 + 1.0)/3 = 0.65 --&amp;gt; 65/100&lt;br /&gt;
&lt;br /&gt;
== Weighted mean ==&lt;br /&gt;
Each grade item can be given a weight, which is then used in the arithmetic mean aggregation to influence the importance of each item in the overall mean. In simple terms, the category &amp;quot;total&amp;quot; will be equal to the sum of the scores in each grade item, these scores being multiplied by the grade items&#039; weights, and that sum being finally divided by the sum of the weights, as shown in this example.&lt;br /&gt;
    A1 70/100 weight 10, A2 20/80 weight 5, A3 10/10 weight 3, category max 100:&lt;br /&gt;
    (0.7*10 + 0.25*5 + 1.0*3)/18 = 0.625 --&amp;gt; 62.5/100&lt;br /&gt;
&lt;br /&gt;
== Simple weighted mean ==&lt;br /&gt;
The difference from Weighted mean is that weight is calculated as Maximum grade - Minimum grade for each item. 100 point assignment has weight 100, 10 point assignment has weight 10.&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10, category max 100:&lt;br /&gt;
    (0.7*100 + 0.25*80 + 1.0*10)/190 = 0.526 --&amp;gt; 52.6/100&lt;br /&gt;
&lt;br /&gt;
== Mean of grades (with extra credits) ==&lt;br /&gt;
Arithmetic mean with a twist. An old, now unsupported aggregation strategy provided here only for backward compatibility with old activities.&lt;br /&gt;
&lt;br /&gt;
== Median of grades ==&lt;br /&gt;
The middle grade (or the mean of the two middle grades) when grades are arranged in order of size. The advantage over the mean is that it is not affected by outliers (grades which are uncommonly far from the mean).&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10, category max 100:&lt;br /&gt;
    0.7 + 0.25 + 1.0 --&amp;gt; 0.70 --&amp;gt; 70/100&lt;br /&gt;
&lt;br /&gt;
== Smallest grade ==&lt;br /&gt;
The result is the smallest grade after normalisation. It is usually used in combination with Aggregate only non-empty grades.&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10, category max 100:&lt;br /&gt;
    min(0.7 + 0.25 + 1.0) = 0.25 --&amp;gt; 25/100&lt;br /&gt;
&lt;br /&gt;
== Highest grade ==&lt;br /&gt;
The result is the highest grade after normalisation.&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10, category max 100:&lt;br /&gt;
    max(0.7 + 0.25 + 1.0) = 1.0 --&amp;gt; 100/100&lt;br /&gt;
&lt;br /&gt;
== Mode of grades ==&lt;br /&gt;
The mode is the grade that occurs the most frequently. It is more often used for non-numerical grades. The advantage over the mean is that it is not affected by outliers (grades which are uncommonly far from the mean). However it loses its meaning once there is more than one most frequently occurring grade (only one is kept), or when all the grades are different from each other.&lt;br /&gt;
    A1 70/100, A2 35/50, A3 20/80, A4 10/10, A5 7/10 category max 100:&lt;br /&gt;
    mode(0.7; 0.7; 0.25; 1.0; 0.7) = 0.7 --&amp;gt; 70/100&lt;br /&gt;
&lt;br /&gt;
== Sum of grades ==&lt;br /&gt;
The sum of all grade values. Scale grades are ignored. This is the only type that does not convert the grades to percentages internally. The Maximum grade of associated category item is calculated automatically as a sum of maximums from all aggregated items.&lt;br /&gt;
    A1 70/100, A2 20/80, A3 10/10:&lt;br /&gt;
    70 + 20 + 10 = 100/190&lt;br /&gt;
&lt;br /&gt;
When the &amp;quot;Sum of grades&amp;quot; aggregation strategy is used, a grade item can act as Extra credit for the category. This means that the grade item&#039;s maximum grade will not be added to the category total&#039;s maximum grade, but the item&#039;s grade will. Following is an example:&lt;br /&gt;
&lt;br /&gt;
* Item 1 is graded 0-100&lt;br /&gt;
* Item 2 is graded 0-75&lt;br /&gt;
* Item 1 has the &amp;quot;Act as extra credit&amp;quot; checkbox ticked, Item 2 doesn&#039;t.&lt;br /&gt;
* Both items belong to Category 1, which has &amp;quot;Sum of grades&amp;quot; as its aggregation strategy&lt;br /&gt;
* Category 1&#039;s total will be graded 0-75&lt;br /&gt;
* A student gets graded 20 on Item 1 and 70 on Item 2&lt;br /&gt;
* The student&#039;s total for Category 1 will be 75/75 (20+70 = 90 but Item 1 only acts as extra credit, so it brings the total to its maximum)&lt;br /&gt;
&lt;br /&gt;
==Available aggregation types==&lt;br /&gt;
[[Image:Available agg types.png|thumb|Available aggregation types setting]]&lt;br /&gt;
In Moodle 1.9.5 onwards, a new available aggregation types setting in &#039;&#039;Administration &amp;gt; Grades &amp;gt; [[Grade category settings]]&#039;&#039; enables administrators to reduce the number of aggregation types.&lt;br /&gt;
&lt;br /&gt;
Note that reducing the number of aggregation types simply results in disabled aggregation types not appearing in the aggregation type dropdown menu. All existing grade category calculations remain the same, regardless of whether the aggregation type is later disabled by an administrator.&lt;br /&gt;
&lt;br /&gt;
[[ca:Agregació de les categories]]&lt;br /&gt;
[[fr:Tendance centrale de la catégorie]]&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61803</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61803"/>
		<updated>2009-08-20T13:12:28Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* link_to_popup_window (54) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61802</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61802"/>
		<updated>2009-08-20T12:09:13Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* link_to_popup_window (54) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61788</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61788"/>
		<updated>2009-08-20T09:02:52Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* link_to_popup_window (54) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;title = $title; // optional&lt;br /&gt;
$options[&#039;height&#039;] = $height; // optional&lt;br /&gt;
$options[&#039;width&#039;] = $width; // optional&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61787</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61787"/>
		<updated>2009-08-20T08:58:53Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* formerr (120) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61786</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61786"/>
		<updated>2009-08-20T08:53:38Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* print_table (140) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (120) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61784</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61784"/>
		<updated>2009-08-20T06:33:14Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: /* notice_yesno (79) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (120) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (with options in arrays):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, new moodle_url($linkyes, $optionsyes), new moodle_url($linkno, $optionsno));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
New code (if the &amp;quot;get&amp;quot; method is required):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (140) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclass = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();      // note the change of rowclass[] to rowclasses[]&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61783</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61783"/>
		<updated>2009-08-20T06:31:39Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (1) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (0) ===&lt;br /&gt;
&lt;br /&gt;
=== close_window_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: This is not for general use, do not confuse with help_icon()&lt;br /&gt;
&lt;br /&gt;
=== formerr (120) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
formerr($string);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;error_text($error);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (79) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = html_form::make_button($linkyes, $optionsyes, get_string(&#039;yes&#039;), $methodyes);&lt;br /&gt;
$formcancel = html_form::make_button($linkno, $optionsno, get_string(&#039;no&#039;), $methodno);&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// if $baseurl == &#039;http://domain.com/index.php?var1=1&amp;amp;amp;var2=&#039;&lt;br /&gt;
$select = html_select::make_popup_form(&#039;http://domain.com/index.php?var1=1&#039;, &#039;var2&#039;, $options, $formid, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional, set to false if no &amp;quot;nothing&amp;quot; option is desired (when $selectlabel == &#039;&#039; in original call)&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
$select-&amp;gt;form-&amp;gt;button-&amp;gt;text = $submitvalue; // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
*The $optionsextra param is not supported. If your code uses it, you should find another way to add extra params to your &amp;lt;option&amp;gt; tags without using this horrible hack which usually includes inline JS or CSS.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (10) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_footer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_with_help (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_heading (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_headline (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_headline($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_paging_bar (2) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The last two instances of print_paging_bar are found in the old tablelib, which will soon be deprecated.&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_scale_menu_helpbutton($courseid, $scale);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_button(help_button::make_scale_menu($courseid, $scale));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (0) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (140) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclass = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();      // note the change of rowclass[] to rowclasses[]&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_time_selector (0) ===&lt;br /&gt;
&lt;br /&gt;
=== print_user_picture (0) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new moodle_user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (0) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Developement:How_Moodle_outputs_HTML]]&lt;br /&gt;
* [[Development:Migrating your code to the 2.0 rendering_API]]&lt;br /&gt;
&lt;br /&gt;
{{CategoryDeveloper}}&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61782</id>
		<title>Development:Deprecated functions in 2.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/38/en/index.php?title=Development:Deprecated_functions_in_2.0&amp;diff=61782"/>
		<updated>2009-08-20T06:28:33Z</updated>

		<summary type="html">&lt;p&gt;Nicolasconnault: Reverted edits by Nicolasconnault (Talk) to last version by Mudrd8mz&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
This page lists the old HTML-outputting functions of pre-2.0 lib/weblib.php and their 2.0 equivalents using $OUTPUT functions. &lt;br /&gt;
&lt;br /&gt;
== General notes ==&lt;br /&gt;
The principle of the new rendering API is to let the developer build metadata-rich components that &#039;&#039;represent&#039;&#039; HTML elements, but may be rendered in many different ways. A menu component, for example, could be rendered as a &amp;lt;select&amp;gt; element, or as a list of radio buttons or check boxes.&lt;br /&gt;
&lt;br /&gt;
The following functions have been arranged in alphabetical order, although some of them are very closely related to each other. The number of occurrences of these function calls at the time of writing are indicated in parentheses.&lt;br /&gt;
&lt;br /&gt;
== Functions to migrate ==&lt;br /&gt;
=== button_to_popup_window (4) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
button_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return, $id, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $linkname;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $title;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;id = $id;&lt;br /&gt;
$form-&amp;gt;url = $url;&lt;br /&gt;
$form-&amp;gt;add_class($class);&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to button_to_popup_window() will not work. The $height and $width params are also part of the popup params. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu (192) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex, $id, $listbox, $multiple, $class);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected); // Required&lt;br /&gt;
$select-&amp;gt;nothinglabel = $nothing;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;id = $id;&lt;br /&gt;
$select-&amp;gt;listbox = $listbox;&lt;br /&gt;
$select-&amp;gt;multiple = $multiple;&lt;br /&gt;
$select-&amp;gt;add_classes($class);&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_nested (6) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_nested($options, $name, $selected, $nothing, $script, $nothingvalue, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make($options, $name, $selected);&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;nothingvalue = $nothingvalue;&lt;br /&gt;
$select-&amp;gt;nested = true;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: &lt;br /&gt;
#The lang string &amp;quot;choose&amp;quot; is no longer used, in favour of &amp;quot;choosedots&amp;quot;.&lt;br /&gt;
#The $script param is no longer supported. Please use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_menu_yesno (5) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
choose_from_menu_yesno($name, $selected, $script, $return, $disabled, $tabindex);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$select = moodle_select::make_yes_no($name, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled;&lt;br /&gt;
$select-&amp;gt;tabindex = $tabindex;&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $script param has been dropped, you need to use component::add_action() instead.&lt;br /&gt;
&lt;br /&gt;
=== choose_from_radio (6) ===&lt;br /&gt;
=== close_window_button (34) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
close_window_button($name, $return, $reloadopener);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;close_window_button(get_string($name));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: You must pass a language string already processed by get_string().&lt;br /&gt;
&lt;br /&gt;
=== print_continue (91) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_continue($link, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;continue_button($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== doc_link (30) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;doc_link($path, $text, $iconpath);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== helpbutton (391) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
helpbutton($page, $title, $module, $image, $linktext, $text, $return, $imagetext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$helpicon = new help_icon();&lt;br /&gt;
$helpicon-&amp;gt;page = $page; // required&lt;br /&gt;
$helpicon-&amp;gt;text = $title; // required&lt;br /&gt;
$helpicon-&amp;gt;module = $module; // defaults to &#039;moodle&#039;&lt;br /&gt;
$helpicon-&amp;gt;linktext = $linktext;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;help_icon($helpicon);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== link_to_popup_window (54) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
link_to_popup_window($url, $name, $linkname, $height, $width, $title, $options, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$link = html_link::make($url, $linkname);&lt;br /&gt;
$link-&amp;gt;add_action(new popup_action(&#039;click&#039;, $url, $name, $options));&lt;br /&gt;
echo $OUTPUT-&amp;gt;link_to_popup($link);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: popup parameters ($options) &#039;&#039;&#039;must&#039;&#039;&#039; be prepared as an associative array, not a string as previously. Simply reusing the $options param previously passed to link_to_popup_window() will not work. See lib/deprecatedlib.php for an example of how the legacy function call is handled.&lt;br /&gt;
&lt;br /&gt;
=== notice_yesno (79) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notice_yesno($message, $linkyes, $linkno, $optionsyes, $optionsno, $methodyes, $methodno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simplest form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $linkyes, $linkno);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex form):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$formcontinue = new html_form();&lt;br /&gt;
$formcontinue-&amp;gt;url = new moodle_url($linkyes, $optionsyes);&lt;br /&gt;
$formcontinue-&amp;gt;button-&amp;gt;text = get_string(&#039;yes&#039;);&lt;br /&gt;
$formcontinue-&amp;gt;method = $methodyes;&lt;br /&gt;
&lt;br /&gt;
$formcancel = new html_form();&lt;br /&gt;
$formcancel-&amp;gt;url = new moodle_url($linkno, $optionsno);&lt;br /&gt;
$formcancel-&amp;gt;button-&amp;gt;text = get_string(&#039;no&#039;);&lt;br /&gt;
$formcancel-&amp;gt;method = $methodno;&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;confirm($message, $formcontinue, $formcancel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== notify (548) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
notify($message, $classes, $align, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;notification($message, $classes=&#039;&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS rule for alignment.&lt;br /&gt;
&lt;br /&gt;
=== popup_form (51) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
popup_form($baseurl, $options, $formid, $selected, $nothing, $help, $helptext, $return, $targetwindow, $selectlabel, $optionsextra, $submitvalue, $disabled, $showbutton);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// After converting $options&#039; keys to full URLs:&lt;br /&gt;
$select = moodle_select::make_popup_form($options, $formid, $submitvalue, $selected);&lt;br /&gt;
$select-&amp;gt;disabled = $disabled; // optional&lt;br /&gt;
$select-&amp;gt;set_label($selectlabel, $select-&amp;gt;id); // optional&lt;br /&gt;
$select-&amp;gt;set_help_icon($help, $helptext); // optional&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;select($select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: You must convert the $options array so that the index keys represent a full URL: $baseurl . $key . $optionsextra[$key]. See lib/deprecatedlib.php for an example of conversion.&lt;br /&gt;
&lt;br /&gt;
=== print_arrow (15) ===&lt;br /&gt;
=== print_box* (380) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_box($message, $classes, $ids, $return);&lt;br /&gt;
print_box_start($classes, $ids, $return);&lt;br /&gt;
print_box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;box($message, $classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_start($classes, $ids);&lt;br /&gt;
echo $OUTPUT-&amp;gt;box_end();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_checkbox (33) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_checkbox($name, $value, $checked, $label, $alt, $script, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$checkbox = new html_select_option();&lt;br /&gt;
$checkbox-&amp;gt;value = $value; // Required&lt;br /&gt;
$checkbox-&amp;gt;selected = $checked;&lt;br /&gt;
$checkbox-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;label-&amp;gt;text = $label;&lt;br /&gt;
$checkbox-&amp;gt;alt = $alt;&lt;br /&gt;
                                               &lt;br /&gt;
echo $OUTPUT-&amp;gt;checkbox($checkbox, $name);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: html_select_option is a component that can be rendered as a select &amp;lt;option&amp;gt;, a radio button or a checkbox. It holds sufficient information to render all these elements, except the $name variable which is attached to a moodle_select component. This is why we pass the $name string to $OUTPUT-&amp;gt;checkbox().&lt;br /&gt;
&lt;br /&gt;
=== print_container (153) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_container($message, $clearfix, $classes, $idbase, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($clearfix) {&lt;br /&gt;
    $classes .= &#039; clearfix&#039;;&lt;br /&gt;
}&lt;br /&gt;
echo $OUTPUT-&amp;gt;container($message, $classes, $idbase);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_date_selector (11) ===&lt;br /&gt;
=== print_footer (569) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_footer($course, $usercourse, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;footer();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: No parameters are required.&lt;br /&gt;
&lt;br /&gt;
=== print_header (501) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_header($title, $heading, $navigation, $focus, $meta, $cache, $button, $menu, $usexml, $bodytags, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_heading($heading); // Required&lt;br /&gt;
$PAGE-&amp;gt;set_title($title);&lt;br /&gt;
$PAGE-&amp;gt;set_cacheable($cache);&lt;br /&gt;
$PAGE-&amp;gt;set_focuscontrol($focus);&lt;br /&gt;
$PAGE-&amp;gt;set_button($button);&lt;br /&gt;
echo $OUTPUT-&amp;gt;header($navigation, $menu);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Navigation code is being rewritten, this doc will then be updated with the new usage.&lt;br /&gt;
&lt;br /&gt;
=== print_header_with_help (0) ===&lt;br /&gt;
=== print_heading (436) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_heading($text, $align, $size, $class, $return, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
echo $OUTPUT-&amp;gt;heading($text, $size, $class, $id);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: Use a CSS class rule to control alignment.&lt;br /&gt;
&lt;br /&gt;
=== print_heading_block (9) ===&lt;br /&gt;
=== print_headline (11) ===&lt;br /&gt;
=== print_paging_bar (41) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_paging_bar($totalcount, $page, $perpage, $baseurl, $pagevar, $nocurr, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$pagingbar = new moodle_paging_bar();&lt;br /&gt;
$pagingbar-&amp;gt;totalcount = $totalcount; // Required&lt;br /&gt;
$pagingbar-&amp;gt;page = $page; // Required&lt;br /&gt;
$pagingbar-&amp;gt;perpage = $perpage; // Required&lt;br /&gt;
$pagingbar-&amp;gt;baseurl = $baseurl; // Required&lt;br /&gt;
$pagingbar-&amp;gt;pagevar = $pagevar;&lt;br /&gt;
$pagingbar-&amp;gt;nocurr = $nocurr;&lt;br /&gt;
echo $OUTPUT-&amp;gt;paging_bar($pagingbar);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_scale_menu_helpbutton (6) ===&lt;br /&gt;
=== print_side_block (4) ===&lt;br /&gt;
=== print_single_button (108) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_single_button($link, $options, $label, $method, $notusedanymore, $return, $tooltip, $disabled, $jsconfirmmessage, $formid)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$form = new html_form();&lt;br /&gt;
$form-&amp;gt;url = new moodle_url($link, $options); // Required&lt;br /&gt;
$form-&amp;gt;button = new html_button();&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;text = $label; // Required&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;disabled = $disabled;&lt;br /&gt;
$form-&amp;gt;button-&amp;gt;title = $tooltip;&lt;br /&gt;
$form-&amp;gt;method = $method;&lt;br /&gt;
$form-&amp;gt;id = $formid;&lt;br /&gt;
&lt;br /&gt;
if ($jsconfirmmessage) {&lt;br /&gt;
    $confirmaction = new component_action(&#039;click&#039;, &#039;confirm_dialog&#039;, array(&#039;message&#039; =&amp;gt; $jsconfirmmessage));&lt;br /&gt;
    $form-&amp;gt;button-&amp;gt;add_action($confirmaction);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
$output = $OUTPUT-&amp;gt;button($form);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== print_spacer (20) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_spacer($height, $width, $br, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$spacer = new html_image();&lt;br /&gt;
$spacer-&amp;gt;height = $height;&lt;br /&gt;
$spacer-&amp;gt;width = $width;&lt;br /&gt;
echo $OUTPUT-&amp;gt;spacer($spacer);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: The $br attribute has been dropped. You can simply add a line break manually if you need one.&lt;br /&gt;
&lt;br /&gt;
=== print_table (140) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new stdClass();&lt;br /&gt;
$table-&amp;gt;class = &#039;mytable&#039;;&lt;br /&gt;
$table-&amp;gt;head  = array(&#039;Firstname&#039;, &#039;Lastname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclass = array();&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
print_table($table, $return);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$table = new html_table();&lt;br /&gt;
$table-&amp;gt;set_classes(&#039;mytable&#039;); // note the new style of setting CSS class&lt;br /&gt;
$table-&amp;gt;head = array(&#039;First name&#039;, &#039;Last name&#039;);&lt;br /&gt;
$table-&amp;gt;colclasses = array(&#039;name fname&#039;,&#039;name lname&#039;);&lt;br /&gt;
$table-&amp;gt;rowclasses = array();      // note the change of rowclass[] to rowclasses[]&lt;br /&gt;
// (other table properties here)&lt;br /&gt;
$table-&amp;gt;data = array(array(...),array(...),array(...));&lt;br /&gt;
echo $OUTPUT-&amp;gt;table($newtable);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes: The new html_table object has the same member variables as the one originally used by print_table(), but has additional, required methods. You must map the old $table object to the new html_table object, as demonstrated above and in lib/deprecatedlib.php (see old print_table function).&lt;br /&gt;
&lt;br /&gt;
=== print_textarea (55) ===&lt;br /&gt;
=== print_textfield (2) ===&lt;br /&gt;
=== print_time_selector (9) ===&lt;br /&gt;
=== print_user_picture (77) ===&lt;br /&gt;
&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
print_user_picture($user, $courseid, $picture, $size, $return, $link, $target, $alttext);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (simple):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code (complex: alternate text, size, different image and popup action):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$userpic = new user_picture();&lt;br /&gt;
$userpic-&amp;gt;user = $user;&lt;br /&gt;
$userpic-&amp;gt;courseid = $courseid;&lt;br /&gt;
$userpic-&amp;gt;size = $size;&lt;br /&gt;
$userpic-&amp;gt;link = $link;&lt;br /&gt;
$userpic-&amp;gt;alttext = $alttext;&lt;br /&gt;
$userpic-&amp;gt;image-&amp;gt;src = $picture;&lt;br /&gt;
$userpic-&amp;gt;add_action(new popup_action(&#039;click&#039;, new moodle_url($target)));&lt;br /&gt;
&lt;br /&gt;
echo $OUTPUT-&amp;gt;user_picture($userpic);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== update_course_button (0) ===&lt;br /&gt;
&lt;br /&gt;
=== update_module_button (94) ===&lt;br /&gt;
Old code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$button = update_module_button($cm-&amp;gt;id, $course-&amp;gt;id, get_string(&#039;modulename&#039;, &#039;workshop&#039;)); // passed to print_header_simple()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
New code:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$PAGE-&amp;gt;set_button($OUTPUT-&amp;gt;update_module_button($cm-&amp;gt;id, &#039;workshop&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Note: $courseid param has been dropped.&lt;br /&gt;
&lt;br /&gt;
=== update_tag_button (4) ===&lt;br /&gt;
&lt;br /&gt;
== Non-supported functions ==&lt;br /&gt;
These functions have been completely dropped in 2.0, most likely because they were used very little or not at all. All calls to these functions in core should have been replaced.&lt;br /&gt;
=== blocks_print_group ===&lt;br /&gt;
=== print_file_picture ===&lt;br /&gt;
=== print_png ===&lt;br /&gt;
=== print_scale_menu ===&lt;br /&gt;
=== print_side_block_end ===&lt;br /&gt;
=== print_side_block_start ===&lt;br /&gt;
=== print_timer_selector ===&lt;br /&gt;
=== print_user ===&lt;br /&gt;
=== update_categories_search_button ===&lt;br /&gt;
=== update_mymoodle_icon ===&lt;/div&gt;</summary>
		<author><name>Nicolasconnault</name></author>
	</entry>
</feed>