Mod authors: Changes in SMF 2.0: Difference between revisions From Online Manual

Jump to: navigation, search
No edit summary
 
m (Bot: Automated text replacement (-  + ))
 
(20 intermediate revisions by 7 users not shown)
Line 1: Line 1:
SMF 2.0 has had some large code changes, a lot of which affect how mods are written. Code has been restructured for greater efficiency, several new features have been added (which make certain mods obsolete), etc. Due to the volume of changes, almost all mods designed for SMF 1.1 will not work with SMF 2.0. This document is a short introduction on converting SMF 1.1 mods to SMF 2.0. It is not an exhaustive reference, but should help you get your mod up and running on SMF 2.0.
SMF 2.0 has had some large code changes, a lot of which affect how mods are written. Code has been restructured for greater efficiency, several new features have been added (which make certain mods obsolete), etc. Due to the volume of changes, almost all mods designed for SMF 1.1 will not work with SMF 2.0. This document is a short introduction on converting SMF 1.1 mods to SMF 2.0. It is not an exhaustive reference, but should help you get your mod up and running on SMF 2.0.


<span id="post_overview">
== Database Queries ==
'''Overview:'''
SMF 1.1 only supported MySQL, and hence, MySQL functions are usually used in mods. In SMF 2.0, a database abstraction layer has been added, allowing for different database systems to be used (at the time of writing, MySQL, PostgreSQL, and SQLite are supported). As such, all MySQL function calls willl need to be changed to use the new SMF functions.
</span><ul class="bbc_list"><li>[[#post_db|" class="bbc_link">Database Queries]]
<ul class="bbc_list"><li>[[#post_db_column|" class="bbc_link">Column Names]]</li><li>[[#post_db_query|" class="bbc_link">db_query function]]</li><li>[[#post_db_example|" class="bbc_link">Example]]</li></ul></li><li>[[#post_id_member|" class="bbc_link">$ID_MEMBER removal]]</li><li>[[#post_menu|" class="bbc_link">Menus]]
<ul class="bbc_list"><li>[[#post_menu_main|" class="bbc_link">Main Menu]]</li><li>[[#post_menu_admin|" class="bbc_link">Administration Menu]]</li></ul></li></ul>
<span id="post_db">
<span style="font-size: 4;" class="bbc_size">Database Queries</span></span>----SMF 1.1 only supported MySQL, and hence, MySQL functions are usually used in mods. In SMF 2.0, a database abstraction layer has been added, allowing for different database systems to be used (at the time of writing, MySQL, PostgreSQL, and SQLite are supported). As such, all MySQL function calls willl need to be changed to use the new SMF functions.


Because multiple database systems are supported, it is recommended that you do '''not''' use MySQL-specific SQL features (eg. '''ON DUPLICATE KEY UPDATE'''. If you stick to SQL92 SQL features, you can be assured that your mod ''should'' work on the majority of modern <acronym title="Relational Database Management Systems">RDBMS systems</acronym>.
Because multiple database systems are supported, it is recommended that you do '''not''' use MySQL-specific SQL features (eg. '''ON DUPLICATE KEY UPDATE'''). If you stick to SQL92 SQL features, you can be assured that your mod ''should'' work on the majority of modern <abbr title="Relational Database Management Systems">RDBMS systems</abbr>.


The main functions are listed below:
The main functions are listed below:
<table class="bbc_table"><tr><td>'''Function used in SMF 1.1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '''</td><td>'''SMF 2.0 equivalent'''</td></tr><tr><td>db_query</td><td>$smcFunc&#91;&#039;db_query&#039;]</td></tr><tr><td>mysql_fetch_assoc</td><td>$smcFunc&#91;&#039;db_fetch_assoc&#039;]</td></tr><tr><td>mysql_fetch_row</td><td>$smcFunc&#91;&#039;db_fetch_row&#039;]</td></tr><tr><td>mysql_num_rows</td><td>$smcFunc&#91;&#039;db_num_rows&#039;]</td></tr><tr><td>mysql_free_result</td><td>$smcFunc&#91;&#039;db_free_result&#039;]</td></tr><tr><td>mysql_real_escape_string or mysql_escape_string</td><td>$smcFunc&#91;&#039;db_escape_string&#039;]</td></tr></table>You will find a more indepth and detailed information about the SMF 2.0 functions in our [[SMF 2.0 Database Functions]] topic on the community forums.
{|
[[#post_overview|" class="bbc_link">Back to overview]]
|-
! Function used in SMF 1.1
! SMF 2.0 equivalent
|-
| db_query
| $smcFunc['db_query']
|-
| mysql_fetch_assoc
| $smcFunc['db_fetch_assoc']
|-
| mysql_fetch_row
| $smcFunc['db_fetch_row']
|-
| mysql_num_rows
| $smcFunc['db_num_rows']
|-
| mysql_free_result
| $smcFunc['db_free_result']
|-
| mysql_real_escape_string or mysql_escape_string
| $smcFunc['db_escape_string']
|}
You will find a more in-depth and detailed information about the SMF 2.0 functions in our [[$smcFunc|SMF 2.0 Database Functions]] topic on the community forums.


<span id="post_db_column">
=== Column Names ===
'''Column Names'''
In SMF 2.0, all uppercase column names have been changed. This was done because some database systems do not support uppercase column names. The index columns that had uppercase names in SMF 1.1 (eg. ID_MSG, ID_TOPIC, ID_MEMBER) have had their names changes to lowercase (id_msg, id_topic, id_member). Additionally, any columns that used camel case (memberName) have changed to use an underscore between words (member_name)
In SMF 2.0, all uppercase column names have been changed. This was done because some database systems do not support uppercase column names. The index columns that had uppercase names in SMF 1.1 (eg. ID_MSG, ID_TOPIC, ID_MEMBER) have had their names changes to lowercase (id_msg, id_topic, id_member). Additionally, any columns that used camel case (memberName) have changed to use an underscore between words (member_name)


An example is below
An example is below
[[#post_overview|" class="bbc_link">Back to overview]]


<span id="post_db_example">
=== Code example ===
'''Code example'''
This code is for SMF 1.1:
This code is for SMF 1.1:
</span></span><div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>echo &#039;
&nbsp;&nbsp;&nbsp;&lt;ul&gt;&#039;;


// Get all the topics in board 1
echo '
$result = db_query(&quot;
    <ul>';
&nbsp;&nbsp;&nbsp;SELECT t.ID_TOPIC, m.posterName, m.subject
&nbsp;&nbsp;&nbsp;FROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)
// Get all the topics in board 1
&nbsp;&nbsp;&nbsp;WHERE t.ID_BOARD = 1
$result = db_query("
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AND m.ID_MSG = t.ID_FIRST_MSG
    SELECT t.ID_TOPIC, m.posterName, m.subject
&nbsp;&nbsp;&nbsp;LIMIT 10&quot;, __FILE__, __LINE__);
    FROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)
&nbsp;&nbsp;&nbsp;
    WHERE t.ID_BOARD = 1
// Loop through all results  
      AND m.ID_MSG = t.ID_FIRST_MSG
while ($row = mysql_fetch_assoc($result))
    LIMIT 10", __FILE__, __LINE__);
{
   
&nbsp;&nbsp;&nbsp;// Echo this result
// Loop through all results
&nbsp;&nbsp;&nbsp;echo &#039;
while ($row = mysql_fetch_assoc($result))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;&#039;, $row&#91;&#039;subject&#039;], &#039; by &#039;, $row&#91;&#039;posterName&#039;], &#039;&lt;/li&gt;&#039;;
{
}
    // Echo this result
    echo '
      <li>', $row['subject'], ' by ', $row['posterName'], '</li>';
}
mysql_free_result($result);
echo '
    </ul>';


mysql_free_result($result);
echo &#039;
&nbsp;&nbsp;&nbsp;&lt;/ul&gt;&#039;;
</code>
And this is the SMF 2.0 equivalent:
And this is the SMF 2.0 equivalent:
<div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>echo &#039;
echo '
&nbsp;&nbsp;&nbsp;&lt;ul&gt;&#039;;
    <ul>';
 
// Get all the topics in board 1
// Get all the topics in board 1
$result = $smcFunc&#91;&#039;db_query&#039;](&#039;&#039;, &quot;
$result = $smcFunc['db_query']('', "
&nbsp;&nbsp;&nbsp;SELECT t.id_topic, m.poster_name, m.subject
    SELECT t.id_topic, m.poster_name, m.subject
&nbsp;&nbsp;&nbsp;FROM {db_prefix}topics AS t
    FROM {db_prefix}topics AS t
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
      INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
&nbsp;&nbsp;&nbsp;WHERE t.id_board = {int:id_board}
    WHERE t.id_board = {int:id_board}
&nbsp;&nbsp;&nbsp;LIMIT 10&quot;,
    LIMIT 10",
&nbsp;&nbsp;&nbsp;array(
    array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;id_board&#039; =&gt; 1,
      'id_board' => 1,
&nbsp;&nbsp;&nbsp;));
    ));
&nbsp;&nbsp;&nbsp;
   
// Loop through all results  
// Loop through all results  
while ($row = $smcFunc&#91;&#039;db_fetch_assoc&#039;]($result))
while ($row = $smcFunc['db_fetch_assoc']($result))
{
{
&nbsp;&nbsp;&nbsp;// Echo this result
    // Echo this result
&nbsp;&nbsp;&nbsp;echo &#039;
    echo '
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;&#039;, $row&#91;&#039;subject&#039;], &#039; by &#039;, $row&#91;&#039;poster_name&#039;], &#039;&lt;/li&gt;&#039;;
      <li>', $row['subject'], ' by ', $row['poster_name'], '</li>';
}
}
$smcFunc['db_free_result']($result);
echo '
    </ul>';


$smcFunc&#91;&#039;db_free_result&#039;]($result);
== $ID_MEMBER ==
In SMF 1.1, the $ID_MEMBER variable contained the current user's ID. SMF 2.0 has removed this variable. Any code using $ID_MEMBER will need to be edited so it uses either $user_info['id'] or $context['user']['id'].


echo &#039;
== Menus ==
&nbsp;&nbsp;&nbsp;&lt;/ul&gt;&#039;;
=== Main menu ===
</code>[[#post_overview|" class="bbc_link">Back to overview]]
 
 
<span id="post_id">
'''$ID_MEMBER'''
In SMF 1.1, the $ID_MEMBER variable contained the current user&#039;s ID. SMF 2.0 has removed this variable. Any code using $ID_MEMBER will need to be edited so it uses either $user_info&#91;&#039;id&#039;] or $context&#91;&#039;user&#039;]&#91;&#039;id&#039;].
 
<span id="post_menu">
<span style="font-size: 4;" class="bbc_size">Menus</span></span></span>----<span id="post_menu_main">
'''Main menu'''
In SMF 1.1, each theme had its own main menu in index.template.php. For example, the code for the Calendar button in the SMF 1.1 default theme (Core) looks like this:
In SMF 1.1, each theme had its own main menu in index.template.php. For example, the code for the Calendar button in the SMF 1.1 default theme (Core) looks like this:
</span><div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>&nbsp;&nbsp;&nbsp;if ($context&#91;&#039;allow_calendar&#039;])
    if ($context['allow_calendar'])
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo ($current_action == &#039;calendar&#039; || $context&#91;&#039;browser&#039;]&#91;&#039;is_ie4&#039;]) ? &#039;&lt;td class=&quot;maintab_active_&#039; . $first . &#039;&quot;&gt;&amp;nbsp;&lt;/td&gt;&#039; : &#039;&#039; , &#039;
      echo ($current_action == 'calendar' || $context['browser']['is_ie4']) ? '<td class="maintab_active_' . $first . '"> </td>' : '' , '
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td valign=&quot;top&quot; class=&quot;maintab_&#039; , $current_action == &#039;calendar&#039; ? &#039;active_back&#039; : &#039;back&#039; , &#039;&quot;&gt;
            <td valign="top" class="maintab_' , $current_action == 'calendar' ? 'active_back' : 'back' , '">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href=&quot;&#039;, $scripturl, &#039;?action=calendar&quot;&gt;&#039; , $txt&#91;&#039;calendar24&#039;] , &#039;&lt;/a&gt;
                <a href="', $scripturl, '?action=calendar">' , $txt['calendar24'] , '</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;&#039; , $current_action == &#039;calendar&#039; ? &#039;&lt;td class=&quot;maintab_active_&#039; . $last . &#039;&quot;&gt;&amp;nbsp;&lt;/td&gt;&#039; : &#039;&#039;;
            </td>' , $current_action == 'calendar' ? '<td class="maintab_active_' . $last . '"> </td>' : '';
</code>
SMF 2.0 has moved all the menu items to Subs.php, in a &quot;setupMenuContext&quot; function. This simplifies theme writing, and makes it easier for mod authors (just edit the Subs.php file, and a button appears on all themes). As an example, the Calendar button has become:
<div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;calendar&#039; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;title&#039; =&gt; $txt&#91;&#039;calendar&#039;],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;href&#039; =&gt; $scripturl . &#039;?action=calendar&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;show&#039; =&gt; $context&#91;&#039;allow_calendar&#039;],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;sub_buttons&#039; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;view&#039; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;title&#039; =&gt; $txt&#91;&#039;calendar_menu&#039;],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;href&#039; =&gt; $scripturl . &#039;?action=calendar&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;show&#039; =&gt; true,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;post&#039; =&gt; array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;title&#039; =&gt; $txt&#91;&#039;calendar_post_event&#039;],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;href&#039; =&gt; $scripturl . &#039;?action=calendar;sa=post;sesc=&#039; . $context&#91;&#039;session_id&#039;],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;show&#039; =&gt; allowedTo(&#039;calendar_post&#039;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
</code>In Subs.php. A new feature is that each button can have several &quot;sub-buttons&quot;. In the future, some themes may render these sub-buttons as a dropdown menu. This is done on the simplemachines.org community forum.
[[#post_overview|" class="bbc_link">Back to overview]]


<span id="post_menu_admin">
SMF 2.0 has moved all the menu items to Subs.php, in a "setupMenuContext" function. This simplifies theme writing, and makes it easier for mod authors (just edit the Subs.php file, and the added button appears on all themes). As an example, the Calendar button has become: (Subs.php)
'''Administration menu'''
        'calendar' => array(
In SMF 1.1, the administration menu was defined in the adminIndex() function in Subs.php. For example, the &quot;Forum&quot; section looks like:
            'title' => $txt['calendar'],
</span><div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>&nbsp;&nbsp;&nbsp;// Admin area &#039;Forum&#039;.
            'href' => $scripturl . '?action=calendar',
&nbsp;&nbsp;&nbsp;if (allowedTo(array(&#039;manage_boards&#039;, &#039;admin_forum&#039;, &#039;manage_smileys&#039;, &#039;manage_attachments&#039;, &#039;moderate_forum&#039;)))
            'show' => $context['allow_calendar'],
&nbsp;&nbsp;&nbsp;{
            'sub_buttons' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;] = array(
              'view' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;title&#039; =&gt; $txt&#91;&#039;layout_controls&#039;],
                  'title' => $txt['calendar_menu'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;areas&#039; =&gt; array()
                  'href' => $scripturl . '?action=calendar',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);
                  'show' => true,
              ),
              'post' => array(
                  'title' => $txt['calendar_post_event'],
                  'href' => $scripturl . '?action=calendar;sa=post;sesc=' . $context['session_id'],
                  'show' => allowedTo('calendar_post'),
              ),
            ),
        ),


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (allowedTo(&#039;manage_boards&#039;))
A new feature is that each button can have several "sub-buttons". Curve-based themes may render these sub-buttons as a dropdown menu. This is done on the simplemachines.org community forum.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;manage_boards&#039;] =&nbsp; &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=manageboards&quot;&gt;&#039; . $txt[4] . &#039;&lt;/a&gt;&#039;;


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (allowedTo(array(&#039;admin_forum&#039;, &#039;moderate_forum&#039;)))
=== Administration menu ===
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;posts_and_topics&#039;] = &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=postsettings&quot;&gt;&#039; . $txt&#91;&#039;manageposts&#039;] . &#039;&lt;/a&gt;&#039;;
In SMF 1.1, the administration menu was defined in the adminIndex() function in Subs.php. For example, the "Forum" section looks like:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (allowedTo(&#039;admin_forum&#039;))
    // Admin area 'Forum'.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
    if (allowedTo(array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum')))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;manage_calendar&#039;] = &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=managecalendar&quot;&gt;&#039; . $txt&#91;&#039;manage_calendar&#039;] . &#039;&lt;/a&gt;&#039;;
    {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;manage_search&#039;] = &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=managesearch&quot;&gt;&#039; . $txt&#91;&#039;manage_search&#039;] . &#039;&lt;/a&gt;&#039;;
      $context['admin_areas']['layout'] = array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
          'title' => $txt['layout_controls'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (allowedTo(&#039;manage_smileys&#039;))
          'areas' => array()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;manage_smileys&#039;] = &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=smileys&quot;&gt;&#039; . $txt&#91;&#039;smileys_manage&#039;] . &#039;&lt;/a&gt;&#039;;
      );
      if (allowedTo('manage_boards'))
          $context['admin_areas']['layout']['areas']['manage_boards'] =  '<a href="' . $scripturl . '?action=manageboards">' . $txt[4] . '</a>';
      if (allowedTo(array('admin_forum', 'moderate_forum')))
          $context['admin_areas']['layout']['areas']['posts_and_topics'] = '<a href="' . $scripturl . '?action=postsettings">' . $txt['manageposts'] . '</a>';
      if (allowedTo('admin_forum'))
      {
          $context['admin_areas']['layout']['areas']['manage_calendar'] = '<a href="' . $scripturl . '?action=managecalendar">' . $txt['manage_calendar'] . '</a>';
          $context['admin_areas']['layout']['areas']['manage_search'] = '<a href="' . $scripturl . '?action=managesearch">' . $txt['manage_search'] . '</a>';
      }
      if (allowedTo('manage_smileys'))
          $context['admin_areas']['layout']['areas']['manage_smileys'] = '<a href="' . $scripturl . '?action=smileys">' . $txt['smileys_manage'] . '</a>';
      if (allowedTo('manage_attachments'))
          $context['admin_areas']['layout']['areas']['manage_attachments'] = '<a href="' . $scripturl . '?action=manageattachments">' . $txt['smf201'] . '</a>';
         
    }


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (allowedTo(&#039;manage_attachments&#039;))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$context&#91;&#039;admin_areas&#039;]&#91;&#039;layout&#039;]&#91;&#039;areas&#039;]&#91;&#039;manage_attachments&#039;] = &#039;&lt;a href=&quot;&#039; . $scripturl . &#039;?action=manageattachments&quot;&gt;&#039; . $txt&#91;&#039;smf201&#039;] . &#039;&lt;/a&gt;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;}
</code>
Much like the main menu, SMF 2.0 has seperated the menu items from the actual menu itself (which is handled by Subs-Menu.php and the theme). The code for this same menu looks a lot simpler in SMF 2.0:
Much like the main menu, SMF 2.0 has seperated the menu items from the actual menu itself (which is handled by Subs-Menu.php and the theme). The code for this same menu looks a lot simpler in SMF 2.0:
<div class="codeheader">: <a href="javascript:void(0);" onclick="return smfSelectText(this);" class="codeoperation"></a></div><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;layout&#039; =&gt; array(
      'layout' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;title&#039; =&gt; $txt&#91;&#039;layout_controls&#039;],
          'title' => $txt['layout_controls'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;manage_boards&#039;, &#039;admin_forum&#039;, &#039;manage_smileys&#039;, &#039;manage_attachments&#039;, &#039;moderate_forum&#039;),
          'permission' => array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;areas&#039; =&gt; array(
          'areas' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;manageboards&#039; =&gt; array(
            'manageboards' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;admin_boards&#039;],
                'label' => $txt['admin_boards'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManageBoards.php&#039;,
                'file' => 'ManageBoards.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManageBoards&#039;,
                'function' => 'ManageBoards',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;manage_boards&#039;),
                'permission' => array('manage_boards'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;postsettings&#039; =&gt; array(
            'postsettings' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;manageposts&#039;],
                'label' => $txt['manageposts'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManagePosts.php&#039;,
                'file' => 'ManagePosts.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManagePostSettings&#039;,
                'function' => 'ManagePostSettings',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;admin_forum&#039;, &#039;moderate_forum&#039;),
                'permission' => array('admin_forum', 'moderate_forum'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;managecalendar&#039; =&gt; array(
            'managecalendar' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;manage_calendar&#039;],
                'label' => $txt['manage_calendar'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManageCalendar.php&#039;,
                'file' => 'ManageCalendar.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManageCalendar&#039;,
                'function' => 'ManageCalendar',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;admin_forum&#039;),
                'permission' => array('admin_forum'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;managesearch&#039; =&gt; array(
            'managesearch' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;manage_search&#039;],
                'label' => $txt['manage_search'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManageSearch.php&#039;,
                'file' => 'ManageSearch.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManageSearch&#039;,
                'function' => 'ManageSearch',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;admin_forum&#039;),
                'permission' => array('admin_forum'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;smileys&#039; =&gt; array(
            'smileys' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;smileys_manage&#039;],
                'label' => $txt['smileys_manage'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManageSmileys.php&#039;,
                'file' => 'ManageSmileys.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManageSmileys&#039;,
                'function' => 'ManageSmileys',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;manage_smileys&#039;),
                'permission' => array('manage_smileys'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;manageattachments&#039; =&gt; array(
            'manageattachments' => array(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;label&#039; =&gt; $txt&#91;&#039;attachments_avatars&#039;],
                'label' => $txt['attachments_avatars'],
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;file&#039; =&gt; &#039;ManageAttachments.php&#039;,
                'file' => 'ManageAttachments.php',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;function&#039; =&gt; &#039;ManageAttachments&#039;,
                'function' => 'ManageAttachments',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;permission&#039; =&gt; array(&#039;manage_attachments&#039;),
                'permission' => array('manage_attachments'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
            ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
          ),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),
      ),
</code>
 
[[Category:Customizing SMF]]
[[Category:Developing SMF]]

Latest revision as of 12:11, 1 July 2013

SMF 2.0 has had some large code changes, a lot of which affect how mods are written. Code has been restructured for greater efficiency, several new features have been added (which make certain mods obsolete), etc. Due to the volume of changes, almost all mods designed for SMF 1.1 will not work with SMF 2.0. This document is a short introduction on converting SMF 1.1 mods to SMF 2.0. It is not an exhaustive reference, but should help you get your mod up and running on SMF 2.0.

Database Queries

SMF 1.1 only supported MySQL, and hence, MySQL functions are usually used in mods. In SMF 2.0, a database abstraction layer has been added, allowing for different database systems to be used (at the time of writing, MySQL, PostgreSQL, and SQLite are supported). As such, all MySQL function calls willl need to be changed to use the new SMF functions.

Because multiple database systems are supported, it is recommended that you do not use MySQL-specific SQL features (eg. ON DUPLICATE KEY UPDATE). If you stick to SQL92 SQL features, you can be assured that your mod should work on the majority of modern RDBMS systems.

The main functions are listed below:

Function used in SMF 1.1 SMF 2.0 equivalent
db_query $smcFunc['db_query']
mysql_fetch_assoc $smcFunc['db_fetch_assoc']
mysql_fetch_row $smcFunc['db_fetch_row']
mysql_num_rows $smcFunc['db_num_rows']
mysql_free_result $smcFunc['db_free_result']
mysql_real_escape_string or mysql_escape_string $smcFunc['db_escape_string']

You will find a more in-depth and detailed information about the SMF 2.0 functions in our SMF 2.0 Database Functions topic on the community forums.

Column Names

In SMF 2.0, all uppercase column names have been changed. This was done because some database systems do not support uppercase column names. The index columns that had uppercase names in SMF 1.1 (eg. ID_MSG, ID_TOPIC, ID_MEMBER) have had their names changes to lowercase (id_msg, id_topic, id_member). Additionally, any columns that used camel case (memberName) have changed to use an underscore between words (member_name)

An example is below

Code example

This code is for SMF 1.1:

echo '
    '; // Get all the topics in board 1 $result = db_query(" SELECT t.ID_TOPIC, m.posterName, m.subject FROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m) WHERE t.ID_BOARD = 1 AND m.ID_MSG = t.ID_FIRST_MSG LIMIT 10", __FILE__, __LINE__); // Loop through all results while ($row = mysql_fetch_assoc($result)) { // Echo this result echo '
  • ', $row['subject'], ' by ', $row['posterName'], '
  • '; } mysql_free_result($result); echo '

';

And this is the SMF 2.0 equivalent:

echo '
    '; // Get all the topics in board 1 $result = $smcFunc['db_query'](, " SELECT t.id_topic, m.poster_name, m.subject FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) WHERE t.id_board = {int:id_board} LIMIT 10", array( 'id_board' => 1, )); // Loop through all results while ($row = $smcFunc['db_fetch_assoc']($result)) { // Echo this result echo '
  • ', $row['subject'], ' by ', $row['poster_name'], '
  • '; } $smcFunc['db_free_result']($result); echo '

';

$ID_MEMBER

In SMF 1.1, the $ID_MEMBER variable contained the current user's ID. SMF 2.0 has removed this variable. Any code using $ID_MEMBER will need to be edited so it uses either $user_info['id'] or $context['user']['id'].

Menus

Main menu

In SMF 1.1, each theme had its own main menu in index.template.php. For example, the code for the Calendar button in the SMF 1.1 default theme (Core) looks like this:

   if ($context['allow_calendar'])

echo ($current_action == 'calendar' || $context['browser']['is_ie4']) ? ' ' : , '

               <a href="', $scripturl, '?action=calendar">' , $txt['calendar24'] , '</a>

' , $current_action == 'calendar' ? ' ' : ;

SMF 2.0 has moved all the menu items to Subs.php, in a "setupMenuContext" function. This simplifies theme writing, and makes it easier for mod authors (just edit the Subs.php file, and the added button appears on all themes). As an example, the Calendar button has become: (Subs.php)

        'calendar' => array(
           'title' => $txt['calendar'],
           'href' => $scripturl . '?action=calendar',
           'show' => $context['allow_calendar'],
           'sub_buttons' => array(
              'view' => array(
                 'title' => $txt['calendar_menu'],
                 'href' => $scripturl . '?action=calendar',
                 'show' => true,
              ),
              'post' => array(
                 'title' => $txt['calendar_post_event'],
                 'href' => $scripturl . '?action=calendar;sa=post;sesc=' . $context['session_id'],
                 'show' => allowedTo('calendar_post'),
              ),
           ),
        ),

A new feature is that each button can have several "sub-buttons". Curve-based themes may render these sub-buttons as a dropdown menu. This is done on the simplemachines.org community forum.

Administration menu

In SMF 1.1, the administration menu was defined in the adminIndex() function in Subs.php. For example, the "Forum" section looks like:

   // Admin area 'Forum'.
   if (allowedTo(array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum')))
   {
      $context['admin_areas']['layout'] = array(
         'title' => $txt['layout_controls'],
         'areas' => array()
      );

      if (allowedTo('manage_boards'))
         $context['admin_areas']['layout']['areas']['manage_boards'] =  '<a href="' . $scripturl . '?action=manageboards">' . $txt[4] . '</a>';

      if (allowedTo(array('admin_forum', 'moderate_forum')))
         $context['admin_areas']['layout']['areas']['posts_and_topics'] = '<a href="' . $scripturl . '?action=postsettings">' . $txt['manageposts'] . '</a>';
      if (allowedTo('admin_forum'))
      {
         $context['admin_areas']['layout']['areas']['manage_calendar'] = '<a href="' . $scripturl . '?action=managecalendar">' . $txt['manage_calendar'] . '</a>';
         $context['admin_areas']['layout']['areas']['manage_search'] = '<a href="' . $scripturl . '?action=managesearch">' . $txt['manage_search'] . '</a>';
      }
      if (allowedTo('manage_smileys'))
         $context['admin_areas']['layout']['areas']['manage_smileys'] = '<a href="' . $scripturl . '?action=smileys">' . $txt['smileys_manage'] . '</a>';

      if (allowedTo('manage_attachments'))
         $context['admin_areas']['layout']['areas']['manage_attachments'] = '<a href="' . $scripturl . '?action=manageattachments">' . $txt['smf201'] . '</a>';
         
   }

Much like the main menu, SMF 2.0 has seperated the menu items from the actual menu itself (which is handled by Subs-Menu.php and the theme). The code for this same menu looks a lot simpler in SMF 2.0:

      'layout' => array(
         'title' => $txt['layout_controls'],
         'permission' => array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum'),
         'areas' => array(
            'manageboards' => array(
               'label' => $txt['admin_boards'],
               'file' => 'ManageBoards.php',
               'function' => 'ManageBoards',
               'permission' => array('manage_boards'),
            ),
            'postsettings' => array(
               'label' => $txt['manageposts'],
               'file' => 'ManagePosts.php',
               'function' => 'ManagePostSettings',
               'permission' => array('admin_forum', 'moderate_forum'),
            ),
            'managecalendar' => array(
               'label' => $txt['manage_calendar'],
               'file' => 'ManageCalendar.php',
               'function' => 'ManageCalendar',
               'permission' => array('admin_forum'),
            ),
            'managesearch' => array(
               'label' => $txt['manage_search'],
               'file' => 'ManageSearch.php',
               'function' => 'ManageSearch',
               'permission' => array('admin_forum'),
            ),
            'smileys' => array(
               'label' => $txt['smileys_manage'],
               'file' => 'ManageSmileys.php',
               'function' => 'ManageSmileys',
               'permission' => array('manage_smileys'),
            ),
            'manageattachments' => array(
               'label' => $txt['attachments_avatars'],
               'file' => 'ManageAttachments.php',
               'function' => 'ManageAttachments',
               'permission' => array('manage_attachments'),
            ),
         ),
      ),


Advertisement: