Server-Side Validation
Data Validation in Models
namespace Vendor\Module\Model;
use Magento\Framework\Data\Object\IdentityInterface;
use Magento\Framework\Validation\ValidatorInterface;
class Product implements IdentityInterface
{
public function validate()
{
$errors = [];
if (empty($this->getName())) {
$errors[] = __('Product name is required');
}
if (strlen($this->getName()) > 255) {
$errors[] = __('Product name must be less than 255 characters');
}
if (!filter_var($this->getPrice(), FILTER_VALIDATE_FLOAT)) {
$errors[] = __('Price must be a valid number');
}
if ($this->getPrice() < 0) {
$errors[] = __('Price cannot be negative');
}
return $errors;
}
}
Controller Validation
namespace Vendor\Module\Controller\Adminhtml;
use Magento\Backend\App\Action;
class Save extends Action
{
public function execute()
{
$data = $this->getRequest()->getParams();
// Validate required fields
$requiredFields = ['name', 'sku', 'price'];
foreach ($requiredFields as $field) {
if (empty($data[$field])) {
$this->messageManager->addErrorMessage(
__('%1 is required', ucfirst($field))
);
return $this->resultRedirectFactory->create()->setPath('*/*/');
}
}
// Validate data types
if (!is_numeric($data['price']) || $data['price'] < 0) {
$this->messageManager->addErrorMessage(__('Invalid price'));
return $this->resultRedirectFactory->create()->setPath('*/*/');
}
}
}
Key Points
- Always validate on the server side, never trust client validation
- Validate data types, lengths, and formats
- Provide clear error messages for invalid input
- Use Magento's validation framework for consistency
Input Filtering
Magento Input Filter
use Magento\Framework\DataObject\Factory as DataObjectFactory;
class InputFilter
{
private $dataObjectFactory;
public function __construct(DataObjectFactory $dataObjectFactory)
{
$this->dataObjectFactory = $dataObjectFactory;
}
public function filter($input)
{
$filtered = [];
// Remove whitespace
$filtered['name'] = trim($input['name'] ?? '');
// Strip HTML tags
$filtered['description'] = strip_tags($input['description'] ?? '');
// Sanitize email
$filtered['email'] = filter_var($input['email'] ?? '', FILTER_SANITIZE_EMAIL);
// Sanitize integer
$filtered['quantity'] = filter_var($input['quantity'] ?? 0, FILTER_SANITIZE_NUMBER_INT);
// Sanitize float
$filtered['price'] = filter_var($input['price'] ?? 0, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
return $filtered;
}
}
Filter Varien Data
use Varien_Object;
$object = new Varien_Object($inputData);
// Apply filters
$object->setData(
'name',
preg_replace('/[^a-zA-Z0-9\s]/', '', $object->getName())
);
// Sanitize using Varien_Filter_Input
$filters = [
'name' => ['stripTags', 'trim'],
'email' => ['validateEmail'],
'price' => ['validateNumber', 'greaterThanZero'],
];
Key Points
- Filter input before processing, not after
- Use appropriate filters for each data type
- Preserve original data for error messages
- Log filtered input for debugging
Magento Built-in Validators
EAV Attribute Validation
// Add validation to EAV attribute
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_field',
[
'type' => 'varchar',
'label' => 'Custom Field',
'input' => 'text',
'required' => true,
'validate_rules' => json_encode([
'max_text_length' => 255,
'min_text_length' => 1,
]),
]
);
Form Validation
<!-- app/code/Vendor/Module/view/adminhtml/templates/form.phtml -->
<form id="custom-form" action="<?= $block->getFormAction() ?>" method="post">
<?= $block->getBlockHtml('formkey') ?>
<div class="field required">
<label for="name">Name</label>
<input type="text" name="name" id="name"
class="input-text required-entry"
maxlength="255" />
</div>
<div class="field required">
<label for="email">Email</label>
<input type="email" name="email" id="email"
class="input-text required-entry validate-email" />
</div>
<div class="field required">
<label for="price">Price</label>
<input type="text" name="price" id="price"
class="input-text required-entry validate-number validate-greater-than-zero" />
</div>
</form>
<script>
require(['jquery', 'mage/validation'], function($) {
$('#custom-form').validation();
});
</script>
Custom Validator
namespace Vendor\Module\Model\Validation;
use Magento\Framework\Validation\ValidatorInterface;
use Magento\Framework\Validation\Result;
class CustomValidator implements ValidatorInterface
{
public function validate($entity)
{
$result = new Result();
if (strlen($entity->getData('sku')) < 3) {
$result->addError(__('SKU must be at least 3 characters'));
}
if (!preg_match('/^[A-Z]{2}\d{6}$/', $entity->getData('sku'))) {
$result->addError(__('SKU format must be XX######'));
}
return $result;
}
}
Key Points
- Use Magento's built-in validators for common patterns
- Custom validators implement ValidatorInterface
- Combine client-side and server-side validation
- Validate early in the request lifecycle
Data Sanitization
PHP Sanitization Functions
// String sanitization
$name = trim($input);
$name = preg_replace('/[^a-zA-Z0-9\s\-]/', '', $name);
$name = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
// Email sanitization
$email = filter_var($input, FILTER_SANITIZE_EMAIL);
// URL sanitization
$url = filter_var($input, FILTER_SANITIZE_URL);
// Integer sanitization
$quantity = filter_var($input, FILTER_SANITIZE_NUMBER_INT);
// Float sanitization
$price = filter_var($input, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
// Strip HTML
$clean = strip_tags($input, '<p><br><strong><em>');
// Remove null bytes
$clean = str_replace(chr(0), '', $input);
Magento Data Sanitization
use Magento\Framework\Escaper;
class DataSanitizer
{
private $escaper;
public function __construct(Escaper $escaper)
{
$this->escaper = $escaper;
}
public function sanitize($data)
{
return [
'name' => $this->escaper->escapeHtml($data['name']),
'url' => $this->escaper->escapeUrl($data['url']),
'css' => $this->escaper->escapeCss($data['css']),
'js' => $this->escaper->escapeJs($data['js']),
];
}
}
Key Points
- Sanitize before storing in database
- Use context-appropriate sanitization
- Preserve data integrity while removing threats
- Log sanitization for security auditing
Practice Problems
Create a custom validator for product SKUs that enforces a specific format (2 letters + 6 digits).
Solution
<?php
namespace Vendor\Module\Model\Validation;
use Magento\Framework\Validation\ValidatorInterface;
use Magento\Framework\Validation\Result;
class SkuFormatValidator implements ValidatorInterface
{
public function validate($entity)
{
$result = new Result();
$sku = $entity->getData('sku');
if (empty($sku)) {
$result->addError(__('SKU is required'));
return $result;
}
if (!preg_match('/^[A-Z]{2}\d{6}$/', $sku)) {
$result->addError(__('SKU must be format XX######'));
}
return $result;
}
} Build a sanitization pipeline that processes user input through multiple stages.
Solution
public function sanitize($input) {
$sanitized = $input;
$log = [];
// Trim whitespace
$sanitized = trim($sanitized);
if ($sanitized !== $input) {
$log[] = 'Trimmed whitespace';
}
// Remove HTML tags
$stripped = strip_tags($sanitized);
if ($stripped !== $sanitized) {
$log[] = 'Removed HTML tags';
$sanitized = $stripped;
}
// Escape HTML entities
$escaped = htmlspecialchars($sanitized, ENT_QUOTES, 'UTF-8');
if ($escaped !== $sanitized) {
$log[] = 'Escaped HTML entities';
$sanitized = $escaped;
}
if (!empty($log)) {
$this->logger->info('Input sanitized', ['actions' => $log]);
}
return $sanitized;
} Quiz
1. Why validate on the server side?
2. Which function sanitizes email addresses?
3. What does strip_tags() do?
4. How should validation errors be handled?
Flashcards
Question
Server-side validation reason?
Click to reveal answer
Answer
Client-side validation can be bypassed
Question
Email sanitization?
Click to reveal answer
Answer
filter_var($email, FILTER_SANITIZE_EMAIL)
Question
Magento validation classes?
Click to reveal answer
Answer
ValidatorInterface, Escaper, Varien_Filter_Input
Question
Input validation rule?
Click to reveal answer
Answer
Validate early, sanitize before storage, never trust client
Revision Notes
Key Takeaways
- 1. Always validate on the server side
- 2. Use PHP's filter_var() for input sanitization
- 3. Magento provides Escaper class for output escaping
- 4. Combine client-side UX with server-side security
Interview Tips
- • Explain why client-side validation is insufficient
- • Discuss different sanitization methods
- • Know Magento's validation framework
Cheat Sheet
Input Validation
- Always validate server-side
- Sanitize: filter_var(), strip_tags()
- Magento: Escaper, ValidatorInterface
- Validate types, lengths, formats