создание компонента Joomla

’tag’

Использование класса JRoute в компоненте для отображения ссылок в Joomla 1.7

Май 29, 2012

Класс JRoute имеет один единственный метод «_». Данный метод позволяет при передаче ему ссылки отобразить ее как обычную ссылку, либо в SEF виде. Также при разработке не нужно заботиться о передаче имени домена сайта.

Следующая запись:

JRoute::_('index.php?option=com_simple&view=user&id=' . $user->user_id');

при $user->user_id равным 42 преобразуется в следующий вид:
http://localhost/joomla17/index.php?option=com_simple&view=user&id=42

Однако, если включен параметр "Search Engine Friendly URLs", то ссылка будет SEF вида.

Примечание

Класс JRoute следует использовать исключительно для перелинковки, а точнее применения полученной ссылки в теге <a>.

Tags: , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка

Использование языковых файлов в шаблоне компонента в Joomla 1.7

Май 29, 2012

Языковые файлы компонентов, отвечающие за открытую часть сайта, находятся в папке:
/language/ru-RU

Языковой файл компонента com_simple имеет следующее название:
ru-RU.com_simple.ini

Поместим в данный файл строчку:
COM_SIMPLE_USER_H1="Пользователь"

Теперь языковая переменная COM_SIMPLE_USER_H1 доступна из шаблона компонента в открытой части.

В папке tmpl находится шаблон default.php. Указываем содержимое:

<?php defined( '_JEXEC' ) or die; ?>

<h1><?php echo JText::_('COM_SIMPLE_USER_H1'); ?> <?php echo $this->escape($this->item->name); ?></h1>

Проверяем вывод на экран:
http://localhost/joomla17/index.php?option=com_simple&view=user&id=42

В теге h1 теперь находится:
Пользователь Super User

Для вывода и перевода строки COM_SIMPLE_USER_H1 используется класс JText и метод "_".

Если перевод для строки не задан, то будет отображено значение по-умолчанию. В данном случае COM_SIMPLE_USER_H1.

В Настройках Joomla 1.7 из Закрытой части сайта можно включить режим отладки языка, что позволит видеть все переводимые строки, окруженные символами **.

Tags: , , , , , , , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка

Комплексные запросы к базе данных в Joomla 1.7

Май 28, 2012

Ранее я писал про простой запрос в модели через прямое подключение к базе данных, например:

$user_id = JRequest::getInt('id');

$db = $this->getDbo();
$query = $db->getQuery(true);

$query->select('name');
$query->from('#__users')
	->where('id = ' . $user_id);

$db->setQuery($query);
$row = $db->loadObject();

Дополнительные возможности скрываются в файле databasequery.php:
/libraries/joomla/database/databasequery.php

Речь идет о следующих методах (часть):

  • join
  • rightJoin
  • leftJoin
  • outerJoin
  • group
  • length

Методы находятся в классе JDatabaseQuery.

По сути запрос может быть любого вида, но как мы видим, он не прописывается напрямую и вручную, а создается через подключение требуемых методов.

Так, более сложных запрос по выборке из двух страниц будет реализован так:

$query->select('m.id, m.title, description')
	->from('#__menu as m')
	->join('INNER', '#__menu_types AS t USING(id)')
	->where('description = ""');

Видно, что в запросе был использован тип объединения INNER JOIN (оператор).

При внимательном изучении файла databasequery.php видно, что можно использовать вместо join метод innerJoin:

public function innerJoin($conditions) {
	$this->join('INNER', $conditions);

	return $this;
}

Строка с запросом может быть в несколько строчек:

$query->select('m.id, m.title, description');
$query->from('#__menu as m');
$query->innerJoin('#__menu_types AS t USING(id)');
$query->where('description = ""');

Теперь можно не использовать класс JTable в модели компонента, который позволяет выводить запись по идентификатору, а использовать свой запрос любой сложности. Работа с классом JTable демонстрировалась в данной записи:

Файл databasequery.php

<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Element Class.
 *
 * @package     Joomla.Platform
 * @subpackage  Database
 * @since       11.1
 */
class JDatabaseQueryElement
{
	/**
	 * @var    string  The name of the element.
	 * @since  11.1
	 */
	protected $name = null;

	/**
	 * @var    array  An array of elements.
	 * @since  11.1
	 */
	protected $elements = null;

	/**
	 * @var    string  Glue piece.
	 * @since  11.1
	 */
	protected $glue = null;

	/**
	 * Constructor.
	 *
	 * @param   string  $name      The name of the element.
	 * @param   mixed   $elements  String or array.
	 * @param   string  $glue      The glue for elements.
	 *
	 * @return  JDatabaseQueryElement
	 *
	 * @since   11.1
	 */
	public function __construct($name, $elements, $glue = ',')
	{
		$this->elements	= array();
		$this->name		= $name;
		$this->glue		= $glue;

		$this->append($elements);
	}

	/**
	 * Magic function to convert the query element to a string.
	 *
	 * @return  string
	 *
	 * @since   11.1
	 */
	public function __toString()
	{
		if (substr($this->name, -2) == '()') {
			return PHP_EOL.substr($this->name, 0, -2).'('.implode($this->glue, $this->elements).')';
		}
		else {
			return PHP_EOL.$this->name.' '.implode($this->glue, $this->elements);
		}
	}

	/**
	 * Appends element parts to the internal list.
	 *
	 * @param   mixed  String or array.
	 *
	 * @return  void
	 *
	 * @since   11.1
	 */
	public function append($elements)
	{
		if (is_array($elements)) {
			$this->elements = array_merge($this->elements, $elements);
		}
		else {
			$this->elements = array_merge($this->elements, array($elements));
		}
	}

	/**
	 * Gets the elements of this element.
	 *
	 * @return  string
	 *
	 * @since   11.1
	 */
	public function getElements()
	{
		return $this->elements;
	}
}

/**
 * Query Building Class.
 *
 * @package     Joomla.Platform
 * @subpackage  Database
 * @since       11.1
 */
abstract class JDatabaseQuery
{
	/**
	 * @var    resource  The database connection resource.
	 * @since  11.1
	 */
	protected $db = null;

	/**
	 * @var    string  The query type.
	 * @since  11.1
	 */
	protected $type = '';

	/**
	 * @var    string  The query element for a generic query (type = null).
	 * @since  11.1
	 */
	protected $element = null;

	/**
	 * @var    object  The select element.
	 * @since  11.1
	 */
	protected $select = null;

	/**
	 * @var    object  The delete element.
	 * @since  11.1
	 */
	protected $delete = null;

	/**
	 * @var    object  The update element.
	 * @since  11.1
	 */
	protected $update = null;

	/**
	 * @var    object  The insert element.
	 * @since  11.1
	 */
	protected $insert = null;

	/**
	 * @var    object  The from element.
	 * @since  11.1
	 */
	protected $from = null;

	/**
	 * @var    object  The join element.
	 * @since  11.1
	 */
	protected $join = null;

	/**
	 * @var    object  The set element.
	 * @since  11.1
	 */
	protected $set = null;

	/**
	 * @var    object  The where element.
	 * @since  11.1
	 */
	protected $where = null;

	/**
	 * @var    object  The group by element.
	 * @since  11.1
	 */
	protected $group = null;

	/**
	 * @var    object  The having element.
	 * @since  11.1
	 */
	protected $having = null;

	/**
	 * @var    object  The column list for an INSERT statement.
	 * @since  11.1
	 */
	protected $columns = null;

	/**
	 * @var    object  The values list for an INSERT statement.
	 * @since  11.1
	 */
	protected $values = null;

	/**
	 * @var    object  The order element.
	 * @since  11.1
	 */
	protected $order = null;

	/**
	 * Magic method to provide method alias support for quote() and quoteName().
	 *
	 * @param   string  $method  The called method.
	 * @param   array   $args    The array of arguments passed to the method.
	 *
	 * @return  string  The aliased method's return value or null.
	 *
	 * @since   11.1
	 */
	public function __call($method, $args)
	{
		if (empty($args)) {
			return;
		}

		switch ($method)
		{
			case 'q':
				return $this->quote($args[0], isset($args[1]) ? $args[1] : true);
				break;

			case 'qn':
				return $this->quoteName($args[0]);
				break;

			case 'e':
				return $this->escape($args[0], isset($args[1]) ? $args[1] : false);
				break;
		}
	}

	/**
	 * Class constructor.
	 *
	 * @param   JDatabase  $db  The database connector resource.
	 *
	 * @return  JDatabaseQuery
	 * @since   11.1
	 */
	public function __construct(JDatabase $db = null)
	{
		$this->db = $db;
	}

	/**
	 * Magic function to convert the query to a string.
	 *
	 * @return  string	The completed query.
	 *
	 * @since   11.1
	 */
	public function __toString()
	{
		$query = '';

		switch ($this->type)
		{
			case 'element':
				$query .= (string) $this->element;
				break;

			case 'select':
				$query .= (string) $this->select;
				$query .= (string) $this->from;
				if ($this->join) {
					// special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}

				if ($this->where) {
					$query .= (string) $this->where;
				}

				if ($this->group) {
					$query .= (string) $this->group;
				}

				if ($this->having) {
					$query .= (string) $this->having;
				}

				if ($this->order) {
					$query .= (string) $this->order;
				}

				break;

			case 'delete':
				$query .= (string) $this->delete;
				$query .= (string) $this->from;

				if ($this->join) {
					// special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}

				if ($this->where) {
					$query .= (string) $this->where;
				}

				break;

			case 'update':
				$query .= (string) $this->update;
				$query .= (string) $this->set;

				if ($this->where) {
					$query .= (string) $this->where;
				}

				break;

			case 'insert':
				$query .= (string) $this->insert;

				// Set method
				if ($this->set) {
					$query .= (string) $this->set;
				}
				// Columns-Values method
				elseif ($this->values) {
					if ($this->columns) {
						$query .= (string) $this->columns;
					}

					$query .= ' VALUES ';
					$query .= (string) $this->values;
				}

				break;
		}

		return $query;
	}

	/**
	 * Magic function to get protected variable value
	 *
	 * @param   String
	 * @return  mixed
	 *
	 * @since   11.1
	 */
	public function __get($name)
	{
		return isset($this->$name) ? $this->$name : null;
	}

	/**
	 * Casts a value to a char.
	 *
	 * Ensure that the value is properly quoted before passing to the method.
	 *
	 * @param   string  $value  The value to cast as a char.
	 *
	 * @return  string  Returns the cast value.
	 *
	 * @since   11.1
	 */
	public function castAsChar($value)
	{
		return $value;
	}

	/**
	 * Gets the number of characters in a string.
	 *
	 * Note, use 'length' to find the number of bytes in a string.
	 *
	 * @param   string  $value  A value.
	 *
	 * @return  string  The required char lenght call.
	 *
	 * @since 11.1
	 */
	public function charLength($field)
	{
		return 'CHAR_LENGTH('.$field.')';
	}

	/**
	 * Clear data from the query or a specific clause of the query.
	 *
	 * @param   string  $clear  Optionally, the name of the clause to clear, or nothing to clear the whole query.
	 *
	 * @return  void
	 *
	 * @since   11.1
	 */
	public function clear($clause = null)
	{
		switch ($clause)
		{
			case 'select':
				$this->select = null;
				$this->type = null;
				break;

			case 'delete':
				$this->delete = null;
				$this->type = null;
				break;

			case 'update':
				$this->update = null;
				$this->type = null;
				break;

			case 'insert':
				$this->insert = null;
				$this->type = null;
				break;

			case 'from':
				$this->from = null;
				break;

			case 'join':
				$this->join = null;
				break;

			case 'set':
				$this->set = null;
				break;

			case 'where':
				$this->where = null;
				break;

			case 'group':
				$this->group = null;
				break;

			case 'having':
				$this->having = null;
				break;

			case 'order':
				$this->order = null;
				break;

			case 'columns':
				$this->columns = null;
				break;

			case 'values':
				$this->values = null;
				break;

			default:
				$this->type = null;
				$this->select = null;
				$this->delete = null;
				$this->update = null;
				$this->insert = null;
				$this->from = null;
				$this->join = null;
				$this->set = null;
				$this->where = null;
				$this->group = null;
				$this->having = null;
				$this->order = null;
				$this->columns = null;
				$this->values = null;
				break;
		}

		return $this;
	}

	/**
	 * Adds a column, or array of column names that would be used for an INSERT INTO statement.
	 *
	 * @param   mixed  $columns  A column name, or array of column names.
	 *
	 * @return  JDatabaseQuerySQLAzure  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	function columns($columns)
	{
		if (is_null($this->columns)) {
			$this->columns = new JDatabaseQueryElement('()', $columns);
		}
		else {
			$this->columns->append($columns);
		}

		return $this;
	}

	/**
	 * Concatenates an array of column names or values.
	 *
	 * @param   array   $values     An array of values to concatenate.
	 * @param   string  $separator  As separator to place between each value.
	 *
	 * @return  string  The concatenated values.
	 *
	 * @since   11.1
	 */
	function concatenate($values, $separator = null)
	{
		if ($separator) {
			return 'CONCATENATE('.implode(' || '.$this->quote($separator).' || ', $values).')';
		}
		else{
			return 'CONCATENATE('.implode(' || ', $values).')';
		}
	}

	/**
	 * Gets the current date and time.
	 *
	 * @return  string
	 *
	 * @since   11.1
	 */
	function currentTimestamp()
	{
		return 'CURRENT_TIMESTAMP()';
	}

	/**
	 * Returns a PHP date() function compliant date format for the database driver.
	 *
	 * @return  string  The format string.
	 *
	 * @since   11.1
	 */
	public function dateFormat()
	{
		return 'Y-m-d H:i:s';
	}

	/**
	 * Add a table name to the DELETE clause of the query.
	 *
	 * Note that you must not mix insert, update, delete and select method calls when building a query.
	 *
	 * @param   string  $table  The name of the table to delete from.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function delete($table = null)
	{
		$this->type	= 'delete';
		$this->delete	= new JDatabaseQueryElement('DELETE', null);

		if (!empty($table)) {
			$this->from($table);
		}

		return $this;
	}

	/**
	 * Method to escape a string for usage in an SQL statement.
	 *
	 * @param   string  $text   The string to be escaped.
	 * @param   bool    $extra  Optional parameter to provide extra escaping.
	 *
	 * @return  string  The escaped string.
	 *
	 * @since   11.1
	 * @throws  DatabaseError if the internal db property is not a valid object.
	 */
	public function escape($text, $extra = false)
	{
		if (!($this->db instanceof JDatabase)) {
			throw new DatabaseException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT');
		}

		$this->db->escape($text, $extra);
	}

	/**
	 * Add a table to the FROM clause of the query.
	 *
	 * Note that while an array of tables can be provided, it is recommended you use explicit joins.
	 *
	 * @param   mixed  $tables  A string or array of table names.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function from($tables)
	{
		if (is_null($this->from)) {
			$this->from = new JDatabaseQueryElement('FROM', $tables);
		}
		else {
			$this->from->append($tables);
		}

		return $this;
	}

	/**
	 * Add a grouping column to the GROUP clause of the query.
	 *
	 * @param   mixed  $columns  A string or array of ordering columns.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function group($columns)
	{
		if (is_null($this->group)) {
			$this->group = new JDatabaseQueryElement('GROUP BY', $columns);
		}
		else {
			$this->group->append($columns);
		}

		return $this;
	}

	/**
	 * A conditions to the HAVING clause of the query.
	 *
	 * @param   mixed   $conditions  A string or array of columns.
	 * @param   string  $glue        The glue by which to join the conditions. Defaults to AND.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function having($conditions, $glue='AND')
	{
		if (is_null($this->having)) {
			$glue = strtoupper($glue);
			$this->having = new JDatabaseQueryElement('HAVING', $conditions, " $glue ");
		}
		else {
			$this->having->append($conditions);
		}

		return $this;
	}

	/**
	 * Add an INNER JOIN clause to the query.
	 *
	 * @param   string  $conditions  A string or array of conditions.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function innerJoin($conditions)
	{
		$this->join('INNER', $conditions);

		return $this;
	}

	/**
	 * Add a table name to the INSERT clause of the query.
	 *
	 * Note that you must not mix insert, update, delete and select method calls when building a query.
	 *
	 * @param   mixed  $table  The name of the table to insert data into.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function insert($table)
	{
		$this->type	= 'insert';
		$this->insert	= new JDatabaseQueryElement('INSERT INTO', $table);

		return $this;
	}

	/**
	 * Add a JOIN clause to the query.
	 *
	 * @param   string  $type        The type of join. This string is prepended to the JOIN keyword.
	 * @param   string  $conditions  A string or array of conditions.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function join($type, $conditions)
	{
		if (is_null($this->join)) {
			$this->join = array();
		}
		$this->join[] = new JDatabaseQueryElement(strtoupper($type) . ' JOIN', $conditions);

		return $this;
	}

	/**
	 * Add a LEFT JOIN clause to the query.
	 *
	 * @param   string  $conditions  A string or array of conditions.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function leftJoin($conditions)
	{
		$this->join('LEFT', $conditions);

		return $this;
	}

	/**
	 * Get the length of a string in bytes.
	 *
	 * Note, use 'charLength' to find the number of characters in a string.
	 *
	 * @param   string  $value  The string to measure.
	 *
	 * @return  int
	 *
	 * @since   11.1
	 */
	function length($value)
	{
		return 'LENGTH('.$value.')';
	}

	/**
	 * Get the null or zero representation of a timestamp for the database driver.
	 *
	 * @param   boolean  $quoted  Optionally wraps the null date in database quotes (true by default).
	 *
	 * @return  string  Null or zero representation of a timestamp.
	 *
	 * @since   11.1
	 */
	public function nullDate($quoted = true)
	{
		if (!($this->db instanceof JDatabase)) {
			throw new DatabaseException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT');
		}

		$result = $this->db->getNullDate($quoted);

		if ($quoted) {
			return $this->db->quote($result);
		}

		return $result;
	}

	/**
	 * Add a ordering column to the ORDER clause of the query.
	 *
	 * @param   mixed  $columns  A string or array of ordering columns.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function order($columns)
	{
		if (is_null($this->order)) {
			$this->order = new JDatabaseQueryElement('ORDER BY', $columns);
		}
		else {
			$this->order->append($columns);
		}

		return $this;
	}

	/**
	 * Add an OUTER JOIN clause to the query.
	 *
	 * @param   string  $conditions  A string or array of conditions.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function outerJoin($conditions)
	{
		$this->join('OUTER', $conditions);

		return $this;
	}

	/**
	 * Method to quote and optionally escape a string to database requirements for insertion into the database.
	 *
	 * @param   string  $text    The string to quote.
	 * @param   bool    $escape  True to escape the string, false to leave it unchanged.
	 *
	 * @return  string  The quoted input string.
	 *
	 * @since   11.1
	 * @throws  DatabaseError if the internal db property is not a valid object.
	 */
	public function quote($text, $escape = true)
	{
		if (!($this->db instanceof JDatabase)) {
			throw new DatabaseException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT');
		}

		return $this->db->quote(($escape ? $this->db->escape($text) : $text));
	}

	/**
	 * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection
	 * risks and reserved word conflicts.
	 *
	 * @param   string  $name  The identifier name to wrap in quotes.
	 *
	 * @return  string  The quote wrapped name.
	 *
	 * @since   11.1
	 * @throws  DatabaseError if the internal db property is not a valid object.
	 */
	public function quoteName($name)
	{
		if (!($this->db instanceof JDatabase)) {
			throw new DatabaseException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT');
		}

		return $this->db->quoteName($name);
	}

	/**
	 * Add a RIGHT JOIN clause to the query.
	 *
	 * @param   string  $conditions  A string or array of conditions.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function rightJoin($conditions)
	{
		$this->join('RIGHT', $conditions);

		return $this;
	}

	/**
	 * Add a single column, or array of columns to the SELECT clause of the query.
	 *
	 * Note that you must not mix insert, update, delete and select method calls when building a query.
	 * The select method can, however, be called multiple times in the same query.
	 *
	 * @param   mixed  $columns  A string or an array of field names.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function select($columns)
	{
		$this->type = 'select';

		if (is_null($this->select)) {
			$this->select = new JDatabaseQueryElement('SELECT', $columns);
		}
		else {
			$this->select->append($columns);
		}

		return $this;
	}

	/**
	 * Add a single condition string, or an array of strings to the SET clause of the query.
	 *
	 * @param   mixed   $conditions  A string or array of conditions.
	 * @param   string  $glue        The glue by which to join the condition strings. Defaults to ,.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function set($conditions, $glue=',')
	{
		if (is_null($this->set)) {
			$glue = strtoupper($glue);
			$this->set = new JDatabaseQueryElement('SET', $conditions, "\n\t$glue ");
		}
		else {
			$this->set->append($conditions);
		}

		return $this;
	}

	/**
	 * Add a table name to the UPDATE clause of the query.
	 *
	 * Note that you must not mix insert, update, delete and select method calls when building a query.
	 *
	 * @param   mixed  $tables  A string or array of table names.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function update($tables)
	{
		$this->type = 'update';
		$this->update = new JDatabaseQueryElement('UPDATE', $tables);

		return $this;
	}

	/**
	 * Adds a tuple, or array of tuples that would be used as values for an INSERT INTO statement.
	 *
	 * @param  string  $values  A single tuple, or array of tuples.
	 *
	 * @return  JDatabaseQuerySQLAzure  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	function values($values)
	{
		if (is_null($this->values)) {
			$this->values = new JDatabaseQueryElement('()', $values, '), (');
		}
		else {
			$this->values->append($values);
		}

		return $this;
	}

	/**
	 * Add a single condition, or an array of conditions to the WHERE clause of the query.
	 *
	 * @param   mixed   $conditions  A string or array of where conditions.
	 * @param   string  $glue        The glue by which to join the conditions. Defaults to AND.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   11.1
	 */
	public function where($conditions, $glue = 'AND')
	{
		if (is_null($this->where)) {
			$glue = strtoupper($glue);
			$this->where = new JDatabaseQueryElement('WHERE', $conditions, " $glue ");
		}
		else {
			$this->where->append($conditions);
		}

		return $this;
	}
}

Tags: , , , , , , , , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка

Добавление модели и вида с шаблоном к компоненту в Joomla 1.7

Май 27, 2012

Для начала в папке с компонентом в открытой части сайта необходимо создать папку models.

В папке models должен быть файл с именем равным виду. Например:
http://localhost/index.php?option=com_simple&view=users

В данном случае в папке models должен быть файл users.php.

В то же время необходимо создать папку views с подпапкой users, которая должна содержать файл view.html.php и папку tmpl с файлом default.php.

Файл users.php должен содержать класс модели, имя которого начинается с названия компонента и заканчивается на название модели:
SimpleModelUsers

Судя по содержимому следующей папки:
/libraries/joomla/application/component

у нас в распоряжении имеется несколько классов модели, от которых может быть создан класс модели нашего компонента:

К сожалению, во-первых нет русской документации по данным классам, а также нормального объяснения принципа работы от самих разработчиков на английском. Есть официальная документация, но примеры использования только по самой Джумле нужно искать и самому себе объяснять их.

Класс JModelList позволяет быстро сделать выборку нужных значений запросом из базы данных.

Импортируем класс и определяем наследование класса:

jimport('joomla.application.component.modellist');

class SimpleModelUsers extends JModelList

Теперь через родителя вызываем функцию getListQuery, которая всего лишь создаст почву для нового запроса:

public function getListQuery()
{
	$query = parent::getListQuery();

Теперь добавляем запрос и возвращаем его:

public function getListQuery()
{
	$query = parent::getListQuery();

	$query->select('name');
	$query->from('#__users')
		->where('id > 42');
	return $query;
}

Значения из базы данных могут быть получены посредством вызова функции getItems класса JModelList. Вызов производится из вида, а именно файла view.html.php:

<?php
defined( '_JEXEC' ) or die;

jimport( 'joomla.application.component.view');

class SimpleViewUsers extends JView
{
	protected $items;

	public function display($tpl = null)
	{
		$this->items = $this->get('Items');

		parent::display($tpl);
	}
}

Видно, что изначально импортируется файл с классом JView:

jimport( 'joomla.application.component.view');

Файл находится здесь:
/libraries/joomla/application/component/view.php

Класс вида только один – JView.

Метод display класса JView всего лишь загружает файл шаблона из папки tmpl:

function display($tpl = null)
{
	$result = $this->loadTemplate($tpl);
	if (JError::isError($result)) {
		return $result;
	}
		echo $result;
}

В классе компонента сначала в переменную $items записываются данные из базы данных, полученные через запрос, созданный в модели компонента и выполненный посредством функции getItems класса JModelList.

Функция getItems вызывается через $this->get('Items'). Метод get класса вида JView сначала ищет метод, образованный через слияние "get" и передаваемого названия. В нашем случае "get + Items". Если метод не найден, то метод get класса вида JView обращается к своему родительскому классу JObject.

Полученные данные записываются в переменную $items класса вида компонента:

protected $items;

В завершение вызывается родительский метод display:

parent::display($tpl);

Теперь в файле default.php в папке с шаблонами tmpl можно вывести данные из переменной $items:

<?php defined( '_JEXEC' ) or die; ?>

<?php foreach ($this->items as $item) : ?>
	<?php echo $this->escape($item->name); ?><br />
<?php endforeach; ?>

После запуска в стоке браузера следующего url:
http://localhost/joomla17/index.php?option=com_simple&view=users

На экране будет виден список пользователей.

Заключение

Вид view.html.php:

  • обращается к модели;
  • загружает шаблон.

Tags: , , , , , , , , , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка

Стандартный класс контроллера в Joomla 1.7

Май 26, 2012

Контроллер для компонента образуется от стандартного контроллера Joomla, который включается в основном файле компонента:

jimport('joomla.application.component.controller');

Сам файл стандартного контроллера controller.php находится в следующей папке:
/libraries/joomla/application/component

Если открыть файл controller.php видно, что очень много стандартных методов. Их можно переопределить в контроллере компонента.

До тех пор, пока у нас не задан шаблон отображения и вид (view) компонента, при оригинальном вызове компонента посредством представленного ниже запроса будет невозможно:
http://localhost/joomla17/index.php?option=com_simple

Исполнение завершится ошибкой 500.

Для того, чтобы избежать ошибки необходимо создать папку views и подпапку с нужным видом, к примеру, users. В ней создать файл view.html.php, папку tmpl и файл default.php.

Метод display стандартного контроллера JController найдет нужный шаблон и отобразит его. По-умолчанию шаблон имеет имя default.

Метод display класса JController

/**
 * Typical view method for MVC based architecture
 *
 * This function is provide as a default implementation, in most cases
 * you will need to override it in your own controllers.
 *
 * @param   boolean  $cachable   If true, the view output will be cached
 * @param   array    $urlparams  An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
 *
 * @return  JController  A JController object to support chaining.
 * @since   11.1
 */
public function display($cachable = false, $urlparams = false)
{
	$document	= JFactory::getDocument();
	$viewType	= $document->getType();
	$viewName	= JRequest::getCmd('view', $this->default_view);
	$viewLayout	= JRequest::getCmd('layout', 'default');

	$view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath));

	// Get/Create the model
	if ($model = $this->getModel($viewName)) {
		// Push the model into the view (as default)
		$view->setModel($model, true);
	}

	// Set the layout
	$view->setLayout($viewLayout);

	$view->assignRef('document', $document);

	$conf = JFactory::getConfig();

	// Display the view
	if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1) {
		$option	= JRequest::getCmd('option');
		$cache	= JFactory::getCache($option, 'view');

		if (is_array($urlparams)) {
			$app = JFactory::getApplication();

			$registeredurlparams = $app->get('registeredurlparams');

			if (empty($registeredurlparams)) {
				$registeredurlparams = new stdClass;
			}

			foreach ($urlparams as $key => $value)
			{
				// Add your safe url parameters with variable type as value {@see JFilterInput::clean()}.
				$registeredurlparams->$key = $value;
			}

			$app->set('registeredurlparams', $registeredurlparams);
		}

		$cache->get($view, 'display');

	}
	else {
		$view->display();
	}

	return $this;
}

Как уже было сказано любой метод можно переопределить и, чтобы не создавать файлов можно сделать вывод на экран напрямую из контроллера без подключения вида и шаблона.
components/com_simple/controller.php

<?php
defined( '_JEXEC' ) or die;

jimport('joomla.application.component.controller');

class SimpleController extends JController
{
	public function display()
	{
		echo 'Отображение';
	}
}

Теперь на экране должен быть виден текст "Отображение" в рамках шаблона сайта.

Файл controller.php со стандартным классом JController

<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Application
 *
 * @copyright   Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Base class for a Joomla Controller
 *
 * Controller (Controllers are where you put all the actual code.) Provides basic
 * functionality, such as rendering views (aka displaying templates).
 *
 * @package     Joomla.Platform
 * @subpackage  Application
 * @since       11.1
 */
class JController extends JObject
{
	/**
	 * ACO Section for the controller.
	 *
	 * @var    string
	 * @since  11.1
	 * @deprecated    12.1
	 */
	protected $_acoSection;

	/**
	 * Default ACO Section value for the controller.
	 *
	 * @var    string
	 * @since  11.1
	 * @deprecated    12.1
	 */
	protected $_acoSectionValue;

	/**
	 * The base path of the controller
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _basePath.
	 */
	protected $basePath;

	/**
	 * The default view for the display method.
	 *
	 * @var    string
	 * @since  11.1
	 */
	protected $default_view;

	/**
	 * The mapped task that was performed.
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _doTask.
	 */
	protected $doTask;

	/**
	 * Redirect message.
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _message.
	 */
	protected $message;

	/**
	 * Redirect message type.
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _messageType.
	 */
	protected $messageType;

	/**
	 * Array of class methods
	 *
	 * @var    array
	 * @since  11.1
	 * @note   Replaces _methods.
	 */
	protected $methods;

	/**
	 * The name of the controller
	 *
	 * @var    array
	 * @since  11.1
	 * @note   Replaces _name.
	 */
	protected $name;

	/**
	 * The prefix of the models
	 *
	 * @var    string
	 * @since  11.1
	 */
	protected $model_prefix;

	/**
	 * The set of search directories for resources (views).
	 *
	 * @var    array
	 * @since  11.1
	 * @note   Replaces _path.
	 */
	protected $paths;

	/**
	 * URL for redirection.
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _redirect.
	 */
	protected $redirect;

	/**
	 * Current or most recently performed task.
	 *
	 * @var    string
	 * @since  11.1
	 * @note   Replaces _task.
	 */
	protected $task;

	/**
	 * Array of class methods to call for a given task.
	 *
	 * @var    array
	 * @since  11.1
	 * @note   Replaces _taskMap.
	 */
	protected $taskMap;

	/**
	 * Adds to the stack of model paths in LIFO order.
	 *
	 * @param   mixed   $path    The directory (string), or list of directories (array) to add.
	 * @param   string  $prefix  A prefix for models
	 *
	 * @return  void
	 */
	public static function addModelPath($path, $prefix='')
	{
		jimport('joomla.application.component.model');
		JModel::addIncludePath($path, $prefix);
	}

	/**
	 * Create the filename for a resource.
	 *
	 * @param   string  $type    The resource type to create the filename for.
	 * @param   array   $parts   An associative array of filename information. Optional.
	 *
	 * @return  string  The filename.
	 * @since   11.1
	 * @note    Replaced _createFileName.
	 */
	protected static function createFileName($type, $parts = array())
	{
		$filename = '';

		switch ($type) {
			case 'controller':
				if (!empty($parts['format'])) {
					if ($parts['format'] == 'html') {
						$parts['format'] = '';
					} else {
						$parts['format'] = '.'.$parts['format'];
					}
				} else {
					$parts['format'] = '';
				}

				$filename = strtolower($parts['name']).$parts['format'].'.php';
				break;

			case 'view':
				if (!empty($parts['type'])) {
					$parts['type'] = '.'.$parts['type'];
				}

				$filename = strtolower($parts['name']).'/view'.$parts['type'].'.php';
				break;
		}

		return $filename;
	}

	/**
	 * Method to get a singleton controller instance.
	 *
	 * @param   string  $prefix  The prefix for the controller.
	 * @param   array   $config  An array of optional constructor options.
	 *
	 * @return  mixed   JController derivative class or JException on error.
	 * @since   11.1
	 */
	public static function getInstance($prefix, $config = array())
	{
		static $instance;

		if (!empty($instance)) {
			return $instance;
		}

		// Get the environment configuration.
		$basePath	= array_key_exists('base_path', $config) ? $config['base_path'] : JPATH_COMPONENT;
		$format		= JRequest::getWord('format');
		$command	= JRequest::getVar('task', 'display');

		// Check for array format.
		$filter = JFilterInput::getInstance();

		if (is_array($command)) {
			$command = $filter->clean(array_pop(array_keys($command)), 'cmd');
		}
		else {
			$command = $filter->clean($command, 'cmd');
		}

		// Check for a controller.task command.
		if (strpos($command, '.') !== false) {
			// Explode the controller.task command.
			list($type, $task) = explode('.', $command);

			// Define the controller filename and path.
			$file	= self::createFileName('controller', array('name' => $type, 'format' => $format));
			$path	= $basePath.'/controllers/'.$file;

			// Reset the task without the contoller context.
			JRequest::setVar('task', $task);
		}
		else {
			// Base controller.
			$type	= null;
			$task	= $command;

			// Define the controller filename and path.
			$file	= self::createFileName('controller', array('name' => 'controller'));
			$path	= $basePath.'/'.$file;
		}

		// Get the controller class name.
		$class = ucfirst($prefix).'Controller'.ucfirst($type);

		// Include the class if not present.
		if (!class_exists($class)) {
			// If the controller file path exists, include it.
			if (file_exists($path)) {
				require_once $path;
			}
			else {
				throw new JException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER', $type, $format), 1056, E_ERROR, $type, true);
			}
		}

		// Instantiate the class.
		if (class_exists($class)) {
			$instance = new $class($config);
		}
		else {
			throw new JException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER_CLASS', $class), 1057, E_ERROR, $class, true);
		}

		return $instance;
	}

	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration settings.
	 *                          Recognized key values include 'name', 'default_task', 'model_path', and
	 *                          'view_path' (this list is not meant to be comprehensive).
	 *
	 * @return  JController
	 * @since   11.1
	 */
	public function __construct($config = array())
	{
		// Initialise variables.
		$this->methods		= array();
		$this->message		= null;
		$this->messageType = 'message';
		$this->paths		= array();
		$this->redirect		= null;
		$this->taskMap		= array();

		// Determine the methods to exclude from the base class.
		$xMethods = get_class_methods('JController');

		// Get the public methods in this class using reflection.
		$r			= new ReflectionClass($this);
		$rName		= $r->getName();
		$rMethods	= $r->getMethods(ReflectionMethod::IS_PUBLIC);
		$methods	= array();

		foreach ($rMethods as $rMethod)
		{
			$mName = $rMethod->getName();

			// Add default display method if not explicitly declared.
			if (!in_array($mName, $xMethods) || $mName == 'display') {
				$this->methods[] = strtolower($mName);
				// Auto register the methods as tasks.
				$this->taskMap[strtolower($mName)] = $mName;
			}
		}

		//set the view name
		if (empty($this->name)) {
			if (array_key_exists('name', $config)) {
				$this->name = $config['name'];
			}
			else {
				$this->name = $this->getName();
			}
		}

		// Set a base path for use by the controller
		if (array_key_exists('base_path', $config)) {
			$this->basePath	= $config['base_path'];
		}
		else {
			$this->basePath	= JPATH_COMPONENT;
		}

		// If the default task is set, register it as such
		if (array_key_exists('default_task', $config)) {
			$this->registerDefaultTask($config['default_task']);
		}
		else {
			$this->registerDefaultTask('display');
		}

		// Set the models prefix
		if (empty($this->model_prefix)) {
			if (array_key_exists('model_prefix', $config)) {
				// User-defined prefix
				$this->model_prefix = $config['model_prefix'];
			}
			else {
				$this->model_prefix = $this->name . 'Model';
			}
		}

		// Set the default model search path
		if (array_key_exists('model_path', $config)) {
			// user-defined dirs
			$this->addModelPath($config['model_path'], $this->model_prefix);
		}
		else {
			$this->addModelPath($this->basePath.'/models', $this->model_prefix);
		}

		// Set the default view search path
		if (array_key_exists('view_path', $config)) {
			// User-defined dirs
			$this->setPath('view', $config['view_path']);
		}
		else {
			$this->setPath('view', $this->basePath.'/views');
		}

		// Set the default view.
		if (array_key_exists('default_view', $config)) {
			$this->default_view	= $config['default_view'];
		}
		elseif (empty($this->default_view)) {
			$this->default_view = $this->getName();
		}

	}

	/**
	 * Adds to the search path for templates and resources.
	 *
	 * @param   string  $type  The path type (e.g. 'model', 'view').
	 * @param   mixed   $path  The directory string  or stream array to search.
	 *
	 * @return  JController  A JController object to support chaining.
	 * @since   11.1
	 * @note    Replaces _addPath.
	 */
	protected function addPath($type, $path)
	{
		// Just force path to array
		settype($path, 'array');

		if (!isset($this->paths[$type])) {
			$this->paths[$type] = array();
		}

		// Loop through the path directories
		foreach ($path as $dir)
		{
			// No surrounding spaces allowed!
			$dir = rtrim(JPath::check($dir, '/'), '/').'/';

			// Add to the top of the search dirs
			array_unshift($this->paths[$type], $dir);
		}

		return $this;
	}

	/**
	 * Add one or more view paths to the controller's stack, in LIFO order.
	 *
	 * @param   mixed  $path  The directory (string) or list of directories (array) to add.
	 *
	 * @return  JController  This object to support chaining.
	 */
	public function addViewPath($path)
	{
		$this->addPath('view', $path);

		return $this;
	}

	/**
	 * Authorisation check
	 *
	 * @param   string  $task  The ACO Section Value to check access on
	 *
	 * @return  boolean  True if authorised
	 *
	 * @since   11.1
	 *
	 * @deprecated  12.1   Use JAuthorise
	 */
	public function authorize($task)
	{
		// Deprecation warning.
		JLog::add('JController::authorize() is deprecated.', JLog::WARNING, 'deprecated');

		$this->authorise($task);
	}

	/**
	 * Authorisation check
	 *
	 * @param   string  $task  The ACO Section Value to check access on.
	 *
	 * @return  boolean  True if authorised
	 * @since   11.1
	 */
	public function authorise($task)
	{
		// Only do access check if the aco section is set
		if ($this->_acoSection) {
			// If we have a section value set that trumps the passed task.
			if ($this->_acoSectionValue) {
				// We have one, so set it and lets do the check
				$task = $this->_acoSectionValue;
			}
			// Get the JUser object for the current user and return the authorization boolean
			$user = JFactory::getUser();

			return $user->authorise($this->_acoSection, $task);
		}
		else {
			// Nothing set, nothing to check... so obviously it's ok :) 
			return true;
		}
	}

	/**
	 * Method to check whether an ID is in the edit list.
	 *
	 * @param   string   $context  The context for the session storage.
	 * @param   integer  $id       The ID of the record to add to the edit list.
	 *
	 * @return  boolean  True if the ID is in the edit list.
	 * @since   11.1
	 */
	protected function checkEditId($context, $id)
	{
		if ($id) {
			$app	= JFactory::getApplication();
			$values = (array) $app->getUserState($context.'.id');

			$result	= in_array((int) $id, $values);

			if (JDEBUG) {
				jimport('joomla.error.log');
				$log = JLog::getInstance('jcontroller.log.php')->addEntry(
					array('comment' => sprintf('Checking edit ID %s.%s: %d %s', $context, $id, (int) $result, str_replace("\n", ' ', print_r($values, 1))))
				);
			}

			return $result;
		}
		else {
			// No id for a new item.
			return true;
		}
	}

	/**
	 * Method to load and return a model object.
	 *
	 * @param   string  $name    The name of the model.
	 * @param   string  $prefix  Optional model prefix.
	 * @param   array   $config  Configuration array for the model. Optional.
	 *
	 * @return  mixed   Model object on success; otherwise null failure.
	 * @since   11.1
	 * @note    Replaces _createModel.
	 */
	protected function createModel($name, $prefix = '', $config = array())
	{
		// Clean the model name
		$modelName		= preg_replace('/[^A-Z0-9_]/i', '', $name);
		$classPrefix	= preg_replace('/[^A-Z0-9_]/i', '', $prefix);

		$result = JModel::getInstance($modelName, $classPrefix, $config);

		return $result;
	}

	/**
	 * Method to load and return a view object. This method first looks in the
	 * current template directory for a match and, failing that, uses a default
	 * set path to load the view class file.
	 *
	 * Note the "name, prefix, type" order of parameters, which differs from the
	 * "name, type, prefix" order used in related public methods.
	 *
	 * @param   string  $name    The name of the view.
	 * @param   string  $prefix  Optional prefix for the view class name.
	 * @param   string  $type    The type of view.
	 * @param   array   $config  Configuration array for the view. Optional.
	 *
	 * @return  mixed  View object on success; null or error result on failure.
	 * @since   11.1
	 * @note    Replaces _createView.
	 */
	protected function createView($name, $prefix = '', $type = '', $config = array())
	{
		// Clean the view name
		$viewName		= preg_replace('/[^A-Z0-9_]/i', '', $name);
		$classPrefix	= preg_replace('/[^A-Z0-9_]/i', '', $prefix);
		$viewType		= preg_replace('/[^A-Z0-9_]/i', '', $type);

		// Build the view class name
		$viewClass = $classPrefix . $viewName;

		if (!class_exists($viewClass)) {
			jimport('joomla.filesystem.path');
			$path = JPath::find(
				$this->paths['view'],
				$this->createFileName('view', array('name' => $viewName, 'type' => $viewType))
			);

			if ($path) {
				require_once $path;

				if (!class_exists($viewClass)) {
					$result = JError::raiseError(
						500,
						JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_CLASS_NOT_FOUND', $viewClass, $path)
					);

					return null;
				}
			}
			else {
				return null;
			}
		}

		return new $viewClass($config);
	}

	/**
	 * Typical view method for MVC based architecture
	 *
	 * This function is provide as a default implementation, in most cases
	 * you will need to override it in your own controllers.
	 *
	 * @param   boolean  $cachable   If true, the view output will be cached
	 * @param   array    $urlparams  An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
	 *
	 * @return  JController  A JController object to support chaining.
	 * @since   11.1
	 */
	public function display($cachable = false, $urlparams = false)
	{
		$document	= JFactory::getDocument();
		$viewType	= $document->getType();
		$viewName	= JRequest::getCmd('view', $this->default_view);
		$viewLayout	= JRequest::getCmd('layout', 'default');

		$view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath));

		// Get/Create the model
		if ($model = $this->getModel($viewName)) {
			// Push the model into the view (as default)
			$view->setModel($model, true);
		}

		// Set the layout
		$view->setLayout($viewLayout);

		$view->assignRef('document', $document);

		$conf = JFactory::getConfig();

		// Display the view
		if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1) {
			$option	= JRequest::getCmd('option');
			$cache	= JFactory::getCache($option, 'view');

			if (is_array($urlparams)) {
				$app = JFactory::getApplication();

				$registeredurlparams = $app->get('registeredurlparams');

				if (empty($registeredurlparams)) {
					$registeredurlparams = new stdClass;
				}

				foreach ($urlparams as $key => $value)
				{
					// Add your safe url parameters with variable type as value {@see JFilterInput::clean()}.
					$registeredurlparams->$key = $value;
				}

				$app->set('registeredurlparams', $registeredurlparams);
			}

			$cache->get($view, 'display');

		}
		else {
			$view->display();
		}

		return $this;
	}

	/**
	 * Execute a task by triggering a method in the derived class.
	 *
	 * @param   string  $task  The task to perform. If no matching task is found, the '__default' task is executed, if defined.
	 *
	 * @return  mixed   The value returned by the called method, false in error case.
	 * @since   11.1
	 */
	public function execute($task)
	{
		$this->task = $task;

		$task = strtolower($task);
		if (isset($this->taskMap[$task])) {
			$doTask = $this->taskMap[$task];
		}
		elseif (isset($this->taskMap['__default'])) {
			$doTask = $this->taskMap['__default'];
		}
		else {
			return JError::raiseError(404, JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task));
		}

		// Record the actual task being fired
		$this->doTask = $doTask;

		// Make sure we have access
		if ($this->authorise($doTask)) {
			$retval = $this->$doTask();
			return $retval;
		}
		else {
			return JError::raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
		}
	}

	/**
	 * Method to get a model object, loading it if required.
	 *
	 * @param   string   $name    The model name. Optional.
	 * @param   string   $prefix  The class prefix. Optional.
	 * @param   array    $config  Configuration array for model. Optional.
	 *
	 * @return  object   The model.
	 * @since   11.1
	 */
	public function getModel($name = '', $prefix = '', $config = array())
	{
		if (empty($name)) {
			$name = $this->getName();
		}

		if (empty($prefix)) {
			$prefix = $this->model_prefix;
		}

		if ($model = $this->createModel($name, $prefix, $config)) {
			// Task is a reserved state
			$model->setState('task', $this->task);

			// Let's get the application object and set menu information if it's available
			$app	= JFactory::getApplication();
			$menu	= $app->getMenu();

			if (is_object($menu)) {
				if ($item = $menu->getActive()) {
					$params	= $menu->getParams($item->id);
					// Set default state data
					$model->setState('parameters.menu', $params);
				}
			}
		}
		return $model;
	}

	/**
	 * Method to get the controller name
	 *
	 * The dispatcher name is set by default parsed using the classname, or it can be set
	 * by passing a $config['name'] in the class constructor
	 *
	 * @return  string  The name of the dispatcher
	 * @since   11.1
	 */
	public function getName()
	{
		$name = $this->name;

		if (empty($name)) {
			$r = null;
			if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
				JError::raiseError(500, JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'));
			}
			$name = strtolower($r[1]);
		}

		return $name;
	}

	/**
	 * Get the last task that is being performed or was most recently performed.
	 *
	 * @return  string  The task that is being performed or was most recently performed.
	 * @since   11.1
	 */
	public function getTask()
	{
		return $this->task;
	}

	/**
	 * Gets the available tasks in the controller.
	 *
	 * @return  array  Array[i] of task names.
	 * @since   11.1
	 */
	public function getTasks()
	{
		return $this->methods;
	}

	/**
	 * Method to get a reference to the current view and load it if necessary.
	 *
	 * @param   string  $name    The view name. Optional, defaults to the controller name.
	 * @param   string  $type    The view type. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for view. Optional.
	 *
	 * @return  object  Reference to the view or an error.
	 * @since   11.1
	 */
	public function getView($name = '', $type = '', $prefix = '', $config = array())
	{
		static $views;

		if (!isset($views)) {
			$views = array();
		}

		if (empty($name)) {
			$name = $this->getName();
		}

		if (empty($prefix)) {
			$prefix = $this->getName() . 'View';
		}

		if (empty($views[$name])) {
			if ($view = $this->createView($name, $prefix, $type, $config)) {
				$views[$name] = & $view;
			}
			else {
				$result = JError::raiseError(
					500,
					JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND', $name, $type, $prefix)
				);

				return $result;
			}
		}

		return $views[$name];
	}

	/**
	 * Method to add a record ID to the edit list.
	 *
	 * @param    string   $context  The context for the session storage.
	 * @param    integer  $id       The ID of the record to add to the edit list.
	 *
	 * @return  void
	 * @since   11.1
	 */
	protected function holdEditId($context, $id)
	{
		// Initialise variables.
		$app	= JFactory::getApplication();
		$values	= (array) $app->getUserState($context.'.id');

		// Add the id to the list if non-zero.
		if (!empty($id)) {
			array_push($values, (int) $id);
			$values = array_unique($values);
			$app->setUserState($context.'.id', $values);

			if (JDEBUG) {
				jimport('joomla.error.log');
				$log = JLog::getInstance('jcontroller.log.php')->addEntry(
					array('comment' => sprintf('Holding edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1))))
				);
			}
		}
	}

	/**
	 * Redirects the browser or returns false if no redirect is set.
	 *
	 * @return  boolean  False if no redirect exists.
	 * @since   11.1
	 */
	public function redirect()
	{
		if ($this->redirect) {
			$app = JFactory::getApplication();
			$app->redirect($this->redirect, $this->message, $this->messageType);
		}

		return false;
	}

	/**
	 * Register the default task to perform if a mapping is not found.
	 *
	 * @param   string   $method  The name of the method in the derived class to perform if a named task is not found.
	 *
	 * @return  JController  A JController object to support chaining.
	 * @since   11.1
	 */
	public function registerDefaultTask($method)
	{
		$this->registerTask('__default', $method);

		return $this;
	}

	/**
	 * Register (map) a task to a method in the class.
	 *
	 * @param   string   $task    The task.
	 * @param   string   $method  The name of the method in the derived class to perform for this task.
	 *
	 * @return  JController  A JController object to support chaining.
	 * @since   11.1
	 */
	public function registerTask($task, $method)
	{
		if (in_array(strtolower($method), $this->methods)) {
			$this->taskMap[strtolower($task)] = $method;
		}

		return $this;
	}

	/**
	 * Unregister (unmap) a task in the class.
	 *
	 * @param   string  $task  The task.
	 *
	 * @return  JController  This object to support chaining.
	 * @since   11.1
	 */
	public function unregisterTask($task)
	{
		unset($this->taskMap[strtolower($task)]);

		return $this;
	}

	/**
	 * Method to check whether an ID is in the edit list.
	 *
	 * @param   string   $context  The context for the session storage.
	 * @param   integer  $id       The ID of the record to add to the edit list.
	 *
	 * @return  void
	 * @since   11.1
	 */
	protected function releaseEditId($context, $id)
	{
		$app	= JFactory::getApplication();
		$values = (array) $app->getUserState($context.'.id');

		// Do a strict search of the edit list values.
		$index = array_search((int) $id, $values, true);

		if (is_int($index)) {
			unset($values[$index]);
			$app->setUserState($context.'.id', $values);

			if (JDEBUG) {
				jimport('joomla.error.log');
				$log = JLog::getInstance('jcontroller.log.php')->addEntry(
					array('comment' => sprintf('Releasing edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1))))
				);
			}
		}
	}

	/**
	 * Sets the access control levels.
	 *
	 * @param   string   $section  The ACO section (eg, the component).
	 * @param   string   $value    The ACO section value (if using a constant value).
	 *
	 * @return  void
	 *
	 * @deprecated  12.1  Use JAccess
	 *
	 * @see     Jaccess
	 * @since   11.1
	 */
	public function setAccessControl($section, $value = null)
	{
		$this->_acoSection = $section;
		$this->_acoSectionValue = $value;
	}

	/**
	 * Sets the internal message that is passed with a redirect
	 *
	 * @param   string  $text  Message to display on redirect.
	 * @param   string  $type  Message type (since 11.1). Optional, defaults to 'message'.
	 *
	 * @return  string  Previous message
	 * @since   11.1
	 */
	public function setMessage($text, $type = 'message')
	{
		$previous			= $this->message;
		$this->message		= $text;
		$this->messageType	= $type;

		return $previous;
	}

	/**
	 * Sets an entire array of search paths for resources.
	 *
	 * @param   string  $type  The type of path to set, typically 'view' or 'model'.
	 * @param   string  $path  The new set of search paths. If null or false, resets to the current directory only.
	 *
	 * @return  void
	 *
	 * @note    Replaces _setPath.
	 * @since   11.1
	 */
	protected function setPath($type, $path)
	{
		// clear out the prior search dirs
		$this->paths[$type] = array();

		// actually add the user-specified directories
		$this->addPath($type, $path);
	}

	/**
	 * Set a URL for browser redirection.
	 *
	 * @param   string  $url   URL to redirect to.
	 * @param   string  $msg   Message to display on redirect. Optional, defaults to value set internally by controller, if any.
	 * @param   string  $type  Message type. Optional, defaults to 'message' or the type set by a previous call to setMessage.
	 *
	 * @return  JController  This object to support chaining.
	 *
	 * @since   11.1
	 */
	public function setRedirect($url, $msg = null, $type = null)
	{
		$this->redirect = $url;
		if ($msg !== null) {
			// Controller may have set this directly
			$this->message	= $msg;
		}

		// Ensure the type is not overwritten by a previous call to setMessage.
		if (empty($type)) {
			if (empty($this->messageType)) {
				$this->messageType = 'message';
			}
		}
		// If the type is explicitly set, set it.
		else {
			$this->messageType = $type;
		}

		return $this;
	}
}

Tags: , , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка

Добавление контроллера к компоненту в Joomla 1.7

Май 26, 2012

Сначала необходимо создать файл controller.php в папке с компонентом в открытой части сайта:
/components/com_simple/controller.php

Для работы контроллера необходимо подключить стандартный класс контроллера:

jimport('joomla.application.component.controller');

Далее создается класс с именем компонента:

class SimpleController extends JController

К примеру, пользователь вводит в строке браузера:
http://localhost/joomla17/index.php?option=com_simple&task=delete

Для того, чтобы обработать task, т.е. задачу, требуется создать функцию в controller.php с аналогичным именем:

class SimpleController extends JController
{
	public function delete()
	{
		echo "Удаление";
	}
}

На экране пользователь в рамках использованного шаблона для отображения сайта увидит сообщение "Удаление".

Однако, я не указал, как будет получено значение task и как контроллер взаимодействует с компонентом.

В файл компонента в открытой части simple.php добавляется аналогичная запись импорта класса контроллера:

jimport('joomla.application.component.controller');

Далее получается контроллер для нашего компонента по имени:

$controller = JController::getInstance('Simple');

После в контроллер сообщается значение task:

$controller->execute(JRequest::getCmd('task'));

В завершение прописывается строка, отвечающая за перенаправление:

$controller->redirect();

Принцип работы

При запуске компонента вызывается основной файл simple.php, в котором запрашивается контроллер. Контроллер получает значение task и вызывает соответствующую функцию. При необходимости осуществляется перенаправление.

Если же в контроллере нет соответствующей task функции, то работа компонента прекращается и исполнение заканчивается выводом на экран пользователя ошибкой 500.

Tags: , , , , , , , , ,
Записано в Joomla, Программирование    |    Постоянная ссылка