unleashing creative freedom with modx - 2015-08-26 at php zwolle
TRANSCRIPT
Agenda
• What is MODX, for whom, available features, how to build a MODX site
• Tour of the MODX Manager (back-end)
• The Architecture of MODX, xPDO ORM, extending and overriding, the future
MOD-what?
• Open Source
• Written in PHP (of course)
• Primarily used with MySQL, other drivers available
• Already 10 years old young
• Content Management System Framework Platform
All the features of a CMS
rich text editor versioning user groups multisite templates multilingual extensions
markdown media browser hierarchical page tree commercial support automatic menu builder blogging permissions seo
friendly urls server-side caching
Template Variables
• Custom field for resources
• Commonly “TV”
• Tied to templates
• Text, image, select, checkbox, date, radio, richtext, tag and custom types available
• [[*name-of-tv]]
Snippets
• PHP!
• Comparable to a function
• Accepts properties
• [[name-of-snippet]] or [[!name-of-snippet]]
Snippet “helloWorld”
Template
But wait, there’s more!
• [[name-of-snippet]]
• [[!name-of-snippet]]
• = uncached!
• [[++name-of-setting]][[!++name-of-setting]]
• [[$name-of-chunk]][[!$name-of-chunk]]
• [[*name-of-field]][[!*name-of-field]]
But wait, there’s even more!
• [[helloWorld? &property=`value ̀]]
• [[$head? &extraCss=`<link rel=.. href=..> ̀]]
No need to reinventthe wheel
• Packages (aka extras, add-ons, extensions, third party components…) provide common functionality
• Install via Package Installer inside the manager
Example: getResources
• Lists resources matching conditions
• Uses a Chunk as template
• Use Cases:
• Article listings
• Dynamic (sub)menus
• RSS feed generation
Template
Chunk “blogListItem”
Secure by Design
• Automatic $_GET, $_POST, $_REQUEST sanitisation in the request handler
• xPDO ORM prevents SQL Injections
• 28 CVE entries, 8 since 2014 • WordPress: 906, already ~85 in 2015 • Drupal: 915, already ~120 in 2015
2015-07, cve.mitre.org
xPDO
• Object Relational Bridge / ORM
• Open Source (modxcms/xpdo)
• Extension to PHP’s PDO
• Support for MySQL, sqlsrv (and more)
Fetching a Single Object
$c = 5;
$obj = $modx->getObject(‘modChunk’, $c);
$c2 = array(‘name’ => ‘head’);
$obj = $modx->getObject(‘modChunk’, $c2)
Easy Query Builder
$c = $modx->newQuery(‘modResource’);
$c->where([
‘parent’ => 0,
‘AND:pagetitle:LIKE => ‘%About%’
]);
$matches = $modx->getCollection(‘modResource’, $c);
foreach ($matches as $modResource) { . . . }
Automatic Filtering
$search = $_POST[‘search’];
$c = $modx->newQuery(‘modResource’);
$c->where([
‘introtext:LIKE’ => “%{$search}%”,
]);
$modx->setPlaceholder(‘search’, sanitise($search));
function sanitise($value) { return htmlentities($value, ENT_QUOTES, ‘UTF-8’); }
👍
⚠
Custom Models with xPDO
1. Create an xPDO Package Schema (XML)
2. Use build script to write schema into the actual model files/classes
3. Register it before use ($modx->addPackage)
4. Use any xPDO method (getObject, getCollection) on your custom model
xPDO Package Schema - Head
<?xml version="1.0" encoding="UTF-8"?>
<model package="phpfrl"
baseClass="xPDOSimpleObject"
platform="mysql"
defaultEngine="MyISAM"
version="1.1">
xPDO Package Schema - Object
<?xml version="1.0" encoding="UTF-8"?>
<model package=“phpfrl” …
<object class="frlMeetup" table=“meetups”>
.. fields ..
</object>
<object class="frlSpeaker" table=“speakers”> … </object>
</model>
xPDO Package Schema - Fields<?xml version="1.0" encoding="UTF-8"?>
<model package=“phpfrl” …
<object class="frlMeetup" table=“meetups">
<field key="name" dbtype="varchar" precision="100" phptype="string" null="false" default=“PHP FRL Meetup" />
xPDO Package Schema - Indices
<?xml version="1.0" encoding="UTF-8"?>
<model package=“phpfrl” …
<object class="frlMeetup" table=“meetups"> <field key="name" dbtype=“varchar" … <field key=“starts_on" dbtype=“datetime" <field key="name" dbtype=“varchar" …
<index alias="name" name="name" primary="false" unique="false" type="BTREE"> <column key="name" length="" collation="A" null="false" /> </index> </object>
xPDO Package Schema - Relations<?xml version="1.0" encoding="UTF-8"?>
<model package=“phpfrl” baseClass=“xPDOSimpleObject" …
<object class="frlMeetup" table=“meetups"> <field key="name" dbtype=“varchar” …>
<composite alias=“Speakers” class=“frlSpeaker” local=“id” foreign=“meetup” cardinality=“many” owner=“local” /> </object>
<object class="frlSpeaker" table=“speakers"> <field key="name" dbtype=“varchar” …> <field key="meetup" dbtype=“int” …>
<aggregate alias=“Meetup” class=“frlMeetup” local=“meetup” foreign=“id” cardinality=“one” owner=“foreign” /> </object>
xPDO Generated Model
<?phpclass frlMeetup extends xPDOSimpleObject {
}
<?php
class frlMeetup_mysql extends frlMeetup {
}
Interacting with that model$modx->addPackage(‘phpfrl’, ‘/path/to/model/‘);
$c = $modx->newQuery(‘frlMeetup’);$c->sortby(‘starts_on’, ‘DESC’);$meetup = $modx->getObject(‘frlMeetup’, $c);
echo ‘De volgende meetup is ‘ . $meetup->name . ‘ en vind plaats op ‘ . $meetup->starts_on . ‘. ’;
$speakers = $meetup->getMany(‘Speakers’); // or just $meetup->Speakersforeach ($speakers as $spegfytaker) { echo $speaker->name . ‘ zal vertellen over ‘ . $speaker->subject;}
The Future of MODX
• MODX 3 & MODX Next • Backwards incompatible release (semver) • Cleaning up legacy code no longer relevant • Full namespace support for xPDO models • Composer/packagist support • Proper Dependency Injection in the core • Improved, faster routing with Slim
Interesting links: • MODX.com => official website • rtfm.modx.com => official documentation • github.com/modxcms/revolution => source code • MODX.today => daily links/articles about MODX • modmore.com => premium extras for MODX • https://joind.in/talk/view/15031 => please leave feedback
Enjoy your Creative Freedom