Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sunspikes committed Dec 4, 2014
1 parent 62f4392 commit 4c0bb1d
Show file tree
Hide file tree
Showing 14 changed files with 422 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/vendor
composer.phar
composer.lock
.DS_Store
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: php

php:
- 5.4
- 5.5
- 5.6
- hhvm

before_script:
- travis_retry composer self-update
- travis_retry composer install --prefer-source --no-interaction --dev

script: phpunit
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# ClamAV Validator Rules For Laravel 4

Custom Laravel 4 Validator for file upload ClamAV anti-virus check.

**Note:** this package requires [PHP-ClamAV extension](http://php-clamav.sourceforge.net/).

* [Installation](#installation)
* [Usage](#usage)
* [Copyright and License](#copyright)

<a name="installation"></a>
## Installation

Install and configure the PHP ClamAV extension from [Sourceforge](http://php-clamav.sourceforge.net/)

Install the package through [Composer](http://getcomposer.org).

In your `composer.json` file:

```json
{
"require": {
"laravel/framework": ">=4.1.21",
// ...
"sunspikes/clamav-validator": "dev-master"
}
}
```

**Note:** the minimum version of Laravel that's supported is 4.1.21.

Run `composer install` or `composer update` to install the package.

Add the following to your `providers` array in `app/config/app.php`:

```php
'providers' => array(
// ...

'Sunpikes\ClamavValidator\ClamavValidatorServiceProvider',
),
```


<a name="usage"></a>
## Usage

Use it like any `Validator` rule:

```php
$rules = array(
'my_file_field' => 'clamav',
);
```


<a name="copyright"></a>
## Copyright and License

Copyright 2014 Krishnaprasad MG
30 changes: 30 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "sunspikes/clamav-validator",
"description": "Custom Laravel 4 Validator for file upload ClamAV anti-virus check.",
"keywords": ["laravel", "validator", "clamav", "virus"],
"homepage": "https://github.com/sunspikes/clamav-validator",
"license": "MIT",
"authors": [
{
"name": "Krishnaprasad MG",
"email": "sunspikes@gmail.com"
}
],
"require": {
"php": ">=5.4.0",
"ext-clamav": "*",
"illuminate/support": "4.2.*",
"illuminate/validation": ">=4.1.21"
},
"require-dev": {
"phpunit/phpunit": "4.1.*",
"mockery/mockery": "dev-master"
},
"autoload": {
"psr-0": {
"Sunspikes\\ClamavValidator": "src/"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="ClamAV Validator Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
5 changes: 5 additions & 0 deletions provides.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"providers": [
"Sunspikes\\ClamavValidator\\ClamavValidatorServiceProvider"
]
}
67 changes: 67 additions & 0 deletions src/Sunspikes/ClamavValidator/ClamavValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php namespace Sunspikes\ClamavValidator;

use Illuminate\Validation\Validator;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class ClamavValidator extends Validator
{
/**
* ClamAV scan clean staus code
*
* @var integer
*/
const CLAMAV_STATUS_CLEAN = 0;

/**
* Creates a new instance of ClamavValidator
*/
public function __construct($translator, $data, $rules, $messages)
{
parent::__construct($translator, $data, $rules, $messages);
}

/**
* Validate the uploaded file for virus/malware with ClamAV
*
* @param $attribute string
* @param $value mixed
* @param $parameters array
* @return boolean
*/
public function validateClamav($attribute, $value, $parameters)
{
$file = $this->getFilePath($value);

$code = cl_scanfile($file, $virusname);

if ($code !== self::CLAMAV_STATUS_CLEAN)
{
return false;
}

return true;
}

/**
* Return the file path from the passed object
*
* @param $file mixed
* @return string
*/
protected function getFilePath($file)
{
// if were passed an instance of UploadedFile, return the path
if ($file instanceof UploadedFile)
{
return $file->getPathname();
}

// if we're passed a PHP file upload array, return the "tmp_name"
if (is_array($file) && array_get($file, 'tmp_name') !== null) {
return $file['tmp_name'];
}

// fallback: we were likely passed a path already
return $file;
}
}
105 changes: 105 additions & 0 deletions src/Sunspikes/ClamavValidator/ClamavValidatorServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php namespace Sunspikes\ClamavValidator;

use Illuminate\Support\ServiceProvider;

class ClamavValidatorServiceProvider extends ServiceProvider {

/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;

/**
* The list of validator rules.
*
* @var bool
*/
protected $rules = array(
'clamav',
);

/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->package('sunspikes/clamav-validator', 'clamav-validator');

$this->app->bind('Sunspikes\ClamavValidator\ClamavValidator', function($app)
{
$validator = new ClamavValidator($app['translator'], array(), array(), $app['translator']->get('clamav-validator::validation'));

if (isset($app['validation.presence']))
{
$validator->setPresenceVerifier($app['validation.presence']);
}

return $validator;

});

$this->addNewRules();
}

/**
* Get the list of new rules being added to the validator.
*
* @return array
*/
public function getRules()
{
return $this->rules;
}


/**
* Add new rules to the validator.
*/
protected function addNewRules()
{
foreach($this->getRules() as $rule)
{
$this->extendValidator($rule);
}
}


/**
* Extend the validator with new rules.
*
* @param string $rule
* @return void
*/
protected function extendValidator($rule)
{
$method = studly_case($rule);
$translation = $this->app['translator']->get('clamav-validator::validation');
$this->app['validator']->extend($rule, 'Sunspikes\ClamavValidator\ClamavValidator@validate' . $method, $translation[$rule]);
$this->app['validator']->replacer($rule, 'Sunspikes\ClamavValidator\ClamavValidator@replace' . $method);
}


/**
* Register the service provider.
*
* @return void
*/
public function register()
{
}


/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array();
}
}
5 changes: 5 additions & 0 deletions src/Sunspikes/lang/en/validation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return array(
'clamav' => 'Virus detected in file upload.',
);
Empty file added tests/.gitkeep
Empty file.
46 changes: 46 additions & 0 deletions tests/ValidateServiceProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

use Illuminate\Validation\Factory;
use Illuminate\Support\Str;

class ValidateServiceProviderTest extends PHPUnit_Framework_TestCase {

public function testBoot()
{

$translator = Mockery::mock('Symfony\Component\Translation\TranslatorInterface');
$translator->shouldReceive('get');

$presence = Mockery::mock('Illuminate\Validation\PresenceVerifierInterface');

$factory = new Factory($translator);
$factory->setPresenceVerifier($presence);

$container = Mockery::mock('Illuminate\Container\Container');
$container->shouldReceive('bind');
$container->shouldReceive('offsetGet')->with('translator')->andReturn($translator);
$container->shouldReceive('offsetGet')->with('validator')->andReturn($factory);

$sp = Mockery::mock('Sunspikes\ClamavValidator\ClamavValidatorServiceProvider[package]', array($container));
$sp->shouldReceive('package');
$sp->boot();

$validator = $factory->make(array(), array());

foreach ($validator->getExtensions() as $rule => $class_and_method)
{
$this->assertTrue(in_array($rule, $sp->getRules()));
$this->assertEquals('Sunspikes\ClamavValidator\ClamavValidator@' . 'validate' . studly_case($rule), $class_and_method);

list($class, $method) = Str::parseCallback($class_and_method, null);

$this->assertTrue(method_exists($class, $method));
}

}

public function tearDown() {
Mockery::close();
}

}
Loading

0 comments on commit 4c0bb1d

Please sign in to comment.