14 use Illuminate\Container\Container;
15 use Illuminate\Filesystem\Filesystem;
16 use Illuminate\Translation\FileLoader;
17 use Illuminate\Translation\Translator;
18 use Illuminate\Validation\DatabasePresenceVerifier;
19 use Illuminate\Validation\Factory;
22 import(
'lib.pkp.classes.services.interfaces.EntityWriteInterface');
38 static public function make($props, $rules, $messages = []) {
43 $loader =
new FileLoader(
new Filesystem,
'lang');
44 $translator =
new Translator($loader,
'en');
45 $validation =
new Factory($translator,
new Container);
50 $validation->extend(
'email_or_localhost',
function($attribute, $value, $parameters, $validator) use ($validation) {
51 $emailValidator = $validation->make(
55 if ($emailValidator->passes()) {
58 $regexValidator = $validation->make(
60 [
'value' => [
'regex:/^[-a-zA-Z0-9!#\$%&\'\*\+\.\/=\?\^_\`\{\|\}~]*(@localhost)$/']]
62 if ($regexValidator->passes()) {
70 $validation->extend(
'issn',
function($attribute, $value, $parameters, $validator) use ($validation) {
71 $regexValidator = $validation->make([
'value' => $value], [
'value' =>
'regex:/^(\d{4})-(\d{3}[\dX])$/']);
72 if ($regexValidator->fails()) {
76 $numbers = str_replace(
'-',
'', $value);
78 for ($i = 0; $i < 7; $i++) {
79 $check += $numbers[$i] * (8 - $i);
90 $check = (string) (11 - $check);
93 return ($numbers[7] === $check);
97 $validation->extend(
'orcid',
function($attribute, $value, $parameters, $validator) use ($validation) {
98 $orcidRegexValidator = $validation->make(
100 [
'value' =>
'regex:/^http[s]?:\/\/orcid.org\/(\d{4})-(\d{4})-(\d{4})-(\d{3}[0-9X])$/']
102 if ($orcidRegexValidator->fails()) {
106 $digits = preg_replace(
"/[^0-9X]/",
"", $value);
109 for ($i = 0; $i < 15; $i++) {
110 $total = ($total + $digits[$i]) * 2;
113 $remainder = $total % 11;
114 $result = (12 - $remainder) % 11;
116 return ($digits[15] == ($result == 10 ?
'X' : $result));
120 $validation->extend(
'currency',
function($attribute, $value, $parameters, $validator) {
121 $isoCodes = new \Sokil\IsoCodes\IsoCodesFactory();
122 $currency = $isoCodes->getCurrencies()->getByLetterCode($value);
123 return isset($currency);
140 static $defaultMessages = [];
142 if (empty($defaultMessages)) {
144 'accepted' => __(
'validator.accepted'),
145 'active_url' => __(
'validator.active_url'),
146 'after' => __(
'validator.after'),
147 'alpha' => __(
'validator.alpha'),
148 'alpha_dash' => __(
'validator.alpha_dash'),
149 'alpha_num' => __(
'validator.alpha_num'),
150 'array' => __(
'validator.array'),
151 'before' => __(
'validator.before'),
153 'numeric' => __(
'validator.between.numeric'),
154 'file' => __(
'validator.between.file'),
155 'string' => __(
'validator.between.string'),
156 'array' => __(
'validator.between.array'),
158 'boolean' => __(
'validator.boolean'),
159 'confirmed' => __(
'validator.confirmed'),
160 'currency' => __(
'validator.currency'),
161 'date' => __(
'validator.date'),
162 'date_format' => __(
'validator.date_format'),
163 'different' => __(
'validator.different'),
164 'digits' => __(
'validator.digits'),
165 'digits_between' => __(
'validator.digits_between'),
166 'email' => __(
'validator.email'),
167 'email_or_localhost' => __(
'validator.email'),
168 'exists' => __(
'validator.exists'),
169 'filled' => __(
'validator.filled'),
170 'image' => __(
'validator.image'),
171 'in' => __(
'validator.in'),
172 'integer' => __(
'validator.integer'),
173 'ip' => __(
'validator.ip'),
174 'issn' => __(
'validator.issn'),
175 'json' => __(
'validator.json'),
177 'numeric' => __(
'validator.max.numeric'),
178 'file' => __(
'validator.max.file'),
179 'string' => __(
'validator.max.string'),
180 'array' => __(
'validator.max.array'),
182 'mimes' => __(
'validator.mimes'),
184 'numeric' => __(
'validator.min.numeric'),
185 'file' => __(
'validator.min.file'),
186 'string' => __(
'validator.min.string'),
187 'array' => __(
'validator.min.array'),
189 'not_in' => __(
'validator.not_in'),
190 'numeric' => __(
'validator.numeric'),
191 'present' => __(
'validator.present'),
192 'regex' => __(
'validator.regex'),
193 'required' => __(
'validator.required'),
194 'required_if' => __(
'validator.required_if'),
195 'required_unless' => __(
'validator.required_unless'),
196 'required_with' => __(
'validator.required_with'),
197 'required_with_all' => __(
'validator.required_with_all'),
198 'required_without' => __(
'validator.required_without'),
199 'required_without_all' => __(
'validator.required_without_all'),
200 'same' => __(
'validator.same'),
202 'numeric' => __(
'validator.size.numeric'),
203 'file' => __(
'validator.size.file'),
204 'string' => __(
'validator.size.string'),
205 'array' => __(
'validator.size.array'),
207 'string' => __(
'validator.string'),
208 'timezone' => __(
'validator.timezone'),
209 'unique' => __(
'validator.unique'),
210 'url' => __(
'validator.url'),
214 $messages = array_merge($defaultMessages, $messages);
218 foreach ($messages as $rule => $message) {
219 if (is_string($message)) {
222 foreach ($message as $subRule => $subMessage) {
239 return preg_replace(
'/\{\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/',
':\1', $message);
261 static public function required($validator, $action, $requiredProps, $multilingualProps, $allowedLocales, $primaryLocale) {
262 $validator->after(
function($validator) use ($action, $requiredProps, $multilingualProps, $allowedLocales, $primaryLocale) {
265 $primaryLocaleName = $primaryLocale;
266 foreach ($allLocales as $locale => $name) {
267 if ($locale === $primaryLocale) {
268 $primaryLocaleName = $name;
272 $props = $validator->getData();
274 foreach ($requiredProps as $requiredProp) {
278 if (in_array($requiredProp, $multilingualProps)) {
279 if ($action === VALIDATE_ACTION_ADD) {
280 if (self::isEmpty($props[$requiredProp]) || self::isEmpty($props[$requiredProp][$primaryLocale])) {
281 $validator->errors()->add($requiredProp .
'.' . $primaryLocale, __(
'validator.required'));
284 if (isset($props[$requiredProp]) && array_key_exists($primaryLocale, $props[$requiredProp]) && self::isEmpty($props[$requiredProp][$primaryLocale])) {
285 if (count($allowedLocales) === 1) {
286 $validator->errors()->add($requiredProp, __(
'validator.required'));
288 $validator->errors()->add($requiredProp .
'.' . $primaryLocale, __(
'form.requirePrimaryLocale', array(
'language' => $primaryLocaleName)));
294 if (($action === VALIDATE_ACTION_ADD && self::isEmpty($props[$requiredProp])) ||
295 ($action === VALIDATE_ACTION_EDIT && array_key_exists($requiredProp, $props) && self::isEmpty($props[$requiredProp]))) {
296 $validator->errors()->add($requiredProp, __(
'validator.required'));
308 static private function isEmpty($value) {
320 static public function allowedLocales($validator, $multilingualProps, $allowedLocales) {
321 $validator->after(
function($validator) use ($multilingualProps, $allowedLocales) {
322 $props = $validator->getData();
323 foreach ($props as $propName => $propValue) {
324 if (!in_array($propName, $multilingualProps)) {
327 if (!is_array($propValue)) {
328 $validator->errors()->add($propName .
'.' . current($allowedLocales), __(
'validator.localeExpected'));
331 foreach ($propValue as $localeKey => $localeValue) {
332 if (!in_array($localeKey, $allowedLocales)) {
333 $validator->errors()->add($propName .
'.' . $localeKey, __(
'validator.locale'));
354 static public function temporaryFilesExist($validator, $uploadProps, $multilingualUploadProps, $props, $allowedLocales, $userId) {
355 $validator->after(
function($validator) use ($uploadProps, $multilingualUploadProps, $props, $allowedLocales, $userId) {
356 import(
'lib.pkp.classes.file.TemporaryFileManager');
358 foreach ($uploadProps as $uploadProp) {
359 if (!isset($props[$uploadProp])) {
362 if (in_array($uploadProp, $multilingualUploadProps)) {
363 foreach ($allowedLocales as $localeKey) {
364 if (!isset($props[$uploadProp][$localeKey])
365 || !isset($props[$uploadProp][$localeKey][
'temporaryFileId'])
366 || $validator->errors()->get($uploadProp .
'.' . $localeKey)) {
369 if (!$temporaryFileManager->getFile($props[$uploadProp][$localeKey][
'temporaryFileId'], $userId)) {
370 $validator->errors()->add($uploadProp .
'.' . $localeKey, __(
'common.noTemporaryFile'));
374 if (!isset($props[$uploadProp][
'temporaryFileId'])) {
377 if (!$temporaryFileManager->getFile($props[$uploadProp][
'temporaryFileId'], $userId)) {
378 $validator->errors()->add($uploadProp, __(
'common.noTemporaryFile'));