Declaration of passes(string $attribute, $value): bool must be compatible with Illuminate\Contracts\Validation\Rule::passes($attribute, $value) - laravel

I have created a custom validation rule
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Exception;
class ValidFoo implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes(string $attribute, $value): bool
{
if (!$foo) {
return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message(): string
{
return 'The foo you \'ve provided is not valid.';
}
}
However when I try to submit the form I get this error
Symfony\Component\Debug\Exception\FatalErrorException (E_UNKNOWN)
Declaration of App\Rules\ValidFoo::passes(string $attribute, $value): bool must be compatible with Illuminate\Contracts\Validation\Rule::passes($attribute, $value)
This is Laravel's Rule interface
namespace Illuminate\Contracts\Validation;
interface Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value);
/**
* Get the validation error message.
*
* #return string
*/
public function message();
}

namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Exception;
class ValidFoo implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if (!$foo) {
return false;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message(): string
{
return 'The foo you \'ve provided is not valid.';
}
}
This is a corrected class. Error occurse because you use type hit, but interface does not used type hint

Related

Laravel validator required specific word

I need to validate a string must contains a specific word in the controller.
Something Like this ("%name%" is necessary):
$request->validate([
'pattern' => ['required', 'must_contains:%name%'],
]);
You can create a Custom Rule. To create the custome rule you can do:
php artisan make:rule StrMustContain
Setup class like so:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class StrMustContain implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return str_contains('Magic Phrase', $value);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The expected pattern does not match.';
}
}
Then you can use like:
$request->validate([
'pattern' => ['required', new StrMustContain],
]);
I created a custom validation using this command:
php artisan make:rule StrMustContain
And then changed the class like this:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class StrMustContain implements Rule
{
public $str;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct($str)
{
$this->str = $str;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return str_contains($value, $this->str);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The phrase '.$this->str.' is required.';
}
}
Then I used that:
$request->validate([
'pattern' => ['required', new StrMustContain('%name%')],
]);

How to write preg_match for english and french charaters?

This is my LangRule file
<?php
namespace Modules\Newsletter\Rules;
use Illuminate\Contracts\Validation\Rule;
class LangRule implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return preg_match("/[^a-zA-ZÀ-ÿ.\-'_]*$/",$value);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'Please select either English or French as your input language';
}
}
I want to match English,French and .'-_ from input.
My preg_match is not taking French characters.
Can anyone help how I can do that. Help will be highly appreciated.
You could use unicode properties:
preg_match("/^[a-zA-ZàâäèéêëîïôœùûüÿçÀÂÄÈÉÊËÎÏÔŒÙÛÜŸÇ]+$/", $string);

Laravel - Good practice to put query in custom request?

I use a custom query, and I add a custom rule to it too, and I wanted to know if putting eloquent queries in the rule is a "good practice"?
For me it's pretty dirty, but I don't really see how else to do it, and I haven't found any answers...
I have to make in the rule, parameters...
Edit (add code)
<?php
namespace App\Rules;
use App\Model\Laravel\Api;
use App\Model\Laravel\Package;
use App\Model\Laravel\User;
use Illuminate\Contracts\Validation\Rule;
class ApiMax implements Rule
{
protected $user;
/**
* Create a new rule instance.
*
* #param $user
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$maxApi = $this->getPackageInfo($this->user)->max_api - $this->sumApis($this->user);
if($value > $maxApi)
return false;
return true;
}
public function getPackageInfo(User $user)
{
return Package::where('id', $user->getPackageId())->first();
}
public function sumApis(User $user) {
return Api::where('user_id', $user->getId())->count();
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'You have reached the maximum number of apis with your current offer.';
}
}
Thank you in advance for your tips

Laravel Lighthouse - Receive Eloquent Builder instead of Query Builder in handleBuilder method?

Is there a way to receive an instance of \Illuminate\Database\Eloquent\Builder instead of \Illuminate\Database\Query\Builder in the handleBuilder method when creating a custom ArgBuilderDirective?
See this example:
<?php
namespace Nuwave\Lighthouse\Schema\Directives;
use Nuwave\Lighthouse\Support\Contracts\ArgBuilderDirective;
use Nuwave\Lighthouse\Support\Contracts\DefinedDirective;
class EqDirective extends BaseDirective implements ArgBuilderDirective, DefinedDirective
{
/**
* Name of the directive.
*
* #return string
*/
public function name(): string
{
return 'eq';
}
/**
* Apply a "WHERE = $value" clause.
*
* #param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $builder
* #param mixed $value
* #return \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
*/
public function handleBuilder($builder, $value)
{
// $builder is an instance of \Illuminate\Database\Query\Builder here.
// Is it possible to receive an instance of Illuminate\Database\Eloquent\Builder instead?
return $builder->where(
$this->directiveArgValue('key', $this->nodeName()),
$value
);
}
}

What is the best way for reusable values throughout the application in Symfony 3?

I want to have a file or list that I can update easily with values that might change throughout my application.
I don't really want to hard code text values into the templates. I prefer to have all of these values in one place and labelled correctly.
Examples of values that might get updated are:
Page title
Logo text
Brand or company name
I have thought about two options:
Add them to the twig config in config.yml. This is a bit messy and doesn't seem organised if I decide to put a lot of values there.
Make a database table for these and include the entity in each controller where I need to use the values. This might be creating too much work.
Are there any other options or are one of these more suitable?
Thank you.
You need to create a twig function and use it to return the value you want. For example:
namespace AppBundle\Twig;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class TwigExtension extends \Twig_Extension implements ContainerAwareInterface
{
use ContainerAwareTrait;
/**
* #var ContainerInterface
*/
protected $container;
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('parameter', function($name)
{
try {
return $this->container->getParameter($name);
} catch(\Exception $exception) {
return "";
}
})
);
}
/**
* Returns the name of the extension.
*
* #return string The extension name
*/
public function getName()
{
return 'app.twig.extension';
}
}
This will create a function called parameter and once you call it in twig {{ parameter('my.parameter') }} it will return the parameter. You need to load it as a service, which you can do by adding the following to your services.yml file:
app.twig.extension:
class: AppBundle\Twig\TwigExtension
calls:
- [setContainer, ["#service_container"]]
tags:
- { name: twig.extension }
From personal experience people usually want to be able to change some of the parameters. This is why I usually prefer to create a Setting or Parameter entity which would look something like this:
/**
* Setting
*
* #ORM\Table(name="my_parameters")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ParameterRepository")
*/
class Parameter
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(name="parameter_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="value", type="text", nullable=true)
*/
private $value;
/**
* #param string|null $name
* #param string|null $value
*/
public function __construct($name = null, $value = null)
{
$this->setName($name);
$this->setValue($value);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Parameter
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set value
*
* #param string $value
*
* #return Parameter
*/
public function setValue($value = null)
{
$this->value = serialize($value);
return $this;
}
/**
* Get value
*
* #return string
*/
public function getValue()
{
$data = #unserialize($this->value);
return $this->value === 'b:0;' || $data !== false ? $this->value = $data : null;
}
}
Then I would add a CompilerPass which will help get all of the parameters from the database and cache them so that your app doesn't make unnecessary sql queries to the database. That might look something similar to the following class:
// AppBundle/DependencyInjection/Compiler/ParamsCompilerPass.php
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParamsCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$settings = $em->getRepository('AppBundle:Parameter')->findAll();
foreach($settings as $setting) {
// I like to prefix the parameters with "app."
// to avoid any collision with existing parameters.
$container->setParameter('app.'.strtolower($setting->getName()), $setting->getValue());
}
}
}
And finally, in your bundle class (i.e. src/AppBundle/AppBundle.php) you add the compiler pass:
namespace AppBundle;
use AppBundle\DependencyInjection\Compiler\ParamsCompilerPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $builder)
{
parent::build($builder);
$builder->addCompilerPass(new ParamsCompilerPass(), , PassConfig::TYPE_AFTER_REMOVING);
}
}
Now you can create a DoctrineFixture template to load the parameters you use all the time. With the TwigExtension you will still be able to call the parameter from the twig template and you can create a web UI to change some of the parameters/settings.

Resources