Website development tips PHP, PHPUnit, Symfony, Phing and more by Damian Sromek

8Jul/160

Zdjęcia – Ojcowski Park Narodowy

Ojcowski Park Narodowy

Ojcowski Park Narodowy

Filed under: Photos No Comments
30Jun/160

Program do szybkiego wypełniania dokumentów

Kilka lat temu miałem okazję napisać program, który wspomagał prace z dokumentami.

okno główne sprowadzanie samochodu

Na tej stronie można znaleźć program Speedpaq z prosta instrukcją obsługi jak budować swoje formularze i szablony dokumentów.

 

30Oct/150

Where did the 3d sound go?

There was quite a lot of interesting 3D sound technologies a few years ago.

Are there any new?

List of "old school" 3D sound.

Aureal 3D

http://vimeo.com/3843200 http://www.youtube.com/watch?v=bAhH9pKW6N0 http://www.youtube.com/watch?v=v6ng_bGozSo

CMSS-3D

http://ixbtlabs.com/articles2/sound-technology/

Other

http://www.qsound.com/demos/binaural-audio.htm

http://www.qsound.com/demos/virtualbarbershop_long.htm

DEMOS

http://listenwithyourownears.com/3d-audio-demo-showdown/

http://3diosound.com/index.php?main_page=page&id=16&zenid=vc4qc13m5ka7io5ihjqn9gorg0

http://connect.creativelabs.com/openal/OpenAL%20Wiki/OpenAL%C2%AE%20and%20Windows%20Vista%E2%84%A2.aspx

http://connect.creativelabs.com/alchemy/Lists/Games/AllItems.aspx

http://en.wikipedia.org/wiki/List_of_games_with_EAX_support

http://www.creative.com/soundblaster/technology/eax_advanced_hd/

http://www.creative.com/soundblaster/technology/welcome_flash.asp?j1=eax

Tagged as: No Comments
7Oct/150

“SCRUM czyli jak robić dwa razy więcej dwa razy szybciej” – krótka recenzja

Scrum, czy też ogólnie Agile, są ostatnio bardzo modne w świecie IT. Te metody pracy obiecują szybsze osiągnięcie celu a co za tym idzie zmniejszenie kosztów i wyprzedzenie konkurencji.

Jeff Sutterland (autor książki) wraz z Kenem Schwaberem zdefiniował Scrum już ponad 20 lat temu. Dokładnie w roku 1993. Od tamtego czasu metoda systematycznie zyskuje na popularności, wypierając głównie podejście kaskadowe (Waterfall).

Książka “SCRUM czyli jak robić dwa razy więcej dwa razy szybciej” napisana przez jednego z dwóch twórców tytułowej metodyki jest godna polecenia z kilku względów. Chociaż niektóre, zwłaszcza mocno techniczne osoby może zniechęcić jej “miękkie” podejście do tematu.

“SCRUM czyli jak robić dwa razy więcej dwa razy szybciej” jest swego rodzaju ewangelią. Jeff Sutterland przy pomocy ciekawych ale mało technicznych opowieści stara się uświadomić jakie główne idee stoją za Scrumem.
Książkę czyta się niczym powieść. Czytałem ją z przyjemnością i zaciekawieniem. Strona po stronie rozjaśnia ona fundamentalne wartości, którymi należy kierować się w pracy i w życiu aby osiągnąć sukces.

Osoby, które chciałyby konkretów “Co? Jak? Kiedy? Dlaczego? Jak często?” mogą uznać tę książkę za praktycznie bezwartościową.
Ta książka opisuje głównie filozofię Scruma a nie algorytm postępowania.

Jestem osobą, która przeczytała kilka książek o Scrumie, Agile itp. Mam nawet certyfikat Scrum Mastera. Mogę śmiało polecić tę książkę każdemu, kto złapał “Scrumowego bakcyla”. Pozwala ona bowiem przypomnieć sobie jak ważne są fundamenty tej metody a nie szczegóły jej wdrażania.
Po jej przeczytaniu każdy powinien dużo lepiej zrozumieć Agile Manifesto.

Książkę śmiało można polecić również komuś spoza branży IT, ponieważ Scrum może świetnie sprawdzić się również poza informatyką - nawet w życiu prywatnym.

Filed under: Uncategorized No Comments
29Sep/15Off

How to test Doctrine Migrations?

I'm working on a project that does NOT have a copy of production DB on development environment.
Sometimes we have an issue with DB migrations - they pass on dev DB but fail in production/testing.
It's often beacuse Dev environent data is loaded from Fixtures that use the latest entities - filling all tables properly.

Is there any easy way to make sure Doctrine Migration(s) will pass in production?
Do you have/know any way to write an automatic tests that will make sure data will be migrated properly without downloading the production/testing DB and running the migration manually?
I would like to avoid downloading a production/testing DB to dev machine so I can check migrations becasue that DB contains private data and it can be quite big.

I've found quite simple solution for that. I've figured out simple "smoke tests" for Doctrine Migrations.

I have PHPUnit tests perfoming following steps:

  1. Drop test DB
  2. Create test DB
  3. Load migrations (create schema)
  4. Load fixtures (imitate production data)
  5. Migrate to some older version
  6. Migrate back to the latest version

Below you can find a PHPUnit test doing that.

<?php namespace AppBundle\Tests\PHPUnit\Acceptance\Nonfunctional; 

use Symfony\Component\Process\Process; 
/** 
 * It should be possible to setup the database from the very beginning. 
 * Loading fixtures should also work. 
 */ 
class DatabaseSetupTest extends \PHPUnit_Framework_TestCase 
{ 
    public static function setupTheLatestDb() 
    { 
        $command = APP_CONSOLE_PATH . " --env=test doctrine:database:drop --force --if-exists --no-interaction"; $process = new Process($command); $process->run();
        if (!$process->isSuccessful()) {
            throw new \RuntimeException('Could not drop test Database ' . $process->getOutput() . $process->getErrorOutput());
        }

        $command = APP_CONSOLE_PATH . " --env=test doctrine:database:create --if-not-exists";
        $process = new Process($command);
        $process->run();
        if (!$process->isSuccessful()) {
            throw new \RuntimeException('Could not create test Database ' . $process->getOutput() . $process->getErrorOutput());
        }

        $command = APP_CONSOLE_PATH . " --env=test doctrine:migrations:migrate --no-interaction";
        $process = new Process($command);
        $process->run();
        if (!$process->isSuccessful()) {
            throw new \RuntimeException('Could not create test Database ' . $process->getOutput() . $process->getErrorOutput());
        }
    }

    public static function loadFixtures()
    {
        $command = APP_CONSOLE_PATH
            . ' --env=test --no-interaction doctrine:fixtures:load'
            . ' --fixtures=' . DB_FIXTURES_DIR . '/Production'
            . ' --fixtures=' . DB_FIXTURES_DIR . '/Dummy';
        $process = new Process($command);
        $process->run();

        if (!$process->isSuccessful()) {
            throw new \RuntimeException('Could not load Database fixtures. ' . $process->getOutput() . $process->getErrorOutput());
        }
    }

    public function testDatabaseSetup()
    {
        $caughtException = null;
        $exceptionMessage = '';
        try {
            self::setupTheLatestDb();
        } catch (\RuntimeException $rex) {
            $caughtException = $rex;
            $exceptionMessage = $rex->getMessage();
        }

        $this->assertNull($caughtException, 'Database setup should success. Got an exception: ' . $exceptionMessage);
    }

    public function testLoadFixtures()
    {
        $caughtException = null;
        $exceptionMessage = '';
        try {
            self::loadFixtures();
        } catch (\RuntimeException $rex) {
            $caughtException = $rex;
            $exceptionMessage = $rex->getMessage();
        }

        $this->assertNull($caughtException, 'Database fixtures loading should success. Got an exception: ' . $exceptionMessage);
    }
}
<?php 
namespace AppBundle\Tests\PHPUnit\Acceptance\Nonfunctional; 

use Symfony\Component\Process\Process; 

class DatabaseMigrationsTest extends \PHPUnit_Framework_TestCase 
{ 
    // picking a version we want to test the downgrade/upgrade to/from 
    private $downgradeToVersion = '20150928145744'; 

    public static function setUpBeforeClass() 
    { 
        /** 
         * Note: If you have any issues with this please make sure DatabaseSetupTest tests are passing 
         */ 
        DatabaseSetupTest::setupTheLatestDb(); 
        DatabaseSetupTest::loadFixtures(); 
    } 

    public static function tearDownAfterClass() 
    { 
        /** 
          * Note: If you have any issues with this please make sure DatabaseSetupTest tests are passing 
         */ 
        DatabaseSetupTest::setupTheLatestDb(); 
    } 
 
    public function testDowngrade() 
    { 
        $process = $this->migrate($this->downgradeToVersion);

        $this->assertTrue(
            $process->isSuccessful(),
            'Migration (downgrade) should succeed. ' . $process->getOutput() . $process->getErrorOutput()
        );
        $this->assertContains(
            'reverted (',
            $process->getOutput(),
            'Migration output should confirm success. ' . $process->getOutput() . $process->getErrorOutput()
        );
        $this->assertContains(
            'migrations executed',
            $process->getOutput(),
            'Migration output should confirm success. ' . $process->getOutput() . $process->getErrorOutput()
        );
    }

    /**
     * @depends testDowngrade
     */
    public function testUpgrade()
    {
        $this->migrate($this->downgradeToVersion);

        $process = $this->migrate();

        $this->assertTrue(
            $process->isSuccessful(),
            'Migration to the latest version should succeed. [' . $process->getOutput() . $process->getErrorOutput() .']'
        );
        $this->assertNotRegExp(
            '/Migration \d failed during Execution/',
            $process->getOutput(),
            'Migration to the latest version should succeed. ' . $process->getOutput() . $process->getErrorOutput()
        );
        $this->assertContains(
            'migrations executed',
            $process->getOutput(),
            'Migration output should confirm success. ' . $process->getOutput() . $process->getErrorOutput()
        );
    }

    private function migrate($version = '')
    {
        $command = APP_CONSOLE_PATH . " --env=test --no-interaction doctrine:migrations:migrate {$version}";
        $process = new Process($command);
        $process->run();

        return $process;
    }
}
22Sep/150

Test if Doctrine mapping is correct in Symfony project

Here's an example of test that will inform you when you've created wrong Doctrine mapping

public function testNoErrorsReportedByProfiler()
{
    $client = static::createClient();

    // Enable the profiler for the next request
    // (it does nothing if the profiler is not available)
    $client->enableProfiler();

    $crawler = $client->request('GET', '/');

    $profile = $client->getProfile();
    /* @var \Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector */
    $dbCollector = $profile->getCollector('db');
    $dbData = unserialize($dbCollector->serialize());

    $this->assertCount(0, $dbData['errors'], 'Profiler should not report any DB errors. Got: ' . print_r($dbData['errors'], true));
}
18Jun/150

Behat / Mink “I see dead people” (“I should see”)

If you're using MinkContex in your Behat tests be aware that it's "I should see <text>" looks for given <text> in the whole HTML code.

This means that if your HTML contains "foobar" in <head> section, Behat will mark this step as successful.

If you want to look for a string in <body> you can use I should see "foobar" in the "body *" element

Tagged as: , , No Comments
28Apr/150

Weemto.com

Zapraszam wszystkich do spróbowania quizu www.Weemto.com

Udanej zabawy! 🙂

Tagged as: , No Comments
10Apr/150

Symfony app_dev.php available in Production but protected

Simple trick to not limit your self by disabling app_dev.php in Production

You could allow app_dev.php being used when request contains proper "password", eg. in GET or Cookie

In following example user will get access to app_dev.php if he/she provides "my_secret_param_for_app_dev" with value "passsss"

// app_dev.php

<?php
/**
 * Checks if requester can use app_dev.php
 *
 * Access to app_dev.php is given if
 * - it's a request from local machine
 * OR
 * - GET or COOKIE contains $parameter with proper $token
 *
 * Once access is given COOKIE with given/valid $parameter and $token is set so next requests do not require passing it in GET
 */
function checkAppDevAccess($parameter, $token)
{
    if (
        (isset($_GET[$parameter]) && $_GET[$parameter] === $token)
        || (isset($_COOKIE[$parameter]) && $_COOKIE[$parameter])
        || (
            !isset($_SERVER['HTTP_CLIENT_IP'])
            && !isset($_SERVER['HTTP_X_FORWARDED_FOR'])
            && (in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) && php_sapi_name() !== 'cli-server')
        )
    ) {
        setcookie($parameter, $token, time() + 3600);
} else {
        header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
}

checkAppDevAccess('my_secret_param_for_app_dev', 'passsss');

// ...
// $loader = require_once __DIR__.'/../app/bootstrap.php.cache';


Tagged as: , , No Comments
17Sep/140

Szkolenie z podstaw PHP

Serdecznie zapraszam na szkolenie z podstaw PHP

Link do szkolenia

Filed under: PHP No Comments