-
Notifications
You must be signed in to change notification settings - Fork 30
007. Using the database in the frontend
Now, we want to create a view on the front end.
Newly created files
administrator/components/com_foos/Controller/FooController.php
administrator/components/com_foos/Field/Modal/FooField.php
administrator/components/com_foos/Model/FooModel.php
administrator/components/com_foos/Table/FooTable.php
administrator/components/com_foos/View/Foo/HtmlView.php
administrator/components/com_foos/forms/foo.xml
administrator/components/com_foos/tmpl/foo/foo/edit.php
administrator/components/com_foos/tmpl/foos/modal.php
media/com_foos/js/admin-foos-modal.js
Modified files
administrator/components/com_foos/View/Foos/HtmlView.php
administrator/components/com_foos/foos.xml
administrator/components/com_foos/tmpl/foos/default.php
components/com_foos/Model/FooModel.php
components/com_foos/View/Foo/HtmlView.php
components/com_foos/tmpl/foo/default.php
components/com_foos/tmpl/foo/default.xml
https://github.com/astridx/boilerplate/compare/t6...t7
Component generally have one or more database tables to store their data. When you install your component, you need to run some SQL command to create the table. So the install tag tells Joomla! where this file is. If you are supporting multiple database types, you will need a separate database installation file for each database type. This component supports mysql.
Supported Databases are MySQL minimum 5.6 and PostgreSQL minimum 11. SQL Server support has been dropped. More information you can find here.
When someone uninstalls your component, you will need to run some clean up SQL commands that delete the tables used by your component and remove all traces used by your component and remove all traces. The uninstall SQL files allow you to do that. As with the install SQL files, if you are supporting multiple database types, you will need a separate file for each database type. This component supports mysql.
administrator/components/com_foos/Controller/FooController.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Foos\Administrator\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\FormController;
/**
* Controller for a single foo
*
* @since 1.0
*/
class FooController extends FormController
{
}
administrator/components/com_foos/Field/Modal/FooField.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Foos\Administrator\Field\Modal;
defined('JPATH_BASE') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
/**
* Supports a modal foo picker.
*
* @since 1.0
*/
class FooField extends FormField
{
/**
* The form field type.
*
* @var string
* @since 1.0
*/
protected $type = 'Modal_Foo';
/**
* Method to get the field input markup.
*
* @return string The field input markup.
*
* @since 1.0
*/
protected function getInput()
{
$allowClear = ((string) $this->element['clear'] != 'false');
$allowSelect = ((string) $this->element['select'] != 'false');
// The active foo id field.
$value = (int) $this->value > 0 ? (int) $this->value : '';
// Create the modal id.
$modalId = 'Foo_' . $this->id;
// Add the modal field script to the document head.
HTMLHelper::_('script', 'system/fields/modal-fields.min.js', array('version' => 'auto', 'relative' => true));
// Script to proxy the select modal function to the modal-fields.js file.
if ($allowSelect)
{
static $scriptSelect = null;
if (is_null($scriptSelect))
{
$scriptSelect = array();
}
if (!isset($scriptSelect[$this->id]))
{
Factory::getDocument()->addScriptDeclaration("
function jSelectFoo_" . $this->id . "(id, title, object) {
window.processModalSelect('Foo', '" . $this->id . "', id, title, '', object);
}
"
);
$scriptSelect[$this->id] = true;
}
}
// Setup variables for display.
$linkFoos = 'index.php?option=com_foos&view=foos&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
$linkFoo = 'index.php?option=com_foos&view=foo&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
$modalTitle = Text::_('COM_FOOS_CHANGE_FOO');
$urlSelect = $linkFoos . '&function=jSelectFoo_' . $this->id;
if ($value)
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('name'))
->from($db->quoteName('#__foos_details'))
->where($db->quoteName('id') . ' = ' . (int) $value);
$db->setQuery($query);
try
{
$title = $db->loadResult();
}
catch (\RuntimeException $e)
{
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
}
$title = empty($title) ? Text::_('COM_FOOS_SELECT_A_FOO') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
// The current foo display field.
$html = '';
if ($allowSelect || $allowNew || $allowEdit || $allowClear)
{
$html .= '<span class="input-group">';
}
$html .= '<input class="form-control" id="' . $this->id . '_name" type="text" value="' . $title . '" disabled="disabled" size="35">';
if ($allowSelect || $allowNew || $allowEdit || $allowClear)
{
$html .= '<span class="input-group-append">';
}
// Select foo button
if ($allowSelect)
{
$html .= '<button'
. ' class="btn btn-primary hasTooltip' . ($value ? ' hidden' : '') . '"'
. ' id="' . $this->id . '_select"'
. ' data-toggle="modal"'
. ' type="button"'
. ' data-target="#ModalSelect' . $modalId . '"'
. ' title="' . HTMLHelper::tooltipText('COM_FOOS_CHANGE_FOO') . '">'
. '<span class="icon-file" aria-hidden="true"></span> ' . Text::_('JSELECT')
. '</button>';
}
// Clear foo button
if ($allowClear)
{
$html .= '<button'
. ' class="btn btn-secondary' . ($value ? '' : ' hidden') . '"'
. ' id="' . $this->id . '_clear"'
. ' type="button"'
. ' onclick="window.processModalParent(\'' . $this->id . '\'); return false;">'
. '<span class="icon-remove" aria-hidden="true"></span>' . Text::_('JCLEAR')
. '</button>';
}
if ($allowSelect || $allowNew || $allowEdit || $allowClear)
{
$html .= '</span></span>';
}
// Select foo modal
if ($allowSelect)
{
$html .= HTMLHelper::_(
'bootstrap.renderModal',
'ModalSelect' . $modalId,
array(
'title' => $modalTitle,
'url' => $urlSelect,
'height' => '400px',
'width' => '800px',
'bodyHeight' => 70,
'modalWidth' => 80,
'footer' => '<a role="button" class="btn btn-secondary" data-dismiss="modal" aria-hidden="true">'
. Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . '</a>',
)
);
}
// Note: class='required' for client side validation.
$class = $this->required ? ' class="required modal-value"' : '';
$html .= '<input type="hidden" id="' . $this->id . '_id"' . $class . ' data-required="' . (int) $this->required . '" name="' . $this->name
. '" data-text="' . htmlspecialchars(Text::_('COM_FOOS_SELECT_A_FOO', true), ENT_COMPAT, 'UTF-8') . '" value="' . $value . '">';
return $html;
}
/**
* Method to get the field label markup.
*
* @return string The field label markup.
*
* @since 1.0
*/
protected function getLabel()
{
return str_replace($this->id, $this->id . '_name', parent::getLabel());
}
}
administrator/components/com_foos/Model/FooModel.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Foos\Administrator\Model;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
/**
* Item Model for a Foo.
*
* @since 1.0
*/
class FooModel extends AdminModel
{
/**
* The type alias for this content type.
*
* @var string
* @since 1.0
*/
public $typeAlias = 'com_foos.foo';
/**
* Method to get the row 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 \JForm|boolean A \JForm object on success, false on failure
*
* @since 1.0
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_foos.foo', 'foo', 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.0
*/
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $this->getItem();
$this->preprocessData('com_foos.foo', $data);
return $data;
}
}
administrator/components/com_foos/Table/FooTable.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Foos\Administrator\Table;
defined('_JEXEC') or die;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
/**
* Foos Table class.
*
* @since 1.0
*/
class FooTable extends Table
{
/**
* Constructor
*
* @param DatabaseDriver $db Database connector object
*
* @since 1.0
*/
public function __construct(DatabaseDriver $db)
{
$this->typeAlias = 'com_foos.foo';
parent::__construct('#__foos_details', 'id', $db);
}
}
administrator/components/com_foos/View/Foo/HtmlView.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Foos\Administrator\View\Foo;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
/**
* View to edit a foo.
*
* @since 1.0
*/
class HtmlView extends BaseHtmlView
{
/**
* The \JForm object
*
* @var \JForm
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* Display the view.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise an Error object.
*/
public function display($tpl = null)
{
$this->item = $this->get('Item');
$this->addToolbar();
return parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.0
*/
protected function addToolbar()
{
Factory::getApplication()->input->set('hidemainmenu', true);
$isNew = ($this->item->id == 0);
ToolbarHelper::title($isNew ? Text::_('COM_FOOS_MANAGER_FOO_NEW') : Text::_('COM_FOOS_MANAGER_FOO_EDIT'), 'address foo');
ToolbarHelper::apply('foo.apply');
ToolbarHelper::cancel('foo.cancel', 'JTOOLBAR_CLOSE');
}
}
administrator/components/com_foos/forms/foo.xml
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="id"
type="number"
label="JGLOBAL_FIELD_ID_LABEL"
default="0"
class="readonly"
readonly="true"
/>
<field
name="name"
type="text"
label="COM_FOOS_FIELD_NAME_LABEL"
size="40"
required="true"
/>
</fieldset>
</form>
administrator/components/com_foos/tmpl/foo/foo/edit.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
$app = Factory::getApplication();
$input = $app->input;
// In case of modal
$isModal = $input->get('layout') == 'modal' ? true : false;
$layout = $isModal ? 'modal' : 'edit';
$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : '';
?>
<form action="<?php echo Route::_('index.php?option=com_foos&layout=' . $layout . $tmpl . '&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="foo-form" class="form-validate">
<?php echo $this->getForm()->renderField('name'); ?>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
administrator/components/com_foos/tmpl/foos/modal.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<div class="container-popup">
<?php $this->setLayout('edit'); ?>
<?php echo $this->loadTemplate(); ?>
</div>
administrator/components/com_foos/tmpl/foos/modal.php
<?php
/**
* @package Joomla.Administrator
* @subpackage com_foos
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
$app = Factory::getApplication();
HTMLHelper::_('script', 'com_foos/admin-foos-modal.min.js', array('version' => 'auto', 'relative' => true));
$function = $app->input->getCmd('function', 'jSelectFoos');
$onclick = $this->escape($function);
?>
<div class="container-popup">
<form action="<?php echo Route::_('index.php?option=com_foos&view=foos&layout=modal&tmpl=component&function=' . $function . '&' . Session::getFormToken() . '=1'); ?>" method="post" name="adminForm" id="adminForm" class="form-inline">
<?php if (empty($this->items)) : ?>
<div class="alert alert-warning">
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table table-sm">
<thead>
<tr>
<th scope="col" style="width:10%" class="d-none d-md-table-cell">
</th>
<th scope="col" style="width:1%">
</th>
</tr>
</thead>
<tbody>
<?php
$iconStates = array(
-2 => 'icon-trash',
0 => 'icon-unpublish',
1 => 'icon-publish',
2 => 'icon-archive',
);
?>
<?php foreach ($this->items as $i => $item) : ?>
<?php $lang = ''; ?>
<tr class="row<?php echo $i % 2; ?>">
<th scope="row">
<a class="select-link" href="javascript:void(0)" data-function="<?php echo $this->escape($onclick); ?>" data-id="<?php echo $item->id; ?>" data-title="<?php echo $this->escape($item->name); ?>">
<?php echo $this->escape($item->name); ?>
</a>
</th>
<td>
<?php echo (int) $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="forcedLanguage" value="<?php echo $app->input->get('forcedLanguage', '', 'CMD'); ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
</div>
media/com_foos/js/admin-foos-modal.js
/**
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
(function () {
'use strict';
/**
* Javascript to insert the link
* View element calls jSelectFoo when a foo is clicked
* jSelectFoo creates the link tag, sends it to the editor,
* and closes the select frame.
*/
window.jSelectFoo = function (id, title, catid, object, link, lang) {
var hreflang = '';
if (!Joomla.getOptions('xtd-foos')) {
// Something went wrong
window.parent.Joomla.Modal.getCurrent().close();
return false;
}
var _Joomla$getOptions = Joomla.getOptions('xtd-foos'),
editor = _Joomla$getOptions.editor;
if (lang !== '') {
hreflang = "hreflang = \"".concat(lang, "\"");
}
var tag = "<a ".concat(hreflang, " href=\"").concat(link, "\">").concat(title, "</a>");
window.parent.Joomla.editors.instances[editor].replaceSelection(tag);
window.parent.Joomla.Modal.getCurrent().close();
return true;
};
document.addEventListener('DOMContentLoaded', function () {
// Get the elements
var elements = document.querySelectorAll('.select-link');
for (var i = 0, l = elements.length; l > i; i += 1) {
// Listen for click event
elements[i].addEventListener('click', function (event) {
event.preventDefault();
var functionName = event.target.getAttribute('data-function');
if (functionName === 'jSelectFoo') {
// Used in xtd_foos
window[functionName](event.target.getAttribute('data-id'), event.target.getAttribute('data-title'), null, null, event.target.getAttribute('data-uri'), event.target.getAttribute('data-language'), null);
} else {
// Used in com_menus
window.parent[functionName](event.target.getAttribute('data-id'), event.target.getAttribute('data-title'), null, null, event.target.getAttribute('data-uri'), event.target.getAttribute('data-language'), null);
}
if (window.parent.Joomla.Modal) {
window.parent.Joomla.Modal.getCurrent().close();
}
});
}
});
})();
If see this:
/**
* PLEASE DO NOT MODIFY THIS FILE. WORK ON THE ES6 VERSION.
* OTHERWISE YOUR CHANGES WILL BE REPLACED ON THE NEXT BUILD.
**/
administrator/components/com_foos/View/Foos/HtmlView.php
administrator/components/com_foos/foos.xml
administrator/components/com_foos/tmpl/foos/default.php
components/com_foos/Model/FooModel.php
components/com_foos/View/Foo/HtmlView.php
components/com_foos/tmpl/foo/default.php
components/com_foos/tmpl/foo/default.xml
Now you can zip all files and install them via Joomla Extension Manager. After that you can see a link to your component in the left side menu. Clicking on this link will open the basic back end view.
Now we have . Up to now we have no . We are going to work on this in the next chapter.