Botão ativar/desativar no admin
Na área administrativa do Joomla, nas listagens de componente, encontramos com frequencia um botão de publicar ou despublicar um artigo, ou registro, etc. Neste artigo, vou descrever como criar um botão similar mas para fazer outras funções, como por exemplo chamar uma API externa para cancelar um pagamento, disparar o envio de um email, por exemplo.
Para criar um botão na listagem precisamos criar um arquivo e alterar outros quatro arquivos de um componente: o layout, a view, o controller, no model e no table da entidade de dados.
- Crie o arquivo novo que vai gerar o código HTML dos botões em JPATH_COMPONENT_ADMINISTRATOR /helpers/html/#arquivo#.php:
<?php
/**
* @version $Id: #arquivo#.php $
* @package #PACOTE#
* @subpackage #COMPONENTE# admin helpers html
* @author Brunno Oliveira Prego <brunno@prego.eti.br>
* @copyright Copyright (C) 2019 Brunno Oliveira Prego. All rights reserved.
* @license GNU / GPL version 2 or later
*/
// No direct access
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
/**
* Classe Helper HTML de alteração do estado de ativo/cancelado
* @see [https://forum.joomla.org/viewtopic.php?t=803786](https://forum.joomla.org/viewtopic.php?t=803786)
* @since 1.2.0
*/
abstract class JHtml#ARQUIVO#
{
/**
* @param int $value The featured value
* @param int $i Indice do item na listagem
* @param bool $canChange Whether the value can be changed or not
*
* @return string The anchor tag to toggle featured/unfeatured contacts.
* @since 1.6
*/
public static function #metodo#($value, $i, $canChange = true)
{
$modelname = Factory::getApplication()->input->get('view');
$states = array(
0 => array('cancel', $modelname . '.ativar', '#COMPONENTE#_#ARQUIVO#_CANCELADO', '#COMPONENTE#_ATIVAR_#ARQUIVO#'),
1 => array('loop', $modelname . '.cancelar', '#COMPONENTE#_#ARQUIVO#_ATIVO', '#COMPONENTE#_CANCELAR_#ARQUIVO#'),
);
$state = JArrayHelper::getValue($states, (int) $value, $states[1]);
$html = '<span class="icon-' . $state[0] . '" aria-hidden="true"></span>';
if ($canChange)
{
$html = '<a class="btn btn-micro hasTooltip" href="#" title="' . JText::_($state[3]) . '">' . $html . '</a>';
}
return $html;
}
}
- No template, inclua a celula que quer que o botão seja utilizado:
if (isset($this->items[0]->#campo#))
{
?>
<td class="center">
<?php echo JHtml::_('#arquivo#.#metodo#', $item->#campo#, $i, $canChange); ?>
</td>
<?php
}
?>
- No controler, inclua os metodos referenciados no #arquivo#:
public function ativar()
{
// Inclua aqui chamadas a metodos e APIS que precisem ser feitas antes de alterar o estado para 1 (ativo)
return $this->alteraEstado(1);
}
public function cancelar()
{
// Inclua aqui chamadas a metodos e APIS que precisem ser feitas antes de alterar o estado para 0 (cancelado)
return $this->alteraEstado(0);
}
protected function alteraEstado($estado)
{
$uri = Uri::getInstance();
$app = Factory::getApplication();
$input = $app->input;
$pks = $input->post->get('cid', array(), 'array');
// Get the model
$model = $this->getModel();
// Save the ordering
$return = $model->alteraEstado($pks, $estado);
if ($return)
{
$pedidos = implode(',', $pks);
$estadoAtual = ($estado == 1 ? Text::_('#COMPONENTE#_#ARQUIVO#_ATIVO') : Text::_('#COMPONENTE#_#ARQUIVO#_CANCELADO'));
$app->enqueueMessage(Text::sprintf('#COMPONENTE#_#ARQUIVO#_ESTADO_ALTERADO', $pedidos, $estadoAtual), 'message');
}
else
{
foreach ($model->getErrors() as $erro)
{
$app->enqueueMessage($erro, 'error');
}
}
$this->setRedirect(Route::_($uri));
}
- No model, inclui o metodo alteraEstado:
public function alteraEstado($pks, $estado)
{
$table = $this->getTable();
$user = Factory::getUser();
// Attempt to change the state of the records.
if (!$table->estado($pks, $estado, $user->get('id')))
{
$this->setError($table->getError());
return false;
}
}
- Crie o metodo estado no table:
public function estado($pks = null, $estado = 1, $userId = 0)
{
// Initialise variables.
$k = $this->_tbl_key;
// Sanitize input.
JArrayHelper::toInteger($pks);
$userId = (int) $userId;
$estado = (int) $estado;
// If there are no primary keys set check to see if the instance key is set.
if (empty($pks))
{
if ($this->$k)
{
$pks = array($this->$k);
}
// Nothing to set publishing state on, return false.
else
{
$this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED'));
return false;
}
}
// Build the WHERE clause for the primary keys.
$where = $k . '=' . implode(' OR ' . $k . '=', $pks);
// Update the publishing state for rows with the given primary keys.
$this->_db->setQuery(
'UPDATE `' . $this->_tbl . '`' .
' SET `status` = ' . (int) $estado .
' WHERE (' . $where . ')'
);
$this->_db->execute();
// If the JTable instance value is in the list of primary keys that were set, set the instance.
if (in_array($this->$k, $pks))
{
$this->status = $estado;
}
$this->setError('');
return true;
}
Referência: https://forum.joomla.org/viewtopic.php?t=803786