Recursively delete directories Gau Frette FTP adapter

To with FTP recursively delete files and directories adapter Gau Frette, you can apply following trick to avoid the error message:

ftp_rmdir(): Directory not empty.

1. just delete all files

2. then delete the lowest directories up to the top:

/**
 * @param Filesystem $fileSystem
 */
function deleteAllFilesInDirectory(Filesystem $fileSystem)
{
    // delete files first, than directories
    foreach ($fileSystem->keys() as $key) {
        if (!$fileSystem->isDirectory($key)) {
            $fileSystem->delete($key);
        }
    }
    $keys = $fileSystem->keys();
    usort($keys, function (string $a, string $b){
        $aCount = substr_count($a, '/');
        $bCount = substr_count($b, '/');
        return $bCount <=> $aCount;
    });
    foreach ($keys as $key) {
        $fileSystem->delete($key);
    }
}

Symfony FosUser bundle to apply their own password policy

In the SonataAdmin with FosUser bundle your own rules to define module for the strength of the passwords, can you overwrite the validation.xml, by one in the folder src/application/Sonata/UserBundle/resources/config /. its own validation.XML creates:

<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
        http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="FOS\UserBundle\Model\User">

        <property name="plainPassword">
            <constraint name="NotBlank">
                <option name="message">fos_user.password.blank</option>
                <option name="groups">
                    <value>Registration</value>
                    <value>ResetPassword</value>
                    <value>ChangePassword</value>
                </option>
            </constraint>
            <constraint name="Length">
                <option name="min">8</option>
                <option name="max">50</option>
                <option name="minMessage">fos_user.password.short</option>
                <option name="groups">
                    <value>Registration</value>
                    <value>Profile</value>
                    <value>ResetPassword</value>
                    <value>ChangePassword</value>
                </option>
            </constraint>
            <constraint name="Regex">
                <option name="pattern">/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/</option>
                <option name="message">Das Passwort muss mindestens 8 Zeichen haben, eine Zahl, Groß und Kleinschreibung enthalten.</option>
                <option name="groups">
                    <value>Registration</value>
                    <value>Profile</value>
                    <value>ResetPassword</value>
                    <value>ChangePassword</value>
                </option>
            </constraint>
        </property>
    </class>
</constraint-mapping>

Create symfony brute-force guard for SonataAdmin

For the SonataAdmin bundle There is the possibility of Symofny guards own logic in the login process to incorporate, such as:

  • Defense against brute force attacks by a maximum number of login attempts

In the following example, I have configured a guard for the administration area, It will count, How many times a user incorrectly logged.

The UserManager must then contain the logic, to counting the number of logins for each user, and it formed. also to ban for a period of time. more…

Execute PHP script as a Windows service

Under Windows, scripts can be, that's endless run with PHP using a service implemented.

This has the advantage of, that is the memory consumption with the time to infinity, with endless script versions and a recovery and restart functionality can be implemented, to keep the service over long periods of time running.

Furthermore, the service receives from the operating system events, if e.g.. a shutdown is, to be able to stop in time itself and not corrupt data to produce cancellation in a non-atomic operation.

To create a Windows service, you need the win32service PHP library.

You can here them Download and in the php.ini embed:

extension=php_win32service.dll

Create service more…

PHP cURL verify a self-signed FTPS certificate

Unfortunately, you can with the PHP FTP extension no SSL certificates of FTPS servers to verify, to prevent man-in-the-middle attacks.

But it is possible through PHP-cURL the self-signed certificate to verify:

public function checkFTPSCertificate(): bool
{
    $ftp_certificate = 'path/to/cert.crt'

    $ftp_server = 'ftp://foo.de/';
    $ftp_user = 'user';
    $ftp_password = 'password';

    $ch = curl_init();

    // curl_setopt($ch, CURLOPT_VERBOSE, '1');
    curl_setopt($ch, CURLOPT_URL, $ftp_server);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, $ftp_user . ':' . $ftp_password);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);


    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, '1'); // Überprüfung des Serverzertifikats
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '2');
    curl_setopt($ch, CURLOPT_CAINFO , $ftp_certificate);
    curl_setopt($ch, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);
    curl_setopt($ch, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);

    $result = curl_exec($ch);
    $error_no = curl_errno($ch);
    $error_msg = curl_error($ch);
    curl_close ($ch);
    return $error_no == 0 && empty($error_msg);
}

Working Gau Frette with file streams

To with Gau Frette (Symfony extension) to be able to perform also stream operations on files, can you get the little scrawny documented Stream wrapper use.

This is configured in the gaufrette.yaml:

knp_gaufrette:
    stream_wrapper: ~
    filesystems:
        backup1:
            adapter: backup

And can then be z.B. the following mass is a csv. Write file:

$stream = fopen('gaufrette://backup1/datei.csv', 'w+');

fputcsv($stream, [1,2,3]);

Dynamically configure symfony service ID using parameters

If you like in his Depnedency configuration of injection (services.yml) the service injections make dynamically configurable wants about the parameters.yml,

parameters:
    my_class: 'App\MyClass'

can you do this using the Symfony expression language component do:

composer require symfony/expression-language

Then you can define in the services.yml:

services:
    App\Command\MyCommand:
      arguments:
        - '@=service(parameter("my_class"))'

Windows composer update fatal error: Allowed memory size of 1610612736 bytes exhausted

My composer despite unlimited storage has the following error message:

 composer update
 Loading composer repositories with package information
 Updating dependencies (including require-dev)

 VirtualAlloc() failed: [0x00000008] Zur Verarbeitung dieses Befehls sind nicht gen
 VirtualAlloc() failed: [0x00000008] Zur Verarbeitung dieses Befehls sind nicht gen

 Fatal error: Out of memory (allocated 1260388352) (tried to allocate 201326600 bytes) in phar://C:/ProgramData/ComposerSetup/bin/composer.phar/src/Composer/DependencyResolver/RuleSet.php on line 83

If you can no longer perform a composer update under Windows, Although it has the memory limit to unlimited, then you have a problem:

The Windows Xammp is only as 32 bit system available and RAM can provide only 2 GB at the moment, a further increase is not possible.

The solution is to run composer with a 64-bit PHP on the console (This then has up to 4 GB memory).

  • Download PHP x 64 version
  • unzip it and creating a php.ini (the umbennnen php.ini-development)
  • increase memory limit in php.ini: memory_limit =. -1
  • run on the console:
"C:\php-7.2.12-nts-Win32-VC15-x64\php" C:\ProgramData\ComposerSetup\bin\composer.phar update