Salta ai contenuti

Migliori Pratiche di Sviluppo dei Moduli

Questo documento consolida le migliori pratiche per lo sviluppo di moduli XOOPS di alta qualità. Il rispetto di queste linee guida garantisce moduli mantenibili, sicuri e performanti.

Organizzare il codice in livelli:

src/
├── Domain/ # Business logic, entities
├── Application/ # Use cases, services
├── Infrastructure/ # Database, external services
└── Presentation/ # Controllers, templates

Ogni classe deve avere un’unica ragione per cambiare:

// Good: Focused classes
class ArticleRepository { /* persistence only */ }
class ArticleValidator { /* validation only */ }
class ArticleNotifier { /* notifications only */ }
// Bad: God class
class Article {
public function save() { }
public function validate() { }
public function notify() { }
public function generatePDF() { }
}

Iniettare le dipendenze, non crearle:

// Good
public function __construct(
private readonly ArticleRepositoryInterface $repository
) {}
// Bad
public function __construct() {
$this->repository = new ArticleRepository();
}

Usa strict types e type declarations:

<?php
declare(strict_types=1);
final class ArticleService
{
public function findById(int $id): ?Article
{
// ...
}
public function create(CreateArticleDTO $dto): Article
{
// ...
}
}

Usa le eccezioni appropriatamente:

// Throw specific exceptions
throw new ArticleNotFoundException($id);
throw new ValidationException($errors);
throw new UnauthorizedException('Cannot edit this article');
// Catch at appropriate level
try {
$article = $service->create($dto);
} catch (ValidationException $e) {
return $this->renderForm($e->getErrors());
} catch (UnauthorizedException $e) {
return $this->redirectToLogin();
}

Evita null dove possibile:

// Use null object pattern
public function getAuthor(): UserInterface
{
return $this->author ?? new AnonymousUser();
}
// Use Optional/Maybe pattern
public function findById(int $id): ?Article
{
// Explicitly nullable return
}
$criteria = new CriteriaCompo();
$criteria->add(new Criteria('status', 'published'));
$criteria->add(new Criteria('category_id', $categoryId));
$criteria->setSort('created_at');
$criteria->setOrder('DESC');
$criteria->setLimit($limit);
$items = $handler->getObjects($criteria);
$sql = sprintf(
"SELECT * FROM %s WHERE id = %d AND title = %s",
$db->prefix('mymodule_items'),
intval($id),
$db->quoteString($title)
);
$db->query('START TRANSACTION');
try {
$handler->insert($article);
$handler->insert($metadata);
$db->query('COMMIT');
} catch (\Exception $e) {
$db->query('ROLLBACK');
throw $e;
}
use Xmf\Request;
$id = Request::getInt('id', 0);
$title = Request::getString('title', '');
$data = Request::getArray('data', []);
// Additional validation
if (strlen($title) < 5) {
throw new ValidationException('Title too short');
}
// In form
$form->addElement(new XoopsFormHiddenToken());
// On submit
if (!$GLOBALS['xoopsSecurity']->check()) {
redirect_header('index.php', 3, 'Invalid token');
}
if (!$helper->isUserAdmin()) {
redirect_header('index.php', 3, _NOPERM);
}
if (!$permHandler->isGranted('edit', $categoryId)) {
throw new UnauthorizedException();
}
$cache = $helper->getCache();
$cacheKey = "articles_{$categoryId}_{$limit}";
$articles = $cache->read($cacheKey);
if ($articles === false) {
$articles = $handler->getArticles($categoryId, $limit);
$cache->write($cacheKey, $articles, 3600);
}
// Use indexes
// Add to sql/mysql.sql:
// INDEX `idx_status_date` (`status`, `created_at`)
// Select only needed columns
$handler->getObjects($criteria, false, true); // asArray = true
// Use pagination
$criteria->setLimit($perPage);
$criteria->setStart($offset);
public function testCreateArticle(): void
{
$repository = $this->createMock(ArticleRepositoryInterface::class);
$repository->expects($this->once())->method('save');
$service = new ArticleService($repository);
$dto = new CreateArticleDTO('Title', 'Content');
$article = $service->create($dto);
$this->assertInstanceOf(Article::class, $article);
}
  • Clean-Code - Principi di codice pulito
  • Code-Organization - Struttura del progetto
  • Testing - Guida ai test
  • ../02-Core-Concepts/Security/Security-Best-Practices - Guida alla sicurezza