Skip to content

Commit b970e8a

Browse files
committed
Add files
1 parent 40bc474 commit b970e8a

File tree

5 files changed

+392
-0
lines changed

5 files changed

+392
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/.idea
2+
/vendor
3+
composer.phar
4+
composer.lock
5+
.DS_Store

composer.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "idma/parsley-laravel",
3+
"description": "Converts Eloquent rules to Parsley rules",
4+
"keywords": ["laravel", "parsley", "html", "form"],
5+
"authors": [
6+
{
7+
"name": "idma",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {
12+
"php": ">=5.4.0",
13+
"illuminate/support": "~5.0",
14+
"illuminate/html": "~5.0",
15+
"illuminate/translation" : "~5.0"
16+
},
17+
"autoload": {
18+
"psr-0": {
19+
"Idma\\ParsleyLaravel": "src/"
20+
}
21+
},
22+
"config": {
23+
"preferred-install": "dist"
24+
},
25+
"minimum-stability": "dev"
26+
}
+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
namespace Idma\LaravelParsley;
4+
5+
use Illuminate\Html\FormBuilder as BaseFormBuilder;
6+
7+
class FormBuilder extends BaseFormBuilder {
8+
/**
9+
* @type \Illuminate\Database\Eloquent\Model
10+
*/
11+
protected $model;
12+
protected $modelName = null;
13+
14+
/**
15+
* @type Parsley
16+
*/
17+
protected $parsley = null;
18+
protected $validationRules = [];
19+
protected $customAttributes = [];
20+
21+
public static $abc = 1;
22+
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
public function open(array $options = []) {
27+
if ($this->model && !isset($options['method'])) {
28+
$options['method'] = $this->model->getAttribute('id') ? 'put' : 'post';
29+
}
30+
31+
$method = strtoupper(array_get($options, 'method', 'post'));
32+
33+
// We need to extract the proper method from the attributes. If the method is
34+
// something other than GET or POST we'll use POST since we will spoof the
35+
// actual method since forms don't support the reserved methods in HTML.
36+
$attributes['method'] = $this->getMethod($method);
37+
38+
$attributes['action'] = $this->getAction($options);
39+
40+
$attributes['accept-charset'] = 'UTF-8';
41+
42+
// If the method is PUT, PATCH or DELETE we will need to add a spoofer hidden
43+
// field that will instruct the Symfony request to pretend the method is a
44+
// different method than it actually is, for convenience from the forms.
45+
$append = $this->getAppendage($method);
46+
47+
if (isset($options['files']) && $options['files']) {
48+
$options['enctype'] = 'multipart/form-data';
49+
}
50+
51+
// Finally we're ready to create the final form HTML field. We will attribute
52+
// format the array of attributes. We will also add on the appendage which
53+
// is used to spoof requests for this PUT, PATCH, etc. methods on forms.
54+
$attributes = array_merge($attributes, array_except($options, $this->reserved));
55+
56+
// Finally, we will concatenate all of the attributes into a single string so
57+
// we can build out the final form open statement. We'll also append on an
58+
// extra value for the hidden _method field if it's needed for the form.
59+
$attributes = $this->html->attributes($attributes);
60+
61+
return '<form'.$attributes.'>'.$append;
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public function model($model, array $options = []) {
68+
$this->setModel($model);
69+
70+
return $this->open($options);
71+
}
72+
73+
public function openModel($model, array $options = []) {
74+
return $this->model($model, $options);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
public function label($name, $value = null, $options = []) {
81+
$this->labels[] = $name;
82+
83+
$options = $this->html->attributes($options);
84+
85+
$value = e($this->formatLabel($name, $value));
86+
87+
$for = ($this->modelName && !starts_with($name, '_')) ? $this->modelName.'-'.$name : $name;
88+
89+
return '<label for="'.$for.'"'.$options.'>'.$value.'</label>';
90+
}
91+
92+
public function helpBlock($value, array $options = []) {
93+
if (isset($options['class'])) {
94+
$options['class'] = 'help-block '.$options['class'];
95+
} else {
96+
$options['class'] = 'help-block';
97+
}
98+
99+
return '<span'.$this->html->attributes($options).'>'.$value.'</span>';
100+
}
101+
102+
public function input($type, $name, $value = null, $options = [])
103+
{
104+
$options = array_merge($options, $this->createParsleyRulesForField($name));
105+
return parent::input($type, $name, $value, $options);
106+
}
107+
108+
/**
109+
* @param $name
110+
*
111+
* @return array
112+
*/
113+
protected function createParsleyRulesForField($name) {
114+
if (isset($this->validationRules[$name]) && !starts_with($name, '_')) {
115+
$rules = explode('|', $this->validationRules[$name]);
116+
$parsleyRules = [];
117+
118+
$parsleyRules = array_merge($parsleyRules, $this->parsley->convertRules($name, $rules, $this->customAttributes));
119+
120+
return $parsleyRules;
121+
}
122+
123+
return [];
124+
}
125+
126+
/**
127+
* {@inheritdoc}
128+
*/
129+
// public function getIdAttribute($name, $attributes) {
130+
// $id = null;
131+
//
132+
// if (array_key_exists('id', $attributes)) {
133+
// $id = $attributes['id'];
134+
// } else {
135+
// $id = $name;
136+
// }
137+
//
138+
// if ($this->modelName && $id && !starts_with($id, '_')) {
139+
// return $this->modelName.'-'.$id;
140+
// }
141+
//
142+
// return null;
143+
// }
144+
145+
public function setModel($model) {
146+
$this->model = $model;
147+
$this->modelName = strtolower((new \ReflectionClass($this->model))->getShortName());
148+
149+
if (method_exists($this->model, 'getParsleyRules')) {
150+
$this->validationRules = $this->model->getParsleyRules();
151+
152+
if (property_exists($this->model, 'getParsleyCustomAttributes')) {
153+
$_model = $this->model;
154+
$this->customAttributes = $_model::$customAttributes;
155+
}
156+
157+
$this->parsley = new Parsley($this->customAttributes);
158+
}
159+
}
160+
161+
/**
162+
* Gets the short model name.
163+
*
164+
* @return string
165+
*/
166+
public function getModelName() {
167+
return $this->modelName;
168+
}
169+
170+
public function name() {
171+
return $this->getModelName();
172+
}
173+
}

src/Idma/ParsleyLaravel/Parsley.php

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace Idma\LaravelParsley;
4+
5+
use Illuminate\Translation\Translator;
6+
7+
class Parsley {
8+
/**
9+
* @type Translator
10+
*/
11+
protected $translator = null;
12+
protected $customAttributes = [];
13+
14+
public function __construct(array $customAttributes = [])
15+
{
16+
$this->customAttributes = $customAttributes;
17+
$this->translator = app()['translator'];
18+
}
19+
20+
public function convertRules($attribute, $rules)
21+
{
22+
$attrs = [];
23+
$message = null;
24+
25+
foreach ($rules as $rule) {
26+
list($rule, $params) = explode(':', $rule . ':');
27+
28+
$params = explode(',', str_replace(' ', '', $params));
29+
30+
$parsleyRule = $rule;
31+
32+
$isNumeric = $this->isNumericRule($rule);
33+
$message = $this->getMessage($attribute, $rule);
34+
35+
switch ($rule) {
36+
case 'required':
37+
case 'email':
38+
break;
39+
40+
case 'min':
41+
if (!$isNumeric) {
42+
$parsleyRule = 'minlength';
43+
}
44+
45+
$message = str_replace(':min', $params[0], $message);
46+
break;
47+
48+
case 'max':
49+
if (!$isNumeric) {
50+
$parsleyRule = 'maxlength';
51+
}
52+
53+
$message = str_replace(':max', $params[0], $message);
54+
break;
55+
56+
case 'between':
57+
$parsleyRule = 'length';
58+
$params = str_replace([':min', ':max'], $params, '[:min,:max]');
59+
$message = str_replace([':min', ':max'], $params, $message);
60+
break;
61+
62+
case 'alpha_num':
63+
$parsleyRule = 'alphanum';
64+
$params = '/^\d[a-zа-яё\-\_]+$/i';
65+
break;
66+
67+
case 'alpha_dash':
68+
$parsleyRule = 'pattern';
69+
$params = '/^\d[a-zа-яё\-\_]+$/i';
70+
break;
71+
72+
case 'alpha':
73+
$parsleyRule = 'pattern';
74+
$params = '/^[a-zа-яё]+$/i';
75+
break;
76+
77+
case 'regex':
78+
$parsleyRule = 'pattern';
79+
break;
80+
81+
case 'confirmed':
82+
$parsleyRule = 'equalto';
83+
$params = "#{$attribute}_confirmation";
84+
break;
85+
86+
default:
87+
$message = null;
88+
}
89+
90+
if ($message) {
91+
if (is_array($params) && count($params) == 1) {
92+
$params = $params[0];
93+
}
94+
95+
$attrs['data-parsley-' . $parsleyRule] = $params;
96+
$attrs['data-parsley-' . $parsleyRule . '-message'] = str_replace(':attribute', $this->getAttribute($attribute), $message);
97+
}
98+
99+
$message = null;
100+
}
101+
102+
return $attrs;
103+
}
104+
105+
protected function getMessage($attribute, $rule)
106+
{
107+
$lowerRule = snake_case($rule);
108+
$customKey = "validation.custom.{$attribute}.{$lowerRule}";
109+
110+
$customMessage = $this->translator->trans($customKey);
111+
112+
if ($customMessage !== $customKey) {
113+
return $customMessage;
114+
} else if (in_array($rule, ['size', 'between', 'min', 'max'])) {
115+
if ($this->isNumericRule($rule)) {
116+
$key = "validation.{$lowerRule}.numeric";
117+
} else {
118+
$key = "validation.{$lowerRule}.string";
119+
}
120+
121+
return $this->translator->trans($key);
122+
}
123+
124+
$key = "validation.{$lowerRule}";
125+
126+
if ($key != ($value = $this->translator->trans($key))) {
127+
return $value;
128+
}
129+
130+
return '';
131+
}
132+
133+
/**
134+
* Get the displayable name of the attribute.
135+
*
136+
* @param string $attribute
137+
* @return string
138+
*/
139+
protected function getAttribute($attribute)
140+
{
141+
if (isset($this->customAttributes[$attribute])) {
142+
return $this->customAttributes[$attribute];
143+
}
144+
145+
$key = "validation.attributes.{$attribute}";
146+
147+
if (($line = $this->translator->trans($key)) !== $key) {
148+
return $line;
149+
} else {
150+
return str_replace('_', ' ', snake_case($attribute));
151+
}
152+
}
153+
154+
protected function isNumericRule($rule) {
155+
return in_array(ucfirst($rule), ['Integer', 'Numeric']);
156+
}
157+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Idma\LaravelParsley;
4+
5+
use Illuminate\Html\HtmlServiceProvider;
6+
7+
class ParsleyLaravelServiceProvider extends HtmlServiceProvider
8+
{
9+
/**
10+
* {@inheritdoc}
11+
*/
12+
public function register()
13+
{
14+
$this->package('idma/parsley-laravel');
15+
16+
parent::register();
17+
}
18+
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
protected function registerFormBuilder()
23+
{
24+
$this->app->bindShared('form', function($app)
25+
{
26+
$form = new FormBuilder($app['html'], $app['url'], $app['session.store']->getToken());
27+
28+
return $form->setSessionStore($app['session.store']);
29+
});
30+
}
31+
}

0 commit comments

Comments
 (0)