Skip to content

Instantly share code, notes, and snippets.

View NightJar's full-sized avatar

Dylan Wagstaff NightJar

View GitHub Profile
@NightJar
NightJar / mfa-status.md
Created June 20, 2019 23:46
Multi factor authentication overview (@ 21 June 2019)

SilverStripe 4 security enahncements

This is a quick overview of a suite of 5 new modules that are focused around security and member authentication with the CMS.

  • silverstripe/mfa
  • silverstripe/login-forms
  • silverstripe/security-extensions
  • silverstripe/webauthn-authenticator
  • silverstripe/totp-authenticator
@NightJar
NightJar / Silverstripe-queries.md
Created February 4, 2020 20:42
Silverstripe & SQL

Why don't Silverstripe CMS queries run in MySQL?

When debugging an ORM call, you may find yourself collecting the SQL that will be exectued via the DataList::sql function - this is great, but when copied and pasted into e.g. PHPMyAdmin, MySQL Workbench, HeidiSQL, DBeaver, Sequel Pro, etc... it doesn't seem to work!

Lets look at an example query that might* be used for a template call such as <% if $Menu(1) %>:

SELECT DISTINCT count(DISTINCT "SiteTree_Live"."ID") AS "Count"
 FROM "SiteTree_Live"
 WHERE (("SiteTree_Live"."ParentID" = 0))
<?php
namespace Nightjar\SS4UpgradeTasks;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
use SilverStripe\Assets\File;
use SilverStripe\Control\Director;
use SilverStripe\Core\ClassInfo;
@NightJar
NightJar / ContentBit.php
Created May 26, 2021 04:57
Repair existing snapshots which have erroneously not recorded their author
<?php
namespace App\Tests\Migrations\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class ContentBit extends DataObject implements TestOnly
{
private static $table_name = 'BitOfContent';
@NightJar
NightJar / Site IA review query.sql
Created February 27, 2023 02:53
An SQL query that will get a list of every page on the site (regardless of visibility to any given user) along with published status. Useful for information architecture (IA) reviews by site owners or groups thereof.
-- file names are relative to the active database's data directory (e.g. /var/lib/mysql/SS_yoursite/${outfile}.csv) and are therefore only readable by the mysql user (use sudo) - or output to an absolute path with write permission e.g. /tmp as below
with recursive kids as (
select st.ID, URLSegment, cast(URLSegment as varchar(1000)) as Link, ParentID, Title, st.Version, LastEdited
from SiteTree st
left join Page pagedata on st.ID = pagedata.ID
where st.ParentID = 0
union all
select child.ID, child.URLSegment, cast(concat(parent.Link, '/', child.URLSegment) as varchar(1000)) as Link, child.ParentID, child.Title, child.Version, child.LastEdited
from SiteTree as child
@NightJar
NightJar / frontend-build-testing.md
Created March 28, 2023 08:49
I tested various JS & CSS build systems for the purpose of building a Silverstripe CMS module

All tests were in relation to building ConfigCodes

As the Silverstripe Admin ecosystem is severely out of date (WebPack 2), and I've also never learnt to configure a build system from scratch. It was time to up my game. Although these musings might not be entirely accurate, they are my experience, and the thoughts on that particular use case at that time.

The headings are in chronological order of testing.

@NightJar
NightJar / LegacyReplacementBackend.php
Last active February 20, 2024 12:36
FIX: silverstripe/admin moved jQuery.Entwine and now your site doesn't load because of a third-party dependency that isn't updated yet
<?php
namespace Your\Namespace\Requirements;
use SilverStripe\View\Requirements_Backend;
class LegacyReplacementBackend extends Requirements_Backend
{
public function javascript($file, $options = [])
{
@NightJar
NightJar / beMoreEfficient.php
Created May 16, 2024 11:09
Stop doing 1+N queries when using summary fields with relations (e.g. GridFieldDataColumns or GridFieldExportButton)
<?php
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Queries\SQLSelect;
function alterListToSummaryFields(DataList $list): SQLSelect
{
$model = $list->dataClass();
$instance = $model::create();