├── .gitattributes ├── .github └── workflows │ ├── phpcs.yml │ ├── phpstan.yml │ └── phpunit.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── conf └── Conf.php ├── phpcs.xml ├── phpstan.neon ├── phpunit.xml ├── public_html ├── AutoInstall.php ├── Index.php ├── composerInstall.view.php └── static │ ├── css │ ├── index.css │ └── index.min.css │ ├── file │ └── test.txt │ ├── img │ └── iconTest.png │ └── js │ ├── composer-install.js │ ├── composer-install.min.js │ ├── funcoes.js │ ├── funcoes.min.js │ └── notify.min.js ├── sonar-project.properties ├── src ├── Arrays.php ├── CI.php ├── Compare.php ├── DependencyInjection │ ├── FormatAux.php │ ├── Rules.php │ ├── StrfTime.php │ ├── TraitRule.php │ ├── TraitRuleArray.php │ ├── TraitRuleDate.php │ ├── TraitRuleFile.php │ ├── TraitRuleInteger.php │ ├── TraitRuleString.php │ └── data │ │ ├── DataConvertTypesBool.php │ │ └── DataDdds.php ├── Format.php ├── Utility.php ├── ValidateCnpj.php ├── ValidateCpf.php ├── ValidateDate.php ├── ValidateFile.php ├── ValidateHour.php ├── ValidatePhone.php ├── ValidateString.php ├── Validator.php └── resource │ ├── Common.php │ ├── ComposerInstall.php │ └── ConstantPhpStan.php └── tests ├── UnitArrayTest.php ├── UnitCompareTest.php ├── UnitFormatTest.php ├── UnitIntegerTest.php ├── UnitRuleTest.php ├── UnitStringTest.php ├── UnitUtilityTest.php ├── UnitValidateCnpjTest.php ├── UnitValidateCpfTest.php ├── UnitValidateDateTest.php ├── UnitValidateHourTest.php ├── UnitValidatePhoneTest.php ├── UnitValidateStringTest.php └── data └── UnitCiTest.php /.gitattributes: -------------------------------------------------------------------------------- 1 | *.php text eol=lf 2 | *.json text eol=lf 3 | *.md text eol=lf 4 | -------------------------------------------------------------------------------- /.github/workflows/phpcs.yml: -------------------------------------------------------------------------------- 1 | name: "PHPCS - CI" 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - "**.php" 7 | - "phpcs.xml" 8 | - ".github/workflows/phpcs.yml" 9 | push: 10 | paths: 11 | - "**.php" 12 | - "phpcs.xml" 13 | - ".github/workflows/phpcs.yml" 14 | 15 | jobs: 16 | phpcs: 17 | name: Run PHP_CodeSniffer 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v4 22 | 23 | - name: Run PHP_CodeSniffer 24 | uses: chindit/actions-phpcs@master 25 | with: 26 | files: "**.php" 27 | standard: phpcs.xml 28 | dir: src/ 29 | -------------------------------------------------------------------------------- /.github/workflows/phpstan.yml: -------------------------------------------------------------------------------- 1 | on: [push] 2 | name: "PHPStan - CI" 3 | 4 | jobs: 5 | phpstan: 6 | name: Run PHPStan 7 | runs-on: ubuntu-latest 8 | steps: 9 | # Set up PHP 10 | - name: Set up PHP 11 | uses: shivammathur/setup-php@v2 12 | with: 13 | php-version: "8.4" 14 | extensions: mbstring, json 15 | 16 | # Checkout project 17 | - name: Checkout project 18 | uses: actions/checkout@v4 19 | 20 | # Install Composer dependencies 21 | - name: Install Composer dependencies 22 | run: composer install --prefer-dist --no-progress --no-suggest 23 | 24 | # Run PHPStan 25 | - name: Run PHPStan 26 | run: vendor/bin/phpstan analyse conf src --level=9 --configuration=phpstan.neon --autoload-file=src/resource/ConstantPhpStan.php --memory-limit=512M 27 | -------------------------------------------------------------------------------- /.github/workflows/phpunit.yml: -------------------------------------------------------------------------------- 1 | name: "PHPUnit - CI" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "**" 7 | pull_request: 8 | 9 | jobs: 10 | build-test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up PHP 17 | uses: shivammathur/setup-php@v2 18 | with: 19 | php-version: "8.3" 20 | extensions: xdebug 21 | ini-values: memory_limit=512M 22 | coverage: xdebug 23 | tools: composer:v2 24 | 25 | - name: Validate composer.json and composer.lock 26 | run: composer validate --strict 27 | 28 | - name: Install Composer dependencies 29 | run: composer install --prefer-dist --no-interaction --no-progress --no-suggest 30 | 31 | - name: Check Composer platform requirements 32 | run: composer check-platform-reqs 33 | 34 | - name: Show PHP version 35 | run: php -v 36 | 37 | - name: Run PHPUnit tests with coverage 38 | run: ./vendor/bin/phpunit --configuration phpunit.xml --coverage-clover=coverage.xml 39 | 40 | - name: Upload coverage report 41 | uses: actions/upload-artifact@v4 42 | with: 43 | name: coverage-report 44 | path: coverage.xml 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .vscode 3 | .phpunit.result.cache 4 | 5 | # ---- SonarQube 6 | .sonar/ 7 | .scannerwork/ 8 | 9 | # ---- PHPUnit 10 | .phpunit.result.cache 11 | /.phpunit.cache 12 | 13 | # --- Coverage 14 | /coverage/ 15 | clover.xml 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 brunoconte3 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dev-utils 2 | 3 | A complete library, with PSR standard and guarantee of all methods unit tested by phpunit and passed by phpstan. 4 | 5 | - Class of Arrays 6 | - Comparison Class 7 | - Formatting Class 8 | - Utility Class 9 | - Validate Data in General 10 | - Validate Upload Files 11 | 12 | ## Installation 13 | 14 | Install using Composer: 15 | 16 | ```bash 17 | composer require brunoconte3/dev-utils 18 | ``` 19 | 20 | Or add to your `composer.json`: 21 | 22 | ```json 23 | "brunoconte3/dev-utils": "2.8.0" 24 | ``` 25 | 26 | ## Data Validation Example 27 | 28 | `Data` 29 | 30 | ```php 31 | $data = [ 32 | 'name' => 'brunoconte3', 33 | 'email' => 'brunoconte3@gmail.com', 34 | 'validatePassingJson' => '@&451', 35 | 'newPassword' => 'min:5', 36 | 'confirmPassword' => 'min:5|equals:newPassword', 37 | ]; 38 | ``` 39 | 40 | `Rules` 41 | 42 | ```php 43 | $rules = [ 44 | 'name' => 'required|regex:/^[a-zA-Z\s]+$/', 45 | 'email' => 'required|email|max:50', 46 | 'validatePassingJson' => '{"required":"true","type":"alpha"}', 47 | ]; 48 | ``` 49 | 50 | `Validating the data according to the rules` 51 | 52 | ```php 53 | require 'vendor/autoload.php'; 54 | 55 | $validator = new DevUtils\Validator(); 56 | $validator->set($data, $rules); 57 | 58 | if(!$validator->getErros()){ 59 | echo 'Data successfully validated'; 60 | } else { 61 | var_dump($validator->getErros()); 62 | } 63 | ``` 64 | 65 | ## Validating File(s) Upload 66 | 67 | With validators fileName, maxFile, maxUploadSize, mimeType, minFile, minUploadSize, minHeight, minWidth, maxHeight, 68 | maxWidth and requiredFile, you can set the minimum and maximum size (bytes) of the file; minimum and maximum amount of files; allowed extensions; minimum and maximum height and length of images, validate the name of the file and define if the field of type "File" is mandatory. 69 | 70 | `Example:` 71 | 72 | ```html 73 | 74 | 75 |
76 | ... 77 | 78 | 79 | 88 | 89 | 90 | ``` 91 | 92 | ```php 93 | $fileUploadSingle, 106 | 'fileUploadMultiple' => $fileUploadMultiple, 107 | ]; 108 | 109 | $rules = [ 110 | 'fileUploadSingle' => 'requiredFile|fileName|mimeType:jpeg;png;jpg;txt;docx;xlsx;pdf|minUploadSize:10| 111 | maxUploadSize:100|minWidth:200|maxWidth:200', 112 | 'fileUploadMultiple' => 'fileName|mimeType:jpeg|minFile:1|maxFile:3|minUploadSize:10| 113 | minWidth:200|maxWidth:200|maxUploadSize:100, Mensagem personalizada aqui', 114 | ]; 115 | 116 | $validator = new DevUtils\Validator(); 117 | Format::convertTypes($datas, $rules); 118 | $validator->set($datas, $rules); 119 | 120 | if (!$validator->getErros()) { 121 | echo 'Data successfully validated'; 122 | } else { 123 | echo ''; 124 | print_r($validator->getErros()); 125 | } 126 | } 127 | ``` 128 | 129 | ## Validation types (validators) 130 | 131 | - alpha: `Checks that the field contains only alphabetic characters` 132 | - alphaNoSpecial: `Checks if the field contains regular text characters, it cannot have accents` 133 | - alphaNum: `Checks if the field contains alphanumeric characters` 134 | - alphaNumNoSpecial: `Checks if the field contains letters without accents, numbers, cannot special character` 135 | - array: `Checks if the variable is an array` 136 | - arrayValues: `Checks whether the variable has one of the options in the specified array` 137 | - bool: `Values of logical type.` `Ex: true or false, 1 or 0, yes or no` 138 | - companyIdentification: `Validates if the CNPJ is valid, passing CNPJ with or without mask` 139 | - dateAmerican: `Validates if the American date is valid` 140 | - dateBrazil: `Validates if the Brazilian date is valid` 141 | - dateNotFuture: `Validates if the date not greater than date current (accepts Brazilian or American format)` 142 | - ddd: `Validates ddd informed in YYY or YY format, by UF or in general` `Ex: ddd:pr, ddd do Paraná/Brazil, or just ddd` 143 | - email: `Check if it's a valid email` 144 | - equals: `Checks if the field is the same as another field, example above in the documentation, look for equals` 145 | - fileName: `Checks that the filename is a valid name, and formats the name by removing special characters` 146 | - float: `Checks if the value is of type floating(real value)` 147 | - hour: `Validates if the time is valid` 148 | - identifier: `Validates if the CPF is valid, passing CPF with or without mask` 149 | - identifierOrCompany: `Validates if the CPF or CNPJ is valid, passing CPF or CNPJ with or without mask` 150 | - int: `Checks if the value is of type integer (If the format is String, it tries to parse it)` 151 | - integer: `Checks if the value is of type integer (here checks exact typing)` 152 | - ip: `Checks if the value is a valid IP address` 153 | - json: `Checks if the value is a valid json` 154 | - lower: `Checks if all characters are lowercase` 155 | - mac: `Checks if the value is a valid MAC address` 156 | - max: `Sets the maximum size of the value` 157 | - minHeight: `Sets the minimum height size (pixels) of the image` 158 | - minWidth: `Sets the minimum size in length (pixels) of the image` 159 | - maxHeight: Sets the maximum height (pixels) size of the image`` 160 | - maxWidth: `Sets the maximum size in length (pixels) of the image` 161 | - maxFile: `Sets the maximum number of files to upload` 162 | - maxUploadSize: `Sets the maximum file size (bytes)` 163 | - maxWords: `Defines the maximum number of words in a string` 164 | - min: `Sets the minimum size of the value` 165 | - minFile: `Sets the minimum amount of files to upload` 166 | - minWords: `Defines the minimum number of words in a string` 167 | - mimeType: `Defines the extension(s) allowed for upload` 168 | - minUploadSize: `Sets the minimum file size (bytes)` 169 | - numeric: `Checks if the value contains only numeric values (Left zero accepted)` 170 | - numMax: `Sets a maximum value, with the minimum being zero` 171 | - numMin: `Sets a minimum value, with the minimum being zero` 172 | - numMonth: `Checks if the value is a valid month (1 to 12)` 173 | - notSpace: `Checks if the string contains spaces` 174 | - noWeekend: `Checks if the date (Brazilian or American is not a Weekend)` 175 | - optional: `If inserted, it only validates if the value is different from empty, null or false` 176 | - phone: `Checks if the value matches a valid phone. (DDD + NUMBERS) 10 or 11 digits` 177 | - plate: `Checks if the value matches the shape of a license plate` 178 | - regex: `Defines a rule for the value through a regular expression` 179 | - required: `Set the field to mandatory` 180 | - requiredFile: `Sets the field of type 'File' as mandatory` 181 | - rgbColor: `Checks if the string has a valid RGB Color` 182 | - timestamp: `Checks if the value is a valid timestamp (accepts Brazilian or American format)` 183 | - upper: `Checks if all characters are uppercase` 184 | - url: `Checks if the value is a valid URL address` 185 | - zipcode: `Checks if the value matches the format of a zip code` 186 | 187 | ## Defining custom message 188 | 189 | After defining some of our rules to the data you can also add a custom message using the ',' delimiter in some specific rule or using the default message. 190 | 191 | `Example:` 192 | 193 | ```php 194 | set($datas, [ 197 | 'name' => 'required, The name field cannot be empty', 198 | 'email' => 'email, The email field is incorrect|max:50', 199 | 'password' => 'min:8, nat least 8 characters|max:12, no máximo 12 caracteres.', 200 | ]); 201 | ``` 202 | 203 | ## Formatting Examples 204 | 205 | ```php 206 | 39.678.379/0001-29 213 | Format::convertTimestampBrazilToAmerican('15/04/2021 19:50:25'); //Convert Timestamp Brazil to American format 214 | Format::currency('113', 'R$ '); //Default currency BR ==> 123.00 - the 2nd parameter chooses the Currency label 215 | Format::currencyUsd('1123.45'); //Default currency USD ==> 1,123.45 - the 2nd parameter chooses the Currency label 216 | Format::dateAmerican('12-05-2020'); //return date ==> 2020-05-12 217 | Format::dateBrazil('2020-05-12'); //return date ==> 12/05/2020 218 | Format::identifier('73381209000'); //CPF ==> 733.812.090-00 219 | Format::identifierOrCompany('30720870089'); //CPF/CNPJ Brazil ==> 307.208.700-89 220 | Format::falseToNull(false); //Return ==> null 221 | Format::lower('CArrO'); //lowercase text ==> carro - the 2nd parameter chooses the charset, UTF-8 default 222 | //[Apply any type of Mask, accepts space, points and others] 223 | Format::mask('#### #### #### ####', '1234567890123456'); //Mask ==> 1234 5678 9012 3456 224 | Format::maskStringHidden('065.775.009.96', 3, 4, '*'); //Mask of string ==> 065.***.009.96 225 | Format::onlyNumbers('548Abc87@'); //Returns only numbers ==> 54887; 226 | Format::onlyLettersNumbers('548Abc87@'); //Returns only letters and numbers ==> 548Abc87; 227 | Format::pointOnlyValue('1.350,45'); //Currency for recording on the BD ==> 1350.45 228 | Format::removeAccent('Açafrão'); //Remove accents and character 'ç' ==> Acafrao 229 | //Removes all special characters ==> "Acafrao com Espaco", 2nd parameter chooses whether to allow space, default true 230 | Format::removeSpecialCharacters('Açafrão com Espaco %$#@!', true); 231 | Format::returnPhoneOrAreaCode('44999998888', false); //Returns only the phone number ==> 999998888 232 | Format::returnPhoneOrAreaCode('44999998888', true); //Returns only the phone's area code ==> 44 233 | Format::reverse('Abacaxi'); //Returns inverted string ==> ixacabA 234 | Format::telephone('44999998888'); //Return phone format brazil ==> (44) 99999-8888 235 | Format::ucwordsCharset('aÇafrÃo maCaRRão'); //Return first capital letter ==> Açafrão Macarrão 236 | Format::upper('Moto'); //lowercase text ==> MOTO - the 2nd parameter chooses the charset, UTF-8 default 237 | Format::zipCode('87030585'); //CEP format brazil ==> 87030-585 238 | Format::writeDateExtensive('06/11/2020'); //Date by Long Brazilian format ==> sexta-feira, 06 de novembro de 2020 239 | Format::writeCurrencyExtensive(1.97); //Coin by Extensive Brazilian format ==> um real e noventa e sete centavos 240 | Format::convertStringToBinary('amor'); //String to binary ==> 1100001 1101101 1101111 1110010 241 | Format::slugfy('Polenta frita e Parmesão'); //Returns a slug from a string ==> polenta-frita-e-parmesao 242 | 243 | $data = [ 244 | 'treatingIntType' => '12', 245 | 'handlingFloatType' => '9.63', 246 | 'treatingBooleanType' => 'true', 247 | 'handlingNumericType' => '11', 248 | ]; 249 | $rules = [ 250 | 'treatingIntType' => 'convert|int', 251 | 'handlingFloatType' => 'convert|float', 252 | 'treatingBooleanType' => 'convert|bool', 253 | 'handlingNumericType' => 'convert|numeric', 254 | ]; 255 | Format::convertTypes($data, $rules); //Convert the value to its correct type ['bool', 'float', 'int', 'numeric',] 256 | /*** Return 257 | [ 258 | 'treatingIntType' => int 12 259 | 'handlingFloatType' => float 9.63 260 | 'treatingBooleanType' => boolean true 261 | 'handlingNumericType' => float 11 262 | ] 263 | ***/ 264 | 265 | $array = [ 266 | 0 => '1', 267 | 1 => '123', 268 | 'a' => '222', 269 | 'b' => 333, 270 | 'c' => '', 271 | ]; 272 | $newArray = Format::emptyToNull($array); //Convert empty to null, - the 2nd parameter is optional, passing the desired exception 273 | /*** Return 274 | [ 275 | 0 => 1, 276 | 1 => 123, 277 | 'a' => 222, 278 | 'b' => 333, 279 | 'c' => null, 280 | ]; 281 | **/ 282 | 283 | //$value = Format::arrayToInt($array); ==> Option for other than by Reference 284 | Format::arrayToIntReference($array); //Formats array values in integer ==> 285 | [ 286 | 0 => 1, 287 | 1 => 123, 288 | 'a' => 222, 289 | 'b' => 333, 290 | 'c' => 0, 291 | ]; 292 | 293 | ``` 294 | 295 | ## Formatting Upload File(s) 296 | 297 | `Example: Uploading a single file` 298 | 299 | ```php 300 | 'JPG - Upload Validation v.1.jpg', 304 | 'type' => 'image/jpeg', 305 | 'tmp_name' => '/tmp/phpODnLGo', 306 | 'error' => 0, 307 | 'size' => 8488, 308 | ]; 309 | 310 | Format::restructFileArray($fileUploadSingle); // Call of the method responsible for normalizing the array 311 | [ 312 | 0 => [ 313 | 'name' => 'jpg___upload_validation_v_1.jpg', 314 | 'type' => 'image/jpeg', 315 | 'tmp_name' => '/tmp/phpBmqX1i', 316 | 'error' => 0, 317 | 'size' => 8488, 318 | 'name_upload' => '22-01-2021_13_1830117018768373446425980271611322393600ad419619ec_jpg___upload_validation_v_1.jpg', 319 | ] 320 | ] 321 | 322 | ``` 323 | 324 | `Example: Uploading multiple files` 325 | 326 | ```php 327 | [ 331 | '0' => 'JPG - Upload Validation v.1.jpg', 332 | '1' => 'PDF - Upload Validation v.1.pdf', 333 | '2' => 'PNG - Upload Validation v.1.png', 334 | ], 335 | 'type' => [ 336 | '0' => 'image/jpeg', 337 | '1' => 'application/pdf', 338 | '2' => 'image/png', 339 | ], 340 | 'tmp_name' => [ 341 | '0' => '/tmp/phpODnLGo', 342 | '1' => '/tmp/phpfmb0tL', 343 | '2' => '/tmp/phpnoejk8', 344 | ], 345 | 'error' => [ 346 | '0' => 0, 347 | '1' => 0, 348 | '2' => 0, 349 | ], 350 | 'size' => [ 351 | '0' => 8488, 352 | '1' => 818465, 353 | '2' => 1581312, 354 | ], 355 | ]; 356 | 357 | Format::restructFileArray($fileUploadMultiple); // Call of the method responsible for normalizing the array 358 | [ 359 | 0 => [ 360 | 'name' => 'jpg___upload_validation_v_1.jpg', 361 | 'type' => 'image/jpeg', 362 | 'tmp_name' => '/tmp/phpBmqX1i', 363 | 'error' => 0, 364 | 'size' => 8488, 365 | 'name_upload' => '22-01-2021_13_1830117018768373446425980271611322393600ad419619ec_jpg___upload_validation_v_1.jpg', 366 | ], 367 | 1 => [ 368 | 'name' => 'pdf___upload_validation_v_1.pdf', 369 | 'type' => 'application/pdf', 370 | 'tmp_name' => '/tmp/phpYo0w7c', 371 | 'error' => 0, 372 | 'size' => 818465, 373 | 'name_upload' => '22-01-2021_13_170624609160164419213582611971611322393600ad41961a5a_pdf___upload_validation_v_1.pdf', 374 | ], 375 | 2 => [ 376 | 'name' => 'png___upload_validation_v_1.png', 377 | 'type' => 'image/png', 378 | 'tmp_name' => '/tmp/phpme7Yf7', 379 | 'error' => 0, 380 | 'size' => 1581312, 381 | 'name_upload' => '22-01-2021_13_8675237129330338531328755051611322393600ad41961ac8_png___upload_validation_v_1.png', 382 | ], 383 | ] 384 | 385 | ``` 386 | 387 | ## Comparisons Examples 388 | 389 | ```php 390 | Returns [bool] 400 | Compare::startDateLessThanEnd('30/07/2020', '30/06/2020'); //Accepts American date too 401 | 402 | //Difference between hours ==> 01:36:28 [Hours displays negative and positive difference] 403 | Compare::differenceBetweenHours('10:41:55', '12:18:23'); 404 | 405 | //Compares if the start time is less than the end time (3rd parameter, accept custom message) 406 | Compare::startHourLessThanEnd('12:05:01', '10:20:01'); 407 | 408 | //Compares the date to the current date, and returns the person's age 409 | Compare::calculateAgeInYears('20/05/1989'); 410 | 411 | //Compares fields for equality, returns boolean 412 | //optional third parameter, false to not compare caseSensitive, default true 413 | Compare::checkDataEquality('AçaFrão', 'Açafrão'); 414 | 415 | //Compares if desired content exists in String, returns boolean 416 | Compare::contains('AçaFrão', 'çaF'); 417 | 418 | //Compares the corresponding URL with the second parameter, starts with the string entered in the first parameter. Returns boolean. 419 | Compare::beginUrlWith('/teste', '/teste/variavel'); 420 | 421 | //Compares the corresponding URL with the second parameter, ends with the string entered in the first parameter. Returns boolean. 422 | Compare::finishUrlWith('/teste', 'sistema/teste'); 423 | 424 | //Compares if the corresponding string with the first parameter is equal to the substring obtained from the second parameter. Extracting to compare 7 characters from the second parameter starting at position 0. Returns boolean. 425 | Compare::compareStringFrom('sistema', 'sistema/teste', 0, 7); 426 | 427 | ``` 428 | 429 | ## Validations in the form of Methods 430 | 431 | ```php 432 | 15, 'segundo' => 25]; 469 | var_dump(Arrays::searchKey($array, 'primeiro')); // Search for key in array, and Return position ==> returns 0 470 | var_dump(Arrays::searchKey($array, 'segundo')); // Search for key in array, and Return position ==> returns 1 471 | var_dump(Arrays::searchKey($array, 'nao-existe')); // Search for key in array, and Return position ==> returns null 472 | 473 | $array = ['primeiro' => 10, 'segundo' => 20]; 474 | Arrays::renameKey($array, 'primeiro', 'novoNome'); 475 | var_dump($array); //Rename array key ==> ['novoNome' => 10, 'segundo' => 20]; 476 | 477 | $array = [ 478 | 'frutas' => ['fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva'], 479 | 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 480 | 'legume' => 'Tomate' 481 | ]; 482 | 483 | // Checks in the array, if there is any index with the desired value 484 | var_dump(Arrays::checkExistIndexByValue($array, 'Tomate')); 485 | 486 | // Performs the search in the array, through the key and Return an array with all indexes located 487 | var_dump(Arrays::findValueByKey($array, 'verduras')); 488 | 489 | // Performs the search in the array, through a value and returns an array with all items located 490 | var_dump(Arrays::findIndexByValue($array, 'Tomate')); 491 | 492 | $xml = new SimpleXMLElement(''); 493 | Arrays::convertArrayToXml($array, $xml); // Convert array to Xml 494 | var_dump($xml->asXML()); 495 | 496 | $array = [ 497 | 'frutas' => ['fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva'], 498 | 'verduras' => '{"verdura_1": "Rúcula", "verdura_2": "Acelga", "verdura_3": "Alface"}' 499 | ]; 500 | 501 | // Checks the array, if it has any index with JSON and turns it into an array 502 | Arrays::convertJsonIndexToArray($array); 503 | var_dump($array); 504 | 505 | $array = [ 506 | 'pessoa' => [ 507 | 'pedidos' => ['pedido1', 'pedido2'], 508 | 'categorias' => [ 509 | 'subcategorias' => [ 510 | 'subcategoria1' => 'valor teste' 511 | ] 512 | ] 513 | ] 514 | ]; 515 | 516 | // Checks if a specific index exists in a multilevel array 517 | var_dump(Arrays::checkExistIndexArrayRecursive($array, 'subcategoria1')); // Return true 518 | 519 | ``` 520 | 521 | ## Utilities 522 | 523 | ```php 524 | Number of characters in the password (Required) 535 | bool $uppercase ==> If there will be capital letters 536 | bool $lowercase ==> If there will be lowercase letters 537 | bool $numbers ==> if there will be numbers 538 | bool $symbols ==> if there will be symbols 539 | */ 540 | Utility::generatePassword(10); 541 | 542 | /* 543 | * @return string -> Full URL string 544 | * @param string $host -> system domain 545 | * @param string $absolutePath -> absolute path 546 | * @param string $https -> 'on' to generate https url, null or other value, generate http url 547 | */ 548 | Utility::buildUrl('localhost', '/sua-url/complemento', 'on'); // Return to URL 549 | ``` 550 | 551 | ## Check the minimum coverage of CI/CD unit tests using PHPUnit 552 | 553 | ```php 554 | file: .gitlab-ci.yml 555 | Add Lines: 556 | 557 | script: 558 | - composer install 559 | - ./vendor/bin/phpunit --coverage-xml coverage #Here generates the coverage file 560 | - php ./vendor/brunoconte3/dev-utils/src/CI.php coverage/index.xml 80 #Change the value 80 to your value 561 | 562 | 563 | file: .gitignore 564 | Add Line: /coverage/ 565 | ``` 566 | 567 | ## Will perform pull request, please execute unit tests, and phpstan level 9 568 | 569 | `./vendor/bin/phpunit --coverage-xml coverage` 570 | `./vendor/bin/phpstan analyse -c phpstan.neon --level 9` 571 | `If you don't know how to run phpstan, I execute and adjust whatever is necessary` 572 | 573 | # License 574 | 575 | The validator is an open-source application licensed under the [MIT License](https://opensource.org/licenses/MIT). 576 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "brunoconte3/dev-utils", 3 | "description": "A complete PHP utility library for validating, formatting, comparing data, and more.", 4 | "keywords": [ 5 | "validation", "utils", "format", "array", "dev", "utility", "compare" 6 | ], 7 | "license": "MIT", 8 | "homepage": "https://github.com/brunoconte3/dev-utils", 9 | "authors": [{ 10 | "name": "Bruno Conte", 11 | "email": "brunoconte3@gmail.com", 12 | "role": "Creator/Developer" 13 | }, 14 | { 15 | "name": "Walter de Padua Junior", 16 | "email": "wpadua8@gmail.com", 17 | "role": "Developer" 18 | }, 19 | { 20 | "name": "Jonathan Bersot Augusto", 21 | "email": "jonathanbersot21@gmail.com", 22 | "role": "Developer" 23 | }, 24 | { 25 | "name": "Robson Willian da Silva", 26 | "email": "robsonwillian.ads@gmail.com", 27 | "role": "Developer" 28 | }, 29 | { 30 | "name": "Rafael Henrique Barbosa Pereira", 31 | "email": "rafael@agenciab33.com.br", 32 | "role": "Developer" 33 | }, 34 | { 35 | "name": "Rafael Gomes de Souza", 36 | "email": "gomes.webads@gmail.com", 37 | "role": "Developer" 38 | }, 39 | { 40 | "name": "Adalberto Silveira Nápoles", 41 | "email": "adalbertosn1982@gmail.com", 42 | "role": "Developer" 43 | }, 44 | { 45 | "name": "Antonio Cruz", 46 | "email": "ajcf97@gmail.com", 47 | "role": "Developer" 48 | }, 49 | { 50 | "name": "Caio Brioli", 51 | "email": "caiobrioli777@hotmail.com", 52 | "role": "Developer" 53 | }, 54 | { 55 | "name": "Willian Joaquim Barros Lúcio", 56 | "email": "willian_jbl@hotmail.com", 57 | "role": "Developer" 58 | }, 59 | { 60 | "name": "Eliseu Lorena Vidal", 61 | "email": "eliseuvidal0@hotmail.com", 62 | "role": "Developer" 63 | }, 64 | { 65 | "name": "Guilherme Henrique Ribeiro", 66 | "email": "guilherme.ribeiro30@hotmail.com", 67 | "role": "Developer" 68 | }, 69 | { 70 | "name": "Wellington Valentin Salatta", 71 | "email": "wellsalatta@gmail.com", 72 | "role": "Developer" 73 | }, 74 | { 75 | "name": "Erick Hiroki Abe / 阿部広紀", 76 | "email": "erickhirokiabe@gmail.com", 77 | "role": "Developer" 78 | } 79 | ], 80 | "support": { 81 | "issues": "https://github.com/brunoconte3/dev-utils/issues", 82 | "source": "https://github.com/brunoconte3/dev-utils" 83 | }, 84 | "suggest": { 85 | "ext-gd": "To use the GD implementation", 86 | "ext-mbstring": "To use Format::lower() etc.", 87 | "ext-intl": "To use Format with Date" 88 | }, 89 | "require": { 90 | "php": "^8.3 || ^8.4" 91 | }, 92 | "autoload": { 93 | "psr-4": { 94 | "DevUtils\\conf\\": "conf/", 95 | "DevUtils\\": "src/" 96 | } 97 | }, 98 | "autoload-dev": { 99 | "psr-4": { 100 | "DevUtils\\Test\\": "tests/" 101 | } 102 | }, 103 | "require-dev": { 104 | "phpunit/phpunit": "^12.1", 105 | "phpstan/phpstan": "^2.1" 106 | }, 107 | "minimum-stability": "stable", 108 | "prefer-stable": true 109 | } 110 | -------------------------------------------------------------------------------- /conf/Conf.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | reportUnmatchedIgnoredErrors: false 3 | ignoreErrors: 4 | - '#no value type specified in iterable type array#' 5 | - 6 | message: "#expects Countable\\|iterable, array\\|bool given#" 7 | paths: 8 | - tests/UnitTestString.php 9 | - tests/UnitTestRule.php 10 | - tests/UnitTestInteger.php 11 | - 12 | message: "#Call to an undefined method object::addChild#" 13 | path: src/Arrays.php 14 | - 15 | message: "#Cannot access offset 'textoError' on array\\|bool#" 16 | path: tests/UnitTestRule.php 17 | - 18 | message: "#Call to an undefined method object::asXML#" 19 | path: tests/UnitArrayTest.php 20 | - 21 | message: "#Strict comparison using === between callable-string and#" 22 | paths: 23 | - DependencyInjection/Rules.php 24 | - src/DependencyInjection/Rules.php 25 | - 26 | message: "#invalidRule\\(\\) is unused#" 27 | path: src/DependencyInjection/Rules.php 28 | - 29 | message: "#is always true#" 30 | path: src/DependencyInjection/Rules.php 31 | - 32 | message: "#strval expects bool\\|float\\|int\\|resource\\|string\\|null#" 33 | path: src/DependencyInjection/Rules.php 34 | - '#function strval expects bool\|float\|int\|resource\|string\|null, mixed given#' 35 | - '#function intval expects array\|bool\|float\|int\|resource\|string\|null, mixed given#' 36 | - '#function floatval expects array\|bool\|float\|int\|resource\|string\|null, mixed given#' 37 | - 38 | message: "#Result of \\|\\| is always true#" 39 | path: src/Format.php 40 | - 41 | message: "#Strict comparison using === between 0#" 42 | path: src/Format.php 43 | 44 | bootstrapFiles: 45 | - vendor/autoload.php 46 | - src/resource/ConstantPhpStan.php 47 | 48 | paths: 49 | - conf 50 | - src 51 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 |./ 5 |6 | vendor/* 7 | 8 |9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 |18 | 21 |19 | 20 | 3 | 26 | -------------------------------------------------------------------------------- /public_html/AutoInstall.php: -------------------------------------------------------------------------------- 1 | instalar(); 13 | } 14 | $arquivo = str_replace([ 15 | '\\', 16 | '\\\\', 17 | '/', 18 | '//', 19 | ], DIRECTORY_SEPARATOR, ('composerInstall.view.php')); 20 | if (!file_exists($arquivo)) { 21 | echo 'Houve um erro. A view composerInstall não existe!'; 22 | } 23 | if (!require_once($arquivo)) { 24 | echo 'Houve um erro ao carregar a view composerInstall!'; 25 | } 26 | exit(); 27 | } 28 | -------------------------------------------------------------------------------- /public_html/Index.php: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |4 | 6 |5 | 7 | 11 |8 | 10 |./tests/ 9 |12 | 16 |13 | 15 |14 | 17 | 25 |18 | 21 |src 19 |tests 20 |22 | 24 |src/CI.php 23 |brunoconte3/dev-utils 26 | 27 | 28 | 29 | 30 |31 |116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /public_html/composerInstall.view.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |32 | 35 |brunoconte3/dev-utils
33 | Espaço para fazer seus testes 34 |36 | 115 |37 |114 |38 | Aqui vem os seus testes!'; 40 | $array = [ 41 | 'cpfOuCnpj' => '04764334879', 42 | 'nomePais' => 'Brasil', 43 | 'dadosEmpresa' => ['empresa' => 'cooper'], 44 | ]; 45 | $rules = [ 46 | 'cpfOuCnpj' => 'identifierOrCompany', 47 | 'nomePais' => 'required|alpha', 48 | 'dadosEmpresa' => 'required|array', 49 | ]; 50 | $validator = new Validator(); 51 | $validator->set($array, $rules); 52 | ?> 53 |65 |54 | getErros())) { 56 | echo 'Sucesso! dados válidos!
'; 57 | } else { 58 | echo 'Revise a entrada!
'; 59 | print_r($validator->getErros()); 60 | } 61 | ?> 62 |64 |
63 |66 | $fileUploadSingle, 72 | 'fileUploadMultiple' => $fileUploadMultiple 73 | ]; 74 | $ruleSingle = 'requiredFile|fileName|mimeType:jpeg;png;jpg;txt;docx;xlsx;pdf|minUploadSize:10|'; 75 | $ruleSingle .= 'maxUploadSize:30000|maxFile:1|minWidth:200|maxWidth:200|minHeight:200|'; 76 | $ruleSingle .= 'maxHeight:200'; 77 | $ruleMultiple = 'fileName|mimeType:jpeg;png|minFile:1|maxFile:3|minUploadSize:10'; 78 | $ruleMultiple .= '|minWidth:200|maxWidth:200|minHeight:200|maxHeight:200|'; 79 | $ruleMultiple .= 'maxUploadSize:30000, Mensagem personalizada aqui!'; 80 | $rules = [ 81 | 'fileUploadSingle' => $ruleSingle, 82 | 'fileUploadMultiple' => $ruleMultiple 83 | ]; 84 | $validator = new Validator(); 85 | $validator->set($array, $rules); ?> 86 |113 |87 | getErros()); ?> 88 |
89 |90 | 95 |96 | 111 |112 |Instalação do Docker 6 | 7 | 8 | 9 | 10 | 11 |12 | 28 |13 |27 |14 |26 |15 |25 |16 |18 |Olá Dev!
17 |19 |24 |Para configurar o seu ambiente de desenvolvimento antes precisamos instalar as 20 | dependências necessárias do projeto. 21 |
23 |
apenas clique no botão abaixo e aguarde... 22 |29 |35 |30 | 33 |34 |36 |43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /public_html/static/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0px; 3 | margin: 0px; 4 | background: #F8F9FA; 5 | } 6 | 7 | .container { 8 | width: auto; 9 | max-width: 1280px; 10 | padding: 15px 15px; 11 | margin-right: auto; 12 | margin-left: auto; 13 | } 14 | 15 | .container>header#body-title-page>h1 { 16 | margin: 0px; 17 | text-align: center; 18 | color: green; 19 | } 20 | 21 | .container>header#body-title-page>small { 22 | display: block; 23 | width: 100%; 24 | text-align: center; 25 | margin-bottom: 15px; 26 | } 27 | 28 | section.body-section-class { 29 | background-color: white; 30 | padding: 15px; 31 | min-height: 400px; 32 | } 33 | 34 | div#bd-form-upload { 35 | position: relative; 36 | display: flex; 37 | width: 100%; 38 | flex-direction: row; 39 | } 40 | 41 | div#bd-form-upload>form { 42 | display: flex; 43 | flex-flow: row wrap; 44 | align-items: stretch; 45 | width: 100%; 46 | } 47 | 48 | div#bd-form-upload>form>div { 49 | display: flex; 50 | flex-flow: row wrap; 51 | align-items: center; 52 | width: 100%; 53 | padding: 10px; 54 | } 55 | 56 | div#bd-form-upload>form>div:last-child { 57 | align-items: flex-end !important; 58 | } 59 | 60 | div#bd-form-upload>form>div>label { 61 | display: block; 62 | margin-bottom: 10px; 63 | width: 100%; 64 | } 65 | 66 | div#bd-form-upload>form>div>input[type='file'] { 67 | width: 100%; 68 | border: 1px solid #ccc; 69 | } 70 | -------------------------------------------------------------------------------- /public_html/static/css/index.min.css: -------------------------------------------------------------------------------- 1 | body{padding:0;margin:0;background:#f8f9fa}.container{width:auto;max-width:1280px;padding:15px 15px;margin-right:auto;margin-left:auto}.container>header#body-title-page>h1{margin:0;text-align:center;color:green}.container>header#body-title-page>small{display:block;width:100%;text-align:center;margin-bottom:15px}section.body-section-class{background-color:#fff;padding:15px;min-height:400px}div#bd-form-upload{position:relative;display:flex;width:100%;flex-direction:row}div#bd-form-upload>form{display:flex;flex-flow:row wrap;align-items:stretch;width:100%}div#bd-form-upload>form>div{display:flex;flex-flow:row wrap;align-items:center;width:100%;padding:10px}div#bd-form-upload>form>div:last-child{align-items:flex-end!important}div#bd-form-upload>form>div>label{display:block;margin-bottom:10px;width:100%}div#bd-form-upload>form>div>input[type=file]{width:100%;border:1px solid #ccc} -------------------------------------------------------------------------------- /public_html/static/file/test.txt: -------------------------------------------------------------------------------- 1 | do not delete -------------------------------------------------------------------------------- /public_html/static/img/iconTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunoconte3/dev-utils/8fb0e57ecd7b3d7985c78d397ea6685e298e2c9e/public_html/static/img/iconTest.png -------------------------------------------------------------------------------- /public_html/static/js/composer-install.js: -------------------------------------------------------------------------------- 1 | let d = document; 2 | d.addEventListener("DOMContentLoaded", () => { 3 | d.querySelector('#btnIniciar').addEventListener('click', () => { 4 | d.querySelector('#btnIniciar').setAttribute('disabled', 'disabled'); 5 | d.querySelector('#btnIniciar > span').innerHTML = 'Aguarde'; 6 | d.querySelector('#btnIniciar > em').classList.remove('d-none'); 7 | d.querySelector('#btnIniciar > em').classList.add('d-inline-block'); 8 | dispararAlerta('Este processo pode ser demorado...', 'info'); 9 | adicionarNoLog('Iniciando a Instalação das dependências'); 10 | adicionarNoLog('Este processo pode ser demorado...'); 11 | 12 | iniciar(); 13 | }); 14 | }); 15 | 16 | async function iniciar() { 17 | let counter = 0; 18 | let retorno = false; 19 | while (counter < 3) { 20 | counter++; 21 | d.querySelector('#textArea').innerHTML += ` 22 | ------------------------------------------------------------------ 23 | TENTATIVA ${counter} 24 | ------------------------------------------------------------------ 25 | `; 26 | retorno = await instalar(); 27 | if (!retorno['erro']) { 28 | dispararSucesso(); 29 | break; 30 | } else { 31 | adicionarNoLog(retorno['log']); 32 | } 33 | 34 | } 35 | 36 | if (retorno['erro']) { 37 | let texto = 'Limite máximo de tentativas excedido. Verifique o LOG e se necessário tente novamente!'; 38 | dispararAlerta(texto); 39 | dispararErro(texto); 40 | alterarBotao(0); 41 | } 42 | } 43 | 44 | async function instalar() { 45 | let concluido = false; 46 | let log = ''; 47 | let diretorio = 'Index.php'; 48 | let form = new FormData(); 49 | form.append('instalar', 'S'); 50 | await fetch(new Request(diretorio, { 51 | method: 'POST', 52 | body: form 53 | })).then((resposta) => { 54 | return resposta.json(); 55 | }).then((retorno) => { 56 | if (!retorno['erro']) { 57 | concluido = true; 58 | return; 59 | } 60 | log = retorno['log']; 61 | }).catch((erro) => { 62 | adicionarNoLog(erro); 63 | }); 64 | console.log(log.indexOf('Generating autoload files')); 65 | if (log.indexOf('Generating autoload files') > 0) { 66 | return { 'erro': false, 'log': log } 67 | } else { 68 | return { 'erro': !concluido, 'log': log } 69 | } 70 | }; 71 | 72 | function adicionarNoLog(texto) { 73 | let data = Date(Date.now()); 74 | d.querySelector('#textArea').innerHTML += data.toLocaleString('pt-BR', { 75 | "dateStyle": "short" 76 | }) + '\n' + texto; 77 | d.querySelector('#textArea').innerHTML += ` 78 | -------------------------------------------------------------------------------- 79 | `; 80 | } 81 | 82 | function alterarBotao(tipo) { 83 | switch (tipo) { 84 | case 1: 85 | d.querySelector('#btnIniciar > span').innerHTML = 'Erro!'; 86 | d.querySelector('#btnIniciar > em').classList.add('d-none'); 87 | d.querySelector('#btnIniciar > em').classList.remove('d-inline-block'); 88 | break; 89 | case 2: 90 | 91 | d.querySelector('#btnIniciar > span').innerHTML = 'Sucesso!'; 92 | d.querySelector('#btnIniciar > em').classList.add('d-none'); 93 | d.querySelector('#btnIniciar > em').classList.remove('d-inline-block'); 94 | break; 95 | case 0: 96 | default: 97 | d.querySelector('#btnIniciar').removeAttribute('disabled'); 98 | d.querySelector('#btnIniciar > em').classList.add('d-none'); 99 | d.querySelector('#btnIniciar > em').classList.remove('d-inline-block'); 100 | d.querySelector('#btnIniciar > span').innerHTML = 'Clique Aqui'; 101 | break; 102 | } 103 | } 104 | 105 | function dispararErro(texto) { 106 | adicionarNoLog(texto); 107 | alterarBotao(1); 108 | setTimeout(() => { 109 | alterarBotao(0); 110 | }, 2500); 111 | } 112 | 113 | function dispararSucesso() { 114 | alterarBotao(2); 115 | dispararAlerta('Processo Finalizado! Agora você será redirecionado a página principal do Projeto!', 'success'); 116 | setTimeout(() => { 117 | window.location.href = 'Index.php'; 118 | }, 2500); 119 | } 120 | -------------------------------------------------------------------------------- /public_html/static/js/composer-install.min.js: -------------------------------------------------------------------------------- 1 | let d=document;async function iniciar(){let counter=0,retorno=!1;for(;counter<3;){if(counter++,d.querySelector("#textArea").innerHTML+=`\n------------------------------------------------------------------\n TENTATIVA ${counter}\n------------------------------------------------------------------\n`,retorno=await instalar(),!retorno.erro){dispararSucesso();break}adicionarNoLog(retorno.log)}if(retorno.erro){let texto="Limite máximo de tentativas excedido. Verifique o LOG e se necessário tente novamente!";dispararAlerta(texto),dispararErro(texto),alterarBotao(0)}}async function instalar(){let concluido=!1,log="",diretorio="Index.php",form=new FormData;return form.append("instalar","S"),await fetch(new Request(diretorio,{method:"POST",body:form})).then(resposta=>resposta.json()).then(retorno=>{retorno.erro?log=retorno.log:concluido=!0}).catch(erro=>{adicionarNoLog(erro)}),console.log(log.indexOf("Generating autoload files")),log.indexOf("Generating autoload files")>0?{erro:!1,log:log}:{erro:!concluido,log:log}}function adicionarNoLog(texto){let data=Date(Date.now());d.querySelector("#textArea").innerHTML+=data.toLocaleString("pt-BR",{dateStyle:"short"})+"\n"+texto,d.querySelector("#textArea").innerHTML+="\n--------------------------------------------------------------------------------\n"}function alterarBotao(tipo){switch(tipo){case 1:d.querySelector("#btnIniciar > span").innerHTML="Erro!",d.querySelector("#btnIniciar > em").classList.add("d-none"),d.querySelector("#btnIniciar > em").classList.remove("d-inline-block");break;case 2:d.querySelector("#btnIniciar > span").innerHTML="Sucesso!",d.querySelector("#btnIniciar > em").classList.add("d-none"),d.querySelector("#btnIniciar > em").classList.remove("d-inline-block");break;case 0:default:d.querySelector("#btnIniciar").removeAttribute("disabled"),d.querySelector("#btnIniciar > em").classList.add("d-none"),d.querySelector("#btnIniciar > em").classList.remove("d-inline-block"),d.querySelector("#btnIniciar > span").innerHTML="Clique Aqui"}}function dispararErro(texto){adicionarNoLog(texto),alterarBotao(1),setTimeout(()=>{alterarBotao(0)},2500)}function dispararSucesso(){alterarBotao(2),dispararAlerta("Processo Finalizado! Agora você será redirecionado a página principal do Projeto!","success"),setTimeout(()=>{window.location.href="Index.php"},2500)}d.addEventListener("DOMContentLoaded",()=>{d.querySelector("#btnIniciar").addEventListener("click",()=>{d.querySelector("#btnIniciar").setAttribute("disabled","disabled"),d.querySelector("#btnIniciar > span").innerHTML="Aguarde",d.querySelector("#btnIniciar > em").classList.remove("d-none"),d.querySelector("#btnIniciar > em").classList.add("d-inline-block"),dispararAlerta("Este processo pode ser demorado...","info"),adicionarNoLog("Iniciando a Instalação das dependências"),adicionarNoLog("Este processo pode ser demorado..."),iniciar()})}); -------------------------------------------------------------------------------- /public_html/static/js/funcoes.js: -------------------------------------------------------------------------------- 1 | function dispararAlerta(msg, status = 'warning', time = 5000, icon = '') { 2 | $('.alert').remove(); 3 | $.notify({ 4 | icon: icon, 5 | message: msg 6 | }, { 7 | type: status, 8 | allow_dismiss: true, 9 | newest_on_top: true, 10 | showProgressbar: false, 11 | placement: { 12 | from: "top", 13 | align: "center" 14 | }, 15 | z_index: 1031, 16 | delay: time, 17 | timer: 200, 18 | animate: { 19 | enter: 'animated fadeInDown', 20 | exit: 'animated fadeOutUp' 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /public_html/static/js/funcoes.min.js: -------------------------------------------------------------------------------- 1 | function dispararAlerta(msg,status="warning",time=5e3,icon=""){$(".alert").remove(),$.notify({icon:icon,message:msg},{type:status,allow_dismiss:!0,newest_on_top:!0,showProgressbar:!1,placement:{from:"top",align:"center"},z_index:1031,delay:time,timer:200,animate:{enter:"animated fadeInDown",exit:"animated fadeOutUp"}})} -------------------------------------------------------------------------------- /public_html/static/js/notify.min.js: -------------------------------------------------------------------------------- 1 | /* Project: Bootstrap Growl = v3.1.3 | Description: Turns standard Bootstrap alerts into "Growl-like" notifications. | Author: Mouse0270 aka Robert McIntosh | License: MIT License | Website: https://github.com/mouse0270/bootstrap-growl */ 2 | !function (t) { "function" == typeof define && define.amd ? define(["jquery"], t) : t("object" == typeof exports ? require("jquery") : jQuery) }(function (t) { function e(e, i, n) { var i = { content: { message: "object" == typeof i ? i.message : i, title: i.title ? i.title : "", icon: i.icon ? i.icon : "", url: i.url ? i.url : "#", target: i.target ? i.target : "-" } }; n = t.extend(!0, {}, i, n), this.settings = t.extend(!0, {}, s, n), this._defaults = s, "-" == this.settings.content.target && (this.settings.content.target = this.settings.url_target), this.animations = { start: "webkitAnimationStart oanimationstart MSAnimationStart animationstart", end: "webkitAnimationEnd oanimationend MSAnimationEnd animationend" }, "number" == typeof this.settings.offset && (this.settings.offset = { x: this.settings.offset, y: this.settings.offset }), this.init() } var s = { element: "body", position: null, type: "info", allow_dismiss: !0, newest_on_top: !1, showProgressbar: !1, placement: { from: "top", align: "right" }, offset: 20, spacing: 10, z_index: 1031, delay: 5e3, timer: 1e3, url_target: "_blank", mouse_over: null, animate: { enter: "animated fadeInDown", exit: "animated fadeOutUp" }, onShow: null, onShown: null, onClose: null, onClosed: null, icon_type: "class", template: '' }; String.format = function () { for (var t = arguments[0], e = 1; e < arguments.length; e++)t = t.replace(RegExp("\\{" + (e - 1) + "\\}", "gm"), arguments[e]); return t }, t.extend(e.prototype, { init: function () { var t = this; this.buildNotify(), this.settings.content.icon && this.setIcon(), "#" != this.settings.content.url && this.styleURL(), this.placement(), this.bind(), this.notify = { $ele: this.$ele, update: function (e, s) { var i = {}; "string" == typeof e ? i[e] = s : i = e; for (var e in i) switch (e) { case "type": this.$ele.removeClass("alert-" + t.settings.type), this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass("progress-bar-" + t.settings.type), t.settings.type = i[e], this.$ele.addClass("alert-" + i[e]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-" + i[e]); break; case "icon": var n = this.$ele.find('[data-notify="icon"]'); "class" == t.settings.icon_type.toLowerCase() ? n.removeClass(t.settings.content.icon).addClass(i[e]) : (n.is("img") || n.find("img"), n.attr("src", i[e])); break; case "progress": var a = t.settings.delay - t.settings.delay * (i[e] / 100); this.$ele.data("notify-delay", a), this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow", i[e]).css("width", i[e] + "%"); break; case "url": this.$ele.find('[data-notify="url"]').attr("href", i[e]); break; case "target": this.$ele.find('[data-notify="url"]').attr("target", i[e]); break; default: this.$ele.find('[data-notify="' + e + '"]').html(i[e]) }var o = this.$ele.outerHeight() + parseInt(t.settings.spacing) + parseInt(t.settings.offset.y); t.reposition(o) }, close: function () { t.close() } } }, buildNotify: function () { var e = this.settings.content; this.$ele = t(String.format(this.settings.template, this.settings.type, e.title, e.message, e.url, e.target)), this.$ele.attr("data-notify-position", this.settings.placement.from + "-" + this.settings.placement.align), this.settings.allow_dismiss || this.$ele.find('[data-notify="dismiss"]').css("display", "none"), (this.settings.delay <= 0 && !this.settings.showProgressbar || !this.settings.showProgressbar) && this.$ele.find('[data-notify="progressbar"]').remove() }, setIcon: function () { "class" == this.settings.icon_type.toLowerCase() ? this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon) : this.$ele.find('[data-notify="icon"]').is("img") ? this.$ele.find('[data-notify="icon"]').attr("src", this.settings.content.icon) : this.$ele.find('[data-notify="icon"]').append('37 |42 |38 | 39 | 40 |41 |') }, styleURL: function () { this.$ele.find('[data-notify="url"]').css({ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)", height: "100%", left: "0px", position: "absolute", top: "0px", width: "100%", zIndex: this.settings.z_index + 1 }), this.$ele.find('[data-notify="dismiss"]').css({ position: "absolute", right: "10px", top: "5px", zIndex: this.settings.z_index + 2 }) }, placement: function () { var e = this, s = this.settings.offset.y, i = { display: "inline-block", margin: "0px auto", position: this.settings.position ? this.settings.position : "body" === this.settings.element ? "fixed" : "absolute", transition: "all .5s ease-in-out", zIndex: this.settings.z_index }, n = !1, a = this.settings; switch (t('[data-notify-position="' + this.settings.placement.from + "-" + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { return s = Math.max(s, parseInt(t(this).css(a.placement.from)) + parseInt(t(this).outerHeight()) + parseInt(a.spacing)) }), 1 == this.settings.newest_on_top && (s = this.settings.offset.y), i[this.settings.placement.from] = s + "px", this.settings.placement.align) { case "left": case "right": i[this.settings.placement.align] = this.settings.offset.x + "px"; break; case "center": i.left = 0, i.right = 0 }this.$ele.css(i).addClass(this.settings.animate.enter), t.each(Array("webkit", "moz", "o", "ms", ""), function (t, s) { e.$ele[0].style[s + "AnimationIterationCount"] = 1 }), t(this.settings.element).append(this.$ele), 1 == this.settings.newest_on_top && (s = parseInt(s) + parseInt(this.settings.spacing) + this.$ele.outerHeight(), this.reposition(s)), t.isFunction(e.settings.onShow) && e.settings.onShow.call(this.$ele), this.$ele.one(this.animations.start, function () { n = !0 }).one(this.animations.end, function () { t.isFunction(e.settings.onShown) && e.settings.onShown.call(this) }), setTimeout(function () { n || t.isFunction(e.settings.onShown) && e.settings.onShown.call(this) }, 600) }, bind: function () { var e = this; if (this.$ele.find('[data-notify="dismiss"]').on("click", function () { e.close() }), this.$ele.mouseover(function () { t(this).data("data-hover", "true") }).mouseout(function () { t(this).data("data-hover", "false") }), this.$ele.data("data-hover", "false"), this.settings.delay > 0) { e.$ele.data("notify-delay", e.settings.delay); var s = setInterval(function () { var t = parseInt(e.$ele.data("notify-delay")) - e.settings.timer; if ("false" === e.$ele.data("data-hover") && "pause" == e.settings.mouse_over || "pause" != e.settings.mouse_over) { var i = (e.settings.delay - t) / e.settings.delay * 100; e.$ele.data("notify-delay", t), e.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow", i).css("width", i + "%") } t <= - e.settings.timer && (clearInterval(s), e.close()) }, e.settings.timer) } }, close: function () { var e = this, s = parseInt(this.$ele.css(this.settings.placement.from)), i = !1; this.$ele.data("closing", "true").addClass(this.settings.animate.exit), e.reposition(s), t.isFunction(e.settings.onClose) && e.settings.onClose.call(this.$ele), this.$ele.one(this.animations.start, function () { i = !0 }).one(this.animations.end, function () { t(this).remove(), t.isFunction(e.settings.onClosed) && e.settings.onClosed.call(this) }), setTimeout(function () { i || (e.$ele.remove(), e.settings.onClosed && e.settings.onClosed(e.$ele)) }, 600) }, reposition: function (e) { var s = this, i = '[data-notify-position="' + this.settings.placement.from + "-" + this.settings.placement.align + '"]:not([data-closing="true"])', n = this.$ele.nextAll(i); 1 == this.settings.newest_on_top && (n = this.$ele.prevAll(i)), n.each(function () { t(this).css(s.settings.placement.from, e), e = parseInt(e) + parseInt(s.settings.spacing) + t(this).outerHeight() }) } }), t.notify = function (t, s) { var i = new e(this, t, s); return i.notify }, t.notifyDefaults = function (e) { return s = t.extend(!0, {}, s, e) }, t.notifyClose = function (e) { "undefined" == typeof e || "all" == e ? t("[data-notify]").find('[data-notify="dismiss"]').trigger("click") : t('[data-notify-position="' + e + '"]').find('[data-notify="dismiss"]').trigger("click") } }); 3 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.language = php 2 | 3 | sonar.sourceEncoding = UTF-8 4 | -------------------------------------------------------------------------------- /src/Arrays.php: -------------------------------------------------------------------------------- 1 | null]), array_keys($array), true)); 14 | } 15 | 16 | public static function renameKey(array &$array, string $oldKey, string $newKey): bool 17 | { 18 | $offset = self::searchKey($array, $oldKey); 19 | if ($offset === null) { 20 | return false; 21 | } 22 | $val = &$array[$oldKey]; 23 | $keys = array_keys($array); 24 | $keys[$offset] = $newKey; 25 | $array = array_combine($keys, $array); 26 | $array[$newKey] = &$val; 27 | return true; 28 | } 29 | 30 | public static function checkExistIndexByValue(array $arrayCollection, string $search): bool 31 | { 32 | foreach ($arrayCollection as $array) { 33 | $indice = (!is_array($array) && ($search === strval($array))) ? true : false; 34 | if ((is_array($array) && self::checkExistIndexByValue($array, $search)) || $indice) { 35 | unset($indice); 36 | return true; 37 | } 38 | } 39 | return false; 40 | } 41 | 42 | public static function findValueByKey(array $array, string $searchKey): array 43 | { 44 | $retorno = []; 45 | foreach ($array as $key => $value) { 46 | if (strval(strtolower($key)) === strtolower($searchKey)) { 47 | $retorno[$key] = $value; 48 | } else { 49 | if (is_array($value)) { 50 | $retorno[$key] = self::findValueByKey($value, $searchKey); 51 | } 52 | } 53 | } 54 | return array_filter($retorno); 55 | } 56 | 57 | public static function findIndexByValue(array $array, string | int | bool $searchValue): array 58 | { 59 | $retorno = []; 60 | foreach ($array as $key => $value) { 61 | if (!is_array($value) && ($value === $searchValue)) { 62 | $retorno[$key] = $value; 63 | } else { 64 | if (is_array($value)) { 65 | $retorno[$key] = self::findIndexByValue($value, $searchValue); 66 | } 67 | } 68 | } 69 | return array_filter($retorno); 70 | } 71 | 72 | public static function convertArrayToXml(array $array, object &$xml): void 73 | { 74 | foreach ($array as $key => $value) { 75 | if (is_numeric($key)) { 76 | $key = $value['@attr']; 77 | } 78 | if (is_array($value)) { 79 | unset($value['@attr']); 80 | $subnode = $xml->addChild($key); 81 | 82 | self::convertArrayToXml($value, $subnode); 83 | } else { 84 | $xml->addChild("$key", strtoupper(htmlspecialchars("$value"))); 85 | } 86 | } 87 | } 88 | 89 | public static function convertJsonIndexToArray(array &$array): void 90 | { 91 | array_walk_recursive($array, function (&$value) { 92 | if (is_string($value) && !empty($value)) { 93 | $arr = json_decode($value, true); 94 | if (is_array($arr) && (json_last_error() === JSON_ERROR_NONE)) { 95 | $value = $arr; 96 | } 97 | } 98 | 99 | if (is_array($value)) { 100 | self::convertJsonIndexToArray($value); 101 | } 102 | }); 103 | } 104 | 105 | public static function checkExistIndexArrayRecursive( 106 | ?array $array, 107 | ?string $needle, 108 | bool &$aux = false, 109 | ): bool { 110 | if (!empty($array)) { 111 | foreach ($array as $key => $value) { 112 | if ($key === $needle) { 113 | $aux = true; 114 | } elseif (is_array($value)) { 115 | self::checkExistIndexArrayRecursive($value, $needle, $aux); 116 | } 117 | } 118 | } 119 | return $aux; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/CI.php: -------------------------------------------------------------------------------- 1 |
\n"; 5 | exit(-1); 6 | } 7 | 8 | $file = $argv[1]; 9 | $threshold = floatval($argv[2]); 10 | 11 | $coverage = simplexml_load_file($file); 12 | $ratio = !empty($coverage) ? floatval($coverage->project->directory->totals->lines["percent"]) : 0; 13 | 14 | if ($ratio < $threshold) { 15 | throw new InvalidArgumentException("[FAIL] Code coverage is $ratio% (required minimum is $threshold%)"); 16 | } 17 | 18 | echo "[PASS] Code coverage is $ratio% (required minimum is $threshold%)."; 19 | -------------------------------------------------------------------------------- /src/Compare.php: -------------------------------------------------------------------------------- 1 | -1) { 13 | $dtIni = implode('-', array_reverse(explode('/', $dtIni))); 14 | } 15 | if (strpos($dtFin, '/') > -1) { 16 | $dtFin = implode('-', array_reverse(explode('/', $dtFin))); 17 | } 18 | 19 | $datetime1 = new DateTime($dtIni); 20 | $datetime2 = new DateTime($dtFin); 21 | $interval = $datetime1->diff($datetime2); 22 | 23 | return $interval->format('%R%a'); 24 | } 25 | 26 | public static function startDateLessThanEnd(?string $dtIni, ?string $dtFin): bool 27 | { 28 | if (!empty($dtIni) && !empty($dtFin)) { 29 | if (str_replace('+', '', self::daysDifferenceBetweenData($dtIni, $dtFin)) < '0') { 30 | return false; 31 | } 32 | } else { 33 | return false; 34 | } 35 | return true; 36 | } 37 | 38 | public static function startHourLessThanEnd( 39 | string $hourIni, 40 | string $hourFin, 41 | string $msg = 'Hora Inicial não pode ser maior que a Hora Final!', 42 | ): ?string { 43 | if (!empty($hourIni) && !empty($hourFin)) { 44 | $diff = self::differenceBetweenHours($hourIni, $hourFin); 45 | if (substr($diff, 0, 1) === '-') { 46 | return $msg; 47 | } 48 | } else { 49 | return 'Um ou mais campos horas não foram preenchidos!'; 50 | } 51 | return null; 52 | } 53 | 54 | public static function calculateAgeInYears(string $date): int 55 | { 56 | if (strpos($date, '/') > -1) { 57 | $date = implode('-', array_reverse(explode('/', $date))); 58 | } 59 | $dateBirth = new DateTime($date, new DateTimeZone('America/Sao_Paulo')); 60 | $dataNow = new DateTime("now", new DateTimeZone('America/Sao_Paulo')); 61 | $diff = $dataNow->diff($dateBirth); 62 | return intval($diff->format("%y")); 63 | } 64 | 65 | public static function differenceBetweenHours(string $hourIni, string $hourFin): string 66 | { 67 | $i = 1; 68 | $timeTotal = null; 69 | $times = [$hourFin, $hourIni]; 70 | 71 | foreach ($times as $time) { 72 | $seconds = 0; 73 | list($h, $m, $s) = explode(':', $time); 74 | 75 | $seconds += intval($h) * 3600; 76 | $seconds += intval($m) * 60; 77 | $seconds += intval($s); 78 | 79 | $timeTotal[$i] = $seconds; 80 | $i++; 81 | } 82 | $seconds = $timeTotal[1] - $timeTotal[2]; 83 | $hours = floor($seconds / 3600); 84 | $seconds -= $hours * 3600; 85 | $minutes = str_pad(strval((floor($seconds / 60))), 2, '0', STR_PAD_LEFT); 86 | $seconds -= intval($minutes) * 60; 87 | 88 | if (substr(strval($hours), 0, 1) === '-') { 89 | $hours = '-' . str_pad(substr(strval($hours), 1, 2), 2, '0', STR_PAD_LEFT); 90 | } else { 91 | $hours = str_pad(strval($hours), 2, '0', STR_PAD_LEFT); 92 | } 93 | return "$hours:$minutes:$seconds"; 94 | } 95 | 96 | public static function checkDataEquality( 97 | string $firstValue, 98 | string $secoundValue, 99 | bool $caseSensitive = true, 100 | ): bool { 101 | if ($caseSensitive) { 102 | if ($firstValue !== $secoundValue) { 103 | return false; 104 | } 105 | } else { 106 | if (0 !== strcasecmp($firstValue, $secoundValue)) { 107 | return false; 108 | } 109 | } 110 | return true; 111 | } 112 | 113 | public static function contains(string $value, string $search): bool 114 | { 115 | return strpos($value, $search) !== false; 116 | } 117 | 118 | public static function compareStringFrom(string $search, string $str, int $start, int $length): bool 119 | { 120 | if ($str === $search) { 121 | return true; 122 | } 123 | if (substr($str, $start, $length) === $search) { 124 | return true; 125 | } 126 | return false; 127 | } 128 | 129 | public static function beginUrlWith(string $search, string $url): bool 130 | { 131 | $newSearch = strtoupper(str_replace('/', '', $search)); 132 | $urlLessDivideBar = strtoupper(str_replace('/', '', $url)); 133 | return self::compareStringFrom($newSearch, $urlLessDivideBar, 0, strlen($newSearch)); 134 | } 135 | 136 | public static function finishUrlWith(string $search, string $url): bool 137 | { 138 | $newSearch = strtoupper(str_replace('/', '', $search)); 139 | $urlLessDivideBar = strtoupper(str_replace('/', '', $url)); 140 | return self::compareStringFrom( 141 | $newSearch, 142 | $urlLessDivideBar, 143 | (strlen($urlLessDivideBar) - strlen($newSearch)), 144 | strlen($urlLessDivideBar) 145 | ); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/DependencyInjection/FormatAux.php: -------------------------------------------------------------------------------- 1 | 0 ? 1 : 2); 86 | 87 | for ($i = 0; $i < count($integer); $i++) { 88 | $value = $integer[$i]; 89 | 90 | $rc = (($value > 100) && ($value < 200)) ? 'cento' : $hundred[$value[0]]; 91 | $rd = ($value[1] < 2) ? '' : $ten[$value[1]]; 92 | $rp = ($value[1] == 1) ? $ten10[$value[2]] : $unitary[$value[2]]; 93 | $ru = ($value > 0) ? $rp : ''; 94 | $r = $rc . (($rc && ($rd || $ru)) ? ' e ' : '') . $rd . (($rd && $ru) ? ' e ' : '') . $ru; 95 | $t = count($integer) - 1 - $i; 96 | $s = $value > 1 ? $plural[$t] : $singular[$t]; 97 | $r .= $r ? ' ' . $s : ""; 98 | 99 | if ($value === '000') { 100 | $z++; 101 | } elseif ($z > 0) { 102 | $z--; 103 | } 104 | 105 | if (($t === 1) && ($z > 0) && ($integer[0] > 0)) { 106 | $r .= (($z > 1) ? ' de ' : ' ') . $plural[$t]; 107 | } 108 | if ($r) { 109 | $st = ($i < $end) ? ', ' : ' e '; 110 | $accumulator = $accumulator . ((($i > 0) && ($i <= $end) && ($integer[0] > 0) && ($z < 1)) 111 | ? $st : '') . $r; 112 | } 113 | } 114 | return ($accumulator ? $accumulator : 'zero'); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/DependencyInjection/Rules.php: -------------------------------------------------------------------------------- 1 | errors[$field] = $msg; 37 | } 38 | 39 | private function validateHandleErrorsInArray(array $errorList = [], string $field = ''): void 40 | { 41 | if (!empty($errorList)) { 42 | if (array_key_exists($field, $this->errors)) { 43 | foreach ($errorList as $error) { 44 | array_push($this->errors[$field], $error); 45 | } 46 | $this->errors[$field] = array_unique($this->errors[$field]); 47 | } else { 48 | $this->errors[$field] = $errorList; 49 | } 50 | } 51 | } 52 | 53 | protected function prepareCharset(string $string = '', string $convert = 'UTF-8', bool $bom = false): string 54 | { 55 | $bomchar = pack('H*', 'EFBBBF'); 56 | $regex = preg_replace("/^$bomchar/", '', $string) ?? ''; 57 | $string = trim($regex); 58 | static $enclist = [ 59 | 'UTF-8', 60 | 'ASCII', 61 | 'ISO-8859-1', 62 | 'ISO-8859-2', 63 | 'ISO-8859-3', 64 | 'ISO-8859-4', 65 | 'ISO-8859-5', 66 | 'ISO-8859-6', 67 | 'ISO-8859-7', 68 | 'ISO-8859-8', 69 | 'ISO-8859-9', 70 | 'ISO-8859-10', 71 | 'ISO-8859-13', 72 | 'ISO-8859-14', 73 | 'ISO-8859-15', 74 | 'ISO-8859-16', 75 | 'Windows-1251', 76 | 'Windows-1252', 77 | 'Windows-1254', 78 | ]; 79 | $charsetType = mb_detect_encoding($string); 80 | foreach ($enclist as $item) { 81 | $converted = iconv($item, $item . '//IGNORE', $string); 82 | if (sha1(strval($converted)) == sha1(strval($string))) { 83 | $charsetType = $item; 84 | break; 85 | } 86 | } 87 | if (strtoupper(trim($charsetType)) != strtoupper(trim($convert))) { 88 | return ($bom ? $bomchar : '') . iconv($charsetType, $convert . '//TRANSLIT', $string); 89 | } 90 | return ($bom ? $bomchar : '') . $string; 91 | } 92 | 93 | public static function functionsValidation(): array 94 | { 95 | $data = self::functionsValidationAtoL(); 96 | $data += self::functionsValidationMtoN(); 97 | return $data += self::functionsValidationOtoZ(); 98 | } 99 | 100 | protected function validateOptional(): bool 101 | { 102 | return true; 103 | } 104 | 105 | protected function validateFieldMandatory( 106 | string $field = '', 107 | mixed $value = null, 108 | ?string $message = null, 109 | ): array | string { 110 | if (is_array($value) && (count($value) <= 0)) { 111 | return $this->errors[$field] = !empty($message) ? $message : "O campo $field é obrigatório!"; 112 | } 113 | if ( 114 | !isset($value) 115 | || $value === false 116 | || (is_string($value) && empty(trim($value))) && strval($value) !== '0' 117 | ) { 118 | return $this->errors[$field] = !empty($message) ? $message : "O campo $field é obrigatório!"; 119 | } 120 | return []; 121 | } 122 | 123 | protected function validateFieldType( 124 | string $rule = '', 125 | string $field = '', 126 | mixed $value = null, 127 | ?string $message = null, 128 | ): void { 129 | if (in_array(trim(strtolower($rule)), self::RULES_WITHOUT_FUNCS)) { 130 | return; 131 | } 132 | 133 | $method = trim(self::functionsValidation()[trim($rule)] ?? 'invalidRule'); 134 | 135 | $call = [$this, $method]; 136 | //chama há função de validação, de cada parametro json 137 | if (is_callable($call, true, $method)) { 138 | if (in_array(substr($method, 20), $this->methodsNoRuleValue())) { 139 | call_user_func_array($call, [$field, $value, $message]); 140 | } elseif ($method === 'validateEquals') { 141 | call_user_func_array($call, [$rule, $field, $value, $message]); 142 | } else { 143 | call_user_func_array($call, [$rule, $field, $value, $message]); 144 | } 145 | } else { 146 | $this->errors[$field] = "Há regras de validação não implementadas no campo $field!"; 147 | } 148 | } 149 | 150 | protected function levelSubLevelsArrayReturnJson(array $data, bool $recursive = false): mixed 151 | { 152 | //funcao recurssiva para tratar array e retornar json valido 153 | //essa função serve para validar dados com json_encode múltiplos, e indices quebrados na estrutura 154 | foreach ($data as $key => $val) { 155 | $key = $this->prepareCharset($key, 'UTF-8'); 156 | if (is_string($val) && !empty($val)) { 157 | $arr = json_decode($val, true); 158 | if (is_array($arr) && (json_last_error() === JSON_ERROR_NONE)) { 159 | $val = $arr; 160 | } 161 | } 162 | if (is_array($val)) { 163 | $data[$key] = $this->levelSubLevelsArrayReturnJson($val, true); 164 | } elseif (is_string($val)) { 165 | $data[$key] = $this->prepareCharset(addslashes(strip_tags($val)), 'UTF-8'); 166 | } 167 | } 168 | if ($recursive) { 169 | return $data; 170 | } 171 | // Pré-processa cada valor em $data 172 | $data = $this->preProcess($data); 173 | //se for raiz retorna json 174 | $json = json_encode( 175 | $data, 176 | JSON_UNESCAPED_UNICODE 177 | ) ?: ''; 178 | // Remove quebras de linha, tabulações 179 | return str_replace(["\r", "\n", "\t"], '', $json); 180 | } 181 | 182 | protected function preProcess(mixed $value): mixed 183 | { 184 | if (is_array($value)) { 185 | foreach ($value as $key => $item) { 186 | $value[$key] = $this->preProcess($item); 187 | } 188 | return $value; 189 | } elseif (is_string($value)) { 190 | return preg_replace('/\\\\(?!["\\\\\/bfnrtu])/', '', $value); 191 | } 192 | return $value; 193 | } 194 | 195 | protected function validateSubLevelData( 196 | array $data, 197 | array $rules, 198 | ): array | bool { 199 | //percorre o array de validação para não rodar recurssivamente atoa 200 | foreach ($rules as $key => $val) { 201 | //se for um objeto no primeiro nivel, valida recurssivo 202 | if ((array_key_exists($key, $data) && is_array($data[$key])) && is_array($val)) { 203 | $this->validateSubLevelData($data[$key], $rules[$key]); 204 | } 205 | //valida campos filhos required, porém não existe no array de dados 206 | if (empty($data) && is_array($val) && (strpos(trim(strtolower(strval(json_encode($val)))), 'required'))) { 207 | $this->errors[$key] = "Não foi encontrado o indice $key, campos filhos são obrigatórios!"; 208 | return false; 209 | } 210 | //validação campo a campo 211 | if (is_string($val)) { 212 | $this->validateRuleField($key, ($data[$key] ?? null), $val, array_key_exists($key, $data), $data); 213 | } 214 | } 215 | return $rules; 216 | } 217 | 218 | protected function validateRuleField( 219 | mixed $field, 220 | mixed $value, 221 | mixed $rules, 222 | bool $valid = false, 223 | array $data = [], 224 | ): array { 225 | //se o campo é valido, ele existe no json de dados, no mesmo nivel que a regra 226 | if ($valid) { 227 | //transforma a string json de validação em array para validação 228 | $rulesArray = is_array($rules) ? $rules : []; 229 | if (is_string($rules) && !empty($rules)) { 230 | $rulesArray = json_decode($rules, true); 231 | if (json_last_error() !== JSON_ERROR_NONE) { 232 | $rulesArray = []; 233 | // Suporte ao padrão PIPE, exemplo: 'int|required|min:14|max:14'. 234 | $rulesConf = explode('|', trim($rules)); 235 | if ( 236 | !in_array('optional', $rulesConf) 237 | || (in_array('optional', $rulesConf) && !empty($value) && $value !== 'null') 238 | ) { 239 | foreach ($rulesConf as $valueRuleConf) { 240 | $conf = preg_split('/[\,]/', trim($valueRuleConf), 2); 241 | $ruleArrayConf = explode(':', is_array($conf) ? $conf[0] : ''); 242 | $regEx = (trim(strtolower($ruleArrayConf[0])) == 'regex') ? true : false; 243 | 244 | if (isset($ruleArrayConf[1]) && (strpos($valueRuleConf, ';') > 0) && !$regEx) { 245 | $ruleArrayConf[1] = explode(';', $ruleArrayConf[1]); 246 | } 247 | if (is_array($conf) && array_key_exists(1, $conf) && !empty($conf[1])) { 248 | $rulesArray['mensagem'] = trim(strip_tags($conf[1])); 249 | } 250 | $keyConf = $ruleArrayConf[0]; 251 | $rulesArray[strval($keyConf)] = $ruleArrayConf[1] ?? true; 252 | } 253 | } 254 | } 255 | } 256 | $rulesArray = !empty($rulesArray) && is_array($rulesArray) ? $rulesArray : []; 257 | //irá chamar uma função para cada validação no json de validação, passando o valor para a função 258 | $msgCustomized = $rulesArray['mensagem'] ?? null; 259 | if (array_key_exists('mensagem', $rulesArray)) { 260 | unset($rulesArray['mensagem']); 261 | } 262 | foreach ($rulesArray as $key => $val) { 263 | $val = is_numeric($val) ? intval($val) : $val; 264 | $ruleValue = (!empty($val) || ($val === 0)) ? true : false; 265 | if (!in_array('optional', $rulesArray) || (in_array('optional', $rulesArray) && $ruleValue)) { 266 | if (in_array(trim(strtolower($key)), self::RULES_WITHOUT_FUNCS)) { 267 | continue; 268 | } 269 | $auxValue = $this->errors[$field] ?? ''; 270 | if (is_array($auxValue)) { 271 | foreach ($this->errors[$field] as $chaveErro => $valueErro) { 272 | $auxValue = $this->errors[$field][$chaveErro]; 273 | if ( 274 | !empty($auxValue) 275 | && (is_string($auxValue) && Compare::contains($auxValue, 'obrigatório!')) 276 | ) { 277 | $this->errors[$field][$chaveErro] = 'O campo ' . strval($field) . ' é obrigatório!'; 278 | } else { 279 | $method = trim(Rules::functionsValidation()[trim($key)] ?? 'invalidRule'); 280 | $call = [$this, $method]; 281 | //chama a função de validação, de cada parametro json 282 | if (is_callable($call, true, $method)) { 283 | if ( 284 | in_array(substr($method, 20), $this->methodsNoRuleValue()) 285 | || in_array($method, $this->methodsNoRuleValue()) 286 | ) { 287 | call_user_func_array($call, [$field, $value, $msgCustomized]); 288 | } elseif (substr($method, 20) === 'validateEquals') { 289 | call_user_func_array($call, [$val, $field, $value, $msgCustomized, $data]); 290 | } else { 291 | call_user_func_array($call, [$val, $field, $value, $msgCustomized]); 292 | } 293 | } else { 294 | $this->errors[$field][$chaveErro] = 'Há regras de validação não implementadas' . 295 | 'no campo ' . strval($field) . '!'; 296 | } 297 | } 298 | } 299 | } 300 | 301 | if (is_string($auxValue)) { 302 | if (!empty($this->errors[$field]) && Compare::contains($auxValue, 'obrigatório!')) { 303 | $this->errors[$field] = 'O campo ' . strval($field) . ' é obrigatório!'; 304 | } else { 305 | $method = trim(Rules::functionsValidation()[trim($key)] ?? 'invalidRule'); 306 | $call = [$this, $method]; 307 | //chama a função de validação, de cada parametro json 308 | if (is_callable($call, true, $method)) { 309 | if ( 310 | in_array(substr($method, 20), $this->methodsNoRuleValue()) 311 | || in_array($method, $this->methodsNoRuleValue()) 312 | ) { 313 | call_user_func_array($call, [$field, $value, $msgCustomized]); 314 | } elseif (substr($method, 20) === 'validateEquals') { 315 | call_user_func_array($call, [$val, $field, $value, $msgCustomized, $data]); 316 | } else { 317 | call_user_func_array($call, [$val, $field, $value, $msgCustomized]); 318 | } 319 | } else { 320 | $this->errors[$field] = 'Há regras de validação não implementadas no campo ' 321 | . strval($field) . '!'; 322 | } 323 | } 324 | } 325 | } 326 | } 327 | return []; 328 | } else { 329 | //se o campo é invalido, ele não existe no json de dados no mesmo nivel que a regra 330 | //aqui valida se na regra há filhos obrigatorios para esse campo 331 | $rulesArray = is_array($rules) ? $rules : []; 332 | if (is_string($rules) && !empty($rules)) { 333 | $rulesArray = json_decode($rules, true); 334 | if (json_last_error() !== JSON_ERROR_NONE) { 335 | $rulesArray = []; 336 | //suporte ao padrão PIPE 337 | //'int|required|min:14|max:14', 338 | $rulesConf = explode('|', trim($rules)); 339 | foreach ($rulesConf as $valueRuleConf) { 340 | $ruleArrayConf = explode(':', trim($valueRuleConf)); 341 | $rulesArray[$ruleArrayConf[0]] = $ruleArrayConf[1] ?? true; 342 | } 343 | } 344 | } 345 | $rulesArray = is_array($rulesArray) ? $rulesArray : []; 346 | $jsonRules = $this->levelSubLevelsArrayReturnJson($rulesArray); 347 | $compareA = strpos(trim(strtolower(strval($jsonRules))), 'required'); 348 | if ($compareA !== false) { 349 | $msg = 'O campo: ' . strval($field) . ' não foi encontrado nos dados de entrada, indices filhos são '; 350 | $msg .= 'obrigatórios!'; 351 | if ( 352 | count(array_filter(array_values((array) json_decode(strval($jsonRules), true)), 'is_array')) 353 | === 0 354 | ) { 355 | $msg = 'O campo obrigatório ' . strval($field) . ' não foi encontrado nos dados de entrada!'; 356 | } 357 | $this->errors[$field] = $msg; 358 | } 359 | return $this->errors; 360 | } 361 | } 362 | 363 | protected function validateBoolean(string $field = '', ?string $value = null, ?string $message = null): void 364 | { 365 | if (!filter_var($value, FILTER_VALIDATE_BOOLEAN)) { 366 | $this->errors[$field] = !empty($message) ? 367 | $message : "O campo $field só pode conter valores lógicos. (true, 1, yes)!"; 368 | } 369 | } 370 | 371 | protected function validateFloating(string $field = '', ?string $value = null, ?string $message = null): void 372 | { 373 | if (!filter_var($value, FILTER_VALIDATE_FLOAT)) { 374 | $this->errors[$field] = !empty($message) ? 375 | $message : "O campo $field deve ser do tipo real(flutuante)!"; 376 | } 377 | } 378 | 379 | protected function validateJson(string $field, mixed $value, ?string $message = null): void 380 | { 381 | $value = is_array($value) ? json_encode($value) : $value; 382 | if (is_string($value)) { 383 | $arr = json_decode($value, true); 384 | if (!is_array($arr) || (json_last_error() !== JSON_ERROR_NONE)) { 385 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não contém um json válido!"; 386 | } 387 | } else { 388 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não contém um json válido!"; 389 | } 390 | } 391 | } 392 | -------------------------------------------------------------------------------- /src/DependencyInjection/StrfTime.php: -------------------------------------------------------------------------------- 1 | 'EEE', 36 | '%A' => 'EEEE', 37 | '%b' => 'MMM', 38 | '%B' => 'MMMM', 39 | '%h' => 'MMM', 40 | ]; 41 | 42 | $intlFormatter = function (DateTimeInterface $timestamp, string $format) use ($intlFormats, $locale) { 43 | $tz = $timestamp->getTimezone(); 44 | $dateType = IntlDateFormatter::FULL; 45 | $timeType = IntlDateFormatter::FULL; 46 | $pattern = ''; 47 | 48 | switch ($format) { 49 | case '%c': 50 | $dateType = IntlDateFormatter::LONG; 51 | $timeType = IntlDateFormatter::SHORT; 52 | break; 53 | case '%x': 54 | $dateType = IntlDateFormatter::SHORT; 55 | $timeType = IntlDateFormatter::NONE; 56 | break; 57 | case '%X': 58 | $dateType = IntlDateFormatter::NONE; 59 | $timeType = IntlDateFormatter::MEDIUM; 60 | break; 61 | default: 62 | $pattern = $intlFormats[$format]; 63 | } 64 | $calendar = IntlGregorianCalendar::createInstance(); 65 | $calendar->setGregorianChange(PHP_INT_MIN); 66 | 67 | return (new IntlDateFormatter($locale, $dateType, $timeType, $tz, $calendar, $pattern))->format($timestamp); 68 | }; 69 | 70 | $translateTable = [ 71 | // Day 72 | '%a' => $intlFormatter, 73 | '%A' => $intlFormatter, 74 | '%d' => 'd', 75 | '%e' => function ($timestamp) { 76 | return sprintf('% 2u', $timestamp->format('j')); 77 | }, 78 | '%j' => function ($timestamp) { 79 | // Day number in year, 001 to 366 80 | return sprintf('%03d', $timestamp->format('z') + 1); 81 | }, 82 | '%u' => 'N', 83 | '%w' => 'w', 84 | 85 | // Week 86 | '%U' => function ($timestamp) { 87 | // Number of weeks between date and first Sunday of year 88 | $day = new DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y'))); 89 | return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7); 90 | }, 91 | '%V' => 'W', 92 | '%W' => function ($timestamp) { 93 | // Number of weeks between date and first Monday of year 94 | $day = new DateTime(sprintf('%d-01 Monday', $timestamp->format('Y'))); 95 | return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7); 96 | }, 97 | 98 | // Month 99 | '%b' => $intlFormatter, 100 | '%B' => $intlFormatter, 101 | '%h' => $intlFormatter, 102 | '%m' => 'm', 103 | 104 | // Year 105 | '%C' => function ($timestamp) { 106 | // Century (-1): 19 for 20th century 107 | return floor($timestamp->format('Y') / 100); 108 | }, 109 | '%g' => function ($timestamp) { 110 | return substr($timestamp->format('o'), -2); 111 | }, 112 | '%G' => 'o', 113 | '%y' => 'y', 114 | '%Y' => 'Y', 115 | 116 | // Time 117 | '%H' => 'H', 118 | '%k' => function ($timestamp) { 119 | return sprintf('% 2u', $timestamp->format('G')); 120 | }, 121 | '%I' => 'h', 122 | '%l' => function ($timestamp) { 123 | return sprintf('% 2u', $timestamp->format('g')); 124 | }, 125 | '%M' => 'i', 126 | '%p' => 'A', // AM PM (this is reversed on purpose!) 127 | '%P' => 'a', // am pm 128 | '%r' => 'h:i:s A', // %I:%M:%S %p 129 | '%R' => 'H:i', // %H:%M 130 | '%S' => 's', 131 | '%T' => 'H:i:s', 132 | '%X' => $intlFormatter, 133 | 134 | // Timezone 135 | '%z' => 'O', 136 | '%Z' => 'T', 137 | 138 | // Time and Date Stamps 139 | '%c' => $intlFormatter, 140 | '%D' => 'm/d/Y', 141 | '%F' => 'Y-m-d', 142 | '%s' => 'U', 143 | '%x' => $intlFormatter, 144 | ]; 145 | 146 | $out = preg_replace_callback( 147 | '/(?format($replace); 166 | } else { 167 | $result = $replace($timestamp, $pattern); 168 | } 169 | $result = (string)$result; 170 | 171 | switch ($prefix) { 172 | case '_': 173 | return (string)preg_replace('/\G0(?=.)/', ' ', $result); 174 | case '#': 175 | case '-': 176 | return (string)preg_replace('/^0+(?=.)/', '', $result); 177 | default: 178 | return $result; 179 | } 180 | }, 181 | (string)$format 182 | ); 183 | 184 | return str_replace('%%', '%', strval($out)); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRule.php: -------------------------------------------------------------------------------- 1 | 'validateAlphabets', 25 | 'alphaNoSpecial' => 'validateAlphaNoSpecial', 26 | 'alphaNum' => 'validateAlphaNumerics', 27 | 'alphaNumNoSpecial' => 'validateAlphaNumNoSpecial', 28 | 'array' => 'validateArray', 29 | 'arrayValues' => 'validateArrayValues', 30 | 'bool' => 'validateBoolean', 31 | 'companyIdentification' => 'validateCompanyIdentification', 32 | 'dateAmerican' => 'validateDateAmerican', 33 | 'dateBrazil' => 'validateDateBrazil', 34 | 'dateNotFuture' => 'validateDateNotFuture', 35 | 'email' => 'validateEmail', 36 | 'equals' => 'validateEquals', 37 | 'fileName' => 'validateFileName', 38 | 'float' => 'validateFloating', 39 | 'hour' => 'validateHour', 40 | 'identifier' => 'validateIdentifier', 41 | 'identifierOrCompany' => 'validateIdentifierOrCompany', 42 | 'int' => 'validateInteger', 43 | 'integer' => 'validateIntegerTyped', 44 | 'ip' => 'validateIp', 45 | 'json' => 'validateJson', 46 | 'lower' => 'validateLower', 47 | ]; 48 | } 49 | 50 | private static function functionsValidationMtoN(): array 51 | { 52 | return [ 53 | 'mac' => 'validateMac', 54 | 'max' => 'validateMaximumField', 55 | 'maxFile' => 'validateMaximumFileNumbers', 56 | 'maxUploadSize' => 'validateFileMaxUploadSize', 57 | 'maxWidth' => 'validateMaxWidth', 58 | 'maxHeight' => 'validateMaxHeight', 59 | 'maxWords' => 'validateMaximumWords', 60 | 'min' => 'validateMinimumField', 61 | 'minFile' => 'validateMinimumFileNumbers', 62 | 'minHeight' => 'validateMinHeight', 63 | 'minWidth' => 'validateMinWidth', 64 | 'mimeType' => 'validateFileMimeType', 65 | 'minWords' => 'validateMinimumWords', 66 | 'minUploadSize' => 'validateFileMinUploadSize', 67 | 'notSpace' => 'validateSpace', 68 | 'noWeekend' => 'validateWeekend', 69 | 'numeric' => 'validateNumeric', 70 | 'numMax' => 'validateNumMax', 71 | 'numMin' => 'validateNumMin', 72 | 'numMonth' => 'validateNumMonth', 73 | ]; 74 | } 75 | 76 | private static function functionsValidationOtoZ(): array 77 | { 78 | return [ 79 | 'optional' => 'validateOptional', 80 | 'phone' => 'validatePhone', 81 | 'ddd' => 'validateDdd', 82 | 'plate' => 'validatePlate', 83 | 'regex' => 'validateRegex', 84 | 'required' => 'validateFieldMandatory', 85 | 'requiredFile' => 'validateFileUploadMandatory', 86 | 'rgbColor' => 'validateRgbColor', 87 | 'timestamp' => 'validateTimestamp', 88 | 'type' => 'validateFieldType', 89 | 'upper' => 'validateUpper', 90 | 'url' => 'validateUrl', 91 | 'zipcode' => 'validateZipCode', 92 | ]; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRuleArray.php: -------------------------------------------------------------------------------- 1 | errors[$field] = !empty($message) ? $message : "A variável $field não é um array!"; 11 | } 12 | } 13 | 14 | protected function validateArrayValues( 15 | string $rule = '', 16 | string $field = '', 17 | string $value = '', 18 | ?string $message = '', 19 | ): void { 20 | $ruleArray = explode('-', $rule); 21 | 22 | if (!in_array(trim($value), $ruleArray)) { 23 | $this->errors[$field] = !empty($message) 24 | ? $message 25 | : "O campo $field precisa conter uma das opções [" . str_replace('-', ',', $rule) . '] !'; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRuleDate.php: -------------------------------------------------------------------------------- 1 | errors[$field] = !empty($message) ? 20 | $message : "O campo $field não é uma data válida!"; 21 | } 22 | } 23 | 24 | protected function validateDateAmerican(string $field = '', ?string $value = null, ?string $message = ''): void 25 | { 26 | if (is_numeric($value) && strlen($value) === 8) { 27 | $value = Format::mask('####-##-##', $value); 28 | } 29 | if (empty($value) || !ValidateDate::validateDateAmerican($value)) { 30 | $this->errors[$field] = !empty($message) ? 31 | $message : "O campo $field não é uma data válida!"; 32 | } 33 | } 34 | 35 | protected function validateHour(string $field = '', ?string $value = null, ?string $message = ''): void 36 | { 37 | $value = $value ?? ''; 38 | if (!ValidateHour::validateHour($value)) { 39 | $this->errors[$field] = !empty($message) ? 40 | $message : "O campo $field não é uma hora válida!"; 41 | } 42 | } 43 | 44 | protected function validateTimestamp(string $field = '', string $value = '', ?string $message = ''): void 45 | { 46 | if (!ValidateDate::validateTimeStamp($value)) { 47 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não é um timestamp válido!"; 48 | } 49 | } 50 | 51 | protected function validateWeekend(string $field = '', string $value = '', ?string $message = ''): void 52 | { 53 | if (strpos($value, '/') > -1) { 54 | $value = Format::dateAmerican($value); 55 | } 56 | $day = date('w', (strtotime($value) ?: null)); 57 | if (in_array($day, [0, 6])) { 58 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não pode ser um Final de Semana!"; 59 | } 60 | } 61 | 62 | protected function validateDateNotFuture(string $field = '', string $value = '', ?string $message = ''): void 63 | { 64 | $dateAmerican = Format::dateAmerican($value); 65 | if (!ValidateDate::validateDateNotFuture($dateAmerican)) { 66 | $this->errors[$field] = !empty($message) ? $message : 67 | "O campo $field não pode ser uma data maior que a atual"; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRuleFile.php: -------------------------------------------------------------------------------- 1 | errors[$field][0] = $text; 14 | } 15 | } 16 | 17 | protected function validateFileMaxUploadSize( 18 | string $rule = '', 19 | string $field = '', 20 | array $value = [], 21 | ?string $message = '', 22 | ): void { 23 | $rule = trim($rule); 24 | $this->validateRuleFile($rule, $field, 'maxUploadSize'); 25 | 26 | $this->validateHandleErrorsInArray( 27 | ValidateFile::validateMaxUploadSize(intval($rule), $value, $message), 28 | $field 29 | ); 30 | } 31 | 32 | protected function validateFileMinUploadSize( 33 | string $rule = '', 34 | string $field = '', 35 | array $value = [], 36 | ?string $message = '', 37 | ): void { 38 | $rule = trim($rule); 39 | $this->validateRuleFile($rule, $field, 'minUploadSize'); 40 | 41 | $this->validateHandleErrorsInArray( 42 | ValidateFile::validateMinUploadSize(intval($rule), $value, $message), 43 | $field 44 | ); 45 | } 46 | 47 | protected function validateFileName(string $field = '', array $value = [], ?string $message = ''): void 48 | { 49 | if (empty($value)) { 50 | $this->errors[$field][0] = !empty($message) ? $message : "O campo $field não pode ser vazio!"; 51 | return; 52 | } 53 | 54 | $this->validateHandleErrorsInArray( 55 | ValidateFile::validateFileName($value), 56 | $field 57 | ); 58 | } 59 | 60 | protected function validateFileMimeType( 61 | string | array $rule = '', 62 | string $field = '', 63 | array $value = [], 64 | ?string $message = '', 65 | ): void { 66 | $this->validateHandleErrorsInArray(ValidateFile::validateMimeType($rule, $value, $message), $field); 67 | } 68 | 69 | protected function validateFileUploadMandatory( 70 | string $field = '', 71 | array $value = [], 72 | ?string $message = '', 73 | ): void { 74 | $this->validateHandleErrorsInArray( 75 | ValidateFile::validateFileUploadMandatory($field, $value, $message), 76 | $field 77 | ); 78 | } 79 | 80 | protected function validateMaximumFileNumbers( 81 | string $rule = '', 82 | string $field = '', 83 | array $value = [], 84 | ?string $message = '', 85 | ): void { 86 | $rule = intval(trim($rule)); 87 | $this->validateRuleFile($rule, $field, 'maxFile'); 88 | 89 | $validateResult = ValidateFile::validateMaximumFileNumbers($rule, $field, $value, $message); 90 | $this->validateHandleErrorsInArray($validateResult, $field); 91 | } 92 | 93 | protected function validateMinimumFileNumbers( 94 | string $rule = '', 95 | string $field = '', 96 | array $value = [], 97 | ?string $message = '', 98 | ): void { 99 | $rule = trim($rule); 100 | $this->validateRuleFile($rule, $field, 'minFile'); 101 | 102 | $validateResult = ValidateFile::validateMinimumFileNumbers($rule, $field, $value, $message); 103 | $this->validateHandleErrorsInArray($validateResult, $field); 104 | } 105 | 106 | private function validateFileCalculateSize(string $field): ?string 107 | { 108 | $imgValid = ['image/gif', 'image/png', 'image/jpeg', 'image/bmp', 'image/webp']; 109 | if (!extension_loaded('gd')) { 110 | return 'Biblioteca GD não foi encontrada!'; 111 | } elseif (empty($_FILES)) { 112 | return 'Anexo não foi encontrado!'; 113 | } else { 114 | $msg = 'Para validar minWidth, maxWidth, minHeight e maxHeight o arquivo precisa ser uma imagem!'; 115 | $file = $_FILES[$field] ?? $_FILES; 116 | if (is_iterable($file)) { 117 | foreach ($file as $key => $value) { 118 | if (is_array($value)) { 119 | foreach ($value as $valor) { 120 | if ($key === 'type' && !empty($valor) && !in_array($valor, $imgValid)) { 121 | return $msg; 122 | } 123 | } 124 | } 125 | if ($key === 'type' && !empty($value) && is_string($value) && !in_array($value, $imgValid)) { 126 | return $msg; 127 | } 128 | } 129 | } 130 | } 131 | return null; 132 | } 133 | 134 | protected function validateMinWidth( 135 | string $rule = '', 136 | string $field = '', 137 | array $value = [], 138 | ?string $message = '', 139 | ): void { 140 | $rule = trim($rule); 141 | $this->validateRuleFile($rule, $field, 'minWidth'); 142 | $msg = $this->validateFileCalculateSize($field); 143 | 144 | if (!empty($msg)) { 145 | $this->errors[$field][0] = $msg; 146 | } else { 147 | $this->validateHandleErrorsInArray( 148 | ValidateFile::validateMinWidth($field, intval($rule), $value, $message), 149 | $field 150 | ); 151 | } 152 | } 153 | 154 | protected function validateMinHeight( 155 | string $rule = '', 156 | string $field = '', 157 | array $value = [], 158 | ?string $message = '', 159 | ): void { 160 | $rule = trim($rule); 161 | $this->validateRuleFile($rule, $field, 'minHeight'); 162 | $msg = $this->validateFileCalculateSize($field); 163 | 164 | if (!empty($msg)) { 165 | $this->errors[$field][0] = $msg; 166 | } else { 167 | $this->validateHandleErrorsInArray( 168 | ValidateFile::validateMinHeight($field, intval($rule), $value, $message), 169 | $field 170 | ); 171 | } 172 | } 173 | 174 | protected function validateMaxWidth( 175 | string $rule = '', 176 | string $field = '', 177 | array $value = [], 178 | ?string $message = '', 179 | ): void { 180 | $rule = trim($rule); 181 | $this->validateRuleFile($rule, $field, 'minWidth'); 182 | $msg = $this->validateFileCalculateSize($field); 183 | 184 | if (!empty($msg)) { 185 | $this->errors[$field][0] = $msg; 186 | } else { 187 | $this->validateHandleErrorsInArray( 188 | ValidateFile::validateMaxWidth($field, intval($rule), $value, $message), 189 | $field 190 | ); 191 | } 192 | } 193 | 194 | protected function validateMaxHeight( 195 | string $rule = '', 196 | string $field = '', 197 | array $value = [], 198 | ?string $message = '', 199 | ): void { 200 | $rule = trim($rule); 201 | $this->validateRuleFile($rule, $field, 'maxHeight'); 202 | $msg = $this->validateFileCalculateSize($field); 203 | 204 | if (!empty($msg)) { 205 | $this->errors[$field][0] = $msg; 206 | } else { 207 | $this->validateHandleErrorsInArray( 208 | ValidateFile::validateMaxHeight($field, intval($rule), $value, $message), 209 | $field 210 | ); 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRuleInteger.php: -------------------------------------------------------------------------------- 1 | errors[$field] = !empty($message) ? $message : "O campo $field deve ser do tipo inteiro!"; 11 | } 12 | } 13 | 14 | protected function validateIntegerTyped( 15 | string $field = '', 16 | string|int|null $value = null, 17 | ?string $message = '' 18 | ): void { 19 | if (!is_int($value)) { 20 | $this->errors[$field] = !empty($message) ? $message : "O campo $field deve ser do tipado como inteiro!"; 21 | } 22 | } 23 | 24 | protected function validateNumeric(string $field = '', ?string $value = null, ?string $message = ''): void 25 | { 26 | if (!is_numeric($value)) { 27 | $this->errors[$field] = !empty($message) ? $message : "O campo $field só pode conter valores numéricos!"; 28 | } 29 | } 30 | 31 | protected function validateNumMax( 32 | string $rule = '', 33 | string $field = '', 34 | ?string $value = '', 35 | ?string $message = '', 36 | ): void { 37 | if ($value < 0) { 38 | $this->errors[$field] = !empty($message) ? 39 | $message : "O campo $field deve ter o valor mínimo de zero!"; 40 | } 41 | if ($value > $rule) { 42 | $this->errors[$field] = !empty($message) ? 43 | $message : "O campo $field é permitido até o valor máximo de $rule!"; 44 | } 45 | } 46 | 47 | protected function validateNumMonth(string $field = '', ?string $value = null, ?string $message = ''): void 48 | { 49 | if (!is_numeric($value)) { 50 | $this->errors[$field] = !empty($message) ? 51 | $message : "O campo $field precisa ser do valor inteiro e maior que 0!"; 52 | } elseif ($value > 12 || $value <= 0 || strlen(strval($value)) > 2) { 53 | $this->errors[$field] = !empty($message) ? 54 | $message : "O campo $field não é um mês válido!"; 55 | } 56 | } 57 | 58 | protected function validateNumMin( 59 | string $rule = '', 60 | string $field = '', 61 | ?string $value = '', 62 | ?string $message = '', 63 | ): void { 64 | if (!is_numeric($value)) { 65 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não é um inteiro!"; 66 | } 67 | if (intval($value) < $rule) { 68 | $this->errors[$field] = !empty($message) ? 69 | $message : "O campo $field deve ter o valor mínimo de $rule!"; 70 | } 71 | if (intval($value) < 0) { 72 | $this->errors[$field] = !empty($message) ? 73 | $message : "O campo $field deve ter o valor mínimo de zero!"; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/DependencyInjection/TraitRuleString.php: -------------------------------------------------------------------------------- 1 | errors[$field] = !empty($message) ? 26 | $message : "O campo $field só pode conter caracteres alfabéticos!"; 27 | } 28 | } 29 | 30 | protected function validateAlphaNoSpecial(string $field = '', string $value = '', ?string $message = ''): void 31 | { 32 | if (!preg_match('/^([a-zA-Z\s])+$/', $value) !== false) { 33 | $this->errors[$field] = !empty($message) ? 34 | $message : "O campo $field só pode conter caracteres alfabéticos regular, não pode ter ascentos!"; 35 | } 36 | } 37 | 38 | protected function validateAlphaNumNoSpecial( 39 | string $field = '', 40 | string $value = '', 41 | ?string $message = '', 42 | ): void { 43 | if (!preg_match('/^([a-zA-Z0-9\s])+$/', $value) !== false) { 44 | $this->errors[$field] = !empty($message) ? 45 | $message : "O campo $field só pode conter letras sem acentos e números, não pode carácter especial!"; 46 | } 47 | } 48 | 49 | protected function validateAlphaNumerics(string $field = '', string $value = '', ?string $message = ''): void 50 | { 51 | if ( 52 | !preg_match( 53 | '/^([a-zA-Z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\s])+$/', 54 | $value 55 | ) !== false 56 | ) { 57 | $this->errors[$field] = !empty($message) ? 58 | $message : "O campo $field só pode conter caracteres alfanuméricos!"; 59 | } 60 | } 61 | 62 | protected function validateCompanyIdentification( 63 | string | array $rule = '', 64 | string $field = '', 65 | ?string $value = '', 66 | ?string $message = '', 67 | ): void { 68 | if (is_numeric($value) && strlen($value) === 14) { 69 | $value = Format::mask('##.###.###/####-##', $value); 70 | } 71 | if (empty($value) || !ValidateCnpj::validateCnpj($value, $rule)) { 72 | $this->errors[$field] = !empty($message) ? 73 | $message : "O campo $field é inválido!"; 74 | } 75 | } 76 | 77 | protected function validateDdd( 78 | int | string $rule = '', 79 | int | string $field = '', 80 | string $value = '', 81 | ?string $message = '', 82 | ): void { 83 | if (strlen($value) === 3 || strlen($value) === 2) { 84 | $arrayDdd = DataDdds::returnDddBrazil(); 85 | 86 | if (strlen($value) === 3) { 87 | $arrayDdd = array_map(function ($value) { 88 | if (is_array($value)) { 89 | return array_map(function ($value) { 90 | return '0' . strval($value); 91 | }, $value); 92 | } 93 | }, $arrayDdd); 94 | } 95 | 96 | if (!empty($rule) && array_key_exists($rule, $arrayDdd)) { 97 | if (in_array($value, $arrayDdd[$rule])) { 98 | return; 99 | } 100 | $this->errors[$field] = !empty($message) ? $message : 'O campo ' . $field . 101 | ' não é válido para a sigla ' . $rule; 102 | } 103 | $find = Common::searchLastLayerRecursive($arrayDdd, $value); 104 | if (!$find) { 105 | $this->errors[$field] = !empty($message) ? 106 | $message : "O campo $field é um ddd inexistente ou inválido"; 107 | } 108 | } else { 109 | $this->errors[$field] = !empty($message) ? 110 | $message : "O campo $field deve conter dois ou três dígitos"; 111 | } 112 | } 113 | 114 | protected function validateEmail(string $field = '', string $value = '', ?string $message = ''): void 115 | { 116 | if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { 117 | $this->errors[$field] = !empty($message) ? 118 | $message : "O campo $field deve ser um endereço de e-mail válido!"; 119 | } 120 | } 121 | 122 | protected function validateEquals( 123 | string $rule, 124 | string $field = '', 125 | string $value = '', 126 | ?string $message = '', 127 | array $data = [], 128 | ): void { 129 | if (!isset($data[$rule])) { 130 | $this->errors[$field] = !empty($message) ? 131 | $message : "Uma regra inválida está sendo aplicada no campo $field, verifique a documentação!"; 132 | } elseif ($value !== $data[$rule]) { 133 | $this->errors[$field] = !empty($message) ? 134 | $message : "O campo $field é diferente do campo $rule!"; 135 | } 136 | } 137 | 138 | protected function validateIdentifier(string $field = '', string $value = '', ?string $message = ''): void 139 | { 140 | if (strlen($value) === 11) { 141 | $value = Format::mask('###.###.###-##', $value); 142 | } 143 | if (!ValidateCpf::validateCpf($value)) { 144 | $this->errors[$field] = !empty($message) ? 145 | $message : "O campo $field é inválido!"; 146 | } 147 | } 148 | 149 | protected function validateIdentifierOrCompany( 150 | string | array $rule = '', 151 | string $field = '', 152 | string $value = '', 153 | ?string $message = '', 154 | ): void { 155 | if (strlen($value) === 11) { 156 | $value = Format::mask('###.###.###-##', $value); 157 | } 158 | if (is_numeric($value) && strlen($value) === 14) { 159 | $value = Format::mask('##.###.###/####-##', $value); 160 | } 161 | if (strlen($value) === 14 && !ValidateCpf::validateCpf($value)) { 162 | $this->errors[$field] = !empty($message) ? $message : "O campo $field é inválido!"; 163 | } 164 | if (strlen($value) === 18 && !ValidateCnpj::validateCnpj($value, $rule)) { 165 | $this->errors[$field] = !empty($message) ? $message : "O campo $field é inválido!"; 166 | } 167 | if (!in_array(strlen($value), [11, 14, 18])) { 168 | $this->errors[$field] = !empty($message) ? $message : "O campo $field é inválido!"; 169 | } 170 | } 171 | 172 | protected function validateIp(string $field = '', string $value = '', ?string $message = ''): void 173 | { 174 | if (!filter_var($value, FILTER_VALIDATE_IP)) { 175 | $this->errors[$field] = !empty($message) ? 176 | $message : "O campo $field deve ser um endereço de IP válido!"; 177 | } 178 | } 179 | 180 | protected function validateLower(string $field = '', string $value = '', ?string $message = ''): void 181 | { 182 | if (!ctype_lower(preg_replace('/\W+/', '', $value))) { 183 | $this->errors[$field] = !empty($message) ? $message : "O campo $field precisa ser tudo minúsculo!"; 184 | } 185 | } 186 | 187 | protected function validateMac(string $field = '', string $value = '', ?string $message = ''): void 188 | { 189 | if (!filter_var($value, FILTER_VALIDATE_MAC)) { 190 | $this->errors[$field] = !empty($message) ? 191 | $message : "O campo $field deve ser um endereço de MAC válido!"; 192 | } 193 | } 194 | 195 | protected function validateMinimumField( 196 | string $rule = '', 197 | string $field = '', 198 | string $value = '', 199 | ?string $message = '', 200 | ): void { 201 | if (mb_strlen($value) < $rule) { 202 | $this->errors[$field] = !empty($message) ? 203 | $message : "O campo $field precisa conter no mínimo $rule caracteres!"; 204 | } 205 | } 206 | 207 | protected function validateMinimumWords( 208 | int $rule, 209 | string $field = '', 210 | string $value = '', 211 | ?string $message = '', 212 | ): void { 213 | if (!ValidateString::minWords($value, $rule)) { 214 | $this->errors[$field] = !empty($message) ? 215 | $message : "O campo $field precisa conter no mínimo $rule palavras!"; 216 | } 217 | } 218 | 219 | protected function validateMaximumWords( 220 | int $rule, 221 | string $field = '', 222 | string $value = '', 223 | ?string $message = '', 224 | ): void { 225 | if (!ValidateString::maxWords($value, $rule)) { 226 | $this->errors[$field] = !empty($message) ? 227 | $message : "O campo $field precisa conter no máximo $rule palavras!"; 228 | } 229 | } 230 | 231 | protected function validateMaximumField( 232 | string $rule = '', 233 | string $field = '', 234 | string $value = '', 235 | ?string $message = '', 236 | ): void { 237 | if (mb_strlen($value) > $rule) { 238 | $this->errors[$field] = !empty($message) ? 239 | $message : "O campo $field precisa conter no máximo $rule caracteres!"; 240 | } 241 | } 242 | 243 | protected function validatePlate(string $field = '', string $value = '', ?string $message = ''): void 244 | { 245 | if (!preg_match('/^[A-Z]{3}-[0-9]{4}+$/', $value) !== false) { 246 | $this->errors[$field] = !empty($message) ? 247 | $message : "O campo $field deve corresponder ao formato AAA-0000!"; 248 | } 249 | } 250 | 251 | protected function validatePhone(string $field = '', string $value = '', ?string $message = ''): void 252 | { 253 | if (is_numeric($value) && in_array(strlen($value), [10, 11])) { 254 | if (strlen($value) === 10) { 255 | $value = Format::mask('(##)####-####', $value); 256 | } 257 | if (strlen($value) === 11) { 258 | $value = Format::mask('(##)#####-####', $value); 259 | } 260 | } 261 | if (!ValidatePhone::validate($value)) { 262 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não é um telefone válido!"; 263 | } 264 | } 265 | 266 | protected function validateRegex( 267 | string $rule = '', 268 | string $field = '', 269 | string $value = '', 270 | ?string $message = '', 271 | ): void { 272 | if (!preg_match($rule, $value) !== false) { 273 | $this->errors[$field] = !empty($message) ? 274 | $message : "O campo $field precisa conter um valor com formato válido!"; 275 | } 276 | } 277 | 278 | protected function validateRgbColor(string $field = '', string $value = '', ?string $message = ''): void 279 | { 280 | $regra = '([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])'; 281 | $pattern = '/^' . $regra . '( *),( *)' . $regra . '( *),( *)' . $regra . '( *)$/'; 282 | if (!preg_match($pattern, $value) !== false) { 283 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não é um RGB Color!"; 284 | } 285 | } 286 | 287 | protected function validateSpace(string $field = '', string $value = '', ?string $message = ''): void 288 | { 289 | if (strpos($value, ' ') !== false) { 290 | $this->errors[$field] = !empty($message) ? $message : "O campo $field não pode conter espaço!"; 291 | } 292 | } 293 | 294 | protected function validateUpper(string $field = '', string $value = '', ?string $message = ''): void 295 | { 296 | if (!ctype_upper(preg_replace('/\W+/', '', $value))) { 297 | $this->errors[$field] = !empty($message) ? $message : "O campo $field precisa ser tudo maiúsculo!"; 298 | } 299 | } 300 | 301 | protected function validateUrl(string $field = '', string $value = '', ?string $message = ''): void 302 | { 303 | if (!filter_var($value, FILTER_VALIDATE_URL)) { 304 | $this->errors[$field] = !empty($message) ? 305 | $message : "O campo $field deve ser um endereço de URL válida!"; 306 | } 307 | } 308 | 309 | protected function validateZipCode(string $field = '', string $value = '', ?string $message = ''): void 310 | { 311 | if (is_numeric($value) && strlen($value) === 8) { 312 | $value = Format::mask('#####-###', $value); 313 | } 314 | if (!preg_match('/^([0-9]{2}[0-9]{3}-[0-9]{3})+$/', $value) !== false) { 315 | $this->errors[$field] = !empty($message) ? 316 | $message : "O campo $field deve corresponder ao formato 00000-000!"; 317 | } 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /src/DependencyInjection/data/DataConvertTypesBool.php: -------------------------------------------------------------------------------- 1 | new stdClass(), //true 15 | 'tratandoArray' => [1, 2], //true 16 | 'tratandoInteiroPositivo' => 42, //true 17 | 'tratandoInteiroNegativo' => -42, //true 18 | 'tratandoStringTrue' => 'true', //true 19 | 'tratandoStringOn' => 'on', //true 20 | 'tratandoStringOff' => 'off', //true 21 | 'tratandoStringYes' => 'yes', //true 22 | 'tratandoStringNo' => 'no', //false 23 | 'tratandoStringUm' => '1', // true 24 | 'tratandoNull' => null, // false 25 | 'tratandoInteiroZero' => 0, // false 26 | 'tratandoStringFalse' => 'false', //false 27 | 'tratandoQualquerString' => 'string', //false 28 | 'tratandoStringZero' => '0', // false 29 | 'tratandoStringVazio' => '', // false 30 | ]; 31 | } 32 | 33 | public function arrayRule(): array 34 | { 35 | return [ 36 | 'tratandoClasse' => 'convert|bool', 37 | 'tratandoArray' => 'convert|bool', 38 | 'tratandoInteiroPositivo' => 'convert|bool', 39 | 'tratandoInteiroNegativo' => 'convert|bool', 40 | 'tratandoStringTrue' => 'convert|bool', 41 | 'tratandoStringOn' => 'convert|bool', 42 | 'tratandoStringOff' => 'convert|bool', 43 | 'tratandoStringYes' => 'convert|bool', 44 | 'tratandoStringNo' => 'convert|bool', 45 | 'tratandoStringUm' => 'convert|bool', 46 | 'tratandoNull' => 'convert|bool', 47 | 'tratandoInteiroZero' => 'convert|bool', 48 | 'tratandoStringFalse' => 'convert|bool', 49 | 'tratandoQualquerString' => 'convert|bool', 50 | 'tratandoStringZero' => 'convert|bool', 51 | 'tratandoStringVazio' => 'convert|bool', 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/DependencyInjection/data/DataDdds.php: -------------------------------------------------------------------------------- 1 | [41, 42, 43, 44, 45, 46,], 11 | 'rs' => [51, 53, 54, 55,], 12 | 'sc' => [47, 48, 49,], 13 | ]; 14 | } 15 | 16 | private static function returnSoutheastRegion(): array 17 | { 18 | return [ 19 | 'rj' => [21, 22, 24,], 20 | 'sp' => [11, 12, 13, 14, 15, 16, 17, 18, 19,], 21 | 'es' => [27, 28,], 22 | 'mg' => [31, 32, 33, 34, 35, 37, 38,], 23 | 'df' => [61,], 24 | ]; 25 | } 26 | 27 | private static function returnMidwestRegion(): array 28 | { 29 | return [ 30 | 'go' => [62, 64,], 31 | 'mg' => [31, 32, 33, 34, 35, 37, 38], 32 | 'ms' => [67,], 33 | 'mt' => [65, 66], 34 | ]; 35 | } 36 | 37 | private static function returnNortheastRegion(): array 38 | { 39 | return [ 40 | 'ma' => [98, 99,], 41 | 'al' => [82,], 42 | 'ba' => [71, 73, 74, 75, 77,], 43 | 'ce' => [85, 88,], 44 | 'pb' => [83,], 45 | 'pe' => [87, 81,], 46 | 'pi' => [86, 89,], 47 | 'rn' => [84], 48 | 'se' => [79], 49 | ]; 50 | } 51 | 52 | private static function returnNorthRegion(): array 53 | { 54 | return [ 55 | 'ac' => [68], 56 | 'ap' => [96], 57 | 'am' => [92, 97,], 58 | 'pa' => [91, 93, 94,], 59 | 'ro' => [69,], 60 | 'rr' => [95,], 61 | 'to' => [63,], 62 | ]; 63 | } 64 | 65 | public static function returnDddBrazil(): array 66 | { 67 | $values = self::returnNorthRegion(); 68 | $values += self::returnNortheastRegion(); 69 | $values += self::returnMidwestRegion(); 70 | $values += self::returnSoutheastRegion(); 71 | return $values += self::returnSouthRegion(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Format.php: -------------------------------------------------------------------------------- 1 | 0) ? self::onlyNumbers($value) : '000'; 30 | $value = substr_replace($value, '.', -2, 0); 31 | } else { 32 | $value = (strlen(self::onlyNumbers($value)) > 0) ? self::onlyNumbers($value) : '000'; 33 | } 34 | } 35 | return floatval($value); 36 | } 37 | 38 | private static function formatFileName(string $fileName = ''): string 39 | { 40 | $dataName = explode('.', trim($fileName)); 41 | $ext = end($dataName); 42 | 43 | if (count($dataName) > 1) { 44 | unset($dataName[count($dataName) - 1]); 45 | } 46 | 47 | $dataName = implode('_', $dataName); 48 | $stringNoSpecial = self::removeSpecialCharacters($dataName) ?? ''; 49 | $dataName = preg_replace('/\W/', '_', strtolower($stringNoSpecial)); 50 | 51 | return "{$dataName}.{$ext}"; 52 | } 53 | 54 | private static function generateFileName(?string $nameFile): string 55 | { 56 | return date("d-m-Y_s_") . uniqid(rand() . rand() . rand() . time()) . '_' . $nameFile; 57 | } 58 | 59 | public static function convertTypes(array &$data, array $rules): void 60 | { 61 | $error = []; 62 | foreach ($rules as $key => $value) { 63 | $arrRules = explode('|', $value); 64 | $type = parent::returnTypeToConvert($arrRules); 65 | if (in_array('convert', $arrRules) && !empty($type)) { 66 | try { 67 | if (in_array($key, array_keys($data))) { 68 | $data[$key] = parent::executeConvert($type, $data[$key]); 69 | } 70 | } catch (Exception) { 71 | $error[] = "falhar ao tentar converter {$data[$key]} para $type"; 72 | } 73 | } 74 | } 75 | } 76 | 77 | public static function companyIdentification(string $cnpj): string 78 | { 79 | parent::validateForFormatting('companyIdentification', 14, $cnpj); 80 | $retorno = preg_replace("/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/", "\$1.\$2.\$3/\$4-\$5", $cnpj); 81 | return $retorno ?? ''; 82 | } 83 | 84 | public static function identifier(string $cpf): string 85 | { 86 | parent::validateForFormatting('identifier', 11, $cpf); 87 | $retorno = preg_replace("/(\d{3})(\d{3})(\d{3})(\d{2})/", "\$1.\$2.\$3-\$4", $cpf); 88 | return $retorno ?? ''; 89 | } 90 | 91 | public static function identifierOrCompany(string $cpfCnpj): string 92 | { 93 | if (strlen($cpfCnpj) === 11) { 94 | return self::identifier($cpfCnpj); 95 | } elseif (strlen($cpfCnpj) === 14) { 96 | return self::companyIdentification($cpfCnpj); 97 | } else { 98 | throw new InvalidArgumentException('identifierOrCompany => Valor precisa ser um CPF ou CNPJ!'); 99 | } 100 | } 101 | 102 | public static function telephone(string $number): string 103 | { 104 | if (strlen($number) < 10 || strlen($number) > 11) { 105 | throw new InvalidArgumentException('telephone precisa ter 10 ou 11 números!'); 106 | } 107 | if (!is_numeric($number)) { 108 | throw new InvalidArgumentException('telephone precisa conter apenas números!'); 109 | } 110 | return '(' . substr($number, 0, 2) . ') ' . substr($number, 2, -4) . '-' . substr($number, -4); 111 | } 112 | 113 | public static function zipCode(string $value): string 114 | { 115 | parent::validateForFormatting('zipCode', 8, $value); 116 | return substr($value, 0, 5) . '-' . substr($value, 5, 3); 117 | } 118 | 119 | public static function dateBrazil(string $date): string 120 | { 121 | if (strlen($date) < 8 || strlen($date) > 10) { 122 | throw new InvalidArgumentException('dateBrazil precisa conter 8 à 10 dígitos!'); 123 | } 124 | return date('d/m/Y', (strtotime($date) ?: null)); 125 | } 126 | 127 | public static function dateAmerican(string $date): string 128 | { 129 | if (strlen($date) < 8 || strlen($date) > 10) { 130 | throw new InvalidArgumentException('dateAmerican precisa conter 8 à 10 dígitos!'); 131 | } 132 | if (strpos($date, '/') > -1) { 133 | return implode('-', array_reverse(explode('/', $date))); 134 | } 135 | return date('Y-m-d', (strtotime($date) ?: null)); 136 | } 137 | 138 | public static function arrayToIntReference(array &$array): void 139 | { 140 | $array = array_map('intval', $array); 141 | } 142 | 143 | public static function arrayToInt(array $array): array 144 | { 145 | return array_map('intval', $array); 146 | } 147 | 148 | public static function currency(float | int | string $value, ?string $coinType = ''): string 149 | { 150 | $value = self::formatCurrencyForFloat($value); 151 | return (!empty($value) || $value === 0 || $value === '0') ? 152 | $coinType . number_format(floatval($value), 2, ',', '.') : ''; 153 | } 154 | 155 | public static function currencyUsd(float | int | string $value, ?string $coinType = ''): string 156 | { 157 | $value = self::formatCurrencyForFloat($value); 158 | return (!empty($value)) ? $coinType . number_format(floatval($value), 2, '.', ',') : ''; 159 | } 160 | 161 | public static function returnPhoneOrAreaCode(string $phone, bool $areaCode = false): string | bool 162 | { 163 | $phone = self::onlyNumbers($phone); 164 | if (!empty($phone) && ValidatePhone::validate($phone)) { 165 | $retorno = ($areaCode) ? preg_replace('/\A.{2}?\K[\d]+/', '', $phone) 166 | : preg_replace('/^\d{2}/', '', $phone); 167 | return $retorno ?? ''; 168 | } 169 | return false; 170 | } 171 | 172 | public static function ucwordsCharset(string $string, string $charset = 'UTF-8'): string 173 | { 174 | return mb_convert_case(mb_strtolower($string, $charset), MB_CASE_TITLE, 'UTF-8'); 175 | } 176 | 177 | public static function pointOnlyValue(string $str): string 178 | { 179 | $str = preg_replace('/[^0-9,]/', '', $str) ?? ''; 180 | $retorno = preg_replace('/[^0-9]/', '.', $str); 181 | return $retorno ?? ''; 182 | } 183 | 184 | public static function emptyToNull(array $array, ?string $exception = null): array 185 | { 186 | return array_map(function ($value) use ($exception) { 187 | if (isset($value) && is_array($value)) { 188 | return count($value) > 0 ? $value : null; 189 | } 190 | return (isset($value) && empty(trim($value)) 191 | && $value !== $exception || $value === 'null') ? null : $value; 192 | }, $array); 193 | } 194 | 195 | public static function mask(string $mask, string $str): string 196 | { 197 | $str = str_replace(' ', '', $str); 198 | for ($i = 0; $i < strlen($str); $i++) { 199 | $mask[strpos($mask, "#")] = $str[$i]; 200 | } 201 | return gettype($mask) === 'string' ? strval($mask) : ''; 202 | } 203 | 204 | public static function onlyNumbers(string $str): string 205 | { 206 | $retorno = preg_replace('/[^0-9]/', '', $str); 207 | return $retorno ?? ''; 208 | } 209 | 210 | public static function onlyLettersNumbers(string $str): string 211 | { 212 | $retorno = preg_replace('/[^a-zA-Z0-9]/', '', $str); 213 | return $retorno ?? ''; 214 | } 215 | 216 | public static function upper(string $string, string $charset = 'UTF-8'): string 217 | { 218 | return mb_strtoupper($string, $charset); 219 | } 220 | 221 | public static function lower(string $string, string $charset = 'UTF-8'): string 222 | { 223 | return mb_strtolower($string, $charset); 224 | } 225 | 226 | public static function maskStringHidden( 227 | string $string, 228 | int $qtdHidden, 229 | int $positionHidden, 230 | string $char, 231 | ): ?string { 232 | if (empty(trim($string))) { 233 | return null; 234 | } 235 | if ($qtdHidden > strlen($string)) { 236 | throw new 237 | InvalidArgumentException('Quantidade de caracteres para ocultar não pode ser maior que a String!'); 238 | } 239 | if ($qtdHidden < 1) { 240 | throw new InvalidArgumentException('Quantidade de caracteres para ocultar não pode ser menor que 1!'); 241 | } 242 | $chars = str_repeat($char, $qtdHidden); 243 | return substr_replace($string, $chars, $positionHidden, strlen($chars)); 244 | } 245 | 246 | public static function reverse(string $string, string $charSet = 'UTF-8'): string 247 | { 248 | if (!extension_loaded('iconv')) { 249 | throw new InvalidArgumentException(__METHOD__ . '() requires ICONV extension that is not loaded.'); 250 | } 251 | return iconv('UTF-32LE', $charSet, strrev(iconv($charSet, 'UTF-32BE', $string) ?: '')) ?: ''; 252 | } 253 | 254 | public static function falseToNull(mixed $value): mixed 255 | { 256 | return $value === false ? null : $value; 257 | } 258 | 259 | public static function removeAccent(?string $string): ?string 260 | { 261 | if (empty($string)) { 262 | return null; 263 | } 264 | return preg_replace( 265 | [ 266 | '/(á|à|ã|â|ä)/', 267 | '/(Á|À|Ã|Â|Ä)/', 268 | '/(é|è|ê|ë)/', 269 | '/(É|È|Ê|Ë)/', 270 | '/(í|ì|î|ï)/', 271 | '/(Í|Ì|Î|Ï)/', 272 | '/(ó|ò|õ|ô|ö)/', 273 | '/(Ó|Ò|Õ|Ô|Ö)/', 274 | '/(ú|ù|û|ü)/', 275 | '/(Ú|Ù|Û|Ü)/', 276 | '/(ñ)/', 277 | '/(Ñ)/', 278 | '/(ç)/', 279 | '/(Ç)/', 280 | ], 281 | explode(' ', 'a A e E i I o O u U n N c C'), 282 | $string 283 | ); 284 | } 285 | 286 | public static function removeSpecialCharacters(string $string, bool $space = true): ?string 287 | { 288 | if (empty($string)) { 289 | return null; 290 | } 291 | $newString = self::removeAccent($string) ?? ''; 292 | if ($space) { 293 | return preg_replace("/[^a-zA-Z0-9 ]/", "", $newString); 294 | } 295 | return preg_replace("/[^a-zA-Z0-9]/", "", $newString); 296 | } 297 | 298 | public static function writeDateExtensive(string $date): string 299 | { 300 | if (strpos($date, '/') > -1) { 301 | $date = implode('-', array_reverse(explode('/', $date))); 302 | } 303 | $timestamp = strtotime($date); 304 | if ($timestamp === false) { 305 | throw new InvalidArgumentException('Invalid date format for writeDateExtensive.'); 306 | } 307 | return StrfTime::strftime('%A, %d de %B de %Y', $timestamp, 'pt_BR'); 308 | } 309 | 310 | public static function writeCurrencyExtensive(float $numeral): string 311 | { 312 | if ($numeral <= 0) { 313 | throw new InvalidArgumentException('O valor numeral deve ser maior que zero!'); 314 | } 315 | return parent::extensive($numeral); 316 | } 317 | 318 | public static function restructFileArray(array $file = []): array 319 | { 320 | $arrayFile = []; 321 | 322 | if (!empty($file)) { 323 | $fileError = ValidateFile::validateFileErrorPhp($file); 324 | 325 | if (!empty($fileError)) { 326 | return $fileError; 327 | } 328 | if (isset($file['name'])) { 329 | foreach ($file['name'] as $key => $name) { 330 | $name = self::formatFileName($name); 331 | $params = [ 332 | 'name' => $name, 333 | 'type' => $file['type'][$key], 334 | 'tmp_name' => $file['tmp_name'][$key], 335 | 'error' => $file['error'][$key], 336 | 'size' => $file['size'][$key], 337 | 'name_upload' => self::generateFileName($name), 338 | ]; 339 | array_push($arrayFile, $params); 340 | } 341 | } 342 | } 343 | return $arrayFile; 344 | } 345 | 346 | public static function convertTimestampBrazilToAmerican(string $dt): string 347 | { 348 | if (!ValidateDate::validateTimeStamp($dt)) { 349 | throw new InvalidArgumentException('Data não é um Timestamp!'); 350 | } 351 | 352 | $dateTime = \DateTime::createFromFormat('d/m/Y H:i:s', $dt); 353 | return !empty($dateTime) ? $dateTime->format('Y-m-d H:i:s') : ''; 354 | } 355 | 356 | public static function convertStringToBinary(string $string): string 357 | { 358 | $characters = str_split($string); 359 | $binario = []; 360 | foreach ($characters as $character) { 361 | $data = unpack('H*', $character) ?: []; 362 | $binario[] = base_convert($data[1], 16, 2); 363 | } 364 | return implode(' ', $binario); 365 | } 366 | 367 | public static function slugfy(string $text): string 368 | { 369 | $noSpecialCharacter = self::removeSpecialCharacters(str_replace('-', ' ', $text)) ?? ''; 370 | return str_replace(' ', '-', self::lower($noSpecialCharacter)); 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /src/Utility.php: -------------------------------------------------------------------------------- 1 | = 10 && !boolval(preg_match('@[0-9]@', $result))) { 47 | $result = self::generatePassword($size, $uppercase, $lowercase, $numbers, $symbols); 48 | } 49 | return $result; 50 | } 51 | 52 | /* 53 | * @return string -> Cadeia URL completa 54 | * @param string $host -> Dominio do sistema 55 | * @param string $absolutePath -> Caminho absoluto 56 | * @param string $https -> 'on' para gerar url https, outro valor, gera url http 57 | */ 58 | public static function buildUrl(string $host, string $absolutePath = '', ?string $https = ''): string 59 | { 60 | $protocol = ((isset($https) && ($https === 'on')) ? 'https' : 'http'); 61 | return $protocol . '://' . $host . $absolutePath; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ValidateCnpj.php: -------------------------------------------------------------------------------- 1 | 0)) { 25 | $cnpjExceptionValid = []; 26 | foreach ($cnpjException as $key => $nrInscricao) { 27 | $cnpjExceptionValid[$key] = false; 28 | if (in_array($nrInscricao, $cnpjInvalidate) && in_array($cnpj, $cnpjInvalidate)) { 29 | $cnpjExceptionValid[$key] = true; 30 | } 31 | } 32 | return (in_array(false, $cnpjExceptionValid)) ? false : true; 33 | } 34 | return true; 35 | } 36 | 37 | private static function validateRuleCnpj(string $cnpj): bool 38 | { 39 | if (strlen($cnpj) > 14) { 40 | $cnpj = self::dealCnpj($cnpj); 41 | } 42 | if (strlen($cnpj) < 14) { 43 | return false; 44 | } 45 | 46 | for ($i = 0, $j = 5, $sum = 0; $i < 12; $i++) { 47 | $sum += intval($cnpj[$i]) * $j; 48 | $j = ($j == 2) ? 9 : $j - 1; 49 | } 50 | $rest = $sum % 11; 51 | if ($cnpj[12] != ($rest < 2 ? 0 : 11 - $rest)) { 52 | return false; 53 | } 54 | for ($i = 0, $j = 6, $sum = 0; $i < 13; $i++) { 55 | $sum += intval($cnpj[$i]) * $j; 56 | $j = ($j == 2) ? 9 : $j - 1; 57 | } 58 | $rest = $sum % 11; 59 | return $cnpj[13] == ($rest < 2 ? 0 : 11 - $rest); 60 | } 61 | 62 | private static function dealCnpj(string $cnpj): string 63 | { 64 | $newCnpj = preg_match('/[0-9]/', $cnpj) ? 65 | str_replace(['-', '.', '/'], '', str_pad($cnpj, 14, '0', STR_PAD_LEFT), $cnpj) : 0; 66 | return strval($newCnpj); 67 | } 68 | 69 | public static function validateCnpj(string $cnpj, string | array | bool $cnpjException = ''): bool 70 | { 71 | if (empty($cnpj)) { 72 | return false; 73 | } 74 | if (strlen($cnpj) > 14) { 75 | $cnpj = self::dealCnpj($cnpj); 76 | } 77 | if (!self::validateCnpjSequenceInvalidate($cnpj, $cnpjException)) { 78 | return false; 79 | } 80 | return self::validateRuleCnpj($cnpj); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/ValidateCpf.php: -------------------------------------------------------------------------------- 1 | 11) { 49 | $cpf = self::dealCpf($cpf); 50 | } 51 | if (empty($cpf) || strlen($cpf) !== 11) { 52 | return false; 53 | } 54 | if (self::validateCpfSequenceInvalidate($cpf)) { 55 | return self::validateRuleCpf($cpf); 56 | } 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ValidateDate.php: -------------------------------------------------------------------------------- 1 | format($format) === $date; 63 | 64 | if (!$return) { 65 | $format = 'd/m/Y H:i:s'; 66 | $d = DateTime::createFromFormat($format, $date); 67 | $return = $d && $d->format($format) === $date; 68 | } 69 | return $return; 70 | } 71 | 72 | public static function validateDateNotFuture(string $dateAmerican): bool 73 | { 74 | $dateAmerican = new DateTimeImmutable($dateAmerican); 75 | $dateNow = new DateTimeImmutable(); 76 | $interval = $dateAmerican->diff($dateNow); 77 | $diff = $interval->format('%R%'); 78 | if ($diff === '-') { 79 | return false; 80 | } 81 | return true; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/ValidateFile.php: -------------------------------------------------------------------------------- 1 | $value) { 13 | $file[$paramFile] = [$value]; 14 | } 15 | } 16 | } 17 | 18 | private static function validateFileCount(array $file = []): int 19 | { 20 | if (!empty($file) && isset($file['name'])) { 21 | if (is_array($file['name']) == 1) { 22 | return (count($file['name']) === 1) && empty($file['name'][0]) ? 23 | count($file['name']) - 1 : count($file['name']); 24 | } else { 25 | return (is_string($file['name']) && !empty($file['name'])) ? 1 : 0; 26 | } 27 | } 28 | return 0; 29 | } 30 | 31 | public static function validateFileErrorPhp(array &$file, string $message = ''): array 32 | { 33 | self::validateFileTransformSingleToMultiple($file); 34 | 35 | $phpFileErrors = [ 36 | UPLOAD_ERR_OK => 'Arquivo enviado com sucesso!', 37 | UPLOAD_ERR_INI_SIZE => 'O arquivo enviado excede o limite definido na diretiva UPLOAD_MAX_FILESIZE 38 | do php.ini!', 39 | UPLOAD_ERR_FORM_SIZE => 'O arquivo excede o limite definido em MAX_FILE_SIZE, no fomulário HTML!', 40 | UPLOAD_ERR_PARTIAL => 'O upload do arquivo, foi realizado parcialmente!', 41 | UPLOAD_ERR_NO_FILE => 'Nenhum arquivo foi enviado!', 42 | UPLOAD_ERR_NO_TMP_DIR => 'Pasta temporária ausênte!', 43 | UPLOAD_ERR_CANT_WRITE => 'Falha ao gravar arquivo no disco!', 44 | UPLOAD_ERR_EXTENSION => 'Uma extensão PHP interrompeu o upload do arquivo!', 45 | ]; 46 | 47 | $arrayFileError = []; 48 | foreach ($file['error'] as $key => $codeError) { 49 | if (($codeError > 0) && (array_key_exists($codeError, $phpFileErrors))) { 50 | $nameFile = empty($file['name'][$key]) ? '' : '[' . $file['name'][$key] . '] - '; 51 | $message = (!empty($message)) ? $nameFile . $message : $nameFile . $phpFileErrors[$codeError]; 52 | 53 | array_push($arrayFileError, $message); 54 | } 55 | } 56 | return $arrayFileError; 57 | } 58 | 59 | public static function validateMaxUploadSize( 60 | int $rule = 0, 61 | array $file = [], 62 | ?string $message = '', 63 | ): array { 64 | $arrayFileError = []; 65 | 66 | if (self::validateFileCount($file) > 0) { 67 | self::validateFileTransformSingleToMultiple($file); 68 | 69 | foreach ($file['size'] as $key => $size) { 70 | if ($size > $rule) { 71 | $msgMaxSize = 'O arquivo ' . $file['name'][$key] . ' deve conter, no máximo ' . $rule . ' bytes!'; 72 | $msgMaxSize = (!empty($message)) ? $message : $msgMaxSize; 73 | 74 | array_push($arrayFileError, $msgMaxSize); 75 | } 76 | } 77 | } 78 | return $arrayFileError; 79 | } 80 | 81 | public static function validateMinWidth( 82 | string $field, 83 | ?int $rule, 84 | array $file, 85 | ?string $message = '', 86 | ): array { 87 | $arrayFileError = []; 88 | 89 | if (self::validateFileCount($file) > 0) { 90 | self::validateFileTransformSingleToMultiple($file); 91 | 92 | foreach ($file['tmp_name'] as $tmpName) { 93 | list($width) = getimagesize($tmpName) ?: [0]; 94 | 95 | if ($width > 0 && $width < $rule) { 96 | $msgMinWidth = "O campo $field não pode ser menor que $rule pexels de comprimento!"; 97 | $msgMinWidth = (!empty($message)) ? $message : $msgMinWidth; 98 | array_push($arrayFileError, $msgMinWidth); 99 | } 100 | } 101 | } 102 | return $arrayFileError; 103 | } 104 | 105 | public static function validateMinHeight( 106 | string $field, 107 | ?int $rule, 108 | array $file, 109 | ?string $message = '', 110 | ): array { 111 | $arrayFileError = []; 112 | 113 | if (self::validateFileCount($file) > 0) { 114 | self::validateFileTransformSingleToMultiple($file); 115 | 116 | foreach ($file['tmp_name'] as $tmpName) { 117 | list(, $height) = getimagesize($tmpName) ?: [0, 0]; 118 | 119 | if ($height > 0 && $height < $rule) { 120 | $msgMinHeight = "O campo $field não pode ser menor que $rule pexels de altura!"; 121 | $msgMinHeight = (!empty($message)) ? $message : $msgMinHeight; 122 | array_push($arrayFileError, $msgMinHeight); 123 | } 124 | } 125 | } 126 | return $arrayFileError; 127 | } 128 | 129 | public static function validateMaxWidth( 130 | string $field, 131 | ?int $rule, 132 | array $file, 133 | ?string $message = '', 134 | ): array { 135 | $arrayFileError = []; 136 | 137 | if (self::validateFileCount($file) > 0) { 138 | self::validateFileTransformSingleToMultiple($file); 139 | 140 | foreach ($file['tmp_name'] as $tmpName) { 141 | list($width) = getimagesize($tmpName) ?: [0]; 142 | 143 | if ($width > 0 && $width > $rule) { 144 | $msgMaxWidth = "O campo $field não pode ser maior que $rule pexels de comprimento!"; 145 | $msgMaxWidth = (!empty($message)) ? $message : $msgMaxWidth; 146 | array_push($arrayFileError, $msgMaxWidth); 147 | } 148 | } 149 | } 150 | return $arrayFileError; 151 | } 152 | 153 | public static function validateMaxHeight( 154 | string $field, 155 | ?int $rule, 156 | array $file, 157 | ?string $message = '', 158 | ): array { 159 | $arrayFileError = []; 160 | 161 | if (self::validateFileCount($file) > 0) { 162 | self::validateFileTransformSingleToMultiple($file); 163 | 164 | foreach ($file['tmp_name'] as $tmpName) { 165 | list(, $height) = getimagesize($tmpName) ?: [0, 0]; 166 | 167 | if ($height > 0 && $height > $rule) { 168 | $msgMaxHeight = "O campo $field não pode ser maior que $rule pexels de altura!"; 169 | $msgMaxHeight = (!empty($message)) ? $message : $msgMaxHeight; 170 | array_push($arrayFileError, $msgMaxHeight); 171 | } 172 | } 173 | } 174 | return $arrayFileError; 175 | } 176 | 177 | public static function validateMinUploadSize( 178 | ?int $rule = 0, 179 | array $file = [], 180 | ?string $message = '', 181 | ): array { 182 | $arrayFileError = []; 183 | 184 | if (self::validateFileCount($file) > 0) { 185 | self::validateFileTransformSingleToMultiple($file); 186 | 187 | foreach ($file['size'] as $key => $size) { 188 | if ($size < $rule) { 189 | $msgMinSize = 'O arquivo ' . $file['name'][$key] . ' deve conter, no máximo ' . $rule . ' bytes!'; 190 | $msgMinSize = (!empty($message)) ? $message : $msgMinSize; 191 | 192 | array_push($arrayFileError, $msgMinSize); 193 | } 194 | } 195 | } 196 | return $arrayFileError; 197 | } 198 | 199 | public static function validateFileName(array $file = []): array 200 | { 201 | $arrayFileError = []; 202 | 203 | if (self::validateFileCount($file) > 0) { 204 | self::validateFileTransformSingleToMultiple($file); 205 | 206 | foreach ($file['name'] as $key => $fileName) { 207 | $noSpecialCharacter = Format::removeSpecialCharacters($fileName) ?? ''; 208 | $file['name'][$key] = explode('.', strtolower(trim( 209 | str_replace(' ', '', $noSpecialCharacter) 210 | ))); 211 | } 212 | } 213 | return $arrayFileError; 214 | } 215 | 216 | public static function validateMimeType( 217 | string | array $rule = '', 218 | array $file = [], 219 | ?string $message = '', 220 | ): array { 221 | $arrayFileError = []; 222 | 223 | if (self::validateFileCount($file) > 0) { 224 | self::validateFileTransformSingleToMultiple($file); 225 | 226 | $rule = (is_array($rule)) ? array_map('trim', $rule) : trim($rule); 227 | 228 | foreach ($file['name'] as $fileName) { 229 | $ext = explode('.', $fileName); 230 | 231 | $messageMimeType = 'O arquivo ' . $fileName . ', contém uma extensão inválida!'; 232 | $messageMimeType = (!empty($message)) ? $message : $messageMimeType; 233 | 234 | if (is_string($rule) && (strtolower(end($ext)) != strtolower($rule))) { 235 | array_push($arrayFileError, $messageMimeType); 236 | continue; 237 | } 238 | 239 | if (is_array($rule) && (!in_array(end($ext), $rule))) { 240 | array_push($arrayFileError, $messageMimeType); 241 | } 242 | } 243 | } 244 | return $arrayFileError; 245 | } 246 | 247 | public static function validateFileUploadMandatory( 248 | string $field = '', 249 | array $file = [], 250 | ?string $message = '', 251 | ): array { 252 | $arrayFileError = []; 253 | $message = (!empty($message)) ? $message : "O campo {$field} é obrigatório!"; 254 | 255 | if ( 256 | !empty($file) && 257 | (isset($file['error'])) && 258 | is_array($file['error']) == 1 && 259 | isset($file['error'][0]) && 260 | ($file['error'][0] === UPLOAD_ERR_NO_FILE) || 261 | (is_array($file['error']) == 0 && $file['error'] === UPLOAD_ERR_NO_FILE) 262 | ) { 263 | array_push($arrayFileError, $message); 264 | } 265 | return $arrayFileError; 266 | } 267 | 268 | public static function validateMaximumFileNumbers( 269 | int | string $rule = 0, 270 | int | string $field = '', 271 | array $file = [], 272 | ?string $message = '', 273 | ): array { 274 | $arrayFileError = []; 275 | $message = (!empty($message)) ? $message : "O campo {$field} deve conter, no máximo {$rule} arquivo(s)!"; 276 | 277 | if (self::validateFileCount($file) > $rule) { 278 | array_push($arrayFileError, $message); 279 | } 280 | return $arrayFileError; 281 | } 282 | 283 | public static function validateMinimumFileNumbers( 284 | int | string $rule = 0, 285 | int | string $field = '', 286 | array $file = [], 287 | ?string $message = '', 288 | ): array { 289 | $arrayFileError = []; 290 | $message = (!empty($message)) ? $message : "O campo {$field} deve conter, no mínimo {$rule} arquivo(s)!"; 291 | 292 | if (self::validateFileCount($file) < $rule) { 293 | array_push($arrayFileError, $message); 294 | } 295 | return $arrayFileError; 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /src/ValidateHour.php: -------------------------------------------------------------------------------- 1 | 11) { 17 | return false; 18 | } 19 | if (preg_match('/^[1-9]{2}([0-9]{8}|[1-9]{1}[0-9]{8})$/', $phone)) { 20 | return true; 21 | } 22 | return false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/ValidateString.php: -------------------------------------------------------------------------------- 1 | = $length); 10 | } 11 | 12 | public static function maxWords(string $text, int $length): bool 13 | { 14 | return (count(explode(' ', $text)) <= $length); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Validator.php: -------------------------------------------------------------------------------- 1 | levelSubLevelsArrayReturnJson($data)), true); 12 | if (empty($data)) { 13 | $this->errors['erro'] = 'informe os dados!'; 14 | return false; 15 | } 16 | if ( 17 | count(array_filter(array_keys($data), 'is_numeric')) === count($data) 18 | && 19 | count(array_filter(array_values($data), 'is_array')) === count($data) 20 | ) { 21 | foreach ($data as $val) { 22 | $this->validateSubLevelData((array) $val, $rules); 23 | } 24 | } else { 25 | $this->validateSubLevelData($data, $rules); 26 | } 27 | return true; 28 | } 29 | 30 | public function getErros(): array 31 | { 32 | if (empty($this->errors)) { 33 | return []; 34 | } 35 | return $this->errors; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/resource/Common.php: -------------------------------------------------------------------------------- 1 | verificarAutoload()) { 12 | header('Location: ' . URL_HOST); 13 | exit(); 14 | } 15 | } 16 | 17 | private function executarComposer(): string | bool 18 | { 19 | putenv('COMPOSER_HOME=/root/.composer'); 20 | return shell_exec('cd .. && composer install 2>&1') ?? ''; 21 | } 22 | 23 | private function executarDump(): string | bool 24 | { 25 | putenv('COMPOSER_HOME=/root/.composer'); 26 | return shell_exec('cd .. && composer dump-autoload 2>&1') ?? false; 27 | } 28 | 29 | private function verificarAutoload(): bool 30 | { 31 | return file_exists('./vendor/autoload.php') && is_dir('./vendor'); 32 | } 33 | 34 | public function instalar(): void 35 | { 36 | $retorno = ''; 37 | if (!$this->verificarAutoload()) { 38 | $retorno .= $this->executarComposer(); 39 | } else { 40 | $this->executarDump(); 41 | } 42 | 43 | header('Content-Type: application/json'); 44 | 45 | echo json_encode([ 46 | 'erro' => !$this->verificarAutoload(), 47 | 'log' => $retorno, 48 | ]); 49 | exit(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/resource/ConstantPhpStan.php: -------------------------------------------------------------------------------- 1 | 15, 'segundo' => 25,]; 16 | self::assertIsInt(Arrays::searchKey($array, 'primeiro')); 17 | self::assertNull(Arrays::searchKey($array, 'nao-existe')); 18 | } 19 | 20 | public function testRenameKey(): void 21 | { 22 | $array = ['primeiro' => 10, 'segundo' => 20,]; 23 | self::assertTrue(Arrays::renameKey($array, 'primeiro', 'novoNome')); 24 | self::assertFalse(Arrays::renameKey($array, 'nao-existe', 'novoNome')); 25 | } 26 | 27 | public function testCheckExistIndexByValue(): void 28 | { 29 | $array = [ 30 | 'frutas' => [ 31 | 'fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva', 32 | ], 33 | 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 34 | 'legume' => 'Tomate', 35 | ]; 36 | self::assertTrue(Arrays::checkExistIndexByValue($array, 'Tomate')); 37 | self::assertFalse(Arrays::checkExistIndexByValue($array, 'nao-existe')); 38 | } 39 | 40 | public function testFindValueByKey(): void 41 | { 42 | $array = [ 43 | 'frutas' => [ 44 | 'fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva', 45 | ], 46 | 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 47 | 'legume' => 'Tomate', 48 | ]; 49 | self::assertIsArray(Arrays::findValueByKey($array, 'fruta_2')); 50 | } 51 | 52 | public function testFindIndexByValue(): void 53 | { 54 | $array = [ 55 | 'frutas' => [ 56 | 'fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva', 57 | ], 58 | 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 59 | 'legume' => 'Tomate', 60 | ]; 61 | self::assertIsArray(Arrays::findIndexByValue($array, 'Rúcula')); 62 | } 63 | 64 | public function testConvertArrayToXml(): void 65 | { 66 | $array = [ 67 | 'frutas' => [ 68 | 'fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva', 69 | ], 70 | 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 71 | 'legume' => 'Tomate', 72 | ]; 73 | 74 | $xml = new SimpleXMLElement(' '); 75 | Arrays::convertArrayToXml($array, $xml); 76 | 77 | self::assertIsObject($xml); 78 | self::assertNotEmpty($xml->asXML()); 79 | } 80 | 81 | public function testConvertJsonIndexToArray(): void 82 | { 83 | $array = [ 84 | 'frutas' => [ 85 | 'fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva', 86 | ], 87 | 'verduras' => '{"verdura_1": "Rúcula", "verdura_2": "Acelga", "verdura_3": "Alface"}', 88 | ]; 89 | Arrays::convertJsonIndexToArray($array); 90 | 91 | self::assertIsArray($array); 92 | self::assertIsArray($array['verduras']); 93 | } 94 | 95 | public function testCheckExistsIndexArrayRecursive(): void 96 | { 97 | $array = [ 98 | 'pessoa' => [ 99 | 'pedidos' => ['pedido1', 'pedido2'], 100 | 'categorias' => [ 101 | 'subcategorias' => ['subcategoria1' => 'valor teste'], 102 | ], 103 | ], 104 | ]; 105 | self::assertTrue(Arrays::checkExistIndexArrayRecursive($array, 'subcategoria1')); 106 | self::assertFalse(Arrays::checkExistIndexArrayRecursive($array, 'mercado')); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tests/UnitCompareTest.php: -------------------------------------------------------------------------------- 1 | '12', 27 | 'tratandoTipoIntZero' => '0', 28 | 'tratandoTipoIntNegativo' => '-8', 29 | 'tratandoTipoFloat' => '9.63', 30 | 'tratandoTipoBoolean' => 'true', 31 | 'tratandoTipoNumeric' => '11', 32 | ]; 33 | $rules = [ 34 | 'tratandoTipoInt' => 'convert|int', 35 | 'tratandoTipoIntZero' => 'convert|int', 36 | 'tratandoTipoIntNegativo' => 'convert|int', 37 | 'tratandoTipoFloat' => 'convert|float', 38 | 'tratandoTipoBoolean' => 'convert|bool', 39 | 'tratandoTipoNumeric' => 'convert|numeric', 40 | 'tratandoInexistente' => 'convert|bool', 41 | ]; 42 | Format::convertTypes($data, $rules); 43 | self::assertIsInt($data['tratandoTipoInt']); 44 | self::assertIsInt($data['tratandoTipoIntZero']); 45 | self::assertIsInt($data['tratandoTipoIntNegativo']); 46 | self::assertIsFloat($data['tratandoTipoFloat']); 47 | self::assertIsBool($data['tratandoTipoBoolean']); 48 | self::assertIsNumeric($data['tratandoTipoNumeric']); 49 | self::assertArrayNotHasKey('tratandoInexistente', $data); 50 | } 51 | 52 | public function testConvertTypesBool(): void 53 | { 54 | $convertTypesBool = new DataConvertTypesBool(); 55 | $data = $convertTypesBool->arrayData(); 56 | $rules = $convertTypesBool->arrayRule(); 57 | 58 | Format::convertTypes($data, $rules); 59 | self::assertIsBool($data['tratandoClasse']); 60 | self::assertIsBool($data['tratandoArray']); 61 | self::assertIsBool($data['tratandoInteiroPositivo']); 62 | self::assertIsBool($data['tratandoInteiroNegativo']); 63 | self::assertIsBool($data['tratandoStringTrue']); 64 | self::assertIsBool($data['tratandoStringOn']); 65 | self::assertIsBool($data['tratandoStringOff']); 66 | self::assertIsBool($data['tratandoStringYes']); 67 | self::assertIsBool($data['tratandoStringNo']); 68 | self::assertIsBool($data['tratandoStringUm']); 69 | self::assertIsBool($data['tratandoNull']); 70 | self::assertIsBool($data['tratandoInteiroZero']); 71 | self::assertIsBool($data['tratandoStringFalse']); 72 | self::assertIsBool($data['tratandoQualquerString']); 73 | self::assertIsBool($data['tratandoStringZero']); 74 | self::assertIsBool($data['tratandoStringVazio']); 75 | } 76 | 77 | public function testIdentifier(): void 78 | { 79 | self::assertEquals('894.213.600-10', Format::identifier('89421360010')); 80 | } 81 | 82 | public function testIdentifierOrCompany(): void 83 | { 84 | self::assertEquals('307.208.700-89', Format::identifierOrCompany('30720870089')); 85 | self::assertEquals('12.456.571/0001-14', Format::identifierOrCompany('12456571000114')); 86 | } 87 | 88 | public function testTelephone(): void 89 | { 90 | self::assertEquals('(44) 99999-8888', Format::telephone('44999998888')); 91 | } 92 | 93 | public function testZipCode(): void 94 | { 95 | self::assertEquals('87047-590', Format::zipCode('87047590')); 96 | } 97 | 98 | public function testDateBrazil(): void 99 | { 100 | self::assertEquals('10/10/2020', Format::dateBrazil('2020-10-10')); 101 | } 102 | 103 | public function testDateAmerican(): void 104 | { 105 | self::assertEquals('2020-10-10', Format::dateAmerican('10/10/2020')); 106 | } 107 | 108 | public function testArrayToIntReference(): void 109 | { 110 | $arrayProcessed = [ 111 | 0 => 1, 112 | 1 => 123, 113 | 'a' => 222, 114 | 'b' => 333, 115 | 'c' => 0, 116 | ]; 117 | $arrayReferenced = [ 118 | 0 => '1', 119 | 1 => '123', 120 | 'a' => '222', 121 | 'b' => 333, 122 | 'c' => '', 123 | ]; 124 | Format::arrayToIntReference($arrayReferenced); 125 | self::assertEquals($arrayProcessed, $arrayReferenced); 126 | } 127 | 128 | public function testArrayToInt(): void 129 | { 130 | $arrayProcessed = [ 131 | 0 => 1, 132 | 1 => 123, 133 | 'a' => 222, 134 | 'b' => 333, 135 | 'c' => 0, 136 | ]; 137 | self::assertEquals($arrayProcessed, Format::arrayToInt([ 138 | 0 => '1', 139 | 1 => '123', 140 | 'a' => '222', 141 | 'b' => 333, 142 | 'c' => '', 143 | ])); 144 | } 145 | 146 | public function testCurrency(): void 147 | { 148 | self::assertEquals('1.123,45', Format::currency('1123.45')); 149 | self::assertEquals('R$ 1.123,45', Format::currency('1123.45', 'R$ ')); 150 | self::assertEquals('123,00', Format::currency('123')); 151 | self::assertEquals('123,40', Format::currency('123.4')); 152 | self::assertEquals('123,40', Format::currency('123,4')); 153 | self::assertEquals('1,00', Format::currency('1')); 154 | self::assertEquals('1,00', Format::currency('1.00')); 155 | self::assertEquals('1,00', Format::currency('1,00')); 156 | self::assertEquals('1,25', Format::currency('1.25')); 157 | self::assertEquals('1,25', Format::currency('1,25')); 158 | self::assertEquals('1.400,00', Format::currency('1.400')); 159 | self::assertEquals('1.123,45', Format::currency(1123.45)); 160 | self::assertEquals('R$ 1.123,45', Format::currency(1123.45, 'R$ ')); 161 | self::assertEquals('123,00', Format::currency(123)); 162 | self::assertEquals('123,40', Format::currency(123.4)); 163 | self::assertEquals('1.400,00', Format::currency(1400)); 164 | } 165 | 166 | public function testCurrencyUsd(): void 167 | { 168 | self::assertEquals('1,123.45', Format::currencyUsd('1123.45')); 169 | self::assertEquals('Usd 1,123.45', Format::currencyUsd('1123.45', 'Usd ')); 170 | } 171 | 172 | public function testReturnPhoneOrAreaCode(): void 173 | { 174 | self::assertEquals('44', Format::returnPhoneOrAreaCode('44999998888', true)); 175 | self::assertEquals('999998888', Format::returnPhoneOrAreaCode('44999998888')); 176 | } 177 | 178 | public function testUcwordsCharset(): void 179 | { 180 | self::assertEquals('Açafrão Macarrão', Format::ucwordsCharset('aÇafrÃo maCaRRão')); 181 | } 182 | 183 | public function testPointOnlyValue(): void 184 | { 185 | self::assertEquals('1350.45', Format::pointOnlyValue('1.350,45')); 186 | } 187 | 188 | public function testEmptyToNull(): void 189 | { 190 | $array = [ 191 | 0 => '1', 192 | 'a' => '222', 193 | 'b' => 333, 194 | 'c' => null, 195 | 'd' => null, 196 | 'e' => '0', 197 | 'f' => null, 198 | 'g' => [1, 2,], 199 | ]; 200 | 201 | self::assertSame($array, Format::emptyToNull( 202 | [ 203 | 0 => '1', 204 | 'a' => '222', 205 | 'b' => 333, 206 | 'c' => '', 207 | 'd' => 'null', 208 | 'e' => '0', 209 | 'f' => [], 210 | 'g' => [1, 2,], 211 | ], 212 | '0', 213 | )); 214 | } 215 | 216 | public function testMask(): void 217 | { 218 | self::assertEquals('1234 5678 9012 3456', Format::mask('#### #### #### ####', '1234567890123456')); 219 | } 220 | 221 | public function testOnlyNumbers(): void 222 | { 223 | self::assertEquals('54887', Format::onlyNumbers('548Abc87@')); 224 | } 225 | 226 | public function testOnlyLettersNumbers(): void 227 | { 228 | self::assertEquals('548Abc87', Format::onlyLettersNumbers('548Abc87@')); 229 | } 230 | 231 | public function testUpper(): void 232 | { 233 | self::assertEquals('CARRO', Format::upper('CArrO')); 234 | } 235 | 236 | public function testLower(): void 237 | { 238 | self::assertEquals('carro', Format::lower('CArrO')); 239 | } 240 | 241 | public function testMaskStringHidden(): void 242 | { 243 | self::assertEquals('065.***.009.96', Format::maskStringHidden('065.775.009.96', 3, 4, '*')); 244 | self::assertNull(Format::maskStringHidden('', 3, 4, '*')); 245 | } 246 | 247 | public function testReverse(): void 248 | { 249 | self::assertEquals('ixacabA', Format::reverse('Abacaxi')); 250 | } 251 | 252 | public function testFalseToNull(): void 253 | { 254 | self::assertEquals(null, Format::falseToNull(false)); 255 | } 256 | 257 | public function testRemoveAccent(): void 258 | { 259 | self::assertEquals('Acafrao', Format::removeAccent('Açafrão')); 260 | self::assertEquals('Acafrao com Espaco', Format::removeAccent('Açafrão com Espaço')); 261 | self::assertNull(Format::removeAccent('')); 262 | self::assertNull(Format::removeAccent(null)); 263 | } 264 | 265 | public function testRemoveSpecialCharacters(): void 266 | { 267 | self::assertEquals('Acafrao ', Format::removeSpecialCharacters('Açafrão !@#$%¨&*()_+-=')); 268 | self::assertEquals('Acafrao com Espaco ', Format::removeSpecialCharacters('Açafrão com Espaço %$#@!')); 269 | self::assertEquals('AcafraosemEspaco', Format::removeSpecialCharacters('Açafrão sem Espaço %$#@!', false)); 270 | self::assertNull(Format::removeSpecialCharacters('')); 271 | } 272 | 273 | public function testWriteDateExtensive(): void 274 | { 275 | if (extension_loaded('gd')) { 276 | self::assertEquals('domingo, 08 de novembro de 2020', Format::writeDateExtensive('08/11/2020')); 277 | } else { 278 | self::assertFalse(extension_loaded('gd')); 279 | } 280 | } 281 | 282 | public function testWriteCurrencyExtensive(): void 283 | { 284 | self::assertEquals('um real e noventa e sete centavos', Format::writeCurrencyExtensive(1.97)); 285 | } 286 | 287 | public function testRestructFileArray(): void 288 | { 289 | $fileUploadSingle = [ 290 | 'name' => 'JPG - Validação upload v.1.jpg', 291 | 'type' => 'image/jpeg', 292 | 'tmp_name' => '/tmp/phpODnLGo', 293 | 'error' => 0, 294 | 'size' => 8488, 295 | ]; 296 | 297 | $fileUploadMultiple = [ 298 | 'name' => ['0' => 'JPG - Validação upload v.1.jpg', '1' => 'PDF - Validação upload v.1.pdf'], 299 | 'type' => ['0' => 'image/jpeg', '1' => 'application/pdf'], 300 | 'tmp_name' => ['0' => '/tmp/phpODnLGo', '1' => '/tmp/phpfmb0tL'], 301 | 'error' => ['0' => 0, '1' => 0], 302 | 'size' => ['0' => 8488, '1' => 818465], 303 | ]; 304 | self::assertArrayHasKey('name', Format::restructFileArray($fileUploadSingle)[0]); 305 | self::assertArrayHasKey('name', Format::restructFileArray($fileUploadMultiple)[0]); 306 | self::assertArrayHasKey('name', Format::restructFileArray($fileUploadMultiple)[1]); 307 | } 308 | 309 | public function testConvertTimestampBrazilToAmerican(): void 310 | { 311 | self::assertEquals('2021-04-15 19:50:25', Format::convertTimestampBrazilToAmerican('15/04/2021 19:50:25')); 312 | } 313 | 314 | public function testConvertStringToBinary(): void 315 | { 316 | self::assertEquals('1100001 1101101 1101111 1110010', Format::convertStringToBinary('amor')); 317 | self::assertNotSame('1100001 1101101 1101111 1110010', Format::convertStringToBinary('casa')); 318 | } 319 | 320 | public static function testSlugfy(): void 321 | { 322 | self::assertEquals('polenta-frita-com-bacon-e-parmesao', Format::slugfy('Polenta frita com Bacon e Parmesão')); 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /tests/UnitIntegerTest.php: -------------------------------------------------------------------------------- 1 | '0a', 17 | 'testLeftZero' => '01', 18 | 'testIntZero' => '0', 19 | 'testIntZeroTyped' => 0, 20 | 'testIntOne' => 1, 21 | 'testIntNegative' => -2, 22 | ]; 23 | } 24 | 25 | public function testInteger(): void 26 | { 27 | $array = $this->assembleArrayForTests(); 28 | $rules = [ 29 | 'testIntError' => 'int', 30 | 'testLeftZero' => 'int', 31 | 'testIntZero' => 'int', 32 | 'testIntZeroTyped' => 'int', 33 | 'testIntOne' => 'int', 34 | 'testIntNegative' => 'int', 35 | ]; 36 | $validator = new Validator(); 37 | $validator->set($array, $rules); 38 | self::assertCount(4, $validator->getErros()); 39 | } 40 | 41 | public function testIntegerTyped(): void 42 | { 43 | $array = $this->assembleArrayForTests(); 44 | $rules = [ 45 | 'testIntError' => 'integer', 46 | 'testLeftZero' => 'integer', 47 | 'testIntZero' => 'integer', 48 | 'testIntZeroTyped' => 'integer', 49 | 'testIntOne' => 'integer', 50 | 'testIntNegative' => 'integer', 51 | ]; 52 | 53 | $validator = new Validator(); 54 | $validator->set($array, $rules); 55 | self::assertCount(3, $validator->getErros()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/UnitStringTest.php: -------------------------------------------------------------------------------- 1 | 'a@', 'testValid' => 'aeiouAÉIÓÚ',]; 15 | $rules = ['testError' => 'alpha', 'testValid' => 'alpha',]; 16 | 17 | $validator = new Validator(); 18 | $validator->set($array, $rules); 19 | self::assertCount(1, $validator->getErros()); 20 | } 21 | 22 | public function testAlphaNoSpecial(): void 23 | { 24 | $array = ['testError' => 'aéiou', 'testValid' => 'aEiOU',]; 25 | $rules = ['testError' => 'alphaNoSpecial', 'testValid' => 'alphaNoSpecial',]; 26 | 27 | $validator = new Validator(); 28 | $validator->set($array, $rules); 29 | self::assertCount(1, $validator->getErros()); 30 | } 31 | 32 | public function testAlphaNum(): void 33 | { 34 | $array = ['testError' => 'a1B2Éí3@', 'testValid' => 'a1B2Éí3',]; 35 | $rules = ['testError' => 'alphaNum', 'testValid' => 'alphaNum',]; 36 | 37 | $validator = new Validator(); 38 | $validator->set($array, $rules); 39 | self::assertCount(1, $validator->getErros()); 40 | } 41 | 42 | public function testAlphaNumNoSpecial(): void 43 | { 44 | $array = ['testError' => 'AeioÚ123', 'testValid' => 'AeioU123',]; 45 | $rules = ['testError' => 'alphaNumNoSpecial', 'testValid' => 'alphaNumNoSpecial',]; 46 | 47 | $validator = new Validator(); 48 | $validator->set($array, $rules); 49 | self::assertCount(1, $validator->getErros()); 50 | } 51 | 52 | public function testRgbColor(): void 53 | { 54 | $array = ['testError' => '300, 50, 255', 'testValid' => '0, 43, 233',]; 55 | $rules = ['testError' => 'rgbColor', 'testValid' => 'rgbColor',]; 56 | 57 | $validator = new Validator(); 58 | $validator->set($array, $rules); 59 | self::assertCount(1, $validator->getErros()); 60 | } 61 | 62 | public function testValidateDdd(): void 63 | { 64 | $array = [ 65 | 'testErrorDddTwoDigits' => '60', 66 | 'testValidTwoDigits' => '61', 67 | 'testErrorDddTwoDigitsState' => '11', 68 | 'testValidTwoDigitsState' => '44', 69 | ]; 70 | $rules = [ 71 | 'testErrorDddTwoDigits' => 'ddd', 72 | 'testValidTwoDigits' => 'ddd', 73 | 'testErrorDddTwoDigitsState' => 'ddd:pr', 74 | 'testValidTwoDigitsState' => 'ddd:pr', 75 | ]; 76 | $validator = new Validator(); 77 | $validator->set($array, $rules); 78 | self::assertCount(2, $validator->getErros()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/UnitUtilityTest.php: -------------------------------------------------------------------------------- 1 | add(new DateInterval('P32D'))->format('Y-m-d'); 37 | self::assertEquals(true, ValidateDate::validateDateNotFuture(Format::dateAmerican('28/12/2022'))); 38 | self::assertEquals(false, ValidateDate::validateDateNotFuture($newDateFuture)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/UnitValidateHourTest.php: -------------------------------------------------------------------------------- 1 |