Migration from 1.17 to 2.0

1. Introduction

Version 2.0 of the Adventure PHP Framework includes extensive improvements and changes. The biggest change has been the completely revised class loading model according to PHP standard PSR-0. This increases compatibility and interoperability with other products and allows the APF to natively support PHP namespaces.

To run your application based on the new version various adaptions are necessary to your source code. To ease change the new version ships an automated migration and a tool to separate application from framework code.

The below chapters contain an in-depth description on how to switch to APF 2.0 and which kind of changes have to be applied to your existing application(s) to run them based on this version.

Please note, that the automated migration does not cover each and every bit of your application. Hence, please read chapter 2.3 and chapter 3 carefully!

2. Automated migration

To apply te necessary changes to your existing application easily release 2.0 provides an automated migration based on release 1.17.

Please ensure you have executed all steps listed under Migration from 1.16 to 1.17. In case you are using an even older version please fully migrate to version 1.17 before. Hints on migration from one version to another can be found under Articles.

To apply all required changes to your source code files please find migrate.sh within migration. This shell script executes a couple of PHP scripts that in turn adapt your application to this new version.

In case your development environment is windows, please install the latest cygwin version (download under cygwin.com). Migration for Windows Batch Scripts is not supported.

The below chapters now guide you through the migration process in a step-by-step fashion.

2.1. Preparation

Migration itself is nearly fully automated. Nevertheless, it is strongly recommended to work through the following steps to get better results. The migration script covers around 90-95% of the necessary adaptions but is not able to cover all project specifics.

Please understand that the APF team cannot take responsibility for any damage to your sources. Be sure to completely backup your project and to store your backup at an independent storage location to recover sources in case of any issue.

All migration scripts have been tested carefully based on existing projects of the APF team but we cannot guarantee that all special project implementations are covered and migrated successfully.

In order to get better results, it is recommended to conduct the following preparation steps:

  • Replace all existing @namespace annotations by @package within any doc blocks.
  • Check your project on folder names that are not compatible with PHP namespaces and rename folders if any (please find details on php.net). Example: in case your project includes folders with name foo-bar please rename the folder as well as all occurrences to e.g. foobar.
  • Remove all dynamic import() calls within functions or class methods. The will lead to compile errors after migration anyway.
  • In case you already use namespaces (partially) within your project, the following steps are highly recommended:
    • Remove all existing use statements. This avoids duplicateuse statements after migration.
    • Remove all existing namespace declarations as this helps to avoid wrong namespace assignments. The automated migration assumes that all project namespaces start with APF as their vendor. Separation of application code can be done after migration as described in chapter 6 afterwards anyway.
  • Reformat all PHP source files. This improves detection of code blocks and annotations. Example: remove unnecessary blanks within
    PHP code
    /* @var  \FooClass */

2.2. Migration execution

The migration itself includes three steps: replacing or updating the previously used APF version execution of the migration scripts ans some refinishing work.

2.2.1. Updating APF files

Please change to the project folder and there change to the apps folder where your application files are located. There you'll find APF folders core, extensions, modules, and tools as well as your folders and files.

Now, delete APF folders core, extensions, modules, and tools and download the latest apf-codepack-apf-codepack-2.0-php5-* package under Downloads. Afterwards, please extract within your apps folder.

In addition to the APF folders you know from previous releases a migration folder will show up. Example:

Code
Christian@chrislap /cygdrive/c/***/apps $ ll insgesamt 28K drwx------+ 1 Christian None 0 4. Jul 2013 config/ drwx------+ 1 Christian None 0 3. Jul 2013 core/ drwx------+ 1 Christian None 0 3. Jul 2013 extensions/ drwx------+ 1 Christian None 0 16. Jan 13:01 migration/ drwx------+ 1 Christian None 0 3. Jul 2013 modules/ drwx------+ 1 Christian None 0 4. Jul 2013 sites/ drwx------+ 1 Christian None 0 4. Jul 2013 thirdparty/ drwx------+ 1 Christian None 0 3. Jul 2013 tools/
2.2.2. Script execution

migration contains a couple of PHP files and migrate.sh that executes migration. This script expects the PHP executable as first and only argument. In case you have called it without this required parameter you will be presented an error message:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/migrate.sh ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [ERROR] PHP not found in your PATH-scope. Provide path to php as second parameter. Aborting!

To start the migration right within your apps folder please use the following shell command:

Code
Christian@chrislap /cygdrive/c/***/apps $ ./migration/migrate.sh /cygdrive/c/xampp/php/php

Migration is started and produces the following output:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/migrate.sh /cygdrive/c/xampp/php/php ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [OK] Using given php executable at /cygdrive/c/xampp/php/php. PHP Version: 5.4.16. ###################################### Starting migration ... * Prepare addtaglib declarations for migration ... * Introduced namespace declarations ... * Switched from import() to use ... * Migrated PHPDoc comments ... * Migrated declaration and usage of tags ... * Migrated service calls and di-service configuration ... * Migrated registry calls ... * Migrated session(manager) calls ... * Add missing use statements ... * Clean up unnecessary use statements ... * Migrated Singleton/SessionSingleton calls ... * Migrated CookieManager to Cookie class ... * Migrated PostHandler to RequestHandler class ... * Migrate LinkGenerator calls for action urls ... * Migrated configuration files: * Config calls * Database configuration * Cache configuration * Front controller configuration * GORM configuration * Pager configuration * UMGT module configuration * Contact module configuration ###################################### Migration done! Please check your code and follow instructions within migration documentation!

Now, a couple of refinishing tasks are required. Please find details in chapter 2.3.

Execution of the migration multiple times without restoring the original state leads to unwanted and unpredictable results (e.g. duplicate use statements). Thus, please reset all files to the original state and execute migration afterwards.
Further hints on the automated migration can be found under Migration und Ă„nderungen in 2.0 (German).

2.3. Refinishing

After migration of your application code some refinishing tasks have to be done. The majority of the below-described tasks are dedicated to migrate the bootstrap file of your application (index.php) and resolve pieces that haven't been migrated properly.

2.3.1. Update bootstrap file

The index.php of your application is not covered by the automated migration since every project's bootstrap file is unique. Please apply the following changes to your bootstrap file:

  1. APF 2.0 brings an internal bootstrap file that sets up the internal state of the framework. Thus, please replace
    PHP code
    include('***/core/pagecontroller/pagecontroller.php')
    by
    PHP code
    include('***/core/bootstrap.php');
    Please adapt the path as desired for your application.
  2. Introduce a use statement for each class used within your index.php. Using Singleton the appropriate statement is
    PHP code
    use APF\core\singleton\Singleton;
  3. Remove all import() calls. They have been replaced by use statements in APF 2.0.
  4. Using PHP namespaces for classes, templates, and configuration files it is necessary to switch to absolute class references. This also affects the index.php and using Singleton in particular. Please replace all calls on e.g.
    PHP code
    Singleton::getInstance('Frontcontroller')
    by
    PHP code
    Singleton::getInstance('APF\core\frontcontroller\Frontcontroller')
  5. Switching to PHP namespaces also affects using Registry entries. Please remove all occurrences of "::" by "\". Registry entries like
    PHP code
    Registry::retrieve('apf::core', 'InternalLogTarget')
    are retrieved in version 2.0 as follows:
    PHP code
    Registry::retrieve('APF\core', 'InternalLogTarget'
  6. Switching to PHP namespaces also affects definition or reference to configuration entries. Please revise your application for registration of Front controller actions such as
    PHP code
    $fC->registerAction('cms::core::biz::setmodel', 'setModel')
    and switch to
    PHP code
    $fC->registerAction('APF\cms\core\biz\setmodel', 'setModel')
  7. As noted within introduction templates are also referred to by a PHP-style namespace. Thus, please rewrite all appearances of
    PHP code
    $fC->start('***::pres::templates', 'site')
    loading an initial template to
    PHP code
    echo $fC->start('APF\***\pres\templates', 'site');
2.3.2. Correction of code files

As mentioned above the automated migration covers around 90-95% of the necessary changes that have to be applied. Unfortunately, project-specific use cases cannot be migrated in total. Fir this reason, you will have to correct some things within your project codebase to guarantee it is working again perfectly.

The following list contains a number of steps that have come up during our tests. Please note, that your project is facing further or totally different issues.

  • In order to avoid issues within your application code you may want to use a code inspector to discover potential issues automatically. The APF team recommends using PHPStorm's Code Inspector. After analysis, it comes up with Unused -> Classes, Unused -> Functions as well as Undefined items. You may want to use the automated fix apply feature of PHPStorm to solve a bunch of issues at once.
  • Automated migration does not cover all namespace declarations within your application. This includes session namespaces or namespaces used within custom tags. Please revise your project and replace all occurrences of "::" in strings. Example:
    PHP code
    // Old style $session = new Session('foo::bar'); // New style $session = new Session('VENDOR\foo\bar');

3. Manual migration

Unfortunately, not all components of your application can be migrated by the delivered scripts. This chapter lists components or modules that have to be updated to version 2.0 by hand.

  1. Signatur of the <fcon:importdesign /> tags has been changed fundamentally in version 2.0. This is because modelnamespace, modelfile, and modelclass have been combined into one attribute taking the fully-quallified class name of the model. Please change signature of the tag from
    APF template
    <fcon:importdesign templatenamespace="" modelnamespace="" modelfile="" modelclass="" modelparam="" [sessionsingleton=""] />
    to
    APF template
    <fcon:importdesign template-namespace="" template-param="" model="" [sessionsingleton=""] />

4. FAQs

During our tests of the migration scripts we discovered different types of errors. Within this chapter you'll find all of them together with an appropriate solution.

4.1. preg_replace_callback()

Issue
Code
preg_replace_callback(): Requires argument 2, 'ChainedGenericOutputFilter::replaceLink', to be a valid callback
Solution

Class ChainedGenericOutputFilter is being used without namespace. To fix this the class must be referred to within preg_replace_callback including namespace. Example:

PHP code
preg_replace_callback( '/<a (.*?)href="(.*?)"(.*?)>(.*?)<\/a>/ims', array('APF\core\filter\ChainedGenericOutputFilter', 'replaceLink'), $input );

4.2. ConfigurationException

Issue
Code
Class loader root path for namespace "sites\apf\biz" cannot be determined. Please double-check your configuration!
Solution

The namespace does not include a vendor (first segment of the namespace). Please change the namespace to DOCS\biz for instance. APF ist the default vendor that is registered within bootstrap.php. Details can be read about under Class loading.

4.3. Class not found

Issue
Code
Class 'APF\xyz\pres\documentcontroller\Controller' not found...
Solution

Potentially, a namespace declaration is missing in file APF/xyz/pres/documentcontroller/Controller.php. Please add one on the second line right after <?php:

PHP code
namespace APF\xyz\pres\documentcontroller;
Issue
Code
Fatal error: Class 'Logger' not found in ***\APF\core\singleton\Singleton.php on line 88
Solution

Please do use a fully-qualified namespace for all calls to Singleton::getInstance() or SessionSingleton::getInstance() as well as $this->getServiceObject() - here: APF\core\logging\Logger.

4.4. Fatal Error

Issue
Code
Fatal error: Interface 'APF\core\service\APFDIService' not found in ***\APF\core\pagecontroller\pagecontroller.php on line 320
Solution

Your bootstrap files has not been migrated yet. Please switch from

PHP code
include('./APF/core/pagecontroller/pagecontroller.php');

to

PHP code
include('./APF/core/bootstrap.php');

Further, please apply all changes described in chapter 2.3.1.

Issue
Code
Fatal error: Call to undefined function import() in ***\index.php on line 21
Solution

Please remove all usages of the import() function. This function is no longer necessary with APF 2.0.

4.5. ClassLoader Exception

Issue
Code
Class loader root path for namespace "foo::bar::blah" cannot be determined. Please double-check your configuration!
Solution

Please make sure to only use fully-qualified class names - here: APF\foo\bar\blah. This kind of error comes up after migration with registration of Front controller actions or loading the initial template within an application's bootstrap file.

5. Renamed classes and methods

As you may be used to from former releases some classes and methods have been renamed. This is because we want to ensure consistency and intuitive usage of the API. The following table outlines the changes.

The following classes have been renamed compared to version 1.17:

Old class name New class name
ChainedGenericInputFilter ChainedStandardInputFilter
ChainedGenericOutputFilter ChainedUrlRewritingOutputFilter
SessionManager Session
CookieManager Cookie

The below table shows renamed methods compared to version 1.17:

Old method name New method name
Session::destroySession() Session::destroy()
Session::loadSessionData() Session::load()
Session::loadAllSessionData() Session::loadAll()
Session::getEntryDataKeys() Session::getEntryKeys()
Session::saveSessionData() Session::save()
Session::deleteSessionData() Session::delete()
CookieManager::createCookie() Cookie::setValue()
CookieManager::updateCookie() Cookie::setValue()
CookieManager::readCookie() Cookie::getValue()
CookieManager::deleteCookie() Cookie::delete()
The classes and methods shown here are only listed for the sake of completeness. Migrating to the new notation is included within the automated migration script described in chapter 2.

6. Separation of application code

Since version 2.0 of the Adventure PHP Framework it is possible to separate application code and configuration from the framework's code base or framework components in general. Chapter Class loading and tutorial My first website describe the details behind it.

In case you intend to extract application code and all appropriate configuration you may want to use relocate.sh shipped within the migration folder. This script takes a source and a target namespace as arguments and copies all files below the source namespace to the target including adaption of the namespace usage.

The script supports several use cases relocating namespaces:

  • Namespace: In case your application resides under APF\sites\foo you can move things to another namespace within the same vendor (in this case APF) (e.g. APF\pages\foo).
  • Vendor: The main use case in conjunction with the migration to APF 2.0 is extracting existing namespaces from vendor APF into a new, custom vendor area (e.g. DOCS). The script is able to handle both relocation of a namespace within a certain vendor into a sub-area of another vendor (e.g. APF\sites\foo --> APPLICATION\foo) as well as extract a namespace sub-area into the main area of a new vendor (e.g. APF\sites\foo --> FOO).

The following example shows extraction of the vendor area DOCS into a newly defined vendor area DOCS:

Code
Christian@chrislap /cygdrive/c/***/apps $ migration/relocate.sh /cygdrive/c/xampp/php/php "DOCS" "DOCS" ###################################### # APF 2.0 automatic migration # ###################################### Checking directory ... [OK] Checking PHP executable available ... [OK] Using given php executable at /cygdrive/c/xampp/php/php. PHP Version: 5.4.16. Checking necessary parameters available ... [OK] ###################################### Starting relocation ... Source namespace: DOCS Target namespace: DOCS * Copy files to target structure ... * Re-mapping namespace on target ... ###################################### NOTE: Please note, that relocate.sh does not handle relocation of configuration files. Thus, please revise folder "/cygdrive/c/***/apps/config" and extract configuration files for vendor "APF" to new vendor "DOCS" as desired! ###################################### NOTE: Please be sure to add a new class loader configuration for new vendor "DOCS" within your bootstrap file (index.php). You may want to use the following as a start: use APF\core\loader\RootClassLoader; use APF\core\loader\StandardClassLoader; RootClassLoader::addLoader(new StandardClassLoader('DOCS', '/cygdrive/c/***/DOCS')); ###################################### Relocation done! Please check your code and follow instructions within migration documentation!
Please note, that relocate.sh only copies all relevant files from the source namespace to the desired destination. All original files remain as is.

Using the moved files you need to adapt the bootstrap file of your application. As a basis you may want to use the output that has been generated by the script (see RootClassLoader::addLoader()).

Since the structure of configuration files of your project is something very specific - e.g. configuration namespaces do not consequently follow the application namespaces - we cannot provide automated configuration migration. Thus, you are kindly asked to manually change, rearrange, or adapt configuration files or namespaces as necessary.

After final migration, please remove the original files manually.

Comments

Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.
There are no comments belonging to this article.