Migration Guide 3.0

From Cloudrexx Development Wiki
Jump to: navigation, search

Migrating from Contrexx 1.x.x/2.x.x to Contrexx 3.0.x

The following sections list the changes made to the API of Contrexx from version 1 and 2 to 3.

The full API documentation of version 3 can be found at http://api.contrexx.com/.

The architecture of Contrexx 3 has changed quite a lot compared to version 2. Therefore, if migrating from an older version of Contrexx to Contrexx 3 you will have to migrate your own developed modules/extensions to the architecture of Contrexx 3. This article shall guide you in successfully migrating your custom modules to version 3.

Preparation

Due to the architectural changes made in version 3, most of its framework and API have changed compared to version 1 and 2 of Contrexx. Therefore, custom code, new modules or extensions (refering to them as extensions from this point on) that have been written for version 1 or 2 must be migrated (refactored) to the architecture of version 3. But besides the architectural changes, many improvements to the exiting functionality and additional new features have been implemented as well. Giving that, the functionality of many extensions developed for the older versions might now already be part of the base feature set of version 3, which would make a migration of the extension obsolete. Instead, the extension's function can be reconstructed by using the available features of version 3.

Therefore, before migrating an extension, it is important to analyze it first to determine if a migration is even required.

Determine Migration Path

There are basically two kind of extensions:

  • an independent extension to Contrexx (i.e. a new module)
  • an extension to an existing component of Contrexx (i.e. an extension to the Online Shop)

For the first case, an independent extension, it is not likely that its functionality is covered by a new feature (like an analogous new module) of the new version. Therefore, the whole extension has probably to be migrated to the new architecture.

For the second case, an extension to an existing component of Contrexx, there is a chance that its functionality is covered by a new feature of the new version and would make its migration obsolete. The following steps shall guide you in the process of determining if a migration of such an extension is required or not:

  1. Compare the files of the component containing the extension to those of the original component
    1. Determine the version of the original component. If you can't remember the version the original component was of, you may find the version in the file config/version.php
    2. Fetch the download package of the original version from http://www.contrexx.com/ and depack it for later usage
    3. Use a file comparison tool to determine the differences (change-sets) between the extended component and its original version
  2. For each change-set, you'll have to ask you the following questions:
    • Is the change-set a bugfix that has also been resolved in the new version?
    You may want to check out the list of resolved bugs or compare the appropriate code of the new version to be able to answer this question.
    • Is the change-set an extension that has been implemented in the new version?
    • Can the functionality of the change-set be implemented using an other new feature of the new version?
    To be able to answer those two questions, you may want to check out the list of newly implemented features or manually explore the features of the new version
  3. If none of the above questions could be answered by yes, you'll have to migrate the extension to the new architecture. This should be done as a Customizing. A list of architectural changes can be found in the next section of this article.

File Inclusion

Contrexx 3 introduces Namespaces. Based on this, Contrexx now uses a class loader to load (include) PHP files. This makes the use of the functions include(), include_once(), require() and require_once() obsolete. In conjunction with the new customizing-policy those functions are not only obsolete, but must no longer be used at all in Contrexx 3.

In case the Contrexx ClassLoader is unable to load (re. find) your custom PHP class, you can teach the ClassLoader where to find them. See Legacy Class Cache in article Legacy Class Loader on how to achieve this.

However, if you need to include a code-snippet (without a PHP class), you can use the method Cx\Core\ClassLoader\ClassLoader::loadFile() to do so: <highlightsyntax>\Env::get('ClassLoader')->loadFile('/absolute/path/to/your/PHP/script');</highlightsyntax>

Old files

After an update, old files will still exist but not be loaded. So if you migrate customizings be aware that existing files might not be the ones used. In Contrexx 3 in a worst case scenario this could cause the ClassLoader to load the wrong file. See LegacyClassLoader for further information.

Content

The content system has completely been rewritten. It uses now Doctrine as an ORM instead of accessing the database directly. Therefore the content related database tables contrexx_content* do no longer exist. Existing code that operates directly on these database tables must therefore be migrated to the new content framework.

Aliases

The Alias-System has been rewritten and is now part of the content system (see Page Type Alias). Therefore the database tables contrexx_module_alias* do no longer exist. Existing code that operates directly on these database tables must therefore be migrated to the new content framework (see code example to aliases).

Multi Language

Many modules have been extended to be multi-language cabable. Most of them use now an additonal separate database table to handle the localization of an entity. Exising code that operates directly on these database tables must therefore be migrated to the new ERM of each module.

Affected modules:

  • news
  • block
  • contact
  • shop

Template System

Since version 3, it is recommended to use the Contrexx Sigma template wrapper, instead of the native Sigma template class. The usage of the Contrexx Sigma template is identical to the one of Sigma (see documentation). The only difference is that Contrexx Sigma extends the template system by supporting customizings.

Therefore, initializing a new template object in now done using \Cx\Core\Html\Sigma: <highlightsyntax>// instantiate a new template object $objTemplate = new \Cx\Core\Html\Sigma('.');</highlightsyntax>

Before version 3, you would have used HTML_Template_Sigma(): <highlightsyntax>// do not use anymore! $objTemplate = new HTML_Template_Sigma('.');</highlightsyntax>

Loading in frontend and backend

Module initialization for frontend

If your module does something in frontend, copy the file /core/initFrontend.php to the customizing folder, then search for a long switch/case statement (starting somewhere after row 1055). Add your module as a case (again, replace demo with the name of your module):

case 'demo':
    /** @ignore */
    if (!$cl->loadFile(ASCMS_MODULE_PATH . '/' . $plainSection . '/index.class.php')) {
        die($_CORELANG['TXT_THIS_MODULE_DOESNT_EXISTS']);
    }
    $module = new \Cx\Modules\Demo\FrontendController($pageContent, ...);
    $objTemplate->setVariable('CONTENT_TEXT', $module->getPage());
    break;

For a core module, just change ASCMS_MODULE_PATH to ASCMS_CORE_MODULE_PATH. Be sure to deliver all dependencies to the constructor of your controller (--> Dependency Injection, you may need $_ARRAYLANG, $objDatabase, etc.).

If you use the session, you must initialize it here! See Session handling for more information.

Module initialization for backend

If your module does something in backend, copy the file /core/initBackend.php to the customizing folder, then search for a long switch/case statement (starting somewhere after row 315). Add your module as a case:

case 'workflow':
   if (!$cl->loadFile(ASCMS_MODULE_PATH . '/' . $plainCmd . '/admin.class.php')) {
        die($_CORELANG['TXT_THIS_MODULE_DOESNT_EXISTS']);
    }
    $subMenuTitle = $_CORELANG['TXT_DEMO_MODULE'];
    $module = new \Cx\Modules\Demo\BackendController($objTemplate, ...);
    $module->getPage();
    break;

For a core module, just change ASCMS_MODULE_PATH to ASCMS_CORE_MODULE_PATH. Be sure to deliver all dependencies to the constructor of your controller (--> Dependency Injection, you may need $_ARRAYLANG, $objDatabase, etc.).

You might want to check, if the user is allowed to access this module here. See Development_Permissions for more information.


File System Operations

Setting write access

<highlightsyntax>// Contrexx 2 $objFile = new File(); $objFile->setChmod($absolute_path_to_directory, $web_path_to_directory, $file)

// Contrexx 3 \Cx\Lib\FileSystem\FileSystem::makeWritable($absolute_path_to_directory.$file); </highlightsyntax>

Copying files

<highlightsyntax>// Contrexx 2 $objFile->moveFile($absolute_path_to_directory, $web_path_to_directory, $file, $absolute_dest_path_to_directory, $web_dest_path_to_directory, $dest_file);

// Contrexx 3 try {

   $objFile = new \Cx\Lib\FileSystem\File($absolute_path_to_directory.$file);
   $objFile->copy($absolute_dest_path_to_directory.$dest_file);

} catch (\Cx\Lib\FileSystem\FileSystemException $e) {

   \DBG::msg($e->getMessage());

} </highlightsyntax>

Deleting files

<highlightsyntax>// Contrexx 2 $objFile->delFile($this->imagePath, $this->imageWebPath, 'uploads/'.$fileName);

// Contrexx 3 \Cx\Lib\FileSystem\FileSystem::delete_file($this->imagePath.'uploads/'.$fileName); </highlightsyntax>

Localization (Date)

  • Replace constant ASCMS_DATE_SHORT_FORMAT by ASCMS_DATE_FORMAT_DATE