Composer Patches
cweagans/composer-patches
{
"require": {
"cweagans/composer-patches": "^1.7"
},
"extra": {
"patches": {
"magento/module-catalog": [
{
"subject": "Fix product import issue",
"url": "patches/magento-catalog-import-fix.patch",
"depth": 0
}
],
"magento/module-checkout": [
{
"subject": "Add custom field to checkout",
"url": "https://example.com/patches/checkout-custom-field.patch"
}
]
}
}
}
Patch File Format
--- a/Model/Product/Import.php
+++ b/Model/Product/Import.php
@@ -100,10 +100,15 @@
public function importProducts(array $data)
{
+ // Custom fix for import issue
+ if (empty($data)) {
+ return [];
+ }
+
foreach ($data as $item) {
$this->processItem($item);
}
}
Patch Management
namespace Vendor\Patches\Manager;
class PatchManager
{
private array $patches = [
[
'package' => 'magento/module-catalog',
'subject' => 'Fix product import',
'file' => 'patches/catalog-import.patch',
'applied' => true,
],
];
public function getStatus(): array
{
return $this->patches;
}
public function validatePatches(): ValidationResult
{
$errors = [];
foreach ($this->patches as $patch) {
if (!file_exists($patch['file'])) {
$errors[] = "Missing patch file: {$patch['file']}";
}
}
return new ValidationResult(empty($errors), $errors);
}
}
Security Updates
Security Patch Process
namespace Vendor\Security\Update;
class SecurityUpdateManager
{
private ComposerRunnerInterface $composer;
private DeploymentInterface $deployment;
public function applySecurityPatch(string $patchVersion): UpdateResult
{
// Step 1: Update composer.json
$this->updateVersionConstraints($patchVersion);
// Step 2: Run composer update
$this->composer->update([
'magento/*',
'--with-dependencies',
]);
// Step 3: Apply database updates
$this->deployment->runSetupUpgrade();
// Step 4: Clear cache
$this->deployment->clearCache();
// Step 5: Deploy static content
$this->deployment->deployStaticContent();
return new UpdateResult([
'version' => $patchVersion,
'status' => 'applied',
]);
}
}
Security Patch Checklist
namespace Vendor\Security\Checklist;
class SecurityPatchChecklist
{
public function getChecklist(): array
{
return [
'Backup database',
'Backup files',
'Review patch notes',
'Test in staging',
'Apply to production',
'Run setup:upgrade',
'Clear cache',
'Deploy static content',
'Verify site functionality',
'Monitor logs',
];
}
}
Upgrade Planning
Upgrade Strategy
namespace Vendor\Upgrade\Strategy;
class UpgradePlanner
{
public function planUpgrade(
string $currentVersion,
string $targetVersion
): UpgradePlan {
$steps = [];
// Step 1: Review release notes
$steps[] = new UpgradeStep(
'review',
'Review release notes and breaking changes'
);
// Step 2: Update dependencies
$steps[] = new UpgradeStep(
'dependencies',
'Update composer.json constraints'
);
// Step 3: Apply patches
$steps[] = new UpgradeStep(
'patches',
'Review and update custom patches'
);
// Step 4: Test
$steps[] = new UpgradeStep(
'test',
'Run full test suite in staging'
);
// Step 5: Deploy
$steps[] = new UpgradeStep(
'deploy',
'Deploy to production'
);
return new UpgradePlan(
$currentVersion,
$targetVersion,
$steps
);
}
}
Version Comparison
namespace Vendor\Upgrade\Compare;
class VersionComparator
{
public function compare(
string $from,
string $to
): ComparisonResult {
$fromParts = explode('.', $from);
$toParts = explode('.', $to);
$breakingChanges = [];
// Major version change = breaking
if ($fromParts[0] !== $toParts[0]) {
$breakingChanges[] = 'Major version change - likely breaking changes';
}
// Minor version check
if ($fromParts[1] !== $toParts[1]) {
$breakingChanges[] = 'Minor version change - new features';
}
return new ComparisonResult([
'from' => $from,
'to' => $to,
'breaking_changes' => $breakingChanges,
'risk_level' => empty($breakingChanges) ? 'low' : 'high',
]);
}
}
Patch Documentation
Patch Log
namespace Vendor\Patches\Log;
class PatchLog
{
private PatchLogRepositoryInterface $logRepo;
public function log(
string $package,
string $subject,
string $status,
?string $notes = null
): void {
$log = new PatchLogData([
'package' => $package,
'subject' => $subject,
'status' => $status,
'notes' => $notes,
'applied_by' => $this->auth->getUser()->getName(),
'applied_at' => new \DateTime(),
]);
$this->logRepo->save($log);
}
}
Patch Inventory
namespace Vendor\Patches\Inventory;
class PatchInventory
{
public function getInventory(): array
{
return [
[
'id' => 'PATCH-001',
'package' => 'magento/module-catalog',
'subject' => 'Fix product import issue',
'applied_date' => '2024-01-15',
'applied_by' => 'admin',
'status' => 'applied',
'notes' => 'Fixes CSV import validation',
],
[
'id' => 'PATCH-002',
'package' => 'magento/module-checkout',
'subject' => 'Add custom checkout field',
'applied_date' => '2024-01-20',
'applied_by' => 'developer',
'status' => 'applied',
'notes' => 'Adds company name field',
],
];
}
}
Quiz
1. What is a Composer patch?
2. What should you do before applying security updates?
3. How do you track applied patches?
Flashcards
Question
What is a Composer patch?
Click to reveal answer
Answer
Code modification applied via cweagans/composer-patches
Question
What is a security update?
Click to reveal answer
Answer
Patch addressing security vulnerabilities
Question
What is upgrade planning?
Click to reveal answer
Answer
Strategy for moving between major/minor versions
Question
Why track patches?
Click to reveal answer
Answer
For documentation, rollback, and upgrade planning
Revision Notes
Key Takeaways
- 1. Composer patches apply code modifications automatically
- 2. Security updates require careful planning and backups
- 3. Upgrade planning assesses risk and breaking changes
- 4. Patch documentation tracks applied modifications
- 5. Always test patches in staging before production
Interview Tips
- • Explain the patch application process
- • Discuss security update procedures
- • Describe upgrade planning methodology
- • Talk about patch documentation best practices
Cheat Sheet
Patches:
cweagans/composer-patches
patches in extra section
.patch or .diff files
Security Updates:
Backup → Review → Test → Deploy
composer update with dependencies
setup:upgrade → cache → static deploy
Upgrade Planning:
Review release notes
Update constraints
Test in staging
Deploy to production