Lewati ke konten

Praktik Terbaik Pengembangan module

Dokumen ini menggabungkan praktik terbaik untuk mengembangkan module XOOPS berkualitas tinggi. Mengikuti pedoman ini memastikan module dapat dipelihara, aman, dan berkinerja baik.

Atur kode menjadi beberapa lapisan:

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

Setiap kelas harus memiliki satu alasan untuk berubah:

// 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() { }
}

Suntikkan dependensi, jangan buat:

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

Gunakan tipe dan deklarasi tipe yang ketat:

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

Gunakan pengecualian dengan tepat:

// 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();
}

Hindari null jika memungkinkan:

// 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);
}
  • Kode Bersih - Prinsip kode bersih
  • Kode-Organisasi - Struktur proyek
  • Pengujian - Panduan pengujian
  • ../02-Core-Concepts/Security/Security-Best-Practices - Panduan keamanan