src/php/Arbit/Periodic/Command/FileSystem/Remove.php
protected function removeRecursive( $path, $pattern, Logger $logger )
    {
        // Check if source file exists at all.
        if ( !is_file( $path ) && !is_dir( $path ) )
        {
            $logger->log( "$path is not a valid source.", Logger::WARNING );
            return;
        }

        // Skip non readable files in src directory
        if ( !is_readable( $path ) )
        {
            $logger->log( "$path is not readable, skipping.", Logger::WARNING );
            return;
        }

        // Skip non writeable parent directories
        if ( !is_writeable( $parent = dirname( $path ) ) )
        {
            $logger->log( "$parent is not writable, skipping.", Logger::WARNING );
            return;
        }

        $matchesPattern = (
            ( $pattern === null ) ||
            ( preg_match( $pattern, basename( $path ) ) )
        );

        // Handle files
        if ( is_file( $path ) )
        {
            if ( $matchesPattern )
            {
                unlink( $path );
            }
            return;
        }

        // Handle directory contents
        $dh = opendir( $path );
        while ( ( $file = readdir( $dh ) ) !== false )
        {
            if ( ( $file === '.' ) ||
                ( $file === '..' ) )
            {
                continue;
            }

            $this->removeRecursive(
                $path . '/' . $file,
                ( $matchesPattern ? null : $pattern ),
                $logger
            );
        }

        if ( $matchesPattern )
        {
            rmdir( $path );
        }
    }
protected function removeRecursive( $path, $pattern, Logger $logger )
    {
        // Check if source file exists at all.
        if ( !is_file( $path ) && !is_dir( $path ) )
        {
            $logger->log( "$path is not a valid source.", Logger::WARNING );
            return;
        }

        // Skip non readable files in src directory
        if ( !is_readable( $path ) )
        {
            $logger->log( "$path is not readable, skipping.", Logger::WARNING );
            return;
        }

        // Skip non writeable parent directories
        if ( !is_writeable( $parent = dirname( $path ) ) )
        {
            $logger->log( "$parent is not writable, skipping.", Logger::WARNING );
            return;
        }

        $matchesPattern = (
            ( $pattern === null ) ||
            ( preg_match( $pattern, basename( $path ) ) )
        );

        // Handle files
        if ( is_file( $path ) )
        {
            if ( $matchesPattern )
            {
                unlink( $path );
            }
            return;
        }

        // Handle directory contents
        $dh = opendir( $path );
        while ( ( $file = readdir( $dh ) ) !== false )
        {
            if ( ( $file === '.' ) ||
                ( $file === '..' ) )
            {
                continue;
            }

            $this->removeRecursive(
                $path . '/' . $file,
                ( $matchesPattern ? null : $pattern ),
                $logger
            );
        }

        if ( $matchesPattern )
        {
            rmdir( $path );
        }
    }
Remove files and directories recursively

Remove files and directories recursively. I one operation fails, a
warning will be issued and the operation will be continued.

You may optionally specify a pattern and only files and directories
matching that pattern will be removed. If a directory matches the
pattern all descendents will also be removed.

@param string $path
@param mixed $pattern
@param Logger $logger
@return void