why you shouldn’t edit silver stripe core files (and how to do it anyway)
TRANSCRIPT
Why you shouldn’tedit SilverStripe
core files(and how to do it anyway)
By Loz Calver / @kinglozzer
What do you mean “editingcore files”?
Modifying someone else’s codeCode outside the scope of “your project”Applies to framework, cms and any other modules
Why would I edit core files?Bugs - SilverStripe isn’t (quite) perfectSecurity
need urgent/immediate fixemail us!
Missing/upcoming features - time delay between minor versionsClients!
Why shouldn’t I edit core files?Other developers don’t know what you’ve doneUpdates are harder
(you should all be keeping up to date!)eventually you’ll get bored or frustrated and give up
You might accidentally introduce other issues
How can I avoid editing core?
Workaround 1: ExtensionsExample 1: adding database fields & extra methods
MyMemberExtension.php
<?php
class MyMemberExtension extends DataExtension {
private static $db = array( 'DateOfBirth' => 'SS_Datetime' );
public function SayHi() { return "Hi " . $this->owner->Name; }
}
_config.yml
Member: extensions: - MyMemberExtension
Workaround 1: ExtensionsExample 2: augmenting database queries
BlogPostFilter.php
<?php
class BlogPostFilter extends DataExtension {
public function augmentSQL(SQLQuery &$query) { $stage = Versioned::current_stage();
if ($stage == 'Live' || !Permission::check('VIEW_DRAFT_CONTENT')) { $sqlNow = Convert::raw2sql(SS_Datetime::now()); $query->addWhere(sprintf('"PublishDate" < \'%s\'', $sqlNow)); } }
}
_config.yml
BlogPost: extensions: - BlogPostFilter
Workaround 1: ExtensionsPros
Can be used to add things to built-in classesReusable: package them up, release them as modules!
Cons/CaveatsReliant on extension pointsExtensions have limited power
Workaround 2: InjectorExample: adding an extension hook
ManyManyListWithHook.php
<?php
class ManyManyListWithHook extends ManyManyList {
public function add($item, $extraFields = null) { parent::add($item, $extraFields);
if($item instanceof DataObject) { $item->extend('onAfterManyManyAdd', $this); } }
}
_config.yml
Injector: ManyManyList: class: ManyManyListWithHook
Credit to / module@camspiers silverstripe-cacheinclude
Workaround 2: InjectorExample: using the extension hook
MemberExtension.php
<?php
class MemberExtension extends Extension {
public function onAfterManyManyAdd(ManyManyList $list) { Debug::log('Member added to many_many relation'); }
}
_config.yml
Member: extensions: - MemberExtension
Workaround 2: InjectorPros
Can “replace” an entire classSuper powerful
Cons/CaveatsWith great power comes great responsibilityMust be instantiated with one of:
Class::create()Injector::inst()->get('Class')Injector::inst()->create('Class')Injector::inst()->createWithArgs('Class')
When all else fails, fork it!
Create a fork, apply your fixUse Git to periodically rebase from “upstream”Composer helps to make this easier!
Examplecomposer.json
{ "require": { "silverstripe/cms": "3.1.15", "silverstripe/framework": "3.1.15" }, "repositories": [ { "type": "vcs", "url": "[email protected]:kinglozzer/sapphire.git" } ]}
Examplecomposer.json
{ "require": { "silverstripe/cms": "3.1.15", "silverstripe/framework": "dev-hotfix" }, "repositories": [ { "type": "vcs", "url": "[email protected]:kinglozzer/sapphire.git" } ]}
Not quite...
Fixed!composer.json
{ "require": { "silverstripe/cms": "3.1.15", "silverstripe/framework": "dev-hotfix" }, "repositories": [ { "type": "vcs", "url": "[email protected]:kinglozzer/sapphire.git" } ]}
Fixed!composer.json
{ "require": { "silverstripe/cms": "3.1.15", "silverstripe/framework": "dev-hotfix as 3.1.15" }, "repositories": [ { "type": "vcs", "url": "[email protected]:kinglozzer/sapphire.git" } ]}
ForkingPros
Easier to:keep track of modifications madere-apply changes during updates - rebase/cherry-pickcreate a PR!
Cons/CaveatsWhile easier, it’s still extra effort!Slows down composer updates
SummaryUse extensions where possibleFor simple additions/fixes to methods, Injector should be okayFor anything else you can’t work around, fork as last resortUse Composer!
Thanks/questionsFeedback welcomed!
@kinglozzer @kinglozzer [email protected]