Problem Solution: Special Pythagorean triplet(projecteuler.net)

Future Technology

public class SpecialPythagoreanTriplet {

public static void main(String[] args) {
// TODO Auto-generated method stub

long sum = 0, total = 1000;

for (double a = 1; a <= total / 3; a++) {
for (double b = 1; b <= total / 2; b++) {

double c = total - a - b;
double e = Math.pow(a, 2);
double f = Math.pow(b, 2);
double g = Math.pow(c, 2);

sum = (long) (a * b * c);

if (Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2)) {
System.out.println("a: " + a + " b: " + b + " c: " + c);
System.out.println("e: " + e + " f: " + f + " g: " + g);
System.out.println("Sum: " + sum);
}
}
}

}

}

View original post

Problem Solution: Special Pythagorean triplet(projecteuler.net)

public class SpecialPythagoreanTriplet {

public static void main(String[] args) {
// TODO Auto-generated method stub

long sum = 0, total = 1000;

for (double a = 1; a <= total / 3; a++) {
for (double b = 1; b <= total / 2; b++) {

double c = total - a - b;
double e = Math.pow(a, 2);
double f = Math.pow(b, 2);
double g = Math.pow(c, 2);

sum = (long) (a * b * c);

if (Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2)) {
System.out.println("a: " + a + " b: " + b + " c: " + c);
System.out.println("e: " + e + " f: " + f + " g: " + g);
System.out.println("Sum: " + sum);
}
}
}

}

}

Coding standards

Source : http://drupal.org

Note: The Drupal Coding Standards apply to code within Drupal and its contributed modules. This document is loosely based on the PEAR Coding standards. Comments and names should use US English spelling (e.g., “color” not “colour”).

Drupal coding standards are version-independent and “always-current”. All new code should follow the current standards, regardless of (core) version. Existing code in older versions may be updated, but doesn’t necessarily have to be. Especially for larger code-bases (like Drupal core), updating the code of a previous version for the current standards may too huge of a task. However, code in current versions should follow the current standards.

Note: Do not squeeze coding standards updates/clean-ups into otherwise unrelated patches. Only touch code lines that are actually relevant. To update existing code for the current standards, always create separate and dedicated issues and patches.

Also note:

  • the Coder module provides an automated way of checking for code standards compliance and
  • the Grammar Parser module provides an automated way of rewriting code files in compliance with code standards.

Contents of this Page

Indenting and Whitespace

Use an indent of 2 spaces, with no tabs.

Lines should have no trailing whitespace at the end.

Files should be formatted with \n as the line ending (Unix line endings), not \r\n (Windows line endings).

All text files should end in a single newline (\n). This avoids the verbose “\ No newline at end of file” patch warning and makes patches easier to read since it’s clearer what is being changed when lines are added to the end of a file.

Operators

All binary operators (operators that come between two values), such as +, -, =, !=, ==, >, etc. should have a space before and after the operator, for readability. For example, an assignment should be formatted as $foo = $bar; rather than $foo=$bar;. Unary operators (operators that operate on only one value), such as ++, should not have a space between the operator and the variable or number they are operating on.

Casting

Put a space between the (type) and the $variable in a cast: (int) $mynumber.

Control Structures

Control structures include if, for, while, switch, etc. Here is a sample if statement, since it is the most complicated of them:

if (condition1 || condition2) {
action1;
}
elseif (condition3 && condition4) {
action2;
}
else {
defaultaction;
}

Control statements should have one space between the control keyword and opening parenthesis, to distinguish them from function calls.

You are strongly encouraged to always use curly braces even in situations where they are technically optional. Having them increases readability and decreases the likelihood of logic errors being introduced when new lines are added.

For switch statements:

switch (condition) {
case 1:
action1;
break;

case 2:
action2;
break;

default:
defaultaction;
}

For do-while statements:

do {
actions;
} while ($condition);

Line length and wrapping

The following rules apply to code. See Doxygen and comment formatting conventions for rules pertaining to comments.

  • In general, all lines of code should not be longer than 80 chars.
  • Lines containing longer function names, function/class definitions, variable declarations, etc are allowed to exceed 80 chars.
  • Control structure conditions may exceed 80 chars, if they are simple to read and understand:
      if ($something[‘with’][‘something’][‘else’][‘in’][‘here’] == mymodule_check_something($whatever[‘else’])) {

    }
    if (isset($something[‘what’][‘ever’]) && $something[‘what’][‘ever’] > $infinite && user_access(‘galaxy’)) {

    }
    // Non-obvious conditions of low complexity are also acceptable, but should
    // always be documented, explaining WHY a particular check is done.
    if (preg_match(‘@(/|\\)(\.\.|~)@’, $target) && strpos($target_dir, $repository) !== 0) {
    return FALSE;
    }
  • Conditions should not be wrapped into multiple lines.
  • Control structure conditions should also NOT attempt to win the Most Compact Condition In Least Lines Of Code Award™:
      // DON’T DO THIS!
    if ((isset($key) && !empty($user->uid) && $key == $user->uid) || (isset($user->cache) ? $user->cache : ”) == ip_address() || isset($value) && $value >= time())) {

    }

    Instead, it is recommended practice to split out and prepare the conditions separately, which also permits documenting the underlying reasons for the conditions:

      // Key is only valid if it matches the current user’s ID, as otherwise other
    // users could access any user’s things.
    $is_valid_user = (isset($key) && !empty($user->uid) && $key == $user->uid);

    // IP must match the cache to prevent session spoofing.
    $is_valid_query = (isset($user->cache) ? $user->cache == ip_address() : FALSE);

    // Alternatively, if the request query parameter is in the future, then it
    // is always valid, because the galaxy will implode and collapse anyway.
    $is_valid_query = $is_valid_cache || (isset($value) && $value >= time());

    if ($is_valid_user || $is_valid_query) {

    }

    Note: This example is still a bit dense. Always consider and decide on your own whether people unfamiliar with your code will be able to make sense of the logic.

Function Calls

Functions should be called with no spaces between the function name, the opening parenthesis, and the first parameter; spaces between commas and each parameter, and no space between the last parameter, the closing parenthesis, and the semicolon. Here’s an example:

$var = foo($bar, $baz, $quux);

As displayed above, there should be one space on either side of an equals sign used to assign the return value of a function to a variable. In the case of a block of related assignments, more space may be inserted to promote readability:

$short         = foo($bar);
$long_variable = foo($baz);

Function Declarations

function funstuff_system($field) {
$system[“description”] = t(“This module inserts funny text into posts randomly.”);
return $system[$field];
}

Arguments with default values go at the end of the argument list. Always attempt to return a meaningful value from a function if one is appropriate.

Class Constructor Calls

When calling class constructors with no arguments, always include parentheses:

$foo = new MyClassName();

This is to maintain consistency with constructors that have arguments:

$foo = new MyClassName($arg1, $arg2);

Note that if the class name is a variable, the variable will be evaluated first to get the class name, and then the constructor will be called. Use the same syntax:

$bar = ‘MyClassName’;
$foo = new $bar();
$foo = new $bar($arg1, $arg2);

Arrays

Arrays should be formatted with a space separating each element (after the comma), and spaces around the => key association operator, if applicable:

$some_array = array(‘hello’, ‘world’, ‘foo’ => ‘bar’);

Note that if the line declaring an array spans longer than 80 characters (often the case with form and menu declarations), each element should be broken into its own line, and indented one level:

$form[‘title’] = array(
‘#type’ => ‘textfield’,
‘#title’ => t(‘Title’),
‘#size’ => 60,
‘#maxlength’ => 128,
‘#description’ => t(‘The title of your node.’),
);

Note the comma at the end of the last array element; This is not a typo! It helps prevent parsing errors if another element is placed at the end of the list later.

Quotes

Drupal does not have a hard standard for the use of single quotes vs. double quotes. Where possible, keep consistency within each module, and respect the personal style of other developers.

With that caveat in mind: single quote strings are known to be faster because the parser doesn’t have to look for in-line variables. Their use is recommended except in two cases:

  1. In-line variable usage, e.g. “<h2>$header</h2>”.
  2. Translated strings where one can avoid escaping single quotes by enclosing the string in double quotes. One such string would be “He’s a good person.” It would be ‘He\’s a good person.’ with single quotes. Such escaping may not be handled properly by .pot file generators for text translation, and it’s also somewhat awkward to read.

String Concatenations

Always use a space between the dot and the concatenated parts to improve readability.

<?php
$string = ‘Foo’ . $bar;
$string = $bar . ‘foo’;
$string = bar() . ‘foo’;
$string = ‘foo’ . ‘bar’;
?>

When you concatenate simple variables, you can use double quotes and add the variable inside; otherwise, use single quotes.

<?php
$string = “Foo $bar”;
?>

When using the concatenating assignment operator (‘.=’), use a space on each side as with the assignment operator:

<?php
$string .= ‘Foo’;
$string .= $bar;
$string .= baz();
?>

Comments

Comment standards are discussed on the separate Doxygen and comment formatting conventions page.

Including Code

Anywhere you are unconditionally including a class file, use require_once(). Anywhere you are conditionally including a class file (for example, factory methods), use include_once(). Either of these will ensure that class files are included only once. They share the same file list, so you don’t need to worry about mixing them – a file included with require_once() will not be included again by include_once().

Note: include_once() and require_once() are statements, not functions. You don’t need parentheses around the file name to be included.

When including code from the same directory or a sub-directory, start the file path with “.”:
include_once ./includes/mymodule_formatting.inc
In Drupal 7.x and later versions, use DRUPAL_ROOT:
require_once DRUPAL_ROOT . ‘/’ . variable_get(‘cache_inc’, ‘includes/cache.inc’);

PHP Code Tags

Always use <?php ?> to delimit PHP code, not the shorthand, <? ?>. This is required for Drupal compliance and is also the most portable way to include PHP code on differing operating systems and set-ups.

Note that as of Drupal 4.7, the ?> at the end of code files is purposely omitted. This includes for module and include files. The reasons for this can be summarized as:

  • Removing it eliminates the possibility for unwanted whitespace at the end of files which can cause “header already sent” errors, XHTML/XML validation issues, and other problems.
  • The closing delimiter at the end of a file is optional.
  • PHP.net itself removes the closing delimiter from the end of its files (example: prepend.inc), so this can be seen as a “best practice.”

Semicolons

The PHP language requires semicolons at the end of most lines, but allows them to be omitted at the end of code blocks. Drupal coding standards require them, even at the end of code blocks. In particular, for one-line PHP blocks:

<?php print $tax; ?> — YES
<?php print $tax ?> — NO

Example URLs

Use “example.com” for all example URLs, per RFC 2606.

Naming Conventions

Functions and variables

Functions and variables should be named using lowercase, and words should be separated with an underscore. Functions should in addition have the grouping/module name as a prefix, to avoid name collisions between modules.

Persistent Variables

Persistent variables (variables/settings defined using Drupal’s variable_get()/variable_set() functions) should be named using all lowercase letters, and words should be separated with an underscore. They should use the grouping/module name as a prefix, to avoid name collisions between modules.

Constants

  • Constants should always be all-uppercase, with underscores to separate words. (This includes pre-defined PHP constants like TRUE, FALSE, and NULL.)
  • Module-defined constant names should also be prefixed by an uppercase spelling of the module that defines them.
  • In Drupal 8 and later, constants should be defined using the const PHP language keyword (instead of define()), because it is better for performance:
    <?php
    /**
    * Indicates that the item should be removed at the next general cache wipe.
    */
    const CACHE_TEMPORARY = -1;
    ?>

    Note that const does not work with PHP expressions. define() should be used when defining a constant conditionally or with a non-literal value:

    <?php
    if (!defined(‘MAINTENANCE_MODE’)) {
    define(‘MAINTENANCE_MODE’, ‘error’);
    }
    ?>

Global Variables

If you need to define global variables, their name should start with a single underscore followed by the module/theme name and another underscore.

Classes

Classes should be named using “CamelCase.” For example:

<?php
abstract class DatabaseConnection extends PDO {
?>

Class methods and properties should use “lowerCamelCase”:

<?php
public $lastStatement;
?>

The use of private class methods and properties should be avoided — use protected instead, so that another class could extend your class and change the method if necessary. Protected (and public) methods and properties should not use an underscore prefix, as was common in PHP 4-era code.

For more information on class and OO standards, see the more detailed coverage.

File names

All documentation files should have the file name extension “.txt” to make viewing them on Windows systems easier. Also, the file names for such files should be all-caps (e.g. README.txt instead of readme.txt) while the extension itself is all-lowercase (i.e. txt instead of TXT).

Examples: README.txt, INSTALL.txt, TODO.txt, CHANGELOG.txt etc.

Helper Module

There is a contributed module for assisting with code review. To use this module you must complete the following steps:

  • Install the Coder module.
  • Click on the “Code Review” link in your navigation menu.
  • Scroll down to “Select Specific Modules”.
  • Select the module you wish to review, and click the “Submit” button.

As an alternative to starting from the Code Review link in navigation, you can also review a particular module’s code by clicking on the link on the Modules admin screen.

The Coder module also comes with a command-line script called “Coder Format”, which will not only check your files for standards compliance, but fix them. Use with care!

Developing a Model-View-Controller (MVC) Component for Joomla!1.6 – Part 09

http://docs.joomla.org

Introduction

This tutorial is part of the Developing a Model-View-Controller (MVC) Component for Joomla!1.6 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.

Adding a toolbar

In Joomla!1.6, the administrator interacts generally with components through the use of a toolbar. In the file admin/views/helloworlds/view.html.php put this content. It will create a basic toolbar and a title for the component.

admin/views/helloworlds/view.html.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla view library  jimport('joomla.application.component.view');     /**   * HelloWorlds View   */  class HelloWorldViewHelloWorlds extends JView  {  	/**  	 * HelloWorlds view display method  	 * @return void  	 */  	function display($tpl = null)   	{  		// Get data from the model  		$items = $this->get('Items');  		$pagination = $this->get('Pagination');     		// Check for errors.  		if (count($errors = $this->get('Errors')))   		{  			JError::raiseError(500, implode('<br />', $errors));  			return false;  		}  		// Assign data to the view  		$this->items = $items;  		$this->pagination = $pagination;     		// Set the toolbar  		$this->addToolBar();     		// Display the template  		parent::display($tpl);  	}     	/**  	 * Setting the toolbar  	 */  	protected function addToolBar()   	{  		JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'));  		JToolBarHelper::deleteList('', 'helloworlds.delete');  		JToolBarHelper::editList('helloworld.edit');  		JToolBarHelper::addNew('helloworld.add');  	}  }  

You can find others classic backend actions in the administrator/includes/toolbar.php file of your Joomla!1.6 installation.

Since the view can perform some actions, we have to add some input data. With your favorite file manager and editor, put in the file admin/views/helloworlds/tmpl/default.php

admin/views/helloworlds/tmpl/default.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted Access');  // load tooltip behavior  JHtml::_('behavior.tooltip');  ?>  <form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm">  	<table class="adminlist">  		<thead><?php echo $this->loadTemplate('head');?></thead>  		<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>  		<tbody><?php echo $this->loadTemplate('body');?></tbody>  	</table>  	<div>  		<input type="hidden" name="task" value="" />  		<input type="hidden" name="boxchecked" value="0" />  		<?php echo JHtml::_('form.token'); ?>  	</div>  </form>  

Adding specific controllers

Three actions have been added:

  • helloworlds.delete
  • helloworld.edit
  • helloworld.add

These are compound tasks (controller.task). So two new controllers HelloWorldControllerHelloWorlds and HelloWorldControllerHelloWorld have to be coded.

admin/controllers/helloworlds.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla controlleradmin library  jimport('joomla.application.component.controlleradmin');     /**   * HelloWorlds Controller   */  class HelloWorldControllerHelloWorlds extends JControllerAdmin  {  	/**  	 * Proxy for getModel.  	 * @since	1.6  	 */  	public function getModel($name = 'HelloWorld', $prefix = 'HelloWorldModel')   	{  		$model = parent::getModel($name, $prefix, array('ignore_request' => true));  		return $model;  	}  }  

admin/controllers/helloworld.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla controllerform library  jimport('joomla.application.component.controllerform');     /**   * HelloWorld Controller   */  class HelloWorldControllerHelloWorld extends JControllerForm  {  }  

Adding an editing view

With your favorite file manager and editor, put a file admin/views/helloworld/view.html.php containing:

admin/views/helloworld/view.html.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla view library  jimport('joomla.application.component.view');     /**   * HelloWorld View   */  class HelloWorldViewHelloWorld extends JView  {  	/**  	 * display method of Hello view  	 * @return void  	 */  	public function display($tpl = null)   	{  		// get the Data  		$form = $this->get('Form');  		$item = $this->get('Item');     		// Check for errors.  		if (count($errors = $this->get('Errors')))   		{  			JError::raiseError(500, implode('<br />', $errors));  			return false;  		}  		// Assign the Data  		$this->form = $form;  		$this->item = $item;     		// Set the toolbar  		$this->addToolBar();     		// Display the template  		parent::display($tpl);  	}     	/**  	 * Setting the toolbar  	 */  	protected function addToolBar()   	{  		JRequest::setVar('hidemainmenu', true);  		$isNew = ($this->item->id == 0);  		JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW') : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'));  		JToolBarHelper::save('helloworld.save');  		JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');  	}  }  

This view will display data using a layout.

Put a file admin/views/helloworld/tmpl/edit.php containing

admin/views/helloworld/tmpl/edit.php

<?php  // No direct access  defined('_JEXEC') or die('Restricted access');  JHtml::_('behavior.tooltip');  ?>  <form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>" method="post" name="adminForm" id="helloworld-form">  	<fieldset class="adminform">  		<legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>  		<ul class="adminformlist">  <?php foreach($this->form->getFieldset() as $field): ?>  			<li><?php echo $field->label;echo $field->input;?></li>  <?php endforeach; ?>  		</ul>  	</fieldset>  	<div>  		<input type="hidden" name="task" value="helloworld.edit" />  		<?php echo JHtml::_('form.token'); ?>  	</div>  </form>  

Adding a model and modifying the existing one

The HelloWorldViewHelloWorld view asks form and data from a model. This model has to provide a getTable, a getForm method and a loadData method (called from the JModelAdmin controller)

admin/models/helloworld.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla modelform library  jimport('joomla.application.component.modeladmin');     /**   * HelloWorld Model   */  class HelloWorldModelHelloWorld extends JModelAdmin  {  	/**  	 * Returns a reference to the a Table object, always creating it.  	 *  	 * @param	type	The table type to instantiate  	 * @param	string	A prefix for the table class name. Optional.  	 * @param	array	Configuration array for model. Optional.  	 * @return	JTable	A database object  	 * @since	1.6  	 */  	public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())   	{  		return JTable::getInstance($type, $prefix, $config);  	}  	/**  	 * Method to get the record form.  	 *  	 * @param	array	$data		Data for the form.  	 * @param	boolean	$loadData	True if the form is to load its own data (default case), false if not.  	 * @return	mixed	A JForm object on success, false on failure  	 * @since	1.6  	 */  	public function getForm($data = array(), $loadData = true)   	{  		// Get the form.  		$form = $this->loadForm('com_helloworld.helloworld', 'helloworld', array('control' => 'jform', 'load_data' => $loadData));  		if (empty($form))   		{  			return false;  		}  		return $form;  	}  	/**  	 * Method to get the data that should be injected in the form.  	 *  	 * @return	mixed	The data for the form.  	 * @since	1.6  	 */  	protected function loadFormData()   	{  		// Check the session for previously entered form data.  		$data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());  		if (empty($data))   		{  			$data = $this->getItem();  		}  		return $data;  	}  }  

This model inherits from the JModelAdmin class and uses its loadForm method. This method searches for forms in the forms folder. With your favorite file manager and editor, put a file admin/models/forms/helloworld.xml containing:

admin/models/forms/helloworld.xml

<?xml version="1.0" encoding="utf-8"?>  <form>  	<fieldset>  		<field  			name="id"  			type="hidden"  		/>  		<field  			name="greeting"  			type="text"  			label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"  			description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"  			size="40"  			class="inputbox"  			default=""  		/>  	</fieldset>  </form>  

Packaging the component

Content of your code directory

Create a compressed file of this directory or directly download the archive, modify the code in /admin/models/helloworld.php and install it using the extension manager of Joomla!1.6. You can add a menu item of this component using the menu manager in the backend.

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>  <extension type="component" version="1.6.0" method="upgrade">     	<name>Hello World!</name>  	<!-- The following elements are optional and free of formatting conttraints -->  	<creationDate>November 2009</creationDate>  	<author>John Doe</author>  	<authorEmail>john.doe@example.org</authorEmail>  	<authorUrl>http://www.example.org</authorUrl>  	<copyright>Copyright Info</copyright>  	<license>License Info</license>  	<!--  The version string is recorded in the components table -->  	<version>0.0.9</version>  	<!-- The description is optional and defaults to the name -->  	<description>COM_HELLOWORLD_DESCRIPTION</description>     	<install> <!-- Runs on install -->  		<sql>  			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>  		</sql>  	</install>  	<uninstall> <!-- Runs on uninstall -->  		<sql>  			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>  		</sql>  	</uninstall>  	<update> <!-- Runs on update; New in 1.6 -->  		<schemas>  			<schemapath type="mysql">sql/updates/mysql</schemapath>  		</schemas>  	</update>     	<!-- Site Main File Copy Section -->  	<!-- Note the folder attribute: This attribute describes the folder  		to copy FROM in the package to install therefore files copied  		in this section are copied from /site/ in the package -->  	<files folder="site">  		<filename>index.html</filename>  		<filename>helloworld.php</filename>  		<filename>controller.php</filename>  		<folder>views</folder>  		<folder>models</folder>  		<folder>language</folder>  	</files>     	<administration>  		<!-- Administration Menu Section -->  		<menu>COM_HELLOWORLD_MENU</menu>  		<!-- Administration Main File Copy Section -->  		<!-- Note the folder attribute: This attribute describes the folder  			to copy FROM in the package to install therefore files copied  			in this section are copied from /admin/ in the package -->  		<files folder="admin">  			<!-- Admin Main File Copy Section -->  			<filename>index.html</filename>  			<filename>helloworld.php</filename>  			<filename>controller.php</filename>  			<!-- SQL files section -->  			<folder>sql</folder>  			<!-- tables files section -->  			<folder>tables</folder>  			<!-- models files section -->  			<folder>models</folder>  			<!-- views files section -->  			<folder>views</folder>  			<!-- controllers files section -->  			<folder>controllers</folder>  		</files>     		<languages folder="admin">  			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>  			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>  		</languages>  	</administration>     </extension>  

Developing a Model-View-Controller (MVC) Component for Joomla!1.6 – Part 08

http://docs.joomla.org/

Introduction

This tutorial is part of the Developing a Model-View-Controller (MVC) Component for Joomla!1.6 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.

Joomla!1.6 manages languages for components in four different situations:

  • displaying a component in the public site
  • managing a component in the backend
  • managing menus in the backend
  • installing a component (new in 1.6)

Joomla!1.6 uses two different location folder for languages:

  • one in administrator/language or language
  • one in the component folder (administrator/component/*component*/language or component/*component*/language)

It depends how the component is installed.

Adding language translation in the public site

With your favorite file manager and editor, put a file site/language/en-GB/en-GB.com_helloworld.ini. This file will contain translation for the public part. For the moment, this file is empty

site/language/en-GB/en-GB.com_helloworld.ini

   

For the moment, there are no translations strings in this file.

Adding language translation when managing the component

With your favorite file manager and editor, put a file admin/language/en-GB/en-GB.com_helloworld.ini. This file will contain translation for the backend part.

admin/language/en-GB/en-GB.com_helloworld.ini

COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="This message will be displayed"  COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Message"  COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Greeting"  COM_HELLOWORLD_HELLOWORLD_HEADING_ID="Id"  

Adding language translation when managing the menus in the backend

With your favorite file manager and editor, put a file admin/language/en-GB/en-GB.com_helloworld.sys.ini. This file will contain translation for the backend part.

admin/language/en-GB/en-GB.com_helloworld.sys.ini

COM_HELLOWORLD="Hello World!"  COM_HELLOWORLD_DESCRIPTION="This is the Hello World description"  COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE="Hello World"  COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC="This view displays a selected message"  COM_HELLOWORLD_MENU="Hello World!"  

Adding translation when installing the component

With your favorite file manager and editor, put a file language/en-GB/en-GB.ini. This file will contain translation for the install.

language/en-GB/en-GB.ini

COM_HELLOWORLD="Hello World!"  COM_HELLOWORLD_DESCRIPTION="This is the Hello World description"  

The COM_HELLOWORLD_DESCRIPTION can be used in the helloworld.xml file

Packaging the component

Content of your code directory

Create a compressed file of this directory or directly download the archive and install it using the extension manager of Joomla!1.6. You can add a menu item of this component using the menu manager in the backend.

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>  <extension type="component" version="1.6.0" method="upgrade">     	<name>COM_HELLOWORLD</name>  	<!-- The following elements are optional and free of formatting conttraints -->  	<creationDate>November 2009</creationDate>  	<author>John Doe</author>  	<authorEmail>john.doe@example.org</authorEmail>  	<authorUrl>http://www.example.org</authorUrl>  	<copyright>Copyright Info</copyright>  	<license>License Info</license>  	<!--  The version string is recorded in the components table -->  	<version>0.0.8</version>  	<!-- The description is optional and defaults to the name -->  	<description>COM_HELLOWORLD_DESCRIPTION</description>     	<install> <!-- Runs on install -->  		<sql>  			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>  		</sql>  	</install>  	<uninstall> <!-- Runs on uninstall -->  		<sql>  			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>  		</sql>  	</uninstall>  	<update> <!-- Runs on update; New in 1.6 -->  		<schemas>  			<schemapath type="mysql">sql/updates/mysql</schemapath>  		</schemas>  	</update>     	<!-- Site Main File Copy Section -->  	<!-- Note the folder attribute: This attribute describes the folder  		to copy FROM in the package to install therefore files copied  		in this section are copied from /site/ in the package -->  	<files folder="site">  		<filename>index.html</filename>  		<filename>helloworld.php</filename>  		<filename>controller.php</filename>  		<folder>views</folder>  		<folder>models</folder>  		<folder>language</folder>  	</files>     	<administration>  		<!-- Administration Menu Section -->  		<menu>COM_HELLOWORLD_MENU</menu>  		<!-- Administration Main File Copy Section -->  		<!-- Note the folder attribute: This attribute describes the folder  			to copy FROM in the package to install therefore files copied  			in this section are copied from /admin/ in the package -->  		<files folder="admin">  			<!-- Admin Main File Copy Section -->  			<filename>index.html</filename>  			<filename>helloworld.php</filename>  			<filename>controller.php</filename>  			<!-- SQL files section -->  			<folder>sql</folder>  			<!-- tables files section -->  			<folder>tables</folder>  			<!-- models files section -->  			<folder>models</folder>  			<!-- views files section -->  			<folder>views</folder>  		</files>  		<languages folder="admin">  			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language>  			<language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language>  		</languages>  	</administration>     </extension>  

In this helloworld.xml file, languages are installed in:

  • administrator/language for the admin part (look at the xml languages tag)
  • components/com_helloworld/language for the site part (there are no xml languages tag in the site part of the xml description file, but the language folder is included)

Developing a Model-View-Controller (MVC) Component for Joomla!1.6 – Part 07

http://docs.joomla.org

Introduction

This tutorial is part of the Developing a Model-View-Controller (MVC) Component for Joomla!1.6 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.

Basic backend

Designing the backend interface leads us to create at least a Model-View-Controller triptych. We have to modify the administrator entry point of our component, the admin/helloworld.php file

admin/helloworld.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import joomla controller library  jimport('joomla.application.component.controller');     // Get an instance of the controller prefixed by HelloWorld  $controller = JController::getInstance('HelloWorld');     // Perform the Request task  $controller->execute(JRequest::getCmd('task'));     // Redirect if set by the controller  $controller->redirect();  

Create the general controller

The entry point now get an instance of a HelloWorld prefixed controller. Let create a basic controller for the administrator part:

admin/controller.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla controller library  jimport('joomla.application.component.controller');     /**   * General Controller of HelloWorld component   */  class HelloWorldController extends JController  {  	/**  	 * display task  	 *  	 * @return void  	 */  	function display($cachable = false)   	{  		// set default view if not set  		JRequest::setVar('view', JRequest::getCmd('view', 'HelloWorlds'));     		// call parent behavior  		parent::display($cachable);  	}  }  

This controller will display the ‘HelloWorlds view by default.

Create the view

With your favorite file manager and editor, create a file admin/views/helloworlds/view.html.php containing:

admin/views/helloworlds/view.html.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla view library  jimport('joomla.application.component.view');     /**   * HelloWorlds View   */  class HelloWorldViewHelloWorlds extends JView  {  	/**  	 * HelloWorlds view display method  	 * @return void  	 */  	function display($tpl = null)   	{  		// Get data from the model  		$items = $this->get('Items');  		$pagination = $this->get('Pagination');     		// Check for errors.  		if (count($errors = $this->get('Errors')))   		{  			JError::raiseError(500, implode('<br />', $errors));  			return false;  		}  		// Assign data to the view  		$this->items = $items;  		$this->pagination = $pagination;     		// Display the template  		parent::display($tpl);  	}  }  

In Joomla, views display data using layout. With your favorite file manager and editor, put a file admin/views/helloworlds/tmpl/default.php containing

admin/views/helloworlds/tmpl/default.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted Access');     // load tooltip behavior  JHtml::_('behavior.tooltip');  ?>  <form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm">  	<table class="adminlist">  		<thead><?php echo $this->loadTemplate('head');?></thead>  		<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>  		<tbody><?php echo $this->loadTemplate('body');?></tbody>  	</table>  </form>  

This layout calls several sub-layout (head, foot and body). Each sub-layout corresponds to a file prefixed by the name of the main layout (default), and an underscore.

Put a file admin/views/helloworlds/tmpl/default_head.php containing

admin/views/helloworlds/tmpl/default_head.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted Access');  ?>  <tr>  	<th width="5">  		<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_ID'); ?>  	</th>  	<th width="20">  		<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($this->items); ?>);" />  	</th>			  	<th>  		<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING'); ?>  	</th>  </tr>  

checkAll is a javascript function defined in the Joomla core able to check all items.

Put a file admin/views/helloworlds/tmpl/default_body.php containing

admin/views/helloworlds/tmpl/default_body.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted Access');  ?>  <?php foreach($this->items as $i => $item): ?>  	<tr class="row<?php echo $i % 2; ?>">  		<td>  			<?php echo $item->id; ?>  		</td>  		<td>  			<?php echo JHtml::_('grid.id', $i, $item->id); ?>  		</td>  		<td>  			<?php echo $item->greeting; ?>  		</td>  	</tr>  <?php endforeach; ?>  

JHtml::_ is a helper function able to display several HTML output. In this case, it will display a checkbox for the item.

Put a file admin/views/helloworlds/tmpl/default_foot.php containing

admin/views/helloworlds/tmpl/default_foot.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted Access');  ?>  <tr>  	<td colspan="3"><?php echo $this->pagination->getListFooter(); ?></td>  </tr>  

JPagination is a Joomla class able to manage and display pagination object.

Create the model

The HelloWorlds view asks the model for data. In Joomla!1.6, there is a class able to manage list of data: JModelList. Class JModelList and inherited classes needs only one method:

  • getListQuery which constructs and SQL query

and two states:

  • list.start for determining the list offset
  • list.limit for determining the list length

getItems and getPagination method are defined in JModelList class. They don’t need to be defined in the HelloWorldModelHelloWorlds class.

admin/models/helloworlds.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');  // import the Joomla modellist library  jimport('joomla.application.component.modellist');  /**   * HelloWorldList Model   */  class HelloWorldModelHelloWorlds extends JModelList  {  	/**  	 * Method to build an SQL query to load the list data.  	 *  	 * @return	string	An SQL query  	 */  	protected function getListQuery()  	{  		// Create a new query object.		  		$db = JFactory::getDBO();  		$query = $db->getQuery(true);  		// Select some fields  		$query->select('id,greeting');  		// From the hello table  		$query->from('#__helloworld');  		return $query;  	}  }  

The _populateState method is, by default, automatically called when a state is read by the getState method.

Packaging the component

Content of your code directory

Create a compressed file of this directory or directly download the archive and install it using the extension manager of Joomla!1.6. You can add a menu item of this component using the menu manager in the backend.

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>  <extension type="component" version="1.6.0" method="upgrade">  	<name>Hello World!</name>  	<creationDate>November 2009</creationDate>  	<author>John Doe</author>  	<authorEmail>john.doe@example.org</authorEmail>  	<authorUrl>http://www.example.org</authorUrl>  	<copyright>Copyright Info</copyright>  	<license>License Info</license>  	<version>0.0.7</version>  	<description>Description of the Hello World component ...</description>     	<install> <!-- Runs on install -->  		<sql>  			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>  		</sql>  	</install>  	<uninstall> <!-- Runs on uninstall -->  		<sql>  			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>  		</sql>  	</uninstall>  	<update> <!-- Runs on update; New in 1.6 -->  		<schemas>  			<schemapath type="mysql">sql/updates/mysql</schemapath>  		</schemas>  	</update>     	<files folder="site">  		<filename>index.html</filename>  		<filename>helloworld.php</filename>  		<filename>controller.php</filename>  		<folder>views</folder>  		<folder>models</folder>  	</files>     	<administration>  		<menu>Hello World!</menu>  		<files folder="admin">  			<filename>index.html</filename>  			<filename>helloworld.php</filename>  			<filename>controller.php</filename>  			<folder>sql</folder>  			<folder>tables</folder>  			<folder>models</folder>  			<!-- views files section -->  			<folder>views</folder>  		</files>		  	</administration>  </extension>  

Now you can see in your component hello-world an array with two colums, two rows and checkboxes. You can click the checkboxes in order to select the different options you want.

Developing a Model-View-Controller (MVC) Component for Joomla!1.6 – Part 06

http://docs.joomla.org

Introduction

This tutorial is part of the Developing a Model-View-Controller (MVC) Component for Joomla!1.6 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.

Using the database

Components usually manage their contents using the database. During the install/uninstall/update phase of a component, you can execute SQL queries through the use of SQL text files.

With your favorite file manager and editor put two files admin/sql/install.mysql.utf8.sql and admin/sql/updates/mysql/0.0.6.sql containing:

admin/sql/install.mysql.utf8.sql and admin/sql/updates/mysql/0.0.6.sql

DROP TABLE IF EXISTS `#__helloworld`;     CREATE TABLE `#__helloworld` (    `id` int(11) NOT NULL AUTO_INCREMENT,    `greeting` varchar(25) NOT NULL,     PRIMARY KEY  (`id`)  ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;     INSERT INTO `#__helloworld` (`greeting`) VALUES  	('Hello World!'),  	('Good bye World!');  

This is the install file. It will be executed if your put an appropriate order in the helloworld.xml file

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>  <extension type="component" version="1.6.0" method="upgrade">     	<name>Hello World!</name>  	<!-- The following elements are optional and free of formatting conttraints -->  	<creationDate>November 2009</creationDate>  	<author>John Doe</author>  	<authorEmail>john.doe@example.org</authorEmail>  	<authorUrl>http://www.example.org</authorUrl>  	<copyright>Copyright Info</copyright>  	<license>License Info</license>  	<!--  The version string is recorded in the components table -->  	<version>0.0.6</version>  	<!-- The description is optional and defaults to the name -->  	<description>Description of the Hello World component ...</description>     	<install> <!-- Runs on install -->  		<sql>  			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>  		</sql>  	</install>  	<uninstall> <!-- Runs on uninstall -->  		<sql>  			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>  		</sql>  	</uninstall>  	<update> <!-- Runs on update; New in 1.6 -->  		<schemas>  			<schemapath type="mysql">sql/updates/mysql</schemapath>  		</schemas>  	</update>     	<!-- Site Main File Copy Section -->  	<!-- Note the folder attribute: This attribute describes the folder  		to copy FROM in the package to install therefore files copied  		in this section are copied from /site/ in the package -->  	<files folder="site">  		<filename>index.html</filename>  		<filename>helloworld.php</filename>  		<filename>controller.php</filename>  		<folder>views</folder>  		<folder>models</folder>  	</files>     	<administration>  		<!-- Administration Menu Section -->  		<menu>Hello World!</menu>  		<!-- Administration Main File Copy Section -->  		<!-- Note the folder attribute: This attribute describes the folder  			to copy FROM in the package to install therefore files copied  			in this section are copied from /admin/ in the package -->  		<files folder="admin">  			<!-- Admin Main File Copy Section -->  			<filename>index.html</filename>  			<filename>helloworld.php</filename>  			<!-- SQL files section -->  			<folder>sql</folder>  			<!-- tables files section -->  			<folder>tables</folder>  			<!-- models files section -->  			<folder>models</folder>  		</files>  	</administration>     </extension>  

Do the same for the uninstall file:

With your favorite file manager and editor put a file admin/sql/uninstall.mysql.utf8.sql containing:

admin/sql/uninstall.mysql.utf8.sql

DROP TABLE IF EXISTS `#__helloworld`;  

Adding a new field type

For the moment, we have used a hard coded field type for messages. We need to use our database for choosing the message.

Modify the site/views/helloworld/tmpl/default.xml file and put these lines

site/views/helloworld/tmpl/default.xml

<?xml version="1.0" encoding="utf-8"?>  <metadata>  	<layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">  		<message>COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC</message>  	</layout>  	<fields  		name="request"  		addfieldpath="/administrator/components/com_helloworld/models/fields"  	>  		<fieldset name="request">  			<field  				name="id"  				type="helloworld"  				label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"  				description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"  			/>  		</fieldset>  	</fields>  </metadata>  

It introduces a new field type and tells Joomla to look for the field definition in the /administrator/components/com_helloworld/models/fields folder.

With your favorite file manager and editor put a file admin/models/fields/helloworld.php file containing:

admin/models/fields/helloworld.php

<?php  // No direct access to this file  defined('_JEXEC') or die;     // import the list field type  jimport('joomla.form.helper');  JFormHelper::loadFieldClass('list');     /**   * HelloWorld Form Field class for the HelloWorld component   */  class JFormFieldHelloWorld extends JFormFieldList  {  	/**  	 * The field type.  	 *  	 * @var		string  	 */  	protected $type = 'HelloWorld';     	/**  	 * Method to get a list of options for a list input.  	 *  	 * @return	array		An array of JHtml options.  	 */  	protected function getOptions()   	{  		$db = JFactory::getDBO();  		$query = $db->getQuery(true);  		$query->select('id,greeting');  		$query->from('#__helloworld');  		$db->setQuery((string)$query);  		$messages = $db->loadObjectList();  		$options = array();  		if ($messages)  		{  			foreach($messages as $message)   			{  				$options[] = JHtml::_('select.option', $message->id, $message->greeting);  			}  		}  		$options = array_merge(parent::getOptions(), $options);  		return $options;  	}  }  

The new field type displays a drop-down list of messages to choose from. You can see the result of this change in the menu manager section for the helloworld item.

Display the chosen message

When a menu item of this component is created/updated, Joomla stores the identifier of the message. The HelloWorldModelHelloWorld model has now to compute the message according to this identifier and the data stored in the database.

Modify the site/models/helloworld.php file:

site/models/helloworld.php

<?php  // No direct access to this file  defined('_JEXEC') or die('Restricted access');     // import Joomla modelitem library  jimport('joomla.application.component.modelitem');     /**   * HelloWorld Model   */  class HelloWorldModelHelloWorld extends JModelItem  {  	/**  	 * @var string msg  	 */  	protected $msg;     	/**  	 * Returns a reference to the a Table object, always creating it.  	 *  	 * @param	type	The table type to instantiate  	 * @param	string	A prefix for the table class name. Optional.  	 * @param	array	Configuration array for model. Optional.  	 * @return	JTable	A database object  	 * @since	1.6  	 */  	public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())   	{  		return JTable::getInstance($type, $prefix, $config);  	}  	/**  	 * Get the message  	 * @return string The message to be displayed to the user  	 */  	public function getMsg()   	{  		if (!isset($this->msg))   		{  			$id = JRequest::getInt('id');  			// Get a TableHelloWorld instance  			$table = $this->getTable();     			// Load the message  			$table->load($id);     			// Assign the message  			$this->msg = $table->greeting;  		}  		return $this->msg;  	}  }  

The model now asks the TableHelloWorld to get the message. This table class has to be defined in admin/tables/helloworld.php file

admin/tables/helloworld.php

<?php  // No direct access  defined('_JEXEC') or die('Restricted access');     // import Joomla table library  jimport('joomla.database.table');     /**   * Hello Table class   */  class HelloWorldTableHelloWorld extends JTable  {  	/**  	 * Constructor  	 *  	 * @param object Database connector object  	 */  	function __construct(&$db)   	{  		parent::__construct('#__helloworld', 'id', $db);  	}  }  

You shouldn’t see any differences, but if you access the database you should see a table named jos_helloworld with two columns: id and greeting. And two entries: Hello World! and Good bye World

Packaging the component

Content of your code directory

Create a compressed file of this directory or directly download the archive and install it using the extension manager of Joomla!1.6. You can add a menu item of this component using the menu manager in the backend.