En Route to DrupalCon Austin 2014

I am trying to see if I can take a stab at Drupal project. I have cloned it and checked out the core a bit, mostly the components and the core. One first impression is the familiarity with Symfony and well PHP in general. I am talking about past and present. There is code down there that is not very pleasant at all; however, there is good code too.

Regarding components, I believe it is currently a mix of byproduct drop copy/paste spaguetti code that was before all together and now we have put it in classes and removed the requires. This feels exactly like the book from Paul M. Jones. The process is not at all finished though, so there is this feeling of disconnection and of facade :), something fake. The components are really a move of pieces of code that treat a topic but they are somewhat still to specific to Drupal. The components are defined as code that could even be pulled out of Drupal, however i think they are not mature enough for that. They are good within Drupal for now, there is some more work to be done on them to make them really more generic oriented and more helpful for solving single responsibility problems. Some of them are code ideas split between the core and the components so really they are a refactor of some core classes.

Regarding contribution, I believe the current state of Drupal contribution is too adhoc and prone to errors and time spend on things that elongate the development process. I feel like going 0.00009X of the speed I go on Github. There is no excuse really. Drupal has issues, so Github, Drupal has patches, so Github PRs, Drupal has interdiffs, Github has Diffs and PRs to allow more than one contributor and has forks and much much more. Drupal has a search, so does Github have labels, Drupal has dreditor, Github has diffs and a world class web interface, Drupal has a test system, Github has travis, Drupal has millions of patches, so Github handles much much more across all languages and repos combined, Drupal.org (d.o) is slower than Github, Drupal has a broken API for posting tickets and such, Github has a brand working API interconnected with many libraries and support for integration into other systems like Jira, waffle.io, and what not, Drupal has threads, so does Github can sustain threads with drag and drop graphics, code markdown and realtime facebook-like updates, Drupal has follow feature, so Github has follow and subscribe features for PRs, comments, repos, etc, Drupal has many branches, so Github allows projects to handle branches and tagging and releasing, Drupal has projects so Github does and you have authentication, private and public sides, and you have complete freedom. The only reason I think Drupal does not move to Github perhaps is fear of change. That said Drupal has a great community and thrive, so much that we need to invite it to the PHP arena on Github. We cannot afford to not share with those on the other side of the wall.

Regarding help, there is yesCT which will help you if you approach Drupal channels on IRC. She is such an asset! Thanks for helping me so far figuring things out.

Regarding some good quality code, I saw a plugin system that is very powerful, maybe not fully tested, but good nonetheless. I dislike the CS because it not only is particular amongst good PHP projects but it is just non enforced well. It kind of conveys sloppiness imo, but yes as I take more informations I can change my mind on some things, many things maybe.

I am trying to send patch after patch as I advance reading the core code. I figured if I read the core then it would be helpful when I get to use the release and I can learn things from its source code too. I see very interesting line ideas, the problem is that I see a reminiscence of convoluted practices, but I see an emergent OO feel in Drupal, situation is changing, and there are great minds there. So don’t be shy and start looking at Drupal, after all is not all spaghetti code, it has very good parts, and in its beginnings its architecture is promising.

Often I hear the main argument for Drupal is size, but it is time to change that and let the core quality decide. Not just that is using Symfony but that its other components and core classes can well develop an architecture that is parallel or beyond Symfony.

Encouragements and thanks for reading this. All are my thoughts and never to be taken offensively of any work. These are just appreciations that are changing as I dig but is a first impression.

Mastering Legacy Application Development: Paul M Jones Examined

Screenshot 2014-04-14 10.11.24

Oh boy! that is my expression as I start to edit the book from Paul M Jones that just came out. I will sum it up in saying you will be rewarded that you got to read this book. Especially when you did not know what to do when you landed on that job and face a total legacy challenge. It seems like you have to be brewed for years before you get this straight, but this book almost empowers just about any newbie out there to jump onto those dreaded lead jobs and get them done.

I would only trust someone like Paul Jones or Matthias Noback (have you checked his book too?) for a solid step by step recipe that I can trust to tame the legacy madness at work. He has been doing this for years, and finally he decided it was time to write it down, and what a time you will have reading it!

Going from applications in production that use php 5.0 or even before to applications using modern frameworks running php 5.5, this book’s principles applied systematically are a sure win. In here newbies and experienced developers alike will fill knowledge gaps and will learn a lot of background and history on how applications can also be evolved to the year 2014 by a developer that has learned through many years how to go back in to the past and bring an app to the future with all nuances and explanations on why we do things without loosing the focus of getting the job done in the most professional way possible.

I feel a total different developer now, with a lot more confidence to take on legacy projects thanks to this book. I have met Paul at the SunshinePHP conference some years ago, and I have found a friend and someone I can learn from in the most clear possible straightforward language. He has even sat after his talk and explained architecture of his code to me just because I asked a question. I fully recommend to read him carefully and to appreciate his position within the large PHP community.

Thanks Paul, I am glad you are part of our community.

I truly hope you (the audience) enjoy this book.

Your friend from the php community,

Luis Cordova (@cordoval)

As part of the symfony community and php community at large I am very thankful for the opportunity to have reviewed such great authors like Matthias Noback and Paul M. Jones.
Here I leave my book recommendations and mine at the bottom.

Screenshot 2014-04-14 10.11.06

Screenshot 2014-04-14 10.12.36

Bldr.io and Gushphp.org: Great tools!

If you are a TDD practitioner you don’t want to miss this.

We recently removed Grunfile.js from our Gushphp repository. And we replaced it all with Bldr.io. Bldr.io is written on PHP! And is an excellent tool that for the project’s current needs is perfect. We used Grunt in the past mainly for TDD, so that it would cycle running our PHPUnit tests for Gush. What we didn’t know is this Bldr.io tool can do that and in a very PHP-ish elegant way!

Check this file below:

bldr:
    name: gushphp/gush
    description: Gush Project
    profiles:
        travis:
            description: Travis Profile
            tasks:
                - prepare
                - lint
                - phpcs
                - test
        local:
            description: Local Development Profile
            tasks:
                - testLocal
                - watch
    tasks:
        prepare:
            calls:
                -
                    type: filesystem:remove
                    files: [build/coverage, build/logs]
                -
                    type: filesystem:mkdir
                    failOnError: true
                    files: [build/coverage, build/logs]
                -
                    type: filesystem:touch
                    failOnError: true
                    files: [build/coverage/index.html]
                -
                    type: exec
                    failOnError: true
                    executable: composer
                    arguments: [install, --prefer-dist]
                -
                    type: notify
                    message: Prepare Task Finished
        lint:
            description: Lints the files of the project
            calls:
                -
                    type: apply
                    failOnError: true
                    src:
                        - { path: [src, tests], files: *.php, recursive: true }
                    output: /dev/null
                    executable: php
                    arguments: [-l]

        phpcs:
            description: Runs the PHP Code Sniffer
            calls:
                -
                    type: exec
                    executable: php
                    arguments:
                        - bin/phpcs
                        - --standard=PSR2
                        - --report=full
                        - src/
                -
                    type: exec
                    output: /dev/null
                    append: false
                    executable: php
                    arguments:
                        - bin/phpcs
                        - --standard=PSR2
                        - --report=checkstyle
                        - --report-file=build/logs/checkstyle.xml
                        - src/
        test:
            description: Runs the PHPUnit Tests
            calls:
                -
                    type: exec
                    failOnError: true
                    executable: php
                    arguments:
                        - bin/phpunit
                        - --coverage-html=build/coverage
                        - --coverage-text=php://stdout
        testLocal:
            description: Runs the PHPUnit Tests
            calls:
                -
                    type: exec
                    executable: clear
                -
                    type: exec
                    executable: php
                    arguments:
                        - bin/phpunit
                        - --group=now
        watch:
            description: Watch Task for Local Development
            calls:
                -
                    type: watch
                    src:
                        - { path: [src, tests], files: *.php, recursive: true }
                    task: testLocal

You can see in there that we have a couple of profiles. One for travis which is run by the .travis.yml file inside the same repository and one local that is our TDD flow. The travis profile has a list of tasks defined below under the task keys. The list only comprises a subset of these tasks, namely: prepare, lint, phpcs, and test. Bldr invokes every one of them sequentially preparing by installing composer dependencies, linting our php files, running coding style checks, and finally running the whole test suite for the project.

The output in travis is just beautiful:

Screenshot 2014-04-13 21.34.38

Not only that but the very reason I was using Grunt is totally replaced as with the local profile I can run a much clearer and cleaner on the screen TDD workflow cycle:

Screenshot 2014-04-13 21.39.33

Is just amazing, and a must use. I am removing Grunt from all my projects and replacing them with bldr.io.

It has so much more capabilities and nice architecture to look at.

Screenshot 2014-04-13 21.42.24

Gush is a great project that aims to role model best practices. It also partners with Bldr.io because it makes development simpler.

We are looking into sharing a bldr.yml global configuration that can be served with Gush so to provide shortcuts on Gush flows.

I am thankful to God’s grace for having the opportunity to work on PHP development and to be maintaining a nice tool like Gush, and being able to meet people from the community developing projects such as bldr.io. This I do with great pleasure.
Thanks for reading!

I am also presenting in DrupalCon Austin about Symfony Components here. I gather some help for my trip but i am somewhat of 500$ away to cover for my expenses. If you would like to support me please send your donation to cordoval@gmail.com over paypal. Thank you!

your community friend @cordoval

Deconstructing Symfony: Part I – Getting Rid of Bad Practices Takes Effort

I tried to avoid the bad practice of generating code. So I decided it was enough and created a custom Application.php class on my app/ folder and use that instead inside the console script. Something like this:

#!/usr/bin/env php
<?php
 
set_time_limit(0);
 
require_once __DIR__.'/bootstrap.php.cache';
require_once __DIR__.'/AppKernel.php';
require_once __DIR__.'/Application.php';
 
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
 
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
 
if ($debug) {
    Debug::enable();
}
 
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

The Application.php class basically extends the regular application but overrides this method:

<?php
 
use Symfony\Bundle\FrameworkBundle\Console\Application as BaseApplication;
 
class Application extends BaseApplication
{
    protected function registerCommands()
    {
        $container = $this->getKernel()->getContainer();
 
        if ($container->hasParameter('console.command.ids')) {
            foreach ($container->getParameter('console.command.ids') as $id) {
                $this->add($container->get($id));
            }
        }
 
        $this->addCommands($this->getKernel()->getCommands());
    }
}

The only extra step is to basically register by hand the Commands that you actually:

- care about
- are good commands for your project
- are actually used often
- are safe for your developers
- are within your flow
- are good practices

So the method looks like this:

    public function getCommands()
    {
        $containerAwares = [
            new CacheClearCommand(),
            new DumpCommand(),
            new AssetsInstallCommand(),
            new CacheWarmupCommand(),
            new ConfigDumpReferenceCommand(),
            new ContainerDebugCommand(),
            new RouterDebugCommand(),
            new RouterMatchCommand(),
            new ServerRunCommand(),
            new LintCommand(),
            new CreateDatabaseDoctrineCommand(),
            new DropDatabaseDoctrineCommand(),
            new InfoDoctrineODMCommand(),
            new LoadDataFixturesDoctrineODMCommand(),
            new DebugCommand(),
            new SendEmailCommand(),
        ];
 
        $regularCommands = [
            new UpdateSchemaDoctrineCommand(),
            new UpdateSchemaDoctrineODMCommand(),
            new ClearMetadataCacheDoctrineCommand(),
            new ClearMetadataCacheDoctrineODMCommand(),
            new ClearQueryCacheDoctrineCommand(),
            new ClearResultCacheDoctrineCommand(),
            new EnsureProductionSettingsCommand(),
            new QueryDoctrineODMCommand(),
            new CreateSchemaDoctrineODMCommand(),
            new DropSchemaDoctrineODMCommand(),
            new TailCursorDoctrineODMCommand(),
            new RunDqlDoctrineCommand(),
            new RunSqlDoctrineCommand(),
            new CreateSchemaDoctrineCommand(),
            new DropSchemaDoctrineCommand(),
            new UpdateSchemaDoctrineCommand(),
            new ValidateSchemaCommand(),
        ];
 
        foreach ($containerAwares as $command) {
            $command->setContainer($this->getContainer());
        }
 
        return array_merge($containerAwares, $regularCommands);
    }

You can let go of the commands that are mongodb if you don’t use mongodb. This actually feels faster and I don’t have to worry about generators.

That is it, let the reader understand :)

Encouragements in all good.

@cordoval