Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions module-example-table/mod_table_example/mod_table_example.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>Joomla example table module</name>
<version>1.0.1</version>
<author>me</author>
<creationDate>today</creationDate>
<description>Demonstrates use of Table class APIs</description>
<namespace path="src">My\Module\TableExample</namespace>
<files>
<folder module="mod_table_example">services</folder>
<folder>src</folder>
</files>
</extension>
19 changes: 19 additions & 0 deletions module-example-table/mod_table_example/services/provider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

\defined('_JEXEC') or die;

use Joomla\CMS\Extension\Service\Provider\Module as ModuleServiceProvider;
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory as ModuleDispatcherFactoryServiceProvider;
use Joomla\CMS\Extension\Service\Provider\HelperFactory as HelperFactoryServiceProvider;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;

return new class () implements ServiceProviderInterface {

public function register(Container $container): void
{
$container->registerServiceProvider(new ModuleDispatcherFactoryServiceProvider('\\My\\Module\\TableExample'));
$container->registerServiceProvider(new HelperFactoryServiceProvider('\\My\\Module\\TableExample\\Site\\Helper'));
$container->registerServiceProvider(new ModuleServiceProvider());
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace My\Module\TableExample\Site\Dispatcher;

\defined('_JEXEC') or die;

use Joomla\CMS\Dispatcher\Dispatcher as JoomlaDispatcher;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\Input\Input;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;

class Dispatcher extends JoomlaDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;

/**
* The module instance
*/
protected $module;

/**
* The Joomla Input instance
*/
protected $input;

/**
* Constructor for Dispatcher
*
* @param \stdClass $module The module
* @param CMSApplicationInterface $app The application instance
* @param Input $input The input instance
*/
public function __construct(\stdClass $module, CMSApplicationInterface $app, Input $input)
{
parent::__construct($app, $input);

$this->module = $module;
$this->input = $input;
}

public function dispatch()
{
// This is the entry point for our module code
echo '<h4>Hello ' . $this->module->id . '</h4>';

// Pass the work off into a helper class
// The default Joomla Factory classes set the Database object within the Helper class,
// but not within the Dispatcher class, and we need the dbo for passing to the Table
$helper = $this->getHelperFactory()->getHelper('ExampleTableHelper');
$helper->doBasicTableOperations($this->module->id, $this->input);
$helper->doAdvancedTableOperations($this->module->id, $this->input);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace My\Module\TableExample\Site\Helper;

use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use My\Module\TableExample\Site\Table\ExampleModuleTable;

\defined('_JEXEC') or die;

class ExampleTableHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;

/*
* doBasicTableOperations demonstrates use of the basic Table methods
*
* $id - the id of this module
* $input - the Joomla Input instance
*/
public function doBasicTableOperations($id, $input)
{
// by setting the DatabaseAwareInterface and DatabaseAwareTrait
// Joomla makes available the Database object via an instance method getDatabase()
$moduleTable = new ExampleModuleTable($this->getDatabase());

// we load the database record in the #__modules table which relates to this module
if ($moduleTable->load($id))
{
// demonstrates that the properties are set via the load() call
echo "Module title is {$moduleTable->title}<br>";

// The header tag is held as one of the JSON-encoded params, so we need to decode the params
$moduleParams = json_decode($moduleTable->params, true);
$moduleParams['header_tag'] = 'h2';
// The params will be JSON-encoded in the bind() method before storing in the database because we set in our table class
// $_jsonEncode = array('params');

// get the demonote= HTTP GET parameter and put it into the note field
$note = $input->get('demonote', '', "STRING");
$data = array("note" => $note, "params" => $moduleParams);

// bind the updated data in the $data array
$moduleTable->bind($data);

$moduleTable->check();

// store the data - this will result in a SQL UPDATE to this module's record in the #__modules table
$moduleTable->store();
}
}

/*
* doAdvancedTableOperations demonstrates use of the advanced Table methods
*
* $id - the id of this module
* $input - the Joomla Input instance
*/
public function doAdvancedTableOperations($id, $input)
{
$moduleTable = new ExampleModuleTable($this->getDatabase());
$user = \Joomla\CMS\Factory::getApplication()->getIdentity();

if ($moduleTable->load($id))
{
// checkout/checkin
if ($moduleTable->isCheckedOut($user->id))
{
echo "<br>module record isCheckedOut call returned true<br>";
}
else
{
echo "<br>module record isCheckedOut call returned false<br>";
}

// Read ACL rules - you can also try moving this code to after the setRules() call
if ($rules = $moduleTable->getRules())
{
$rulesString = (string) $rules;
echo "<br>ACL Rules: $rulesString <br>";
}
else
{
echo "<br>As expected, getRules() didn't return anything<br>";
}

// Set the ACL on this module
$userGroups = $user->getAuthorisedGroups();
$randomIndex = array_rand($userGroups);
$newRule = array("core.edit" => array($userGroups[$randomIndex] => 1));
echo "Setting rules to " . json_encode($newRule) . "<br>";
$moduleTable->setRules($newRule);
$moduleTable->store();

// Ordering - change the ordering with other modules in the same template position
$where = 'POSITION = "' . $moduleTable->position . '"';
echo "<br>Next order value: " . $moduleTable->getNextOrder($where) . "<br>";

$moduleTable->move(2, $where);
echo "Ordering value is now: {$moduleTable->ordering}<br>";

$where .= " and published = 1";
$moduleTable->reorder($where);

// Reflection method - getTableName
echo "<br>Table name is {$moduleTable->getTableName()}<br>";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace My\Module\TableExample\Site\Table;

use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseInterface;
use Joomla\Event\DispatcherInterface;

\defined('_JEXEC') or die;

class ExampleModuleTable extends Table
{
// The elements in this $_jsonEncode array will be JSON-encoded in the bind() call
// before the data is written to the database (in store()).
protected $_jsonEncode = array('params');

/**
* @param DatabaseInterface $db Database connector object
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
*/
public function __construct(DatabaseInterface $db, ?DispatcherInterface $dispatcher = null)
{
// We use the functionality of the Joomla Table class
// We need to pass the name of the database table, and the primary key, plus pass in the database object
parent::__construct('#__modules', 'id', $db, $dispatcher);
}

function check()
{
// just change the value of the 'note' property
$this->note .= " added via module";
return true;
}

protected function _getAssetName()
{
return "com_modules.module." . $this->id;
}

protected function _getAssetTitle()
{
return $this->title;
}

// this function copied from the ModuleTable in src/Table/Module.php
protected function _getAssetParentId(?Table $table = null, $id = null)
{
$assetId = null;

// This is a module that needs to parent with the extension.
if ($assetId === null) {
// Build the query to get the asset id of the parent component.
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName('id'))
->from($db->quoteName('#__assets'))
->where($db->quoteName('name') . ' = ' . $db->quote('com_modules'));

// Get the asset id from the database.
$db->setQuery($query);

if ($result = $db->loadResult()) {
$assetId = (int) $result;
}
}

// Return the asset id.
if ($assetId) {
return $assetId;
}

return parent::_getAssetParentId($table, $id);
}
}