Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

User:Mark Johnson/Namespaces: Difference between revisions

From MoodleDocs
m (Made headers higher level)
No edit summary
Line 1: Line 1:
{{Work_in_progress}}
==Notes about using PHP namespaces in Moodle plugin development==
==Notes about using PHP namespaces in Moodle plugin development==


'''Goal:''' To take advantage of namespace features in PHP 5.3 to allow plugins to be written with less verbose function names, while still avoiding name collisions
'''Goal:''' To take advantage of namespace features in PHP 5.3 to allow plugins to be written with less verbose function names, while still avoiding name collisions
===About this document===
For the purposes of this document, the term "function" will be used to refer to any PHP function, constant or class defined in a Moodle plugin library, since namespaces apply to all 3 in the same way.
The exemplar plugin used for this exercise is an admin report used for calculating Target Grades.
===Current Issue===  
===Current Issue===  
When writing a plugin, one creates a lib.php or locallib.php containing a set of functions for use within that plugin.  Each function name (and similarly, constant names and class names) must currently be prefixed in the format <tt>{plugintype}_{pluginname}_</tt>, to avoid a function that performs a similar task in a separate plugin having the same name, thus causing a name collision.   
When writing a plugin, one creates a lib.php or locallib.php containing a set of functions for use within that plugin.  Each function name must currently be prefixed in the format <tt>{plugintype}_{pluginname}_</tt>, to avoid a function that performs a similar task in a separate plugin having the same name, thus causing a name collision.   


This can result in overly verbose function names which inhibits both readability and ease of writing of code. For example, a function for printing tabs in an admin report named targetgrades would need to be called <tt>report_targetgrades_print_tabs()</tt> since there is already a global function called <tt>print_tabs()</tt>. The majority of this name is only there to avoid name collisions, and it otherwise redundant.
This can result in overly verbose function names which inhibits both readability and ease of writing of code. For example, a function for printing tabs in an admin report named targetgrades would need to be called <tt>report_targetgrades_print_tabs()</tt> since there is already a global function called <tt>print_tabs()</tt>. The majority of this name is only there to avoid name collisions, and it otherwise redundant.


===Proposal===
===Proposal===
I am going to upgrade one of my Moodle 1.9 blocks for use in Moodle 2.x. During this process I will alter the libraries to use namespaces, allowing functions, classes and constants to have shorter names while still avoiding name collisions.  In files including these libraries, I will use namespace aliases to allow the functions/classes/constants to be called using much shorter notation.
I am going to upgrade one of my Moodle 1.9 blocks for use in Moodle 2.x. During this process I will alter the libraries to use namespaces, allowing functions, classes and constants to have shorter names while still avoiding name collisions.  In files including these libraries, I will use namespace aliases to allow the functions to be called using much shorter notation.


====Naming convention====
====Naming convention====
As mentioned above, the current naming convention for prefixing functions is <tt>plugintype_pluginname</tt>.  It makes logical sense to use a similar convention in the namespace hierachy - each plugin having a namespace of <tt>plugintype\pluginame</tt>.  For example, all admin reports would have their functions the <tt>report</tt> namespace, and the Target Grades report described above would have it's own sub-namespace, <tt>report\targetgrades</tt>.
As mentioned above, the current naming convention for prefixing functions is <tt>plugintype_pluginname</tt>.  It makes logical sense to use a similar convention in the namespace hierachy - each plugin having a namespace of <tt>plugintype\pluginame</tt>.  For example, all admin reports would have their functions the <tt>report</tt> namespace, and the Target Grades report would have it's own sub-namespace, <tt>report\targetgrades</tt>.
 
====Potential issues====
This may cause issues with some plugin types.  For example, Activity modules require certain functions following the current naming convention to exist in lib.php. Placing these functions within a namespace would prevent them from working properly.
 
Most plugin types will include lib.php and its functions automatically. While this should not cause a problem for the majority of plugin types since the functions shouldn't be accessed unless explicitly requested in the code, it's a potential source of problems to be aware of.
 
===Steps for conversion===
All libraries used by the plugin needed to be put inside the plugin's namespace.  This was achieved by placing the following line at the top of the library files
<code php>namespace report\targetgrades;</code>
Note that the <tt>report</tt> namespace does not already have to have been defined for this to work.
 
Next, the <tt>report_targetgrade</tt>

Revision as of 09:02, 24 May 2011

Note: This page is a work-in-progress. Feedback and suggested improvements are welcome. Please join the discussion on moodle.org or use the talk.


Notes about using PHP namespaces in Moodle plugin development

Goal: To take advantage of namespace features in PHP 5.3 to allow plugins to be written with less verbose function names, while still avoiding name collisions

About this document

For the purposes of this document, the term "function" will be used to refer to any PHP function, constant or class defined in a Moodle plugin library, since namespaces apply to all 3 in the same way.

The exemplar plugin used for this exercise is an admin report used for calculating Target Grades.

Current Issue

When writing a plugin, one creates a lib.php or locallib.php containing a set of functions for use within that plugin. Each function name must currently be prefixed in the format {plugintype}_{pluginname}_, to avoid a function that performs a similar task in a separate plugin having the same name, thus causing a name collision.

This can result in overly verbose function names which inhibits both readability and ease of writing of code. For example, a function for printing tabs in an admin report named targetgrades would need to be called report_targetgrades_print_tabs() since there is already a global function called print_tabs(). The majority of this name is only there to avoid name collisions, and it otherwise redundant.

Proposal

I am going to upgrade one of my Moodle 1.9 blocks for use in Moodle 2.x. During this process I will alter the libraries to use namespaces, allowing functions, classes and constants to have shorter names while still avoiding name collisions. In files including these libraries, I will use namespace aliases to allow the functions to be called using much shorter notation.

Naming convention

As mentioned above, the current naming convention for prefixing functions is plugintype_pluginname. It makes logical sense to use a similar convention in the namespace hierachy - each plugin having a namespace of plugintype\pluginame. For example, all admin reports would have their functions the report namespace, and the Target Grades report would have it's own sub-namespace, report\targetgrades.

Potential issues

This may cause issues with some plugin types. For example, Activity modules require certain functions following the current naming convention to exist in lib.php. Placing these functions within a namespace would prevent them from working properly.

Most plugin types will include lib.php and its functions automatically. While this should not cause a problem for the majority of plugin types since the functions shouldn't be accessed unless explicitly requested in the code, it's a potential source of problems to be aware of.

Steps for conversion

All libraries used by the plugin needed to be put inside the plugin's namespace. This was achieved by placing the following line at the top of the library files namespace report\targetgrades; Note that the report namespace does not already have to have been defined for this to work.

Next, the report_targetgrade