Skip to content

v3-4 Updating articles

Intro

The process of updating a large number of articles needs some special attention, since it's easy to leak memory from Doctrine's listeners, thus a script that needs to process thousands of articles can increase the memory consumption until it crashes.

To ease writing such scripts, XalokNext comes with the wf:cms:page-article:update command.

The command can be invoked like this:

./app/admin/console wf:cms:page-article:update --batch-size=100 <script-name>

This command splits the work into batches of articles, each of the batches being processed in a separate process. If the process of updating one batch fails, the most common case is that the batch size was too large and the process was terminated due to exceeding the memory allocated, so the command automatically halves the batch size and tries again, until no runs are permitted.

The command requires a script-name argument, that is the name of a file stored in the app/PageArticleUpdateScripts. Each of the files contained in this folder must define a class PageArticleUpdateScript that defines at least a process method.

For example, given the file app/PageArticleUpdateScripts/update_title.php:

php
<?php

class PageArticleUpdateScript
{
    public function process($page)
    {
        $modules = $page->getModules();

        foreach ($modules as $module) {
            if ($module['moduleId'] == 'wfed/title/page_title') {
                $module['html'] = sprintf('<h1 class="title">%s</h1>', $module['data']['content']);
            }
        }

        $page->setModules($modules);
    }
}

the command should be invoked:

./app/admin/console wf:cms:page-article:update update_title

BasePageArticleUpdateScript

For some of the standard tasks, you can extend the base class that comes with XalokNext:

php
class PageArticleUpdateScript extends \Wf\Bundle\CmsBaseAdminBundle\Manager\BasePageArticleUpdateScript
{

    public function process($page)
    {
        //... process the page here
    }
}

The base script has methods to manipulate the top level modules (NOT a submodule of a composite). These methods are:

  • replaceModuleHTML
php
$this->replaceModuleHTML(
    $page,
    'wfed/title/page_title',
    function($module) {
        return sprintf(
            '<h1 class="new-title-class">%s</h1>',
            $module['data']['content']
        );
    }
);
  • replaceModuleId
php
$this->replaceModuleId(
    $page,
    'admin/body_text/epigraph',
    'admin/body_text/new-epigraph-module'
);
  • replaceTextModuleContent
php
$this->replaceTextModuleContent(
    $page,
    'wfed/title/page_title',
    function($module) {
        return sprintf(
            'Changed content, old content was: %s',
            $module['data']['content']
        );
    }
);

Please note that this doesn't change the HTML to reflect the change, use replaceModuleHTML for that.

  • replaceModuleSelectorById
php
$this->replaceModuleSelectorById(
    $page,
    'wfed/title/page_title',
    '.new-path .to-title-module-container'
);
  • replaceModuleSelectorBySelector
php
$this->replaceModuleSelectorBySelector(
    $page,
    '.old-path .to-title-module-container',
    '.new-path .to-title-module-container'
);