Migrating from TYPO3 CMS 
to TYPO3 Flow 
10th International TYPO3 Conference, October 9th, Berlin 
CC BY Serge Melki 
https://www.flickr.com/photos/sergemelki/8156340258 
Martin Helmich 
m.helmich@mittwald.de
CC BY-SA Niteshift 
http://commons.wikimedia.org/wiki/File:Balow_Kuhweide_2008-04-28_121.jpg
TYPO3 
Flow 
TYPO3 
Neos 
? 
TYPO3 
CMS
why!? 
CC BY Morgan 
https://www.flickr.com/photos/meddygarnet/3528509573
CC BY Crisada 
https://www.flickr.com/photos/chrisada/2415541623
CC BY Pascal 
https://www.flickr.com/photos/pasukaru76/6310053615
CC BY-SA Malene Thyssen 
http://commons.wikimedia.org/wiki/File:Brown_bear_(Ursus_arctos_arctos)_running.jpg
CC BY Emma Bishop 
https://www.flickr.com/photos/emmabishop/6360703145
Extensions 
Typoscript 
Content
Migrating content 
Read 
https://speakerdeck.com/kdambekalns/migrating-from-typo3-cms-to-typo3-neos
Migrating typoscript 
just don‘t
although... 
page 
= 
PAGE 
page 
{ 
10 
= 
TEMPLATE 
10 
{ 
template 
= 
FILE 
template.file 
= 
fileadmin/site.html 
marks 
{ 
CONTENT 
< 
styles.content.get 
CONTENT_RIGHT 
< 
styles.content.getRight 
} 
} 
} 
page 
= 
TYPO3.Neos:Page 
{ 
body 
{ 
templatePath 
= 
'resource://My.Site/.../Site.html' 
content 
{ 
main 
= 
PrimaryContent 
{ 
nodePath 
= 
'main' 
} 
right 
= 
ContentCollection 
{ 
nodePath 
= 
'right' 
} 
}
Render 
TS2 
Parse 
TS 
Apply 
trans-formations
How to convert an 
Extbase 
extension to 
TYPO3 FLOW
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
? 
Classes/ 
Controller/ 
Domain/ 
… 
Configuration/ 
TypoScript/ 
TCA/ 
Resources/ 
Public/ 
Private/ 
ext_emconf.php 
ext_tables.php 
ext_tables.sql 
Classes/ 
Controller/ 
Domain/ 
… 
Configuration/ 
Migrations/ 
Mysql/ 
Resources/ 
Public/ 
Private/ 
composer.json
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
class 
Tx_MyExt_Domain_Model_Car 
extends 
Tx_Extbase_DomainObject_AbstractEntity 
{ 
/** 
* 
@var 
string 
* 
@validate 
notempty 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Tx_MyExt_Domain_Model_Manufacturer 
*/ 
protected 
$manufacturer; 
} 
namespace 
MyExtDomainModel; 
use 
TYPO3FlowAnnotations 
as 
Flow; 
use 
DoctrineORMMapping 
as 
ORM; 
/** 
* 
@FlowEntity 
*/ 
class 
Car 
{ 
/** 
* 
@var 
string 
* 
@FlowValidate('NotEmpty') 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Manufacturer 
* 
@ORMManyToOne 
*/ 
protected 
$manufacturer; 
}
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
class 
Tx_MyExt_Domain_Model_Car 
extends 
Tx_Extbase_DomainObject_AbstractEntity 
{ 
/** 
* 
@var 
string 
* 
@validate 
notempty 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Tx_MyExt_Domain_Model_Manufacturer 
*/ 
protected 
$manufacturer; 
} 
namespace 
MyExtDomainModel; 
use 
TYPO3FlowAnnotations 
as 
Flow; 
use 
DoctrineORMMapping 
as 
ORM; 
/** 
* 
@FlowEntity 
*/ 
class 
Car 
{ 
/** 
* 
@var 
string 
* 
@FlowValidate('NotEmpty') 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Manufacturer 
* 
@ORMManyToOne 
*/ 
protected 
$manufacturer; 
} 
Namespacify classes 
when necessary
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
class 
Tx_MyExt_Domain_Model_Car 
extends 
Tx_Extbase_DomainObject_AbstractEntity 
{ 
/** 
* 
@var 
string 
* 
@validate 
notempty 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Tx_MyExt_Domain_Model_Manufacturer 
*/ 
protected 
$manufacturer; 
} 
namespace 
MyExtDomainModel; 
use 
TYPO3FlowAnnotations 
as 
Flow; 
use 
DoctrineORMMapping 
as 
ORM; 
/** 
* 
@FlowEntity 
*/ 
class 
Car 
{ 
/** 
* 
@var 
string 
* 
@FlowValidate('NotEmpty') 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Manufacturer 
* 
@ORMManyToOne 
*/ 
protected 
$manufacturer; 
} 
Determine domain object type 
by class inheritance and add 
annotation
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
class 
Tx_MyExt_Domain_Model_Car 
extends 
Tx_Extbase_DomainObject_AbstractEntity 
{ 
/** 
* 
@var 
string 
* 
@validate 
notempty 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Tx_MyExt_Domain_Model_Manufacturer 
*/ 
protected 
$manufacturer; 
} 
namespace 
MyExtDomainModel; 
use 
TYPO3FlowAnnotations 
as 
Flow; 
use 
Convert DoctrineORMannotations. 
Mapping 
as 
ORM; 
/** 
* 
@FlowEntity 
*/ 
class 
Car 
{ 
/** 
* 
@var 
string 
* 
@FlowValidate('NotEmpty') 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Manufacturer 
* 
@ORMManyToOne 
*/ 
protected 
$manufacturer; 
}
TYPO3 CMS 
(Extbase) 
TYPO3 Flow 
class 
Tx_MyExt_Domain_Model_Car 
extends 
Tx_Extbase_DomainObject_AbstractEntity 
{ 
/** 
* 
@var 
string 
* 
@validate 
notempty 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Tx_MyExt_Domain_Model_Manufacturer 
*/ 
protected 
$manufacturer; 
} 
namespace 
MyExtDomainModel; 
use 
TYPO3FlowAnnotations 
as 
Flow; 
use 
DoctrineORMMapping 
as 
ORM; 
/** 
* 
@FlowEntity 
*/ 
class 
Car 
{ 
/** 
Determine association 
cardinality from TCA 
* 
@var 
string 
* 
@FlowValidate('NotEmpty') 
*/ 
protected 
$licenseNumber; 
/** 
* 
@var 
Manufacturer 
* 
@ORMManyToOne 
*/ 
protected 
$manufacturer; 
}
some other stuff to think about 
Convert locallang 
to XLIFF 
create doctrine 
migrations 
from ext_tables.sql 
domain models 
extending TYPO3 classes 
usage of TYPO3 APIs 
(aka. the infamous t3lib_div) 
different value object 
handling
How to convert an 
pibase 
extension to 
TYPO3 FLOW
TYPO3 CMS 
(pibase) 
TYPO3 Flow 
lib/ 
pi1/ 
class.tx_myext_pi1.php 
static/ 
res/ 
ext_emconf.php 
ext_tables.php 
ext_tables.sql 
Classes/ 
Controller/ 
Domain/ 
Plugin/ 
… 
Configuration/ 
Migrations/ 
Mysql/ 
Resources/ 
Public/ 
Private/ 
composer.json 
?
class 
tx_myext_pi1 
extends 
tslib_pibase 
{ 
public 
function 
main($conf, 
$content) 
{ 
$mainTemplate 
= 
$this-­‐>cObj-­‐>fileResource(...); 
$rowTemplate 
= 
$this-­‐>cObj-­‐>fileResource(...); 
$userRes 
= 
$GLOBALS['TYPO3_DB']-­‐>exec_SELECTquery( 
'*', 
'tx_myext_users', 
'deleted=0 
AND 
active=1' 
); 
while($user 
= 
$GLOBALS['TYPO3_DB']-­‐>sql_fetch_assoc($userRes)) 
{ 
$markers 
= 
[ 
"###NAME###" 
=> 
$user['name'], 
"###EMAIL###" 
=> 
$user['email'] 
]; 
$content 
.= 
$this-­‐>cObj-­‐>substituteMarkerArray( 
$rowTemplate, 
$markers 
); 
} 
$markers 
= 
['###USERS###' 
=> 
$content]; 
return 
$this-­‐>cObj-­‐>substituteMarkerArray($mainTemplate, 
$markers); 
} 
}
The world of pain 
Doctrine 2 ORM 
Doctrine 2 DBAL 
(old code) 
Flow 
Resource 
Mgmt. 
Flow 
MVC 
Stack 
Pain abstraction layer
namespace 
MyExtPlugin; 
class 
UserListPlugin 
extends 
MwT3CompatPluginBasePlugin 
{ 
public 
function 
main($conf, 
$content) 
{ 
$mainTemplate 
= 
$this-­‐>cObj-­‐>fileResource(...); 
$rowTemplate 
= 
$this-­‐>cObj-­‐>fileResource(...); 
$userRes 
= 
$this-­‐>database-­‐>exec_SELECTquery( 
'*', 
'tx_myext_users', 
'deleted=0 
AND 
active=1' 
); 
while($user 
= 
$this-­‐>database-­‐>sql_fetch_assoc($userRes)) 
{ 
$markers 
= 
[ 
"###NAME###" 
=> 
$user['name'], 
"###EMAIL###" 
=> 
$user['email'] 
]; 
$content 
.= 
$this-­‐>cObj-­‐>substituteMarkerArray( 
$rowTemplate, 
$markers 
); 
} 
$markers 
= 
['###USERS###' 
=> 
$content]; 
return 
$this-­‐>cObj-­‐>substituteMarkerArray($mainTemplate, 
$markers); 
} 
}
demo time 
CC BY Kenny Louie 
https://www.flickr.com/photos/kwl/4743024076
try it 
https://github.com/mittwald/flow-metamorph
This work is licensed under a Creative 
Commons Attribution-ShareAlike 4.0 
International License. 
http://creativecommons.org/licenses/by-sa/4.0/

T3CON14EU: Migrating from TYPO3 CMS to TYPO3 Flow

  • 1.
    Migrating from TYPO3CMS to TYPO3 Flow 10th International TYPO3 Conference, October 9th, Berlin CC BY Serge Melki https://www.flickr.com/photos/sergemelki/8156340258 Martin Helmich m.helmich@mittwald.de
  • 4.
    CC BY-SA Niteshift http://commons.wikimedia.org/wiki/File:Balow_Kuhweide_2008-04-28_121.jpg
  • 5.
    TYPO3 Flow TYPO3 Neos ? TYPO3 CMS
  • 6.
    why!? CC BYMorgan https://www.flickr.com/photos/meddygarnet/3528509573
  • 7.
    CC BY Crisada https://www.flickr.com/photos/chrisada/2415541623
  • 8.
    CC BY Pascal https://www.flickr.com/photos/pasukaru76/6310053615
  • 9.
    CC BY-SA MaleneThyssen http://commons.wikimedia.org/wiki/File:Brown_bear_(Ursus_arctos_arctos)_running.jpg
  • 10.
    CC BY EmmaBishop https://www.flickr.com/photos/emmabishop/6360703145
  • 11.
  • 12.
    Migrating content Read https://speakerdeck.com/kdambekalns/migrating-from-typo3-cms-to-typo3-neos
  • 13.
  • 14.
    although... page = PAGE page { 10 = TEMPLATE 10 { template = FILE template.file = fileadmin/site.html marks { CONTENT < styles.content.get CONTENT_RIGHT < styles.content.getRight } } } page = TYPO3.Neos:Page { body { templatePath = 'resource://My.Site/.../Site.html' content { main = PrimaryContent { nodePath = 'main' } right = ContentCollection { nodePath = 'right' } }
  • 15.
    Render TS2 Parse TS Apply trans-formations
  • 16.
    How to convertan Extbase extension to TYPO3 FLOW
  • 17.
    TYPO3 CMS (Extbase) TYPO3 Flow ? Classes/ Controller/ Domain/ … Configuration/ TypoScript/ TCA/ Resources/ Public/ Private/ ext_emconf.php ext_tables.php ext_tables.sql Classes/ Controller/ Domain/ … Configuration/ Migrations/ Mysql/ Resources/ Public/ Private/ composer.json
  • 18.
    TYPO3 CMS (Extbase) TYPO3 Flow class Tx_MyExt_Domain_Model_Car extends Tx_Extbase_DomainObject_AbstractEntity { /** * @var string * @validate notempty */ protected $licenseNumber; /** * @var Tx_MyExt_Domain_Model_Manufacturer */ protected $manufacturer; } namespace MyExtDomainModel; use TYPO3FlowAnnotations as Flow; use DoctrineORMMapping as ORM; /** * @FlowEntity */ class Car { /** * @var string * @FlowValidate('NotEmpty') */ protected $licenseNumber; /** * @var Manufacturer * @ORMManyToOne */ protected $manufacturer; }
  • 19.
    TYPO3 CMS (Extbase) TYPO3 Flow class Tx_MyExt_Domain_Model_Car extends Tx_Extbase_DomainObject_AbstractEntity { /** * @var string * @validate notempty */ protected $licenseNumber; /** * @var Tx_MyExt_Domain_Model_Manufacturer */ protected $manufacturer; } namespace MyExtDomainModel; use TYPO3FlowAnnotations as Flow; use DoctrineORMMapping as ORM; /** * @FlowEntity */ class Car { /** * @var string * @FlowValidate('NotEmpty') */ protected $licenseNumber; /** * @var Manufacturer * @ORMManyToOne */ protected $manufacturer; } Namespacify classes when necessary
  • 20.
    TYPO3 CMS (Extbase) TYPO3 Flow class Tx_MyExt_Domain_Model_Car extends Tx_Extbase_DomainObject_AbstractEntity { /** * @var string * @validate notempty */ protected $licenseNumber; /** * @var Tx_MyExt_Domain_Model_Manufacturer */ protected $manufacturer; } namespace MyExtDomainModel; use TYPO3FlowAnnotations as Flow; use DoctrineORMMapping as ORM; /** * @FlowEntity */ class Car { /** * @var string * @FlowValidate('NotEmpty') */ protected $licenseNumber; /** * @var Manufacturer * @ORMManyToOne */ protected $manufacturer; } Determine domain object type by class inheritance and add annotation
  • 21.
    TYPO3 CMS (Extbase) TYPO3 Flow class Tx_MyExt_Domain_Model_Car extends Tx_Extbase_DomainObject_AbstractEntity { /** * @var string * @validate notempty */ protected $licenseNumber; /** * @var Tx_MyExt_Domain_Model_Manufacturer */ protected $manufacturer; } namespace MyExtDomainModel; use TYPO3FlowAnnotations as Flow; use Convert DoctrineORMannotations. Mapping as ORM; /** * @FlowEntity */ class Car { /** * @var string * @FlowValidate('NotEmpty') */ protected $licenseNumber; /** * @var Manufacturer * @ORMManyToOne */ protected $manufacturer; }
  • 22.
    TYPO3 CMS (Extbase) TYPO3 Flow class Tx_MyExt_Domain_Model_Car extends Tx_Extbase_DomainObject_AbstractEntity { /** * @var string * @validate notempty */ protected $licenseNumber; /** * @var Tx_MyExt_Domain_Model_Manufacturer */ protected $manufacturer; } namespace MyExtDomainModel; use TYPO3FlowAnnotations as Flow; use DoctrineORMMapping as ORM; /** * @FlowEntity */ class Car { /** Determine association cardinality from TCA * @var string * @FlowValidate('NotEmpty') */ protected $licenseNumber; /** * @var Manufacturer * @ORMManyToOne */ protected $manufacturer; }
  • 23.
    some other stuffto think about Convert locallang to XLIFF create doctrine migrations from ext_tables.sql domain models extending TYPO3 classes usage of TYPO3 APIs (aka. the infamous t3lib_div) different value object handling
  • 24.
    How to convertan pibase extension to TYPO3 FLOW
  • 25.
    TYPO3 CMS (pibase) TYPO3 Flow lib/ pi1/ class.tx_myext_pi1.php static/ res/ ext_emconf.php ext_tables.php ext_tables.sql Classes/ Controller/ Domain/ Plugin/ … Configuration/ Migrations/ Mysql/ Resources/ Public/ Private/ composer.json ?
  • 26.
    class tx_myext_pi1 extends tslib_pibase { public function main($conf, $content) { $mainTemplate = $this-­‐>cObj-­‐>fileResource(...); $rowTemplate = $this-­‐>cObj-­‐>fileResource(...); $userRes = $GLOBALS['TYPO3_DB']-­‐>exec_SELECTquery( '*', 'tx_myext_users', 'deleted=0 AND active=1' ); while($user = $GLOBALS['TYPO3_DB']-­‐>sql_fetch_assoc($userRes)) { $markers = [ "###NAME###" => $user['name'], "###EMAIL###" => $user['email'] ]; $content .= $this-­‐>cObj-­‐>substituteMarkerArray( $rowTemplate, $markers ); } $markers = ['###USERS###' => $content]; return $this-­‐>cObj-­‐>substituteMarkerArray($mainTemplate, $markers); } }
  • 27.
    The world ofpain Doctrine 2 ORM Doctrine 2 DBAL (old code) Flow Resource Mgmt. Flow MVC Stack Pain abstraction layer
  • 28.
    namespace MyExtPlugin; class UserListPlugin extends MwT3CompatPluginBasePlugin { public function main($conf, $content) { $mainTemplate = $this-­‐>cObj-­‐>fileResource(...); $rowTemplate = $this-­‐>cObj-­‐>fileResource(...); $userRes = $this-­‐>database-­‐>exec_SELECTquery( '*', 'tx_myext_users', 'deleted=0 AND active=1' ); while($user = $this-­‐>database-­‐>sql_fetch_assoc($userRes)) { $markers = [ "###NAME###" => $user['name'], "###EMAIL###" => $user['email'] ]; $content .= $this-­‐>cObj-­‐>substituteMarkerArray( $rowTemplate, $markers ); } $markers = ['###USERS###' => $content]; return $this-­‐>cObj-­‐>substituteMarkerArray($mainTemplate, $markers); } }
  • 30.
    demo time CCBY Kenny Louie https://www.flickr.com/photos/kwl/4743024076
  • 31.
  • 33.
    This work islicensed under a Creative Commons Attribution-ShareAlike 4.0 International License. http://creativecommons.org/licenses/by-sa/4.0/