├── .github ├── FUNDING.yml └── workflows │ └── run-tests.yml ├── src ├── String │ ├── Html2Text.php │ ├── Text.php │ ├── Url.php │ ├── SecondsToTime.php │ ├── Compact.php │ └── HumanFilesize.php ├── Pdf │ ├── CanRegeneratePDF.php │ └── Ghostscript.php ├── Rules │ ├── InKeys.php │ ├── UrlWithoutScheme.php │ ├── MaxWords.php │ ├── Host.php │ ├── HostOrSubdomain.php │ ├── CurrentPassword.php │ └── DimensionsWithMargin.php ├── Blade │ ├── BladeDirectiveHelpers.php │ ├── TestsBladeComponents.php │ ├── DecimalMoneyFormatter.php │ └── IntlMoneyFormatter.php ├── Commands │ └── GenerateSitemap.php ├── Request │ └── ConvertsBase64ToFiles.php └── Database │ └── CountriesInDutch.php ├── CHANGELOG.md ├── LICENSE.md ├── composer.json ├── CONTRIBUTING.md └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [pascalbaljet] 2 | -------------------------------------------------------------------------------- /src/String/Html2Text.php: -------------------------------------------------------------------------------- 1 | 'none', 12 | ]); 13 | 14 | return trim($instance->getText()); 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Rules/InKeys.php: -------------------------------------------------------------------------------- 1 | values = array_keys($values); 18 | } 19 | 20 | public static function make(array $values): self 21 | { 22 | return new static($values); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/String/Url.php: -------------------------------------------------------------------------------- 1 | = 3600) { 19 | return sprintf('%02d:%02d:%02d', ($seconds / 3600), ($seconds / 60 % 60), $seconds % 60); 20 | } 21 | 22 | return sprintf('%02d:%02d', ($seconds / 60 % 60), $seconds % 60); 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/String/Compact.php: -------------------------------------------------------------------------------- 1 | $default) { 22 | $parts[$key] = isset($parts[$key]) ? trim($parts[$key]) : $default; 23 | } 24 | 25 | return $parts; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Rules/UrlWithoutScheme.php: -------------------------------------------------------------------------------- 1 | make([], [])->validateUrl($attribute, $value); 26 | } 27 | 28 | /** 29 | * Get the validation error message. 30 | * 31 | * @return string 32 | */ 33 | public function message() 34 | { 35 | return __('validation.url'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Protone Media B.V. 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. -------------------------------------------------------------------------------- /src/Rules/MaxWords.php: -------------------------------------------------------------------------------- 1 | max = $max; 19 | } 20 | 21 | /** 22 | * Helper method to initialize the rule. 23 | * 24 | * @param integer $max 25 | * @return self 26 | */ 27 | public static function make(int $max): self 28 | { 29 | return new static($max); 30 | } 31 | 32 | /** 33 | * Determine if the validation rule passes. 34 | * 35 | * @param string $attribute 36 | * @param mixed $value 37 | * @return bool 38 | */ 39 | public function passes($attribute, $value) 40 | { 41 | return count(array_filter(explode(' ', $value))) <= $this->max; 42 | } 43 | 44 | /** 45 | * Get the validation error message. 46 | * 47 | * @return string 48 | */ 49 | public function message() 50 | { 51 | return __('validation.max_words'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Blade/TestsBladeComponents.php: -------------------------------------------------------------------------------- 1 | app), function (ViewServiceProvider $viewServiceProvider) { 24 | $viewServiceProvider->registerViewFinder(); 25 | $viewServiceProvider->register(); 26 | }); 27 | } 28 | 29 | /** 30 | * Returns the evaluated view contents for the given view and data. 31 | * 32 | * @param string $view 33 | * @param array $data 34 | * @return string 35 | */ 36 | protected function renderView(string $view, array $data = []): string 37 | { 38 | Artisan::call('view:clear'); 39 | 40 | $view = View::make($view, $data); 41 | 42 | return trim((string) ($view)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Pdf/Ghostscript.php: -------------------------------------------------------------------------------- 1 | bin = $bin; 17 | } 18 | 19 | /** 20 | * Generates a temporary filename for a PDF file. 21 | * 22 | * @return string 23 | */ 24 | private static function tempFile(): string 25 | { 26 | return tempnam(sys_get_temp_dir(), 'ghostscript') . '.pdf'; 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function regeneratePdf(string $pdfContents): string 33 | { 34 | file_put_contents($input = static::tempFile(), $pdfContents); 35 | 36 | (new Process([ 37 | $this->bin, 38 | '-sDEVICE=pdfwrite', 39 | '-dPDFSETTINGS=/prepress', 40 | '-sOutputFile=' . $destination = static::tempFile(), 41 | $input, 42 | ]))->run(); 43 | 44 | return tap(@file_get_contents($destination), function () use ($input, $destination) { 45 | @unlink($input); 46 | @unlink($destination); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/String/HumanFilesize.php: -------------------------------------------------------------------------------- 1 | = 1000000000000) { 23 | $value = round($value / (1024 * 1024 * 1024 * 1024), $precision); 24 | $unit = 'TB'; 25 | } elseif ($value >= 1000000000) { 26 | $value = round($value / (1024 * 1024 * 1024), $precision); 27 | $unit = 'GB'; 28 | } elseif ($value >= 1000000) { 29 | $value = round($value / (1024 * 1024), $precision); 30 | $unit = 'MB'; 31 | } elseif ($value >= 1000) { 32 | $value = round($value / (1024), $precision); 33 | $unit = 'KB'; 34 | } else { 35 | $unit = 'Bytes'; 36 | return number_format($value) . ' ' . $unit; 37 | } 38 | 39 | return ($isNegative ? '-' : '') . number_format($value, $precision) . ' ' . $unit; 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Blade/DecimalMoneyFormatter.php: -------------------------------------------------------------------------------- 1 | format($money); 29 | } 30 | 31 | /** 32 | * Registers a handler for the money formatter. 33 | * 34 | * @param string $name 35 | * @param string $code 36 | * @return void 37 | */ 38 | public static function directive(string $name = 'decimals', string $code = 'EUR') 39 | { 40 | Blade::directive($name, function ($expression) use ($code) { 41 | $parts = static::parseExpression($expression, [1 => "'{$code}'"]); 42 | 43 | return ""; 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Commands/GenerateSitemap.php: -------------------------------------------------------------------------------- 1 | signature = $signature; 33 | 34 | parent::__construct(); 35 | } 36 | 37 | /** 38 | * Execute the console command. 39 | * 40 | * @return mixed 41 | */ 42 | public function handle(SitemapGenerator $sitemapGenerator) 43 | { 44 | $sitemapGenerator 45 | ->setUrl(config('app.url')) 46 | ->writeToFile(public_path('sitemap.xml')); 47 | } 48 | 49 | /** 50 | * Register the command. 51 | * 52 | * @return void 53 | */ 54 | public static function register(string $signature = 'sitemap:generate') 55 | { 56 | Artisan::registerCommand(new static($signature)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Rules/Host.php: -------------------------------------------------------------------------------- 1 | hosts = Arr::wrap($host); 21 | } 22 | 23 | public static function make($host): self 24 | { 25 | return new static($host); 26 | } 27 | 28 | /** 29 | * Determine if the validation rule passes. 30 | * 31 | * @param string $attribute 32 | * @param mixed $value 33 | * @return bool 34 | */ 35 | public function passes($attribute, $value) 36 | { 37 | if (!parse_url($value, PHP_URL_SCHEME)) { 38 | $value = "https://{$value}"; 39 | } 40 | 41 | $host = parse_url($value, PHP_URL_HOST); 42 | 43 | if (!$host) { 44 | return false; 45 | } 46 | 47 | if (Str::startsWith($host, 'www.')) { 48 | $host = Str::after($host, 'www.'); 49 | } 50 | 51 | return in_array($host, $this->hosts); 52 | } 53 | 54 | /** 55 | * Get the validation error message. 56 | * 57 | * @return string 58 | */ 59 | public function message() 60 | { 61 | return __('validation.host'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: run-tests 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | fail-fast: true 13 | matrix: 14 | php: [8.4, 8.3, 8.2] 15 | laravel: ["10.*", "11.*", "12.*"] 16 | dependency-version: [prefer-lowest, prefer-stable] 17 | include: 18 | - laravel: 10.* 19 | testbench: 8.* 20 | - laravel: 11.* 21 | testbench: 9.* 22 | - laravel: 12.* 23 | testbench: 10.* 24 | 25 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} 26 | 27 | steps: 28 | - name: Checkout code 29 | uses: actions/checkout@v2 30 | 31 | - name: Setup PHP 32 | uses: shivammathur/setup-php@v2 33 | with: 34 | php-version: ${{ matrix.php }} 35 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, mysql, mysqli, pdo_mysql 36 | coverage: none 37 | 38 | - name: Install Ghostscript 39 | run: | 40 | sudo apt-get update 41 | sudo apt-get install -y ghostscript 42 | which ghostscript 43 | 44 | - name: Install dependencies 45 | run: | 46 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update 47 | composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest 48 | 49 | - name: Execute tests 50 | run: vendor/bin/phpunit 51 | -------------------------------------------------------------------------------- /src/Blade/IntlMoneyFormatter.php: -------------------------------------------------------------------------------- 1 | format($money); 34 | } 35 | 36 | /** 37 | * Registers a handler for the money formatter. 38 | * 39 | * @param string $name 40 | * @param string $code 41 | * @param string $locale 42 | * @return void 43 | */ 44 | public static function directive(string $name = 'money', string $code = 'EUR', string $locale = 'nl_NL') 45 | { 46 | Blade::directive($name, function ($expression) use ($code, $locale) { 47 | $parts = static::parseExpression($expression, [ 48 | 1 => "'{$code}'", 49 | 2 => "'{$locale}'", 50 | ]); 51 | 52 | return ""; 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Rules/HostOrSubdomain.php: -------------------------------------------------------------------------------- 1 | hosts = Arr::wrap($host); 24 | 25 | $this->publicSuffixList = $publicSuffixList ?: Rules::fromString( 26 | Http::get('https://publicsuffix.org/list/public_suffix_list.dat') 27 | ); 28 | } 29 | 30 | public static function make($host): self 31 | { 32 | return new static($host); 33 | } 34 | 35 | /** 36 | * Determine if the validation rule passes. 37 | * 38 | * @param string $attribute 39 | * @param mixed $value 40 | * @return bool 41 | */ 42 | public function passes($attribute, $value) 43 | { 44 | if (!parse_url($value, PHP_URL_SCHEME)) { 45 | $value = "https://{$value}"; 46 | } 47 | 48 | $host = parse_url($value, PHP_URL_HOST); 49 | 50 | if (!$host) { 51 | return false; 52 | } 53 | 54 | $resolvedDomain = $this->publicSuffixList->resolve($host); 55 | 56 | if ($host !== $resolvedDomain->domain()->toString()) { 57 | return false; 58 | } 59 | 60 | return in_array($resolvedDomain->registrableDomain()->toString(), $this->hosts); 61 | } 62 | 63 | /** 64 | * Get the validation error message. 65 | * 66 | * @return string 67 | */ 68 | public function message() 69 | { 70 | return __('validation.host'); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "protonemedia/laravel-mixins", 3 | "description": "Laravel Mixins", 4 | "keywords": [ 5 | "protonemedia", 6 | "laravel-mixins" 7 | ], 8 | "homepage": "https://github.com/protonemedia/laravel-mixins", 9 | "license": "MIT", 10 | "type": "library", 11 | "authors": [ 12 | { 13 | "name": "Pascal Baljet", 14 | "email": "pascal@protone.media", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.2 || ^8.3 || ^8.4", 20 | "illuminate/support": " ^10.0 || ^11.0 || ^12.0" 21 | }, 22 | "require-dev": { 23 | "html2text/html2text": "^4.3", 24 | "jeremykendall/php-domain-parser": "^6.0", 25 | "laravel/ui": "^4.0", 26 | "mockery/mockery": "^1.4.4", 27 | "moneyphp/money": "^3.3 || ^4.5", 28 | "nesbot/carbon": "^2.71 || ^3.0", 29 | "orchestra/testbench": " ^8.0 || ^9.0 || ^10.0", 30 | "phpunit/phpunit": "^10.4 || ^11.5.3", 31 | "spatie/laravel-sitemap": "^6.0 || ^7.2", 32 | "symfony/process": "^6.0 || ^7.0" 33 | }, 34 | "suggest": { 35 | "html2text/html2text": "To convert HTML to formatted plain text", 36 | "moneyphp/money": "Blade directives to represent money", 37 | "spatie/laravel-sitemap": "To generate sitemaps", 38 | "symfony/process": "To run Ghostscript" 39 | }, 40 | "autoload": { 41 | "psr-4": { 42 | "ProtoneMedia\\LaravelMixins\\": "src" 43 | } 44 | }, 45 | "autoload-dev": { 46 | "psr-4": { 47 | "ProtoneMedia\\LaravelMixins\\Tests\\": "tests" 48 | } 49 | }, 50 | "scripts": { 51 | "test": "vendor/bin/phpunit", 52 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 53 | }, 54 | "config": { 55 | "sort-packages": true 56 | }, 57 | "minimum-stability": "dev", 58 | "prefer-stable": true 59 | } -------------------------------------------------------------------------------- /src/Rules/CurrentPassword.php: -------------------------------------------------------------------------------- 1 | user()->getAuthIdentifier() . '|' . $request->ip()); 26 | } 27 | 28 | /** 29 | * Determine if the validation rule passes. 30 | * 31 | * @param string $attribute 32 | * @param mixed $value 33 | * @return bool 34 | */ 35 | public function passes($attribute, $value) 36 | { 37 | $request = request(); 38 | 39 | if ($this->hasTooManyLoginAttempts($request)) { 40 | $this->tooManyAttempts = true; 41 | return false; 42 | } 43 | 44 | return tap( 45 | Hash::check($value, $request->user()->getAuthPassword()), 46 | fn ($verified) => $verified ? null : $this->incrementLoginAttempts($request) 47 | ); 48 | } 49 | 50 | /** 51 | * Get the validation error message. 52 | * 53 | * @return string 54 | */ 55 | public function message() 56 | { 57 | if ($this->tooManyAttempts) { 58 | $seconds = $this->limiter()->availableIn( 59 | $this->throttleKey(request()) 60 | ); 61 | 62 | return __('auth.throttle', [ 63 | 'seconds' => $seconds, 64 | 'minutes' => ceil($seconds / 60), 65 | ]); 66 | } 67 | 68 | return __('validation.password'); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Rules/DimensionsWithMargin.php: -------------------------------------------------------------------------------- 1 | 0) { 36 | $this->constraints['margin'] = $margin; 37 | } 38 | 39 | return $this; 40 | } 41 | 42 | /** 43 | * Determine if the validation rule passes. 44 | * 45 | * @param string $attribute 46 | * @param mixed $value 47 | * @return bool 48 | */ 49 | public function passes($attribute, $value) 50 | { 51 | $parameters = Collection::make($this->constraints)->map(function ($value, $key) { 52 | return "{$key}={$value}"; 53 | })->all(); 54 | 55 | return $this->validateDimensions($attribute, $value, $parameters); 56 | } 57 | 58 | /** 59 | * It checks for every margin if the underlying rule doesn't fails. 60 | * 61 | * @param array $parameters 62 | * @param int $width 63 | * @param int $height 64 | * @return bool 65 | */ 66 | protected function failsRatioCheck($parameters, $width, $height) 67 | { 68 | if (!isset($parameters['ratio']) || !isset($parameters['margin'])) { 69 | return $this->failsRatioCheckTrait($parameters, $width, $height); 70 | } 71 | 72 | $range = range($parameters['margin'] * -1, $parameters['margin']); 73 | 74 | foreach ($range as $margin) { 75 | if (!$this->failsRatioCheckTrait($parameters, $width + $margin, $height)) { 76 | return false; 77 | } 78 | 79 | if (!$this->failsRatioCheckTrait($parameters, $width, $height + $margin)) { 80 | return false; 81 | } 82 | } 83 | 84 | return true; 85 | } 86 | 87 | /** 88 | * Get the validation error message. 89 | * 90 | * @return string 91 | */ 92 | public function message() 93 | { 94 | return __('validation.dimensions'); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Request/ConvertsBase64ToFiles.php: -------------------------------------------------------------------------------- 1 | request; 27 | } 28 | 29 | /** 30 | * Helper method to get the uploaded files bag. 31 | * 32 | * @return FileBag 33 | */ 34 | private function uploadFilesBag(): FileBag 35 | { 36 | return $this->files; 37 | } 38 | 39 | /** 40 | * Pulls the Base64 contents for each image key and creates 41 | * an UploadedFile instance from it and sets it on the 42 | * request. 43 | * 44 | * @return void 45 | */ 46 | protected function prepareForValidation() 47 | { 48 | $flattened = Arr::dot($this->base64FileKeys()); 49 | 50 | Collection::make($flattened)->each(function ($filename, $key) { 51 | rescue(function () use ($key, $filename) { 52 | $base64Contents = $this->input($key); 53 | 54 | if (!$base64Contents) { 55 | return; 56 | } 57 | 58 | // Generate a temporary path to store the Base64 contents 59 | $tempFilePath = tempnam(sys_get_temp_dir(), $filename); 60 | 61 | // Store the contents using a stream, or by decoding manually 62 | if (Str::startsWith($base64Contents, 'data:') && count(explode(',', $base64Contents)) > 1) { 63 | $source = fopen($base64Contents, 'r'); 64 | $destination = fopen($tempFilePath, 'w'); 65 | 66 | stream_copy_to_stream($source, $destination); 67 | 68 | fclose($source); 69 | fclose($destination); 70 | } else { 71 | file_put_contents($tempFilePath, base64_decode($base64Contents, true)); 72 | } 73 | 74 | $uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true); 75 | 76 | $body = $this->bodyParametersBag()->all(); 77 | Arr::forget($body, $key); 78 | $this->bodyParametersBag()->replace($body); 79 | 80 | $files = $this->uploadFilesBag()->all(); 81 | Arr::set($files, $key, $uploadedFile); 82 | $this->uploadFilesBag()->replace($files); 83 | }, null, false); 84 | }); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Etiquette 8 | 9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code 10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be 11 | extremely unfair for them to suffer abuse or anger for their hard work. 12 | 13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the 14 | world that developers are civilized and selfless people. 15 | 16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient 17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. 18 | 19 | ## Viability 20 | 21 | When requesting or submitting new features, first consider whether it might be useful to others. Open 22 | source projects are used by many developers, who may have entirely different needs to your own. Think about 23 | whether or not your feature is likely to be used by other users of the project. 24 | 25 | ## Procedure 26 | 27 | Before filing an issue: 28 | 29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 30 | - Check to make sure your feature suggestion isn't already present within the project. 31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 32 | - Check the pull requests tab to ensure that the feature isn't already in progress. 33 | 34 | Before submitting a pull request: 35 | 36 | - Check the codebase to ensure that your feature doesn't already exist. 37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 38 | 39 | ## Requirements 40 | 41 | If the project maintainer has any additional requirements, you will find them listed here. 42 | 43 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). 44 | 45 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 46 | 47 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 48 | 49 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 50 | 51 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 52 | 53 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 54 | 55 | **Happy coding**! 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Mixins 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/protonemedia/laravel-mixins.svg?style=flat-square)](https://packagist.org/packages/protonemedia/laravel-mixins) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/protonemedia/laravel-mixins.svg?style=flat-square)](https://packagist.org/packages/protonemedia/laravel-mixins) 5 | [![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/protonemedia/laravel-mixins) 6 | 7 | ## Sponsor Us 8 | 9 | [](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-mixins) 10 | 11 | ❤️ We proudly support the community by developing Laravel packages and giving them away for free. If this package saves you time or if you're relying on it professionally, please consider [sponsoring the maintenance and development](https://github.com/sponsors/pascalbaljet) and check out our latest premium package: [Inertia Table](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-mixins). Keeping track of issues and pull requests takes time, but we're happy to help! 12 | 13 | ## Requirements 14 | 15 | * PHP 8.2+ 16 | * Laravel 10.0 17 | 18 | ## Installation 19 | 20 | You can install the package via composer: 21 | 22 | ```bash 23 | composer require protonemedia/laravel-mixins 24 | ``` 25 | 26 | There's no Service Provider or automatic discovery/registration of anything. All features are opt-in. 27 | 28 | ## Contents 29 | 30 | #### Blade Directives 31 | * [Decimal Money Formatter](#decimal-money-formatter) 32 | * [Intl Money Formatter](#intl-money-formatter) 33 | 34 | #### Console Commands 35 | * [Generate Sitemap](#generate-sitemap) 36 | 37 | #### Validation Rules 38 | * [Current password](#current-password) 39 | * [Dimensions With Margin](#dimensions-with-margin) 40 | * [Host](#host) 41 | * [In Keys](#in-keys) 42 | * [Max Words](#max-words) 43 | * [URL Without Scheme](#url-without-scheme) 44 | 45 | #### String Macros 46 | * [Compact](#compact) 47 | * [Human Filesize](#human-filesize) 48 | * [Text](#text) 49 | * [URL](#url) 50 | * [Seconds to time](#seconds-to-time) 51 | 52 | #### PDF 53 | * [PDF Regeneration](#pdf-regeneration) 54 | 55 | #### Request 56 | * [Convert Base64 input data to files](#convert-base64-input-data-to-files) 57 | 58 | ## Blade Directives 59 | 60 | You can register Blade Directives by calling the `directive` method on the class. You can change the name of a directive with the optional first argument. 61 | 62 | ### Decimal Money Formatter 63 | 64 | *Note: This directive requires the `moneyphp/money` package.* 65 | 66 | Register the directive, for example by adding it to your `AppSerivceProvider`: 67 | 68 | ```php 69 | ProtoneMedia\LaravelMixins\Blade\DecimalMoneyFormatter::directive(); 70 | ``` 71 | 72 | You can customize the name of the directive and the default currency code: 73 | 74 | ```php 75 | ProtoneMedia\LaravelMixins\Blade\DecimalMoneyFormatter::directive('decimals', 'EUR'); 76 | ``` 77 | 78 | The first argument of the directive is the amount in cents. The second optional parameter is the currency. 79 | 80 | ```blade 81 | // 0.99 82 | @decimals(99) 83 | 84 | // 1.00 85 | @decimals(100) 86 | 87 | // 100 88 | @decimals(100, 'XTS') 89 | ``` 90 | 91 | ### Intl Money Formatter 92 | 93 | *Note: This directive requires the `moneyphp/money` package.* 94 | 95 | Register the directive, for example by adding it to your `AppSerivceProvider`: 96 | 97 | ```php 98 | ProtoneMedia\LaravelMixins\Blade\IntlMoneyFormatter::directive(); 99 | ``` 100 | 101 | You can customize the name of the directive, the default currency code and the locale: 102 | 103 | ```php 104 | ProtoneMedia\LaravelMixins\Blade\IntlMoneyFormatter::directive('money', 'EUR', 'nl_NL'); 105 | ``` 106 | 107 | The first argument of the directive is the amount in cents. The optional second parameter is the currency. The optional third parameter is the locale. 108 | 109 | ```blade 110 | // € 0,99 111 | @money(99) 112 | 113 | // € 1,00 114 | @money(100) 115 | 116 | // US$ 1,00 117 | @money(100, 'USD') 118 | 119 | // 1 000,00 $US 120 | @money(100, 'USD', 'fr') 121 | ``` 122 | 123 | ## Commands 124 | 125 | ### Generate Sitemap 126 | 127 | *Note: This command requires the `spatie/laravel-sitemap` package.* 128 | 129 | You can register the command by adding it to your `App\Console\Kernel` file, or by calling the `register` method on the class. 130 | 131 | ```php 132 | ProtoneMedia\LaravelMixins\Commands\GenerateSitemap::register(); 133 | ``` 134 | 135 | You can also set a custom signature: 136 | 137 | ```php 138 | ProtoneMedia\LaravelMixins\Commands\GenerateSitemap::register('generate-sitemap'); 139 | ``` 140 | 141 | It generates a sitemap of your entire site and stores in in the `public` folder as `sitemap.xml`. 142 | 143 | ```bash 144 | php artisan sitemap:generate 145 | ``` 146 | 147 | ## Validation Rules 148 | 149 | ### Current password 150 | 151 | Passes if the value matches the password of the authenticated user. 152 | 153 | ```php 154 | $rule = new ProtoneMedia\LaravelMixins\Rules\CurrentPassword; 155 | ``` 156 | 157 | As of Laravel 9, this validation rule is [built-in](https://laravel.com/docs/9.x/validation#rule-current-password). 158 | 159 | ### Dimensions With Margin 160 | 161 | Extension of the [Dimensions rule](https://laravel.com/docs/master/validation#rule-dimensions) with a `margin` option. Handy when you're working with ratios with repeating decimals. 162 | 163 | ```php 164 | use ProtoneMedia\LaravelMixins\Rules\DimensionsWithMargin; 165 | 166 | $rule = DimensionsWithMargin::make()->ratio(20 / 9)->margin(1), 167 | ``` 168 | 169 | ### Host 170 | 171 | Verifies if the URL matches the given hosts. 172 | 173 | ```php 174 | use ProtoneMedia\LaravelMixins\Rules\Host; 175 | 176 | $rule = Host::make(['facebook.com', 'fb.me']); 177 | ``` 178 | 179 | ### In Keys 180 | 181 | Verifies if the given key or index exists in the array. 182 | 183 | ```php 184 | use ProtoneMedia\LaravelMixins\Rules\InKeys; 185 | 186 | $rule = new InKeys(['laravel' => 'Laravel Framework', 'tailwindcss' => 'Tailwind CSS framework']); 187 | 188 | // same as 189 | 190 | use Illuminate\Validation\Rules\In; 191 | 192 | $rule = new In(['laravel', 'tailwindcss']); 193 | ``` 194 | 195 | ### Max Words 196 | 197 | Passes if the values contains no more words than specified. 198 | 199 | ```php 200 | use ProtoneMedia\LaravelMixins\Rules\MaxWords; 201 | 202 | $rule = MaxWords::make(250); 203 | ``` 204 | 205 | ### URL Without Scheme 206 | 207 | Passes if the URL is valid, even without a scheme. 208 | 209 | ```php 210 | $rule = new ProtoneMedia\LaravelMixins\Rules\UrlWithoutScheme; 211 | ``` 212 | 213 | ## String macros 214 | 215 | You can add new method by using the mixins. 216 | 217 | ### Compact 218 | 219 | ```php 220 | Str::mixin(new ProtoneMedia\LaravelMixins\String\Compact); 221 | 222 | $string = "Hoe simpeler hoe beter. Want hoe minder keuze je een speler laat, hoe groter de kans dat hij het juiste doet."; 223 | 224 | // Hoe simpeler hoe beter. Want hoe ... de kans dat hij het juiste doet. 225 | echo Str::compact($string); 226 | ``` 227 | 228 | It has an optional second argument to specify the length on each side. With the optional third argument, you can specify the sepeator. 229 | 230 | ```php 231 | // Hoe simpeler hoe - het juiste doet. 232 | echo Str::compact($string, 16, ' - '); 233 | ``` 234 | 235 | ### Human Filesize 236 | 237 | Converts a filesize into a human-readable version of the string. 238 | 239 | ```php 240 | Str::mixin(new ProtoneMedia\LaravelMixins\String\HumanFilesize); 241 | 242 | $size = 3456789; 243 | 244 | // '3.3 MB' 245 | Str::humanFilesize($size)); 246 | ``` 247 | 248 | ### Text 249 | 250 | *Note: This macro requires the `html2text/html2text` package.* 251 | 252 | Converts HTML to plain text. 253 | 254 | ```php 255 | Str::mixin(new ProtoneMedia\LaravelMixins\String\Text); 256 | 257 | $html = "

Protone Media

"; 258 | 259 | // Protone Media 260 | Str::text($html); 261 | ``` 262 | 263 | ### URL 264 | 265 | Prepends `https://` if the scheme is missing from the given URL. 266 | 267 | ```php 268 | Str::mixin(new ProtoneMedia\LaravelMixins\String\Url); 269 | 270 | $url = "protone.media"; 271 | 272 | // https://protone.media 273 | Str::url($url); 274 | ``` 275 | 276 | ### Seconds to time 277 | 278 | Converts seconds to a 'mm:ss' / 'hh:mm:ss' format. 279 | 280 | ```php 281 | Str::mixin(new ProtoneMedia\LaravelMixins\String\SecondsToTime); 282 | 283 | Str::secondsToTime(10); // 00:10 284 | Str::secondsToTime(580); // 09:40 285 | Str::secondsToTime(3610); // 01:00:10 286 | 287 | // force 'hh:mm:ss' format, even under an hour: 288 | Str::secondsToTime(580, false); // 00:09:40 289 | ``` 290 | 291 | ## PDF Regeneration 292 | 293 | *Note: Requires the `symfony/process` package.* 294 | 295 | Regenerates the PDF content with Ghostscript. 296 | 297 | ```php 298 | $ghostscript = new ProtoneMedia\LaravelMixins\Pdf\Ghostscript; 299 | 300 | $regeneratedPdf = $ghostscript->regeneratePdf( 301 | file_get_contents('/uploads/invoice.pdf') 302 | ); 303 | ``` 304 | 305 | You can specify the path of the `ghostscript` binary as well: 306 | 307 | ```php 308 | $ghostscript = new Ghostscript('gs-binary'); 309 | ``` 310 | 311 | ## Convert Base64 input data to files 312 | 313 | Add the `ConvertsBase64ToFiles` trait and `base64FileKeys` method to your form request. 314 | 315 | ```php 316 | use Illuminate\Foundation\Http\FormRequest; 317 | use ProtoneMedia\LaravelMixins\Request\ConvertsBase64ToFiles; 318 | 319 | class ImageRequest extends FormRequest 320 | { 321 | use ConvertsBase64ToFiles; 322 | 323 | protected function base64FileKeys(): array 324 | { 325 | return [ 326 | 'jpg_image' => 'Logo.jpg', 327 | ]; 328 | } 329 | 330 | public function rules() 331 | { 332 | return [ 333 | 'jpg_image' => ['required', 'file', 'image'], 334 | ]; 335 | } 336 | } 337 | ``` 338 | 339 | Now you can get the files like regular uploaded files: 340 | 341 | ```php 342 | $jpgFile = $request->file('jpg_image'); 343 | 344 | // Logo.jpg 345 | $jpgFile->getClientOriginalName(); 346 | ``` 347 | 348 | This trait supports nested data as well. You can either reference the keys by a nested array, or with a [dotted notation](https://laravel.com/docs/master/helpers#method-array-dot): 349 | 350 | ```php 351 | class ImageRequest extends FormRequest 352 | { 353 | use ConvertsBase64ToFiles; 354 | 355 | protected function base64FileKeys(): array 356 | { 357 | return [ 358 | 'company.logo' => 'Logo.jpg', 359 | 'user' => [ 360 | 'avatar' => 'Avatar.jpg', 361 | ], 362 | ]; 363 | } 364 | } 365 | ``` 366 | 367 | Want to know more about this trait? Check out the [blog post](https://protone.media/blog/convert-and-store-base64-encoded-files-in-laravel-use-validation-rules-and-access-the-decoded-files-from-the-request-instance). 368 | 369 | ### Testing 370 | 371 | ``` bash 372 | composer test 373 | ``` 374 | 375 | ### Changelog 376 | 377 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 378 | 379 | ## Contributing 380 | 381 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 382 | 383 | ## Other Laravel packages 384 | 385 | * [`Inertia Table`](https://inertiaui.com/inertia-table?utm_source=github&utm_campaign=laravel-mixins): The Ultimate Table for Inertia.js with built-in Query Builder. 386 | * [`Laravel Blade On Demand`](https://github.com/protonemedia/laravel-blade-on-demand): Laravel package to compile Blade templates in memory. 387 | * [`Laravel Cross Eloquent Search`](https://github.com/protonemedia/laravel-cross-eloquent-search): Laravel package to search through multiple Eloquent models. 388 | * [`Laravel Eloquent Scope as Select`](https://github.com/protonemedia/laravel-eloquent-scope-as-select): Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes and constraints by adding them as a subquery. 389 | * [`Laravel FFMpeg`](https://github.com/protonemedia/laravel-ffmpeg): This package provides an integration with FFmpeg for Laravel. The storage of the files is handled by Laravel's Filesystem. 390 | * [`Laravel MinIO Testing Tools`](https://github.com/protonemedia/laravel-minio-testing-tools): Run your tests against a MinIO S3 server. 391 | * [`Laravel Paddle`](https://github.com/protonemedia/laravel-paddle): Paddle.com API integration for Laravel with support for webhooks/events. 392 | * [`Laravel Task Runner`](https://github.com/protonemedia/laravel-task-runner): Write Shell scripts like Blade Components and run them locally or on a remote server. 393 | * [`Laravel Verify New Email`](https://github.com/protonemedia/laravel-verify-new-email): This package adds support for verifying new email addresses: when a user updates its email address, it won't replace the old one until the new one is verified. 394 | * [`Laravel XSS Protection`](https://github.com/protonemedia/laravel-xss-protection): Laravel Middleware to protect your app against Cross-site scripting (XSS). It sanitizes request input, and it can sanatize Blade echo statements. 395 | 396 | ### Security 397 | 398 | If you discover any security related issues, please email pascal@protone.media instead of using the issue tracker. 399 | 400 | ## Credits 401 | 402 | - [Pascal Baljet](https://github.com/protonemedia) 403 | - [All Contributors](../../contributors) 404 | 405 | ## License 406 | 407 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 408 | 409 | ## Treeware 410 | 411 | This package is [Treeware](https://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/protonemedia/laravel-mixins) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. 412 | -------------------------------------------------------------------------------- /src/Database/CountriesInDutch.php: -------------------------------------------------------------------------------- 1 | "Afghanistan", "alpha2" => "af", "alpha3" => "afg"], 9 | ["name" => "Åland", "alpha2" => "ax", "alpha3" => "ala"], 10 | ["name" => "Albanië", "alpha2" => "al", "alpha3" => "alb"], 11 | ["name" => "Algerije", "alpha2" => "dz", "alpha3" => "dza"], 12 | ["name" => "Amerikaanse Maagdeneilanden", "alpha2" => "vi", "alpha3" => "vir"], 13 | ["name" => "Amerikaans-Samoa", "alpha2" => "as", "alpha3" => "asm"], 14 | ["name" => "Andorra", "alpha2" => "ad", "alpha3" => "and"], 15 | ["name" => "Angola", "alpha2" => "ao", "alpha3" => "ago"], 16 | ["name" => "Anguilla", "alpha2" => "ai", "alpha3" => "aia"], 17 | ["name" => "Antarctica", "alpha2" => "aq", "alpha3" => "ata"], 18 | ["name" => "Antigua en Barbuda", "alpha2" => "ag", "alpha3" => "atg"], 19 | ["name" => "Argentinië", "alpha2" => "ar", "alpha3" => "arg"], 20 | ["name" => "Armenië", "alpha2" => "am", "alpha3" => "arm"], 21 | ["name" => "Aruba", "alpha2" => "aw", "alpha3" => "abw"], 22 | ["name" => "Australië", "alpha2" => "au", "alpha3" => "aus"], 23 | ["name" => "Azerbeidzjan", "alpha2" => "az", "alpha3" => "aze"], 24 | ["name" => "Bahama's", "alpha2" => "bs", "alpha3" => "bhs"], 25 | ["name" => "Bahrein", "alpha2" => "bh", "alpha3" => "bhr"], 26 | ["name" => "Bangladesh", "alpha2" => "bd", "alpha3" => "bgd"], 27 | ["name" => "Barbados", "alpha2" => "bb", "alpha3" => "brb"], 28 | ["name" => "België", "alpha2" => "be", "alpha3" => "bel"], 29 | ["name" => "Belize", "alpha2" => "bz", "alpha3" => "blz"], 30 | ["name" => "Benin", "alpha2" => "bj", "alpha3" => "ben"], 31 | ["name" => "Bermuda", "alpha2" => "bm", "alpha3" => "bmu"], 32 | ["name" => "Bhutan", "alpha2" => "bt", "alpha3" => "btn"], 33 | ["name" => "Bolivia", "alpha2" => "bo", "alpha3" => "bol"], 34 | ["name" => "Caribisch Nederland", "alpha2" => "bq", "alpha3" => "bes"], 35 | ["name" => "Bosnië en Herzegovina", "alpha2" => "ba", "alpha3" => "bih"], 36 | ["name" => "Botswana", "alpha2" => "bw", "alpha3" => "bwa"], 37 | ["name" => "Bouveteiland", "alpha2" => "bv", "alpha3" => "bvt"], 38 | ["name" => "Brazilië", "alpha2" => "br", "alpha3" => "bra"], 39 | ["name" => "Britse Maagdeneilanden", "alpha2" => "vg", "alpha3" => "vgb"], 40 | ["name" => "Brits Indische Oceaanterritorium", "alpha2" => "io", "alpha3" => "iot"], 41 | ["name" => "Brunei", "alpha2" => "bn", "alpha3" => "brn"], 42 | ["name" => "Bulgarije", "alpha2" => "bg", "alpha3" => "bgr"], 43 | ["name" => "Burkina Faso", "alpha2" => "bf", "alpha3" => "bfa"], 44 | ["name" => "Burundi", "alpha2" => "bi", "alpha3" => "bdi"], 45 | ["name" => "Cambodja", "alpha2" => "kh", "alpha3" => "khm"], 46 | ["name" => "Canada", "alpha2" => "ca", "alpha3" => "can"], 47 | ["name" => "Centraal-Afrikaanse Republiek", "alpha2" => "cf", "alpha3" => "caf"], 48 | ["name" => "Chili", "alpha2" => "cl", "alpha3" => "chl"], 49 | ["name" => "China", "alpha2" => "cn", "alpha3" => "chn"], 50 | ["name" => "Christmaseiland", "alpha2" => "cx", "alpha3" => "cxr"], 51 | ["name" => "Cocoseilanden", "alpha2" => "cc", "alpha3" => "cck"], 52 | ["name" => "Colombia", "alpha2" => "co", "alpha3" => "col"], 53 | ["name" => "Comoren", "alpha2" => "km", "alpha3" => "com"], 54 | ["name" => "Congo-Brazzaville", "alpha2" => "cg", "alpha3" => "cog"], 55 | ["name" => "Congo-Kinshasa", "alpha2" => "cd", "alpha3" => "cod"], 56 | ["name" => "Cookeilanden", "alpha2" => "ck", "alpha3" => "cok"], 57 | ["name" => "Costa Rica", "alpha2" => "cr", "alpha3" => "cri"], 58 | ["name" => "Cuba", "alpha2" => "cu", "alpha3" => "cub"], 59 | ["name" => "Curaçao", "alpha2" => "cw", "alpha3" => "cuw"], 60 | ["name" => "Cyprus", "alpha2" => "cy", "alpha3" => "cyp"], 61 | ["name" => "Denemarken", "alpha2" => "dk", "alpha3" => "dnk"], 62 | ["name" => "Djibouti", "alpha2" => "dj", "alpha3" => "dji"], 63 | ["name" => "Dominica", "alpha2" => "dm", "alpha3" => "dma"], 64 | ["name" => "Dominicaanse Republiek", "alpha2" => "do", "alpha3" => "dom"], 65 | ["name" => "Duitsland", "alpha2" => "de", "alpha3" => "deu"], 66 | ["name" => "Ecuador", "alpha2" => "ec", "alpha3" => "ecu"], 67 | ["name" => "Egypte", "alpha2" => "eg", "alpha3" => "egy"], 68 | ["name" => "El Salvador", "alpha2" => "sv", "alpha3" => "slv"], 69 | ["name" => "Equatoriaal-Guinea", "alpha2" => "gq", "alpha3" => "gnq"], 70 | ["name" => "Eritrea", "alpha2" => "er", "alpha3" => "eri"], 71 | ["name" => "Estland", "alpha2" => "ee", "alpha3" => "est"], 72 | ["name" => "Ethiopië", "alpha2" => "et", "alpha3" => "eth"], 73 | ["name" => "Faeröer", "alpha2" => "fo", "alpha3" => "fro"], 74 | ["name" => "Falklandeilanden", "alpha2" => "fk", "alpha3" => "flk"], 75 | ["name" => "Fiji", "alpha2" => "fj", "alpha3" => "fji"], 76 | ["name" => "Filipijnen", "alpha2" => "ph", "alpha3" => "phl"], 77 | ["name" => "Finland", "alpha2" => "fi", "alpha3" => "fin"], 78 | ["name" => "Frankrijk", "alpha2" => "fr", "alpha3" => "fra"], 79 | ["name" => "Franse Zuidelijke en Antarctische Gebieden", "alpha2" => "tf", "alpha3" => "atf"], 80 | ["name" => "Frans-Guyana", "alpha2" => "gf", "alpha3" => "guf"], 81 | ["name" => "Frans-Polynesië", "alpha2" => "pf", "alpha3" => "pyf"], 82 | ["name" => "Gabon", "alpha2" => "ga", "alpha3" => "gab"], 83 | ["name" => "Gambia", "alpha2" => "gm", "alpha3" => "gmb"], 84 | ["name" => "Georgië", "alpha2" => "ge", "alpha3" => "geo"], 85 | ["name" => "Ghana", "alpha2" => "gh", "alpha3" => "gha"], 86 | ["name" => "Gibraltar", "alpha2" => "gi", "alpha3" => "gib"], 87 | ["name" => "Grenada", "alpha2" => "gd", "alpha3" => "grd"], 88 | ["name" => "Griekenland", "alpha2" => "gr", "alpha3" => "grc"], 89 | ["name" => "Groenland", "alpha2" => "gl", "alpha3" => "grl"], 90 | ["name" => "Guadeloupe", "alpha2" => "gp", "alpha3" => "glp"], 91 | ["name" => "Guam", "alpha2" => "gu", "alpha3" => "gum"], 92 | ["name" => "Guatemala", "alpha2" => "gt", "alpha3" => "gtm"], 93 | ["name" => "Guernsey", "alpha2" => "gg", "alpha3" => "ggy"], 94 | ["name" => "Guinee", "alpha2" => "gn", "alpha3" => "gin"], 95 | ["name" => "Guinee-Bissau", "alpha2" => "gw", "alpha3" => "gnb"], 96 | ["name" => "Guyana", "alpha2" => "gy", "alpha3" => "guy"], 97 | ["name" => "Haïti", "alpha2" => "ht", "alpha3" => "hti"], 98 | ["name" => "Heard en McDonaldeilanden", "alpha2" => "hm", "alpha3" => "hmd"], 99 | ["name" => "Honduras", "alpha2" => "hn", "alpha3" => "hnd"], 100 | ["name" => "Hongarije", "alpha2" => "hu", "alpha3" => "hun"], 101 | ["name" => "Hongkong", "alpha2" => "hk", "alpha3" => "hkg"], 102 | ["name" => "Ierland", "alpha2" => "ie", "alpha3" => "irl"], 103 | ["name" => "IJsland", "alpha2" => "is", "alpha3" => "isl"], 104 | ["name" => "India", "alpha2" => "in", "alpha3" => "ind"], 105 | ["name" => "Indonesië", "alpha2" => "id", "alpha3" => "idn"], 106 | ["name" => "Irak", "alpha2" => "iq", "alpha3" => "irq"], 107 | ["name" => "Iran", "alpha2" => "ir", "alpha3" => "irn"], 108 | ["name" => "Israël", "alpha2" => "il", "alpha3" => "isr"], 109 | ["name" => "Italië", "alpha2" => "it", "alpha3" => "ita"], 110 | ["name" => "Ivoorkust", "alpha2" => "ci", "alpha3" => "civ"], 111 | ["name" => "Jamaica", "alpha2" => "jm", "alpha3" => "jam"], 112 | ["name" => "Japan", "alpha2" => "jp", "alpha3" => "jpn"], 113 | ["name" => "Jemen", "alpha2" => "ye", "alpha3" => "yem"], 114 | ["name" => "Jersey", "alpha2" => "je", "alpha3" => "jey"], 115 | ["name" => "Jordanië", "alpha2" => "jo", "alpha3" => "jor"], 116 | ["name" => "Kaaimaneilanden", "alpha2" => "ky", "alpha3" => "cym"], 117 | ["name" => "Kaapverdië", "alpha2" => "cv", "alpha3" => "cpv"], 118 | ["name" => "Kameroen", "alpha2" => "cm", "alpha3" => "cmr"], 119 | ["name" => "Kazachstan", "alpha2" => "kz", "alpha3" => "kaz"], 120 | ["name" => "Kenia", "alpha2" => "ke", "alpha3" => "ken"], 121 | ["name" => "Kirgizië", "alpha2" => "kg", "alpha3" => "kgz"], 122 | ["name" => "Kiribati", "alpha2" => "ki", "alpha3" => "kir"], 123 | ["name" => "Kleine afgelegen eilanden van de Verenigde Staten", "alpha2" => "um", "alpha3" => "umi"], 124 | ["name" => "Koeweit", "alpha2" => "kw", "alpha3" => "kwt"], 125 | ["name" => "Kroatië", "alpha2" => "hr", "alpha3" => "hrv"], 126 | ["name" => "Laos", "alpha2" => "la", "alpha3" => "lao"], 127 | ["name" => "Lesotho", "alpha2" => "ls", "alpha3" => "lso"], 128 | ["name" => "Letland", "alpha2" => "lv", "alpha3" => "lva"], 129 | ["name" => "Libanon", "alpha2" => "lb", "alpha3" => "lbn"], 130 | ["name" => "Liberia", "alpha2" => "lr", "alpha3" => "lbr"], 131 | ["name" => "Libië", "alpha2" => "ly", "alpha3" => "lby"], 132 | ["name" => "Liechtenstein", "alpha2" => "li", "alpha3" => "lie"], 133 | ["name" => "Litouwen", "alpha2" => "lt", "alpha3" => "ltu"], 134 | ["name" => "Luxemburg", "alpha2" => "lu", "alpha3" => "lux"], 135 | ["name" => "Macau", "alpha2" => "mo", "alpha3" => "mac"], 136 | ["name" => "Macedonië", "alpha2" => "mk", "alpha3" => "mkd"], 137 | ["name" => "Madagaskar", "alpha2" => "mg", "alpha3" => "mdg"], 138 | ["name" => "Malawi", "alpha2" => "mw", "alpha3" => "mwi"], 139 | ["name" => "Maldiven", "alpha2" => "mv", "alpha3" => "mdv"], 140 | ["name" => "Maleisië", "alpha2" => "my", "alpha3" => "mys"], 141 | ["name" => "Mali", "alpha2" => "ml", "alpha3" => "mli"], 142 | ["name" => "Malta", "alpha2" => "mt", "alpha3" => "mlt"], 143 | ["name" => "Man", "alpha2" => "im", "alpha3" => "imn"], 144 | ["name" => "Marokko", "alpha2" => "ma", "alpha3" => "mar"], 145 | ["name" => "Marshalleilanden", "alpha2" => "mh", "alpha3" => "mhl"], 146 | ["name" => "Martinique", "alpha2" => "mq", "alpha3" => "mtq"], 147 | ["name" => "Mauritanië", "alpha2" => "mr", "alpha3" => "mrt"], 148 | ["name" => "Mauritius", "alpha2" => "mu", "alpha3" => "mus"], 149 | ["name" => "Mayotte", "alpha2" => "yt", "alpha3" => "myt"], 150 | ["name" => "Mexico", "alpha2" => "mx", "alpha3" => "mex"], 151 | ["name" => "Micronesia", "alpha2" => "fm", "alpha3" => "fsm"], 152 | ["name" => "Moldavië", "alpha2" => "md", "alpha3" => "mda"], 153 | ["name" => "Monaco", "alpha2" => "mc", "alpha3" => "mco"], 154 | ["name" => "Mongolië", "alpha2" => "mn", "alpha3" => "mng"], 155 | ["name" => "Montenegro", "alpha2" => "me", "alpha3" => "mne"], 156 | ["name" => "Montserrat", "alpha2" => "ms", "alpha3" => "msr"], 157 | ["name" => "Mozambique", "alpha2" => "mz", "alpha3" => "moz"], 158 | ["name" => "Myanmar", "alpha2" => "mm", "alpha3" => "mmr"], 159 | ["name" => "Namibië", "alpha2" => "na", "alpha3" => "nam"], 160 | ["name" => "Nauru", "alpha2" => "nr", "alpha3" => "nru"], 161 | ["name" => "Nederland", "alpha2" => "nl", "alpha3" => "nld"], 162 | ["name" => "Nepal", "alpha2" => "np", "alpha3" => "npl"], 163 | ["name" => "Nicaragua", "alpha2" => "ni", "alpha3" => "nic"], 164 | ["name" => "Nieuw-Caledonië", "alpha2" => "nc", "alpha3" => "ncl"], 165 | ["name" => "Nieuw-Zeeland", "alpha2" => "nz", "alpha3" => "nzl"], 166 | ["name" => "Niger", "alpha2" => "ne", "alpha3" => "ner"], 167 | ["name" => "Nigeria", "alpha2" => "ng", "alpha3" => "nga"], 168 | ["name" => "Niue", "alpha2" => "nu", "alpha3" => "niu"], 169 | ["name" => "Noordelijke Marianen", "alpha2" => "mp", "alpha3" => "mnp"], 170 | ["name" => "Noord-Korea", "alpha2" => "kp", "alpha3" => "prk"], 171 | ["name" => "Noorwegen", "alpha2" => "no", "alpha3" => "nor"], 172 | ["name" => "Norfolk", "alpha2" => "nf", "alpha3" => "nfk"], 173 | ["name" => "Oeganda", "alpha2" => "ug", "alpha3" => "uga"], 174 | ["name" => "Oekraïne", "alpha2" => "ua", "alpha3" => "ukr"], 175 | ["name" => "Oezbekistan", "alpha2" => "uz", "alpha3" => "uzb"], 176 | ["name" => "Oman", "alpha2" => "om", "alpha3" => "omn"], 177 | ["name" => "Oostenrijk", "alpha2" => "at", "alpha3" => "aut"], 178 | ["name" => "Oost-Timor", "alpha2" => "tl", "alpha3" => "tls"], 179 | ["name" => "Pakistan", "alpha2" => "pk", "alpha3" => "pak"], 180 | ["name" => "Palau", "alpha2" => "pw", "alpha3" => "plw"], 181 | ["name" => "Palestina", "alpha2" => "ps", "alpha3" => "pse"], 182 | ["name" => "Panama", "alpha2" => "pa", "alpha3" => "pan"], 183 | ["name" => "Papoea-Nieuw-Guinea", "alpha2" => "pg", "alpha3" => "png"], 184 | ["name" => "Paraguay", "alpha2" => "py", "alpha3" => "pry"], 185 | ["name" => "Peru", "alpha2" => "pe", "alpha3" => "per"], 186 | ["name" => "Pitcairneilanden", "alpha2" => "pn", "alpha3" => "pcn"], 187 | ["name" => "Polen", "alpha2" => "pl", "alpha3" => "pol"], 188 | ["name" => "Portugal", "alpha2" => "pt", "alpha3" => "prt"], 189 | ["name" => "Puerto Rico", "alpha2" => "pr", "alpha3" => "pri"], 190 | ["name" => "Qatar", "alpha2" => "qa", "alpha3" => "qat"], 191 | ["name" => "Réunion", "alpha2" => "re", "alpha3" => "reu"], 192 | ["name" => "Roemenië", "alpha2" => "ro", "alpha3" => "rou"], 193 | ["name" => "Rusland", "alpha2" => "ru", "alpha3" => "rus"], 194 | ["name" => "Rwanda", "alpha2" => "rw", "alpha3" => "rwa"], 195 | ["name" => "Saint-Barthélemy", "alpha2" => "bl", "alpha3" => "blm"], 196 | ["name" => "Saint Kitts en Nevis", "alpha2" => "kn", "alpha3" => "kna"], 197 | ["name" => "Saint Lucia", "alpha2" => "lc", "alpha3" => "lca"], 198 | ["name" => "Saint-Pierre en Miquelon", "alpha2" => "pm", "alpha3" => "spm"], 199 | ["name" => "Saint Vincent en de Grenadines", "alpha2" => "vc", "alpha3" => "vct"], 200 | ["name" => "Salomonseilanden", "alpha2" => "sb", "alpha3" => "slb"], 201 | ["name" => "Samoa", "alpha2" => "ws", "alpha3" => "wsm"], 202 | ["name" => "San Marino", "alpha2" => "sm", "alpha3" => "smr"], 203 | ["name" => "Saoedi-Arabië", "alpha2" => "sa", "alpha3" => "sau"], 204 | ["name" => "Sao Tomé en Principe", "alpha2" => "st", "alpha3" => "stp"], 205 | ["name" => "Senegal", "alpha2" => "sn", "alpha3" => "sen"], 206 | ["name" => "Servië", "alpha2" => "rs", "alpha3" => "srb"], 207 | ["name" => "Seychellen", "alpha2" => "sc", "alpha3" => "syc"], 208 | ["name" => "Sierra Leone", "alpha2" => "sl", "alpha3" => "sle"], 209 | ["name" => "Singapore", "alpha2" => "sg", "alpha3" => "sgp"], 210 | ["name" => "Sint-Helena, Ascension en Tristan da Cunha", "alpha2" => "sh", "alpha3" => "shn"], 211 | ["name" => "Sint-Maarten", "alpha2" => "mf", "alpha3" => "maf"], 212 | ["name" => "Sint Maarten", "alpha2" => "sx", "alpha3" => "sxm"], 213 | ["name" => "Slovenië", "alpha2" => "si", "alpha3" => "svn"], 214 | ["name" => "Slowakije", "alpha2" => "sk", "alpha3" => "svk"], 215 | ["name" => "Soedan", "alpha2" => "sd", "alpha3" => "sdn"], 216 | ["name" => "Somalië", "alpha2" => "so", "alpha3" => "som"], 217 | ["name" => "Spanje", "alpha2" => "es", "alpha3" => "esp"], 218 | ["name" => "Spitsbergen en Jan Mayen", "alpha2" => "sj", "alpha3" => "sjm"], 219 | ["name" => "Sri Lanka", "alpha2" => "lk", "alpha3" => "lka"], 220 | ["name" => "Suriname", "alpha2" => "sr", "alpha3" => "sur"], 221 | ["name" => "Swaziland", "alpha2" => "sz", "alpha3" => "swz"], 222 | ["name" => "Syrië", "alpha2" => "sy", "alpha3" => "syr"], 223 | ["name" => "Tadzjikistan", "alpha2" => "tj", "alpha3" => "tjk"], 224 | ["name" => "Taiwan", "alpha2" => "tw", "alpha3" => "twn"], 225 | ["name" => "Tanzania", "alpha2" => "tz", "alpha3" => "tza"], 226 | ["name" => "Thailand", "alpha2" => "th", "alpha3" => "tha"], 227 | ["name" => "Togo", "alpha2" => "tg", "alpha3" => "tgo"], 228 | ["name" => "Tokelau", "alpha2" => "tk", "alpha3" => "tkl"], 229 | ["name" => "Tonga", "alpha2" => "to", "alpha3" => "ton"], 230 | ["name" => "Trinidad en Tobago", "alpha2" => "tt", "alpha3" => "tto"], 231 | ["name" => "Tsjaad", "alpha2" => "td", "alpha3" => "tcd"], 232 | ["name" => "Tsjechië", "alpha2" => "cz", "alpha3" => "cze"], 233 | ["name" => "Tunesië", "alpha2" => "tn", "alpha3" => "tun"], 234 | ["name" => "Turkije", "alpha2" => "tr", "alpha3" => "tur"], 235 | ["name" => "Turkmenistan", "alpha2" => "tm", "alpha3" => "tkm"], 236 | ["name" => "Turks- en Caicoseilanden", "alpha2" => "tc", "alpha3" => "tca"], 237 | ["name" => "Tuvalu", "alpha2" => "tv", "alpha3" => "tuv"], 238 | ["name" => "Uruguay", "alpha2" => "uy", "alpha3" => "ury"], 239 | ["name" => "Vanuatu", "alpha2" => "vu", "alpha3" => "vut"], 240 | ["name" => "Vaticaanstad", "alpha2" => "va", "alpha3" => "vat"], 241 | ["name" => "Venezuela", "alpha2" => "ve", "alpha3" => "ven"], 242 | ["name" => "Verenigde Arabische Emiraten", "alpha2" => "ae", "alpha3" => "are"], 243 | ["name" => "Verenigde Staten", "alpha2" => "us", "alpha3" => "usa"], 244 | ["name" => "Verenigd Koninkrijk", "alpha2" => "gb", "alpha3" => "gbr"], 245 | ["name" => "Vietnam", "alpha2" => "vn", "alpha3" => "vnm"], 246 | ["name" => "Wallis en Futuna", "alpha2" => "wf", "alpha3" => "wlf"], 247 | ["name" => "Westelijke Sahara", "alpha2" => "eh", "alpha3" => "esh"], 248 | ["name" => "Wit-Rusland", "alpha2" => "by", "alpha3" => "blr"], 249 | ["name" => "Zambia", "alpha2" => "zm", "alpha3" => "zmb"], 250 | ["name" => "Zimbabwe", "alpha2" => "zw", "alpha3" => "zwe"], 251 | ["name" => "Zuid-Afrika", "alpha2" => "za", "alpha3" => "zaf"], 252 | ["name" => "Zuid-Georgia en de Zuidelijke Sandwicheilanden", "alpha2" => "gs", "alpha3" => "sgs"], 253 | ["name" => "Zuid-Korea", "alpha2" => "kr", "alpha3" => "kor"], 254 | ["name" => "Zuid-Soedan", "alpha2" => "ss", "alpha3" => "ssd"], 255 | ["name" => "Zweden", "alpha2" => "se", "alpha3" => "swe"], 256 | ["name" => "Zwitserland", "alpha2" => "ch", "alpha3" => "che"], 257 | ]; 258 | 259 | /** 260 | * Returns all data. 261 | * 262 | * @return array 263 | */ 264 | public function all(): array 265 | { 266 | return $this->data; 267 | } 268 | } 269 | --------------------------------------------------------------------------------