Compare commits

..

1088 Commits

Author SHA1 Message Date
Alejandro Celaya
26c2aaf567 Merge pull request #1963 from shlinkio/develop
Release 3.7.2
2023-12-26 16:23:49 +01:00
Alejandro Celaya
62b54ceaaf Add v3.7.2 to changelog 2023-12-26 16:16:10 +01:00
Alejandro Celaya
625eba76c7 Merge pull request #1962 from acelaya-forks/feature/disabled-qr-codes
Allow QR codes to be generated for disabled short URLs
2023-12-24 16:55:52 +01:00
Alejandro Celaya
e12bda3f42 Add API test to verify QR codes return a 404 for disabled short URLs 2023-12-24 10:37:09 +01:00
Alejandro Celaya
0f0301ae5c Update changelog 2023-12-24 10:27:25 +01:00
Alejandro Celaya
8d1776af98 Test error when short URLs cannot be resolved 2023-12-24 10:25:58 +01:00
Alejandro Celaya
c597738915 Test how URLs are resolved in QrCodeAction 2023-12-24 10:13:19 +01:00
Alejandro Celaya
639329dbe4 Update installer 2023-12-24 09:48:44 +01:00
Alejandro Celaya
92b0525b6e Update Twitter badge 2023-12-23 11:14:12 +01:00
Alejandro Celaya
06306aabd5 Allow QR codes to be generated for disabled short URLs 2023-12-22 13:29:22 +01:00
Alejandro Celaya
225905fcdb update changelog 2023-12-19 11:22:40 +01:00
Alejandro Celaya
8ca2b3c641 Merge pull request #1955 from acelaya-forks/feature/artifact-actions
Update artifact GitHub actions
2023-12-19 11:19:34 +01:00
Alejandro Celaya
ac1737492b Update artifact GitHub actions 2023-12-19 11:13:13 +01:00
Alejandro Celaya
a63075eb4c Merge pull request #1953 from shlinkio/develop
Release 3.7.1
2023-12-17 20:06:25 +01:00
Alejandro Celaya
97e9dfad67 Merge pull request #1952 from shlinkio/feature/rr-logs-improvement
Feature/rr logs improvement
2023-12-17 19:59:21 +01:00
Alejandro Celaya
17c4f13568 Set fixed versions for Shlink dependencies 2023-12-17 19:49:50 +01:00
Alejandro Celaya
3b5243689b Fine-tune RoadRunner logs to avoid too many useless info 2023-12-17 19:26:28 +01:00
Alejandro Celaya
4d28adf4a7 Merge pull request #1948 from acelaya-forks/feature/fix-postgres-import
Fix error when importing short URLs while using Postgres
2023-12-16 20:38:46 +01:00
Alejandro Celaya
1b14bb07b1 Fix error when importing short URLs while using Postgres 2023-12-16 20:22:39 +01:00
Alejandro Celaya
3a43aa4d41 Merge pull request #1942 from acelaya-forks/feature/geoip-3
Update to geolite2 v3
2023-12-07 07:52:58 +01:00
Alejandro Celaya
2340b4f601 Update to geolite2 v3 2023-12-06 21:48:54 +01:00
Alejandro Celaya
664886eddf Support laminas-diactoros 3 2023-11-30 22:10:41 +01:00
Alejandro Celaya
d3570dac0b Merge pull request #1937 from acelaya-forks/feature/remove-functional
Feature/remove functional
2023-11-30 18:53:21 +01:00
Alejandro Celaya
1854cc2f19 Remove last references to functional-php 2023-11-30 18:39:27 +01:00
Alejandro Celaya
bff4bd12ae Removed more functional-php usages 2023-11-30 14:34:44 +01:00
Alejandro Celaya
549c6605f0 Replaced usage of Functional\contians 2023-11-30 09:13:29 +01:00
Alejandro Celaya
f50263d2d9 Remove usage of Functional\map function 2023-11-29 12:34:13 +01:00
Alejandro Celaya
c80ec54508 Merge pull request #1933 from shlinkio/develop
Release 3.7.0
2023-11-25 20:22:38 +01:00
Alejandro Celaya
a91a560651 Fix typo in version contraint 2023-11-25 20:12:41 +01:00
Alejandro Celaya
a931c60230 Point to actual versions on shlink deps 2023-11-25 20:08:29 +01:00
Alejandro Celaya
479a331008 Merge pull request #1932 from acelaya-forks/feature/ssl-connections
Feature/ssl connections
2023-11-25 18:11:30 +01:00
Alejandro Celaya
5d99b1aef0 Update changelog 2023-11-25 13:08:15 +01:00
Alejandro Celaya
17e0c9176e Add support for SSL on Redis and RabbitMQ connections 2023-11-25 13:04:30 +01:00
Alejandro Celaya
48d7388bdc Merge pull request #1931 from acelaya-forks/feature/update-installer
Update to installer with runtime question
2023-11-25 10:01:19 +01:00
Alejandro Celaya
aa01c034db Update to installer with runtime question 2023-11-25 09:55:01 +01:00
Alejandro Celaya
9035161b65 Merge pull request #1928 from acelaya-forks/feature/redis-urlencoded
Allow redis credentials be URL-decoded before passing them to connection
2023-11-23 11:29:46 +01:00
Alejandro Celaya
df57ca5edb Allow redis credentials be URL-decoded before passing them to connection 2023-11-23 11:22:23 +01:00
Alejandro Celaya
0511c73cc8 Merge pull request #1926 from acelaya-forks/feature/geolite-download-warn
Print a warning when manually running visit:download-db with no license
2023-11-23 09:42:31 +01:00
Alejandro Celaya
a3554eaf74 Print a warning when manually running visit:download-db with no license 2023-11-23 09:31:02 +01:00
Alejandro Celaya
cb0bac55d2 Merge pull request #1920 from acelaya-forks/feature/matomo-integration
Feature/matomo integration
2023-11-22 18:59:45 +01:00
Alejandro Celaya
bd5d3f6897 Update changelog 2023-11-22 18:51:47 +01:00
Alejandro Celaya
5e6e386c5a Add matomo dev config 2023-11-22 18:30:03 +01:00
Alejandro Celaya
e783bdc456 Set referrer when sending visits to Matomo 2023-11-21 10:01:27 +01:00
Alejandro Celaya
316b88cea6 Add 10 second timeout to matomo requests 2023-11-21 08:34:37 +01:00
Alejandro Celaya
c03eea789c Fix LocateVisitTest 2023-11-21 08:25:58 +01:00
Alejandro Celaya
bd5d3cb6fa Create SendVisitToMatomoTest 2023-11-20 10:11:15 +01:00
Alejandro Celaya
e1f2dcc136 Create MatomoTrackerBuilderTest 2023-11-17 23:31:23 +01:00
Alejandro Celaya
5e6ebfa5a9 Update shlink-event-dispatcher 2023-11-17 09:32:07 +01:00
Alejandro Celaya
a7ed14a1c9 Enhance EnableListenerCheckerTest with support for matomo listener 2023-11-16 09:24:52 +01:00
Alejandro Celaya
f88d57b2b6 Do not dispatch async job for matomo if disabled 2023-11-15 20:02:35 +01:00
Alejandro Celaya
9dbd15bc0c Add logic to send visits to a matomo instance 2023-11-15 19:57:58 +01:00
Alejandro Celaya
0edb3e5c2c Update to installer with support for matomo 2023-11-11 20:12:39 +01:00
Alejandro Celaya
7501eca71e Update matomo container 2023-11-09 09:04:41 +01:00
Alejandro Celaya
b145d106b0 Add matomo env vars and config 2023-11-09 08:59:34 +01:00
Alejandro Celaya
b4386a3508 Add matomo container 2023-11-09 08:58:58 +01:00
Alejandro Celaya
36e2a9387d Merge pull request #1917 from acelaya-forks/feature/php-8.3-deps
Update native deps for PHP 8.3 preparation
2023-11-08 19:13:29 +01:00
Alejandro Celaya
14c68b4bbe Update native deps for PHP 8.3 preparation 2023-11-08 18:51:03 +01:00
Alejandro Celaya
d6fedaf926 Merge pull request #1913 from acelaya-forks/feature/fix-delete-multi-segment-visits
Fix short URL visits deletion when multi-segment slugs are enabled
2023-11-08 09:20:06 +01:00
Alejandro Celaya
8d35c1dde2 Fix short URL visits deletion when multi-segment slugs are enabled 2023-11-08 09:06:12 +01:00
Alejandro Celaya
85b5f760e5 Update dev swagger UI 2023-11-05 10:58:41 +01:00
Alejandro Celaya
1a4a107952 Merge pull request #1911 from acelaya-forks/feature/slug-url-chars
Feature/slug url chars
2023-11-05 10:52:46 +01:00
Alejandro Celaya
e431395a12 Update changelog 2023-11-05 10:31:51 +01:00
Alejandro Celaya
cfc3d54122 Do not allow URL reserved characters in custom slugs 2023-11-05 10:30:40 +01:00
Alejandro Celaya
d9d6d5bd9c Merge pull request #1907 from acelaya-forks/feature/php-8.3
Add support for PHP 8.3
2023-11-04 13:30:31 +01:00
Alejandro Celaya
32f465f7a6 Add PHP 8.3 to building pipeline 2023-11-04 13:15:15 +01:00
Alejandro Celaya
4cddb573a0 Ignore all platform reqs on PHP 8.3, as openswoole cannot be installed there 2023-11-04 13:03:10 +01:00
Alejandro Celaya
2cb8486bb3 Add support for PHP 8.3 2023-11-04 12:42:31 +01:00
Alejandro Celaya
2a782ab60b Merge pull request #1897 from acelaya-forks/feature/disable-health-endpoint-logs
Do not log requests to the health endpoint
2023-10-20 20:44:49 +02:00
Alejandro Celaya
5bde273d59 Fix Rest's ConfigProvider test 2023-10-20 09:42:48 +02:00
Alejandro Celaya
41e322fd47 Update changelog 2023-10-20 09:34:20 +02:00
Alejandro Celaya
55885b0f25 Do not log requests to the health endpoint 2023-10-20 09:33:29 +02:00
Alejandro Celaya
d419b9d62d Merge pull request #1891 from acelaya-forks/feature/customizable-cache-namespace
Feature/customizable cache namespace
2023-10-07 11:33:40 +02:00
Alejandro Celaya
3bdc05fbc4 Fix CliTestUtils for PHPUnit 10.4 2023-10-07 10:56:04 +02:00
Alejandro Celaya
57053d66a4 Update changelog 2023-10-06 09:21:53 +02:00
Alejandro Celaya
9d8ea0a4f6 Allow cache namespace to be customizable via env var 2023-10-06 09:19:55 +02:00
Alejandro Celaya
46354baae9 Merge pull request #1886 from acelaya-forks/feature/chronos-3
Update to chronos 3
2023-09-30 21:19:01 +02:00
Alejandro Celaya
27c48414da Update to chronos 3 2023-09-30 21:03:17 +02:00
Alejandro Celaya
25b1138000 Fix merge conflicts 2023-09-23 09:06:38 +02:00
Alejandro Celaya
4cf3bc08f9 Merge pull request #1883 from shlinkio/release/v3.6.4
Release 3.6.4
2023-09-23 08:57:10 +02:00
Alejandro Celaya
7e093a3fd8 Fix date in changelog 2023-09-23 08:41:57 +02:00
Alejandro Celaya
abecf3be02 Merge pull request #1882 from acelaya-forks/feature/create-api-key
Feature/create api key
2023-09-23 08:40:53 +02:00
Alejandro Celaya
3d9b48c5fd Create InitialApiKeyCommand cli test 2023-09-23 08:28:57 +02:00
Alejandro Celaya
ba4a66f772 Add InitialApiKeyCommand unit test 2023-09-23 08:16:22 +02:00
Alejandro Celaya
ec839183e8 Add unit test for ApiKeyService::createInitial 2023-09-23 08:01:10 +02:00
Alejandro Celaya
b0ec0601c1 Update to latest shlink-installer 2023-09-22 10:00:19 +02:00
Alejandro Celaya
637d8334f4 New CLI command to create the initial API key idempotently 2023-09-21 09:47:21 +02:00
Alejandro Celaya
6db46b50e9 Roll back change to allow creating API keys with custom value 2023-09-21 08:58:05 +02:00
Alejandro Celaya
f6b1cc7556 Test API key creation with custom key 2023-09-19 10:14:04 +02:00
Alejandro Celaya
65a0a90a51 Allow custom API keys to be created 2023-09-19 09:10:17 +02:00
Alejandro Celaya
38a7872fbf Merge pull request #1878 from acelaya-forks/feature/add-swagger-ui-dev
Add a swagger ui container for dev env
2023-09-17 12:01:05 +02:00
Alejandro Celaya
5839cc5926 Add a swagger ui container for dev env 2023-09-17 11:59:23 +02:00
Alejandro Celaya
49bd230474 Merge pull request #1874 from acelaya-forks/feature/redis-lock-namespace
Make sure locks include the same cache namespace when sent to Redis
2023-09-12 21:44:45 +02:00
Alejandro Celaya
074f2135f6 Make sure locks include the same cache namespace when sent to Redis 2023-09-12 21:20:38 +02:00
Alejandro Celaya
ef073d59ca Merge pull request #1872 from acelaya-forks/bugfix/db-commands-timeout
Fix incorrect timeout in init commands
2023-09-12 08:33:13 +02:00
Alejandro Celaya
a3b2f94339 Make sure local config is not loaded in tests 2023-09-12 08:21:34 +02:00
Alejandro Celaya
b17c576a30 Fix incorrect timeout in init commands 2023-09-11 09:07:18 +02:00
Alejandro Celaya
bc4156ca3c Merge pull request #1858 from acelaya-forks/feature/update-deps
Update dependencies
2023-08-19 12:51:02 +02:00
Alejandro Celaya
b747b8448e Update dependencies 2023-08-19 12:03:29 +02:00
Alejandro Celaya
aa4b9fc27e Replace references to docker-compose with docker compose 2023-08-03 09:10:05 +02:00
Alejandro Celaya
3f3c2c3d1e Add form config for Feature Request issues 2023-08-03 09:08:35 +02:00
Alejandro Celaya
4b49f8fb7f Use issue form for bugs 2023-07-25 08:45:24 +02:00
Alejandro Celaya
550f3b28ea Use textarea instead of markdown for main field in help-wanted discussion 2023-07-15 11:09:36 +02:00
Alejandro Celaya
6d4c232345 Merge pull request #1844 from acelaya-forks/feature/help-discussion-template
Add discussion template for 'Help wanted'
2023-07-15 10:59:51 +02:00
Alejandro Celaya
2d085ad6f4 Add discussion template for 'Help wanted' 2023-07-15 10:59:39 +02:00
Alejandro Celaya
3ea83f5cc3 Merge pull request #1836 from acelaya-forks/feature/oas-3.1
Feature/oas 3.1
2023-07-12 19:42:42 +02:00
Alejandro Celaya
b47bd0fc7a Use stable version of devizzent/cebe-php-openapi 2023-07-12 11:33:58 +02:00
Alejandro Celaya
27e90c4c26 Update changelog 2023-07-12 11:30:12 +02:00
Alejandro Celaya
ad1a846d8e Remove references to nullable in OAS 2023-07-12 11:29:44 +02:00
Alejandro Celaya
78f75a06df Updated swagger docs to v3.1, and fixed some 'required' definitions 2023-07-12 11:29:44 +02:00
Alejandro Celaya
262d714751 Add ADR for latest docker image publishing change 2023-07-09 11:31:13 +02:00
Alejandro Celaya
f71c3bba5c Merge pull request #1842 from acelaya-forks/feature/docker-build-on-tag
Build docker image only on tags
2023-07-09 09:59:25 +02:00
Alejandro Celaya
8b495064b2 Build docker image only on tags 2023-07-09 09:45:46 +02:00
Alejandro Celaya
57a36204db Merge pull request #1840 from acelaya-forks/feature/docker-no-interactive-init
Improve verbosity hint when an error occurs during docker init
2023-07-06 09:11:04 +02:00
Alejandro Celaya
7cc1722858 Improve verbosity hint when an error occurs during docker init 2023-07-05 09:58:51 +02:00
Alejandro Celaya
af50887361 Fix typo 2023-07-01 16:33:52 +02:00
Alejandro Celaya
99c8c6c8d4 Merge pull request #1832 from acelaya-forks/feature/migrations-config
Refactor cli-config file as it's currently used by doctrine migrations only
2023-06-23 22:05:24 +02:00
Alejandro Celaya
1d7c9fd553 Refactor cli-config file as it's currently used by doctrine migrations only 2023-06-23 09:16:33 +02:00
Alejandro Celaya
274c454fa4 Merge pull request #1827 from acelaya-forks/feature/question-discussion
Make sure people asking questions opens a discussion instead of an issue
2023-06-21 08:55:07 +02:00
Alejandro Celaya
453fcc4675 Make sure people asking questions opens a discussion instead of an issue 2023-06-21 08:54:03 +02:00
Alejandro Celaya
42427bfd74 Merge pull request #1824 from acelaya-forks/feature/api-coverage-fix
Update shlink-test-utils to fix coverage ID on API tests
2023-06-18 19:24:03 +02:00
Alejandro Celaya
33eedd2270 Update shlink-test-utils to fix coverage ID on API tests 2023-06-18 18:59:15 +02:00
Alejandro Celaya
edaf9e34f4 Merge pull request #1823 from acelaya-forks/feature/external-data-providers
Feature/external data providers
2023-06-18 11:06:24 +02:00
Alejandro Celaya
965325aa7c Replace traits with static classes in CLI unit tests 2023-06-18 10:51:59 +02:00
Alejandro Celaya
bdf2bbd0f1 Replace traits with external data providers in Core unit tests 2023-06-18 10:41:24 +02:00
Alejandro Celaya
dc4aab2cab Replace traits with external data providers in API tests 2023-06-18 10:36:45 +02:00
Alejandro Celaya
3b1f6c69de Merge pull request #1822 from acelaya-forks/feature/fix-installer-command-timeouts
Fix incorrect timeout in init commands
2023-06-15 19:07:32 +02:00
Alejandro Celaya
cdf5082cff Fix incorrect timeout in init commands 2023-06-15 18:53:42 +02:00
Alejandro Celaya
61686ed6ea Fix JamesIves/github-pages-deploy-action version 2023-06-14 18:27:03 +02:00
Alejandro Celaya
f63b96fd05 Fix merge conflicts 2023-06-14 18:25:09 +02:00
Alejandro Celaya
228bd83b75 Merge pull request #1818 from acelaya-forks/feature/fix-sqlite-db-creation
Fix Shlink trying to create SQLite database tables even if they already exist
2023-06-14 18:22:39 +02:00
Alejandro Celaya
a21dcb852a Fix Shlink trying to create SQLite database tables even if they already exist 2023-06-14 18:08:39 +02:00
Alejandro Celaya
6558c37b9a Fix merge conflicts 2023-06-11 20:10:29 +02:00
Alejandro Celaya
e6720cce12 Merge pull request #1814 from acelaya-forks/feature/update-test-utils
Update to latest test utils lib
2023-06-11 20:05:45 +02:00
Alejandro Celaya
22d039c550 Update to latest test utils lib 2023-06-11 19:54:33 +02:00
Alejandro Celaya
a21fcd72ce Merge pull request #1807 from acelaya-forks/feature/mercure-options
Use MercureOptions instead of raw config, where possible
2023-06-08 19:00:43 +02:00
Alejandro Celaya
058391cf06 Merge pull request #1809 from acelaya-forks/feature/fix-rr-download
Update to a shlink-installer version that fixes rr download
2023-06-08 18:59:28 +02:00
Alejandro Celaya
24e6acc6e8 Update to a shlink-installer version that fixes rr download 2023-06-08 18:47:55 +02:00
Alejandro Celaya
8e3508f28d Use MercureOptions instead of raw config, where possible 2023-06-06 20:25:14 +02:00
Alejandro Celaya
e72b424968 Fix merge conflicts 2023-06-04 09:33:16 +02:00
Alejandro Celaya
56d299a7dc Merge pull request #1804 from acelaya-forks/feature/release-3.6.1
Feature/release 3.6.1
2023-06-04 09:30:19 +02:00
Alejandro Celaya
575e6bf707 Downgrade PHPUnit to avoid infection error 2023-06-04 09:13:37 +02:00
Alejandro Celaya
e50c21440f Define default values for env vars used in rr prod config 2023-06-04 09:07:41 +02:00
Alejandro Celaya
7cff11080d Update changelog 2023-06-04 08:57:07 +02:00
Alejandro Celaya
72381f9844 Change order to create initial database to avoid permission errors 2023-06-04 08:54:08 +02:00
Alejandro Celaya
7c649e7497 Merge pull request #1801 from acelaya-forks/feature/no-run-disabled-tasks
Feature/no run disabled tasks
2023-06-03 19:19:08 +02:00
Alejandro Celaya
eff308cd43 Update changelog 2023-06-03 17:58:26 +02:00
Alejandro Celaya
bd3745118e Add logic to prevent roadrunner/openswoole jobs for tasks that will do nothing 2023-06-03 17:56:52 +02:00
Alejandro Celaya
602ebef02a Merge pull request #1800 from acelaya-forks/feature/deprecate-openswoole
Deprecate support for openswoole
2023-06-03 10:06:03 +02:00
Alejandro Celaya
9040937376 Stick with PHPUnit 10.1 until API tests coverage is fixed 2023-06-03 09:24:43 +02:00
Alejandro Celaya
a11be5b2ff Deprecate support for openswoole 2023-06-03 09:08:07 +02:00
Alejandro Celaya
6351d0b87d Merge pull request #1797 from acelaya-forks/feature/improve-new-db-check
Feature/improve new db check
2023-06-01 20:01:39 +02:00
Alejandro Celaya
fae3434393 Update changelog 2023-06-01 19:28:15 +02:00
Alejandro Celaya
4013ae87dd Change order to create initial database to avoid permission errors 2023-06-01 19:27:04 +02:00
Alejandro Celaya
cb4ba58b08 Merge pull request #1795 from acelaya-forks/feature/non-orphan-role
Feature/non orphan role
2023-05-31 09:43:18 +02:00
Alejandro Celaya
8c94452348 Fix CLI tests 2023-05-31 09:33:05 +02:00
Alejandro Celaya
ea96a00b12 Update changelog 2023-05-31 09:24:23 +02:00
Alejandro Celaya
be26dd58c3 Add API tests to cover usage of orphan visits restricted keys 2023-05-31 09:22:40 +02:00
Alejandro Celaya
eaba5edf7f Restrict interaction with orphan visits when API key has that role 2023-05-31 09:11:20 +02:00
Alejandro Celaya
12da04ef37 Add ApiKey check to tell if it has any role that is short-url restrictive 2023-05-30 09:32:44 +02:00
Alejandro Celaya
8b03532ddb Add ORPHAN_VISITS_EXCLUDED API key role 2023-05-30 09:15:35 +02:00
Alejandro Celaya
112b54ec7d Merge pull request #1793 from acelaya-forks/feature/drop-php-8.1
Drop support for PHP 8.1
2023-05-29 21:53:30 +02:00
Alejandro Celaya
ee6a8ede0a Drop support for PHP 8.1 2023-05-29 09:43:12 +02:00
Alejandro Celaya
07ce5f05a2 Add missing entry to v3.6.0 changelog 2023-05-29 09:02:59 +02:00
Alejandro Celaya
7b04016ca2 Fix version number on JamesIves/github-pages-deploy-action GitHub action 2023-05-24 08:59:21 +02:00
Alejandro Celaya
b6792d3fb8 Merge pull request #1792 from shlinkio/develop
Release 3.6.0
2023-05-24 08:46:25 +02:00
Alejandro Celaya
2f0d658432 Merge pull request #1791 from acelaya-forks/feature/fix-cpu-100
Update changelog
2023-05-23 23:25:39 +02:00
Alejandro Celaya
8c1865c3ec Update changelog 2023-05-23 23:15:59 +02:00
Alejandro Celaya
096d2098d6 Update installer 2023-05-23 18:42:50 +02:00
Alejandro Celaya
882d64ae11 Add deprecation note for ENABLE_PERIODIC_VISIT_LOCATE env var 2023-05-23 10:55:49 +02:00
Alejandro Celaya
3352bcd186 Merge pull request #1789 from acelaya-forks/feature/improved-dependency-locks
Feature/improved dependency locks
2023-05-21 18:44:10 +02:00
Alejandro Celaya
9743c1624d Update changelog 2023-05-21 18:10:08 +02:00
Alejandro Celaya
e85d59c5a4 Add locks when creating short URL dependencies, to avoid race condition 2023-05-21 18:08:17 +02:00
Alejandro Celaya
ac0ff8fb94 Merge pull request #1787 from acelaya-forks/feature/shlink-init-command
Feature/shlink init command
2023-05-21 14:44:08 +02:00
Alejandro Celaya
90f93ee4ec Update changelog 2023-05-21 14:32:00 +02:00
Alejandro Celaya
794d926e3a Update docker entry point to use new shlink-installer init command 2023-05-21 14:30:20 +02:00
Alejandro Celaya
bd41ebef9f Merge pull request #1785 from acelaya-forks/feature/non-root-support
Allow running docker container as non-root
2023-05-19 20:29:40 +02:00
Alejandro Celaya
725370704f Update changelog 2023-05-19 19:50:05 +02:00
Alejandro Celaya
f03b7689ce Allow running docker container as non-root 2023-05-19 19:48:20 +02:00
Alejandro Celaya
fb31e2a5e4 Merge pull request #1782 from acelaya-forks/feature/clear-orphan-visits
Feature/clear orphan visits
2023-05-18 09:49:31 +02:00
Alejandro Celaya
d688c6da7e Update changelog 2023-05-18 09:36:50 +02:00
Alejandro Celaya
618784dc3b Create command to delete all orphan visits 2023-05-18 09:35:42 +02:00
Alejandro Celaya
9d64d4ed1d Create abstract base class for commands deleting visits 2023-05-18 09:33:15 +02:00
Alejandro Celaya
7f02243c6c Rename short-url:delete-visits to short-url:visits-delete for consistency with other commands 2023-05-18 09:19:01 +02:00
Alejandro Celaya
3916c68126 Add DeleteOrphanVisitsTest API test 2023-05-18 09:09:44 +02:00
Alejandro Celaya
a6f0c66331 Document endpoint to delete orphan visits 2023-05-18 09:06:52 +02:00
Alejandro Celaya
bdfb220126 Create REST action to delete orphan visits 2023-05-18 09:04:28 +02:00
Alejandro Celaya
abcf2f86be Create service to delete orphan visits 2023-05-18 09:01:57 +02:00
Alejandro Celaya
a4d8ebdfc9 Create DB logic to delete orphan visits 2023-05-18 08:58:07 +02:00
Alejandro Celaya
b51c149c30 Merge pull request #1779 from acelaya-forks/feature/clear-short-url-visits
Feature/clear short url visits
2023-05-17 09:20:28 +02:00
Alejandro Celaya
39095a3098 Fix coding styles 2023-05-17 08:57:36 +02:00
Alejandro Celaya
765199727e Update changelog 2023-05-16 09:29:22 +02:00
Alejandro Celaya
c7043af853 Create DeleteShortUrlVisitsCommandTest 2023-05-16 09:26:29 +02:00
Alejandro Celaya
02a8ef7dd9 Create DeleteShortUrlVisitsCommand 2023-05-15 09:48:24 +02:00
Alejandro Celaya
6bb8c1b2f5 Rename CLI Option namespace to Input 2023-05-15 09:02:23 +02:00
Alejandro Celaya
3cf253fd0f Document short URLs visits deletion endpoint 2023-05-14 18:25:27 +02:00
Alejandro Celaya
0365728337 Create DeleteShortUrlVisitsTest 2023-05-14 13:35:15 +02:00
Alejandro Celaya
b8143a5bb4 Create VisitDeleterRepositoryTest 2023-05-14 13:04:45 +02:00
Alejandro Celaya
531a19dde9 Refactor short URL visits deletion layers 2023-05-14 13:04:17 +02:00
Alejandro Celaya
69ff7de481 Create ShortUrlVisitsDeleterTest 2023-05-14 12:32:54 +02:00
Alejandro Celaya
ffc0555c7c Create DeleteShortUrlVisitsActionTest 2023-05-14 12:15:35 +02:00
Alejandro Celaya
84a7981dfa Create REST action to delete short URL visits 2023-05-14 12:00:08 +02:00
Alejandro Celaya
2573c2bf98 Update roadrunner config 2023-05-14 11:56:49 +02:00
Alejandro Celaya
3b4c1501f3 Set platforms to be used for openswoole docker image 2023-05-07 17:13:26 +02:00
Alejandro Celaya
e836bedecc Merge pull request #1775 from acelaya-forks/feature/default-roadrunner
Feature/default roadrunner
2023-05-07 13:34:53 +02:00
Alejandro Celaya
a797b74a70 Standardize logger for all Shlink execution contexts 2023-05-07 13:18:19 +02:00
Alejandro Celaya
ab497403ca Merge pull request #1773 from acelaya-forks/feature/rr-friendly-installer
Update shlink-installer
2023-05-06 18:07:57 +02:00
Alejandro Celaya
d4dea9a1d2 Update shlink-installer 2023-05-06 10:12:42 +02:00
Alejandro Celaya
28d93ea5e0 Update changelog 2023-05-03 08:59:47 +02:00
Alejandro Celaya
e6a31b16ed Switch to roadrunner as default docker runtime 2023-05-03 08:59:09 +02:00
Alejandro Celaya
9553192281 Merge pull request #1766 from acelaya-forks/feature/rr-cli-2.5
Update to rr-cli 2.5, and do not generate config
2023-05-02 20:01:51 +02:00
Alejandro Celaya
74069f2d24 Skip API tests fetching Twitter during CI 2023-05-02 19:51:37 +02:00
Alejandro Celaya
b4b00a57c1 Update chrome user agent used for anti-bots 2023-05-02 19:40:23 +02:00
Alejandro Celaya
a516ef691d Update to rr-cli 2.5, and do not generate config 2023-05-02 08:43:14 +02:00
Alejandro Celaya
e80b7448f5 Merge pull request #1761 from acelaya-forks/feature/null-default-domain
Feature/null default domain
2023-04-23 15:57:02 +02:00
Alejandro Celaya
f129544f83 Update changelog 2023-04-23 15:22:40 +02:00
Alejandro Celaya
9fa291a32f Update shlink-common 2023-04-23 15:20:33 +02:00
Alejandro Celaya
d06e92ffc2 Created CLI test for short URL importing 2023-04-23 13:26:59 +02:00
Alejandro Celaya
1b83344995 Create CLI test checking default domain is ignored even if explicitly provided 2023-04-23 11:20:54 +02:00
Alejandro Celaya
cf49393ef2 Add --show-domain flag to list short URLs command 2023-04-23 11:19:05 +02:00
Alejandro Celaya
f2ecbceae9 Update changelog 2023-04-22 19:46:28 +02:00
Alejandro Celaya
c582eba753 Make sure short URL domain is resolved as null when default one is provided 2023-04-22 19:44:04 +02:00
Alejandro Celaya
de86b62cdd Merge pull request #1759 from acelaya-forks/feature/fix-docker-build
Fix docker image build
2023-04-20 09:00:39 +02:00
Alejandro Celaya
73150471e9 Fix docker image build 2023-04-19 18:57:35 +02:00
Alejandro Celaya
ec751f4ac2 Merge pull request #1758 from acelaya-forks/feature/roadrunner-2023
Feature/roadrunner 2023
2023-04-19 08:11:18 +02:00
Alejandro Celaya
e652166289 Update changelog 2023-04-18 23:24:21 +02:00
Alejandro Celaya
a671d555cb Update to roadrunner 2023 2023-04-18 23:22:48 +02:00
Alejandro Celaya
6240554f4c Merge pull request #1757 from acelaya-forks/feature/shlink-json
Migrate to shlinkio/shlink-json
2023-04-18 23:14:11 +02:00
Alejandro Celaya
4ee9c9bbe3 Migrate to shlinkio/shlink-json 2023-04-18 23:04:58 +02:00
Alejandro Celaya
c830439085 Merge pull request #1752 from acelaya-forks/feature/phpunit-10.1
Update phpunit configs to fulfil v10.1
2023-04-14 09:55:38 +02:00
Alejandro Celaya
f2196583c8 Update phpunit configs to fulfil v10.1 2023-04-14 09:44:01 +02:00
Alejandro Celaya
3dbca2115c Merge pull request #1751 from acelaya-forks/feature/openswoole-22
Add support for openswoole 22
2023-04-14 09:16:47 +02:00
Alejandro Celaya
b45d8de27d Ignore openswoole dep on roadrunner tests CI 2023-04-14 09:02:17 +02:00
Alejandro Celaya
3ba46bbbfa Add support for openswoole 22 2023-04-14 08:58:54 +02:00
Alejandro Celaya
06f3f0c86c Merge pull request #1750 from acelaya-forks/feature/update-delete-artifacts
Update to geekyeggo/delete-artifact@2
2023-04-13 08:58:24 +02:00
Alejandro Celaya
06f07e3e40 Update to geekyeggo/delete-artifact@2 2023-04-12 19:13:35 +02:00
Alejandro Celaya
740740b8c6 Update to latest JamesIves/github-pages-deploy-action 2023-04-12 19:11:06 +02:00
Alejandro Celaya
b6ed39b18b Merge pull request #1749 from shlinkio/develop
Release 3.5.4
2023-04-12 19:03:25 +02:00
Alejandro Celaya
958c4704f8 Merge pull request #1748 from acelaya-forks/feature/create-error
Feature/create error
2023-04-12 18:52:18 +02:00
Alejandro Celaya
ef075fb0ce Fix test when CLI output viewport is too narrow 2023-04-12 18:36:28 +02:00
Alejandro Celaya
556520583a Update changelog 2023-04-12 18:31:57 +02:00
Alejandro Celaya
399c56a097 Print warning when trying to create short URL from CLI on openswoole in verbose mode 2023-04-12 18:30:02 +02:00
Alejandro Celaya
f078d95588 Capture error on real-time update when creating short URL 2023-04-12 09:25:01 +02:00
Alejandro Celaya
33911afcd6 Merge pull request #1744 from acelaya-forks/feature/regression-fix
Feature/regression fix
2023-04-11 19:13:08 +02:00
Alejandro Celaya
ae8d31e83f Add test case for deeplink long URLs 2023-04-11 17:24:38 +02:00
Alejandro Celaya
72c4052012 Be less restrictive when validating long URLs 2023-04-10 18:05:57 +02:00
Alejandro Celaya
f713a1fa7e Merge pull request #1737 from shlinkio/develop
Release 3.5.3
2023-03-31 22:07:51 +02:00
Alejandro Celaya
62488ac4e5 Merge pull request #1739 from acelaya-forks/feature/import-memory-leak
Feature/import memory leak
2023-03-31 10:00:36 +02:00
Alejandro Celaya
ab4c6e5fca Update changelog 2023-03-31 09:48:08 +02:00
Alejandro Celaya
26f4a969c9 Fix memory leak when importing big amounts of visits 2023-03-31 09:46:05 +02:00
Alejandro Celaya
703965915d Merge pull request #1736 from acelaya-forks/feature/lcobucci-jwt-5
Update to latest shlink-common
2023-03-30 18:45:39 +02:00
Alejandro Celaya
24e38a3cf9 Update to latest shlink-common 2023-03-30 18:33:53 +02:00
Alejandro Celaya
b12cfaedf3 Merge pull request #1730 from acelaya-forks/feature/validate-uris
Feature/validate uris
2023-03-25 13:29:36 +01:00
Alejandro Celaya
71807e698c Update changelog 2023-03-25 11:23:01 +01:00
Alejandro Celaya
1d155298c1 Fix API tests 2023-03-25 11:23:01 +01:00
Alejandro Celaya
4dfc5ae681 Fix DB tests 2023-03-25 11:23:01 +01:00
Alejandro Celaya
26f237069c Fixed unit tests 2023-03-25 11:23:01 +01:00
Alejandro Celaya
b6e1c65c4c Enforce a schema to be provided when short URLs are created 2023-03-25 11:23:00 +01:00
Alejandro Celaya
11f94b8306 Merge pull request #1723 from acelaya-forks/feature/tags-list-performance-join-tags
Feature/tags list performance join tags
2023-03-16 21:57:43 +01:00
Alejandro Celaya
01bcedef7a Simplify how ordering field is resolved in tags list 2023-03-04 11:54:30 +01:00
Alejandro Celaya
e51384fcc0 Reduce duplicated logic when checking if an API key is admin 2023-03-04 10:22:46 +01:00
Alejandro Celaya
83c53c8b2e Add correct index on visits potential_bot column 2023-03-04 09:51:14 +01:00
Alejandro Celaya
1afe08caed Simplify how limits are applied to tags query 2023-03-04 09:50:38 +01:00
Alejandro Celaya
7289833928 Move join on short URLs to tags sub-query 2023-03-03 12:10:41 +01:00
Alejandro Celaya
f4d10df0f3 Delete no longer used spec file 2023-02-27 09:28:27 +01:00
Alejandro Celaya
652b0df054 Use native query builders for all queries/sub-queries in tags list 2023-02-27 09:21:11 +01:00
Alejandro Celaya
0e9ea5027c Merge pull request #1705 from shlinkio/develop
Release 3.5.2
2023-02-16 19:36:59 +01:00
Alejandro Celaya
658303d375 Merge pull request #1706 from acelaya-forks/feature/fix-ms-ci
Comment-out unixodbc-dev installation in CI, as it's already present …
2023-02-16 19:33:08 +01:00
Alejandro Celaya
ccc3a4b584 Comment-out unixodbc-dev installation in CI, as it's already present in Ubuntu 22.04 2023-02-16 19:24:09 +01:00
Alejandro Celaya
ef5ac86e0a Add v3.5.2 to changelog 2023-02-15 20:25:55 +01:00
Alejandro Celaya
91b90b276a Merge pull request #1704 from acelaya-forks/feature/stronger-db-detection
Feature/stronger db detection
2023-02-15 19:19:11 +01:00
Alejandro Celaya
85c32c3c9a Fix CreateDatabaseCommandTest 2023-02-15 18:55:25 +01:00
Alejandro Celaya
40838255a7 Make sure database detection is not affected by the existence of foreign tables 2023-02-15 08:52:17 +01:00
Alejandro Celaya
a67ccb384f Merge pull request #1697 from acelaya-forks/feature/phpunit-10
Feature/phpunit 10
2023-02-13 19:15:33 +01:00
Alejandro Celaya
cb31e5a581 Update to phpcov 9 2023-02-13 19:05:27 +01:00
Alejandro Celaya
3c12a55872 Merge branch 'develop' into feature/phpunit-10 2023-02-13 11:54:49 +01:00
Alejandro Celaya
6da8b11674 Update changelog 2023-02-12 19:52:22 +01:00
Alejandro Celaya
552489611f Merge pull request #1700 from acelaya-forks/feature/optimize-tags-query
Feature/optimize tags query
2023-02-12 19:50:23 +01:00
Alejandro Celaya
e48d0f4f0c Upgrade deps for MSSQL tests 2023-02-12 19:08:20 +01:00
Alejandro Celaya
49b6063501 Fix ordering on Postgres 2023-02-12 13:35:05 +01:00
Alejandro Celaya
dd049feb40 Add migration with new index for short_url_id+potential_bot on visits table 2023-02-12 13:12:09 +01:00
Alejandro Celaya
76a86c452e Optimize tags list query performance by using more subqueries 2023-02-12 13:09:24 +01:00
Alejandro Celaya
41aec15fab Migrate new test to PHPUnit 10 2023-02-10 20:45:09 +01:00
Alejandro Celaya
245cb0e35d Fixed merge conflicts 2023-02-10 20:44:05 +01:00
Alejandro Celaya
7a0b1e8494 Merge pull request #1699 from acelaya-forks/feature/fix-robots-txt
Fix dependency injected in CrawlingHelper
2023-02-10 20:41:10 +01:00
Alejandro Celaya
70c1c9f018 Fix dependency injected in CrawlingHelper 2023-02-10 20:26:18 +01:00
Alejandro Celaya
97e965157b Update changelog 2023-02-09 20:43:07 +01:00
Alejandro Celaya
04bbd471ff Migrate from PHPUnit annotations to native attributes 2023-02-09 20:42:18 +01:00
Alejandro Celaya
650a286982 Update to PHPUnit 10 2023-02-09 09:32:38 +01:00
Alejandro Celaya
ad44a8441a Merge pull request #1694 from acelaya-forks/feature/fix-gha-deprecations
Fix usage of deprecated GitHub actions practices
2023-02-06 21:56:35 +01:00
Alejandro Celaya
b339cf2429 Fix usage of deprecated GitHub actions practices 2023-02-06 21:47:04 +01:00
Alejandro Celaya
9cd97c2f1e Merge pull request #1691 from shlinkio/develop
Release 3.5.1
2023-02-04 17:58:27 +01:00
Alejandro Celaya
a7f6b60cba Merge pull request #1690 from acelaya-forks/feature/uninitialized-prop
Update to latest shlink-common including the cache clear fix for redis replication
2023-02-04 17:51:04 +01:00
Alejandro Celaya
0d7dc50670 Update to latest shlink-common including the cache clear fix for redis replication 2023-02-04 17:40:44 +01:00
Alejandro Celaya
4bc5b9261f Merge pull request #1687 from acelaya-forks/feature/ms-case-sensitive
Feature/ms case sensitive
2023-01-30 11:16:13 +01:00
Alejandro Celaya
fb572d5abb Fix accidentally removed statement in new migration 2023-01-30 10:52:07 +01:00
Alejandro Celaya
8fa4219b30 Update changelog 2023-01-30 10:50:47 +01:00
Alejandro Celaya
a52d0cd419 Ensure short_code column is case sensitive in Microsoft SQL server 2023-01-30 10:49:47 +01:00
Alejandro Celaya
0080ab5132 Merge pull request #1686 from acelaya-forks/feature/loose-mode
Rename loosely mode to loose mode
2023-01-29 11:42:52 +01:00
Alejandro Celaya
8afa582aa5 Create ShortUrlModeTest 2023-01-29 11:32:13 +01:00
Alejandro Celaya
d847c7648e Rename loosely mode to loose mode 2023-01-29 10:30:34 +01:00
Alejandro Celaya
c140db16d1 Improve issue templates requesting roadrunner when appropriate 2023-01-29 09:53:47 +01:00
Alejandro Celaya
adbf7c6f5e Fix twitter badge 2023-01-28 11:15:46 +01:00
Alejandro Celaya
5cec697be3 Merge pull request #1683 from shlinkio/develop
Release 3.5.0
2023-01-28 11:10:49 +01:00
Alejandro Celaya
587bbfdd73 Add SemVer-compliant constraints for shlink libs 2023-01-28 10:48:34 +01:00
Alejandro Celaya
b3a2ceedea Merge pull request #1680 from acelaya-forks/feature/loosly-mode
Feature/loosly mode
2023-01-28 10:36:19 +01:00
Alejandro Celaya
621f18bf40 Recover DB test only for platforms in which it passes 2023-01-28 10:20:57 +01:00
Alejandro Celaya
99c1a59dd4 Refactor CustomSlugFilter for simplicity 2023-01-28 10:16:53 +01:00
Alejandro Celaya
3a149c9edc Update changelog 2023-01-28 10:09:54 +01:00
Alejandro Celaya
fdaf5fb2f3 Add support for short URL mode in installer, and handle loosely mode in custom slugs 2023-01-28 10:06:11 +01:00
Alejandro Celaya
2f83e90c8b Add option to do loosely matches on short URLs when mode is loosely 2023-01-26 20:45:36 +01:00
Alejandro Celaya
05acd4ae88 Add two modes for short URLs 2023-01-25 20:33:07 +01:00
Alejandro Celaya
87007677ed Merge pull request #1679 from acelaya-forks/feature/deprecate-url-validation
Deprecated validateUrl option on short URL creation/edition
2023-01-23 20:45:13 +01:00
Alejandro Celaya
4ee0032c2a Deprecated validateUrl option on short URL creation/edition 2023-01-23 20:30:12 +01:00
Alejandro Celaya
06583a0bc1 Merge pull request #1677 from acelaya-forks/feature/openswoole-4.12.1
Updated to openswoole 4.12.1
2023-01-23 08:07:15 +01:00
Alejandro Celaya
024c9c1a7a Fixed paths glob patterns in some workflows 2023-01-22 21:01:46 +01:00
Alejandro Celaya
f3855dbc6f Updated to openswoole 4.12.1 2023-01-22 20:57:48 +01:00
Alejandro Celaya
758dac47c3 Merge pull request #1668 from acelaya-forks/feature/device-long-urls
Feature/device long urls
2023-01-22 12:50:33 +01:00
Alejandro Celaya
81393a76b4 Ensure GITHUB_TOKEN is exposed to roadrunner api tests workflow 2023-01-22 12:43:03 +01:00
Alejandro Celaya
9949bb654d Set more accurate swagger docs in terms of what props are required/nullable for device long URLs 2023-01-22 12:35:07 +01:00
Alejandro Celaya
b0b9902f40 Add unit test to cover device URLs edition, and fix bug thanks to it 2023-01-22 12:18:36 +01:00
Alejandro Celaya
5aa8de11f4 Update version on user agent used to validate URLsç 2023-01-22 12:00:16 +01:00
Alejandro Celaya
b18c9e495f Add API test for short URL edition with device long URLs 2023-01-22 11:47:45 +01:00
Alejandro Celaya
d3590234a3 Add API test for short URL creation with device long URLs 2023-01-22 11:36:00 +01:00
Alejandro Celaya
39adef8ab8 Make it impossible to create a short URL with an empty long URL 2023-01-22 11:27:16 +01:00
Alejandro Celaya
13e443880a Allow device long URLs to be removed from short URLs by providing null value 2023-01-22 11:03:05 +01:00
Alejandro Celaya
45961144b9 Update changelog 2023-01-22 09:47:15 +01:00
Alejandro Celaya
34129b8d24 Update async API docs with device long URLs 2023-01-21 12:09:38 +01:00
Alejandro Celaya
48bd97fe41 Return deviceLongUrls as part of the short URL data and document API changes 2023-01-21 12:05:54 +01:00
Alejandro Celaya
b1b67c497e Add logic to dynamically resolve the long URL to redirect to based on requesting device 2023-01-21 11:15:42 +01:00
Alejandro Celaya
237fb95b4b Update ShortUrlRedirectionBuilder to accept a request object instead of a raw query array 2023-01-21 10:37:12 +01:00
Alejandro Celaya
c1b7c6ba6c Updated to shlink-common with support for proxies for entities with public readonly props 2023-01-21 10:12:52 +01:00
Alejandro Celaya
d8add9291f Removed public readonly prop from entity, as it can cause errors when a proxy is generated 2023-01-21 10:12:52 +01:00
Alejandro Celaya
a93edf158e Added logic to persist device long URLs while creating/editing a short URL 2023-01-21 10:12:52 +01:00
Alejandro Celaya
fdadf3ba07 Created unit test for DeviceLongUrlsValidator 2023-01-21 10:12:52 +01:00
Alejandro Celaya
3e26f1113d Extract device long URL validation to its own validation class 2023-01-21 10:12:52 +01:00
Alejandro Celaya
822652cac3 Allow providing device long URLs during short URL edition 2023-01-21 10:12:52 +01:00
Alejandro Celaya
1447687ebe Add deviceLongUrls to short URL creation 2023-01-21 10:12:52 +01:00
Alejandro Celaya
12150f775d Created persistence for device long URLs 2023-01-21 10:12:52 +01:00
Alejandro Celaya
5f2f179581 Merge pull request #1675 from acelaya-forks/feature/gh-build-improve
Extract docker image building during CI to its own workflow
2023-01-21 10:11:48 +01:00
Alejandro Celaya
407134bab1 Extract docker image building during CI to its own workflow 2023-01-21 09:59:43 +01:00
Alejandro Celaya
de5b895fad Merge pull request #1672 from acelaya-forks/feature/domain
Replace references to doma.in with s.test
2023-01-19 09:30:28 +01:00
Alejandro Celaya
80e3f01562 Replace references to doma.in with s.test 2023-01-19 09:05:52 +01:00
Alejandro Celaya
6904dcfed0 Merge pull request #1665 from acelaya-forks/feature/openswoole-env
Add support to load openswoole-specific config via env vars
2023-01-12 20:10:21 +01:00
Alejandro Celaya
21863e8de6 Add support to load openswoole-specific config via env vars 2023-01-12 19:39:26 +01:00
Alejandro Celaya
d75be372cb Merge pull request #1657 from acelaya-forks/feature/extra-method-redirects
Feature/extra method redirects
2023-01-07 17:20:17 +01:00
Alejandro Celaya
edaf999bf5 Fixed constant assignment on enum which is not valid for PHP 8.1 2023-01-07 17:09:53 +01:00
Alejandro Celaya
3e98485c8b Updated to installer supporting redirect status codes 308 and 307 2023-01-07 17:02:34 +01:00
Alejandro Celaya
cc292886a6 Updated changelog 2023-01-07 13:55:46 +01:00
Alejandro Celaya
0c1b36d0d4 Added config post-processor which sets proper allowed methods based on redirect status codes 2023-01-07 13:51:35 +01:00
Alejandro Celaya
a06957e9fa Moved config post-processors to their own sub-namespace 2023-01-07 13:04:46 +01:00
Alejandro Celaya
390bc59d99 Added support for redirect status code 307 and 308 2023-01-07 11:27:15 +01:00
Alejandro Celaya
85464f0fbb Added ADR with options to support other HTTP methods in short URLs 2023-01-07 10:44:08 +01:00
Alejandro Celaya
42f7a68ba5 Updated dev container base images 2023-01-05 18:50:49 +01:00
Alejandro Celaya
e3397a7c90 Merge pull request #1652 from acelaya-forks/feature/extended-tags-stats
Feature/extended tags stats
2023-01-02 20:25:50 +01:00
Alejandro Celaya
46b4a21617 Fixed missing null check 2023-01-02 20:17:29 +01:00
Alejandro Celaya
fc0aba6311 Updated changelog 2023-01-02 20:03:30 +01:00
Alejandro Celaya
0b96a79c41 Updated async API docs 2023-01-02 20:02:50 +01:00
Alejandro Celaya
a5929ebb29 Added swagger docs for visits summary in tags with stats 2023-01-02 19:58:02 +01:00
Alejandro Celaya
ce9ec0d738 Fixed ordering in tags supporting more fields 2023-01-02 19:49:54 +01:00
Alejandro Celaya
961178fd82 Added amount of bots, non-bots and total visits to the list of tags with stats 2023-01-02 19:28:32 +01:00
Alejandro Celaya
49c73a9590 Merge pull request #1650 from acelaya-forks/feature/handle-malformed-body
Feature/handle malformed body
2023-01-02 13:54:52 +01:00
Alejandro Celaya
92c80e7833 Removed superfluous exception code by using named args 2023-01-02 13:47:16 +01:00
Alejandro Celaya
6d5bce0078 Updated changelog 2023-01-02 13:39:13 +01:00
Alejandro Celaya
112cbb9039 Added API test for malformed request JSON body 2023-01-02 13:38:04 +01:00
Alejandro Celaya
812c5f4993 Added new handled error for when request body is not valid JSON 2023-01-02 13:33:24 +01:00
Alejandro Celaya
921f303404 Merge pull request #1649 from acelaya-forks/feature/detailed-visits-stats
Feature/detailed visits stats
2023-01-02 13:11:20 +01:00
Alejandro Celaya
e0a9f8120c Fixed unintended change in phpdoc 2023-01-02 12:48:23 +01:00
Alejandro Celaya
8ecc241a4b Added API test for the visits stats endpoint 2023-01-02 12:45:08 +01:00
Alejandro Celaya
30e34151ed Updated changelog 2023-01-02 12:36:25 +01:00
Alejandro Celaya
d734578f74 Reflected changes to visits stats in the swagger docs 2023-01-02 12:35:15 +01:00
Alejandro Celaya
37c8328eed Added split info about bots, non-bots and total visits to the visits stats 2023-01-02 12:28:34 +01:00
Alejandro Celaya
e71f6bb528 Documented support for PHP 8.2 in readme 2022-12-29 16:35:20 +01:00
Alejandro Celaya
f7ae52f86e Fixed build badge in README 2022-12-17 10:59:42 +01:00
Alejandro Celaya
067d1cc41c Merge pull request #1637 from shlinkio/develop
Release 3.4.0
2022-12-16 22:55:02 +01:00
Alejandro Celaya
b97af7efb9 Added v3.4.0 to changelog 2022-12-16 22:33:16 +01:00
Alejandro Celaya
fd0ecc05b2 Merge pull request #1634 from acelaya-forks/feature/non-bot-count
Feature/non bot count
2022-12-16 21:02:22 +01:00
Alejandro Celaya
5b934c3f9a Updated changelog 2022-12-16 19:47:17 +01:00
Alejandro Celaya
c7a2f499e0 Added support to order short URLs list by amount of non-bot visits 2022-12-16 19:42:46 +01:00
Alejandro Celaya
713f7e7bc9 Added missing dock block 2022-12-16 18:18:09 +01:00
Alejandro Celaya
09078e4c6a Updated short URL API docs including new visitsSummary 2022-12-16 13:34:40 +01:00
Alejandro Celaya
1f66ec2af5 Fixed API tests 2022-12-16 10:53:44 +01:00
Alejandro Celaya
936e5b3b86 Fixed PublishingUpdatesGeneratorTest 2022-12-16 10:36:09 +01:00
Alejandro Celaya
99f28b569b Created method to get non-bot visits count for a short URL 2022-12-16 10:06:39 +01:00
Alejandro Celaya
0c83dea8b7 Merge pull request #1629 from acelaya-forks/feature/docker-8.2
Feature/docker 8.2
2022-12-14 18:55:37 +01:00
Alejandro Celaya
30edfdbdc5 Updated docker images to PHP 8.2 2022-12-14 15:01:00 +01:00
Alejandro Celaya
60ef98b836 Extracted method to find crawlable short codes to its own query object 2022-12-14 14:38:22 +01:00
Alejandro Celaya
73c8b53882 Split some logic from VisitRepository into its own injectable repository 2022-12-14 12:28:23 +01:00
Alejandro Celaya
425d8f0a3f Merge pull request #1628 from acelaya-forks/feature/split-repos-poc
Split short URL listing capabilities on its own repo and service
2022-12-13 20:48:34 +01:00
Alejandro Celaya
92a83b82a0 Split short URL listing capabilities on its own repo and service 2022-12-13 19:37:02 +01:00
Alejandro Celaya
d1ec15febf Merge pull request #1627 from acelaya-forks/feature/redis-credentials
Feature/redis credentials
2022-12-12 21:00:40 +01:00
Alejandro Celaya
dd345c82ea Updated changelog 2022-12-12 20:51:43 +01:00
Alejandro Celaya
2bf3e6a13b Addedsupport for credentials on redis 2022-12-12 20:50:21 +01:00
Alejandro Celaya
0b04476c99 Merge pull request #1622 from acelaya-forks/feature/filter-out-disabled
Feature/filter out disabled
2022-12-11 18:44:42 +01:00
Alejandro Celaya
229dc93132 Fixed typo 2022-12-11 18:36:46 +01:00
Alejandro Celaya
0952c488be Added exclusion flags to ListShortUrlsCommand 2022-12-11 18:33:40 +01:00
Alejandro Celaya
c4f28b3a32 Renamed ShortUrl::fromMeta to ShortUrl::create 2022-12-11 18:24:47 +01:00
Alejandro Celaya
201f25e0ad Improved API tests to cover exlucding disabled URLs from lists 2022-12-11 13:38:11 +01:00
Alejandro Celaya
0c3523c34a Fixed E2E test suites 2022-12-11 13:22:16 +01:00
Alejandro Celaya
0d7a0ee9ea Fixed more coding styles 2022-12-11 13:11:43 +01:00
Alejandro Celaya
931bdb0cd7 Fixed coding styles 2022-12-11 13:03:19 +01:00
Alejandro Celaya
8807a78463 Improved performance when filtering out shortUrls which reached their limit by using a sub-query 2022-12-11 13:00:06 +01:00
Alejandro Celaya
d832133410 Enhanced db tests for expired short urls filtering 2022-12-11 12:33:17 +01:00
Alejandro Celaya
cdde59b543 Added db test for filtering of disabled short URLs 2022-12-11 11:41:37 +01:00
Alejandro Celaya
463dfe9729 Added support to filter out expired short URLs from list 2022-12-11 10:26:04 +01:00
Alejandro Celaya
805c8c87ba Fixed nasty typo 2022-12-10 19:59:30 +01:00
Alejandro Celaya
7ba2cfc010 Moved true before false in swagger docs 2022-12-10 19:59:30 +01:00
Alejandro Celaya
40794c476f Updated API docs with new short URLs list filters 2022-12-10 19:59:30 +01:00
Alejandro Celaya
c3ab871366 Exposed new short URLs list filtering params 2022-12-10 19:59:30 +01:00
Alejandro Celaya
42a5296f93 Added new params to short URLs list to filter out 'disabled' short ones 2022-12-10 19:59:30 +01:00
Alejandro Celaya
183db4ff80 Merge pull request #1626 from acelaya-forks/feature/fix-ms-sql
Feature/fix ms sql
2022-12-10 19:57:50 +01:00
Alejandro Celaya
0bc9bd9281 Added TrustServerCertificate=true to mssql connections 2022-12-10 19:40:33 +01:00
Alejandro Celaya
9bed7ef156 Updated docker images to MS ODBC 18 for PDO MSSQL 2022-12-10 19:15:38 +01:00
Alejandro Celaya
8f68e4b9f5 Merge pull request #1624 from acelaya-forks/feature/php-8.2-full-support
Feature/php 8.2 full support
2022-12-10 18:37:18 +01:00
Alejandro Celaya
6589c8fce6 Downgraded docker images to latest php 8.1 2022-12-10 17:58:10 +01:00
Alejandro Celaya
38b313a25d Updated changelog 2022-12-10 17:30:35 +01:00
Alejandro Celaya
dab0ebeb99 Updated dockerimages to PHP 8.2 and added full support for this version 2022-12-10 17:29:52 +01:00
Alejandro Celaya
27bf7220b9 Merge pull request #1623 from acelaya-forks/feature/fix-flush-redis
Added missing namespace for cache adapters, causing full cache to be …
2022-12-10 10:21:46 +01:00
Alejandro Celaya
e68ef87c66 Renamed config file from redis to cache 2022-12-10 10:12:56 +01:00
Alejandro Celaya
29b747c192 Added missing namespace for cache adapters, causing full cache to be flushed in some circumstances 2022-12-10 10:11:25 +01:00
Alejandro Celaya
2047d6b772 Merge pull request #1621 from acelaya-forks/feature/default-domain-search
Feature/default domain search
2022-12-08 20:43:42 +01:00
Alejandro Celaya
71e7938b7a Updated changelog 2022-12-08 20:33:59 +01:00
Alejandro Celaya
6bce219eb3 Added test to cover searching short URLs by default domain 2022-12-08 20:32:48 +01:00
Alejandro Celaya
dfcac525bc Enabled search by default domain 2022-12-08 20:22:50 +01:00
Alejandro Celaya
da307aee0a Merge pull request #1620 from acelaya-forks/feature/empty-domain-fix
Feature/empty domain fix
2022-12-07 19:15:29 +01:00
Alejandro Celaya
edf2b5b4c2 Updated changelog 2022-12-07 19:06:58 +01:00
Alejandro Celaya
f41d947cf7 Ensured empty string is ignored as the domain during short URL creation 2022-12-07 19:06:05 +01:00
Alejandro Celaya
54bc169525 Merge pull request #1619 from acelaya-forks/feature/import-orphan-visits
Feature/import orphan visits
2022-12-05 15:03:28 +01:00
Alejandro Celaya
05d55c4000 Added one more case to cover import orphan visits when visits already exist 2022-12-05 14:48:24 +01:00
Alejandro Celaya
739f5eb421 Added test for orphan visits import 2022-12-05 14:42:26 +01:00
Alejandro Celaya
0aab1bdc4e Added test for findMostRecentOrphanVisit 2022-12-04 20:42:28 +01:00
Alejandro Celaya
47f99cf6cc Updated changelog 2022-12-04 20:38:07 +01:00
Alejandro Celaya
55c9773a02 Added logic to import orphan visits 2022-12-04 20:35:38 +01:00
Alejandro Celaya
4b66aaba5c Updated to latest shlink-importer 2022-12-04 12:28:44 +01:00
Alejandro Celaya
4223408090 Updated to common-config with support for valinor 1.0.0 2022-11-28 15:47:59 +01:00
Alejandro Celaya
58e6b0b683 Added badge for Mastodon follow 2022-11-17 19:57:47 +01:00
Alejandro Celaya
891438c672 Updated shlink-config 2022-11-11 16:33:02 +01:00
Alejandro Celaya
910864eaaf Reduced required MSI to 80 2022-11-05 10:54:12 +01:00
Alejandro Celaya
598c0757be Merge pull request #1587 from acelaya-forks/feature/phpstan-phpunit
Feature/phpstan phpunit
2022-10-24 20:34:11 +02:00
Alejandro Celaya
01e0a95e14 Added rest of tests to phpstan check 2022-10-24 20:25:06 +02:00
Alejandro Celaya
f459a99e7e Added db tests to phpstan checks 2022-10-24 20:14:48 +02:00
Alejandro Celaya
85e18a4754 Fixed all phpstan inspections on tests 2022-10-24 20:11:25 +02:00
Alejandro Celaya
1650499a38 Added more stricter types for mocks 2022-10-24 19:59:03 +02:00
Alejandro Celaya
51f243995a Added stricter types for mocks 2022-10-24 19:53:13 +02:00
Alejandro Celaya
aeafb244d9 Merge pull request #1586 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-23 23:18:49 +02:00
Alejandro Celaya
142417dda1 Updated changelog 2022-10-23 23:08:54 +02:00
Alejandro Celaya
da658185c3 Fixed coding styles 2022-10-23 23:07:50 +02:00
Alejandro Celaya
ef82158368 Migrated ApiKeyServiceTest to use PHPUnit mocks 2022-10-23 23:07:17 +02:00
Alejandro Celaya
083ccd36b7 Migrated OverrideDomainMiddlewareTest to use PHPUnit mocks 2022-10-23 23:00:57 +02:00
Alejandro Celaya
d61c79da84 Migrated DropDefaultDomainFromRequestMiddlewareTest to use PHPUnit mocks 2022-10-23 22:56:12 +02:00
Alejandro Celaya
8f76c3e202 Migrated DefaultShortCodesLengthMiddlewareTest to use PHPUnit mocks 2022-10-23 22:55:11 +02:00
Alejandro Celaya
23aa7a015c Migrated CreateShortUrlContentNegotiationMiddlewareTest to use PHPUnit mocks 2022-10-23 22:53:48 +02:00
Alejandro Celaya
674a4416cf Migrated NotConfiguredMercureErrorHandlerTest to use PHPUnit mocks 2022-10-23 22:51:38 +02:00
Alejandro Celaya
db85915c2f Migrated BackwardsCompatibleProblemDetailsHandlerTest to use PHPUnit mocks 2022-10-23 22:48:30 +02:00
Alejandro Celaya
dfc8e8d74e Migrated CrossDomainMiddlewareTest to use PHPUnit mocks 2022-10-23 22:47:34 +02:00
Alejandro Celaya
b2b424a4ed Migrated BodyParserMiddlewareTest to use PHPUnit mocks 2022-10-23 22:45:23 +02:00
Alejandro Celaya
3433899577 Migrated AuthenticationMiddlewareTest to use PHPUnit mocks 2022-10-23 22:40:14 +02:00
Alejandro Celaya
b1f814e118 Migrated InitialApiKeyDelegatorTest to use PHPUnit mocks 2022-10-23 22:36:16 +02:00
Alejandro Celaya
7aa6afeb30 Migrated TagVisitsActionTest to use PHPUnit mocks 2022-10-23 22:28:29 +02:00
Alejandro Celaya
d414496a3c Migrated ShortUrlVisitsActionTest to use PHPUnit mocks 2022-10-23 22:27:27 +02:00
Alejandro Celaya
d4684fd01f Migrated OrphanVisitsActionTest to use PHPUnit mocks 2022-10-23 22:25:54 +02:00
Alejandro Celaya
bb444a02fe Migrated NonOrphanVisitsActionTest to use PHPUnit mocks 2022-10-23 22:24:06 +02:00
Alejandro Celaya
e980a8d121 Migrated GlobalVisitsActionTest to use PHPUnit mocks 2022-10-23 22:23:08 +02:00
Alejandro Celaya
f493baaf2b Migrated DomainVisitsActionTest to use PHPUnit mocks 2022-10-23 22:22:14 +02:00
Alejandro Celaya
28f26920dd Migrated UpdateTagActionTest to use PHPUnit mocks 2022-10-23 22:21:23 +02:00
Alejandro Celaya
69e994c067 Migrated TagsStatsActionTest to use PHPUnit mocks 2022-10-23 22:20:21 +02:00
Alejandro Celaya
656083cb6f Migrated ListTagsActionTest to use PHPUnit mocks 2022-10-23 22:19:14 +02:00
Alejandro Celaya
ab9ea887d2 Migrated DeleteTagsActionTest to use PHPUnit mocks 2022-10-23 22:17:35 +02:00
Alejandro Celaya
9ac6a50e66 Migrated SingleStepCreateShortUrlActionTest to use PHPUnit mocks 2022-10-23 22:16:19 +02:00
Alejandro Celaya
acc9cb94b5 Migrated ResolveShortUrlActionTest to use PHPUnit mocks 2022-10-23 22:14:28 +02:00
Alejandro Celaya
01829c82ee Migrated ListShortUrlsActionTest to use PHPUnit mocks 2022-10-23 22:13:27 +02:00
Alejandro Celaya
9c02ea8799 Migrated EditShortUrlActionTest to use PHPUnit mocks 2022-10-23 22:12:27 +02:00
Alejandro Celaya
d202538581 Migrated DeleteShortUrlActionTest to use PHPUnit mocks 2022-10-23 22:10:41 +02:00
Alejandro Celaya
a84b642ba5 Migrated CreateShortUrlActionTest to use PHPUnit mocks 2022-10-23 22:09:37 +02:00
Alejandro Celaya
74176c298f Migrated ListDomainsActionTest to use PHPUnit mocks 2022-10-23 22:06:48 +02:00
Alejandro Celaya
91e21441f7 Migrated DomainRedirectsActionTest to use PHPUnit mocks 2022-10-23 22:05:51 +02:00
Alejandro Celaya
896b7f2d73 Migrated MercureInfoActionTest to use PHPUnit mocks 2022-10-23 22:04:00 +02:00
Alejandro Celaya
66ed152358 Migrated HealthActionTest to use PHPUnit mocks 2022-10-23 22:02:31 +02:00
Alejandro Celaya
257134cd80 Migrated VisitsForTagPaginatorAdapterTest to use PHPUnit mocks 2022-10-23 21:59:18 +02:00
Alejandro Celaya
a4373aee91 Migrated OrphanVisitsPaginatorAdapterTest to use PHPUnit mocks 2022-10-23 21:56:34 +02:00
Alejandro Celaya
7442905873 Migrated NonOrphanVisitsPaginatorAdapterTest to use PHPUnit mocks 2022-10-23 21:55:06 +02:00
Alejandro Celaya
d3af51f684 Migrated VisitToLocationHelperTest to use PHPUnit mocks 2022-10-23 21:24:30 +02:00
Alejandro Celaya
04419a7242 Migrated VisitLocatorTest to use PHPUnit mocks 2022-10-23 21:21:23 +02:00
Alejandro Celaya
a45d6e6b44 Migrated VisitsTrackerTest to use PHPUnit mocks 2022-10-23 21:08:58 +02:00
Alejandro Celaya
37b1306eb3 Migrated VisitsStatsHelperTest to use PHPUnit mocks 2022-10-23 21:05:13 +02:00
Alejandro Celaya
cff6573767 Migrated RequestTrackerTest to use PHPUnit mocks 2022-10-23 20:45:56 +02:00
Alejandro Celaya
a2f34e02ad Migrated UrlValidatorTest to use PHPUnit mocks 2022-10-23 20:39:06 +02:00
Alejandro Celaya
796543d194 Migrated DoctrineBatchHelperTest to use PHPUnit mocks 2022-10-23 20:32:13 +02:00
Alejandro Celaya
3b25fb27fe Migrated TagsPaginatorAdapterTest to use PHPUnit mocks 2022-10-23 20:28:45 +02:00
Alejandro Celaya
3b20f955ff Migrated TagsInfoPaginatorAdapterTest to use PHPUnit mocks 2022-10-23 20:27:51 +02:00
Alejandro Celaya
c81ae9c40d Migrated TagServiceTest to use PHPUnit mocks 2022-10-23 20:26:44 +02:00
Alejandro Celaya
7ceae7af87 Merge pull request #1585 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-23 20:19:22 +02:00
Alejandro Celaya
5e02cfe375 Fixed coding styles 2022-10-23 18:29:32 +02:00
Alejandro Celaya
6e836b5fd9 Migrated PersistenceShortUrlRelationResolverTest to use PHPUnit mocks 2022-10-23 18:28:28 +02:00
Alejandro Celaya
8753e3a77f Migrated ShortUrlRepositoryAdapterTest to use PHPUnit mocks 2022-10-23 18:17:29 +02:00
Alejandro Celaya
6a2227efc5 Removed all uinnecessary usages of equalsTo param constraint 2022-10-23 18:15:57 +02:00
Alejandro Celaya
1fbcea7a06 Migrated ExtraPathRedirectMiddlewareTest to use PHPUnit mocks 2022-10-23 17:53:09 +02:00
Alejandro Celaya
168c839cf1 Migrated TrimTrailingSlashMiddlewareTest to use PHPUnit mocks 2022-10-23 17:39:57 +02:00
Alejandro Celaya
162e913cc4 Migrated ShortUrlTitleResolutionHelperTest to use PHPUnit mocks 2022-10-23 17:38:04 +02:00
Alejandro Celaya
5aaf50d68e Migrated ShortCodeUniquenessHelperTest to use PHPUnit mocks 2022-10-23 17:35:50 +02:00
Alejandro Celaya
d2f5be1d18 Migrated UrlShortenerTest to use PHPUnit mocks 2022-10-23 11:32:13 +02:00
Alejandro Celaya
36ab455a49 Migrated ShortUrlServiceTest to use PHPUnit mocks 2022-10-23 11:14:01 +02:00
Alejandro Celaya
ee8cab8455 Migrated ShortUrlResolverTest to use PHPUnit mocks 2022-10-23 11:09:40 +02:00
Alejandro Celaya
bd884e85d4 Migrated DeleteShortUrlServiceTest to use PHPUnit mocks 2022-10-23 11:03:47 +02:00
Alejandro Celaya
5ceb6fb740 No longer let pipelines pass on error with PHP 8.2 2022-10-23 11:00:50 +02:00
Alejandro Celaya
0d6155e8bc Merge pull request #1584 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-22 20:51:01 +02:00
Alejandro Celaya
a78c59c11a Fixed coding styles 2022-10-22 20:41:17 +02:00
Alejandro Celaya
173420c608 Migrated ImportedLinksProcessorTest to use PHPUnit mocks 2022-10-22 20:39:55 +02:00
Alejandro Celaya
10b0ec301b Migrated ValidationExceptionTest to use PHPUnit mocks 2022-10-22 20:05:06 +02:00
Alejandro Celaya
1706a869d9 Migrated NotifyVisitToRedisTest to use PHPUnit mocks 2022-10-22 20:04:12 +02:00
Alejandro Celaya
d0393799d2 Migrated NotifyNewShortUrlToRedisTest to use PHPUnit mocks 2022-10-22 19:59:32 +02:00
Alejandro Celaya
739433ba8b Migrated NotifyVisitToRabbitMqTest to use PHPUnit mocks 2022-10-22 19:05:34 +02:00
Alejandro Celaya
a15e9c29c8 Migrated NotifyNewShortUrlToRabbitMqTest to use PHPUnit mocks 2022-10-22 18:49:43 +02:00
Alejandro Celaya
d58f89aa26 Merge pull request #1583 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-22 15:14:57 +02:00
Alejandro Celaya
b7671f70da Fixed coding styles 2022-10-22 14:41:42 +02:00
Alejandro Celaya
52366b9dd4 Removed last reference to prophecytrait in CLI module 2022-10-22 14:41:22 +02:00
Alejandro Celaya
32417e40cb Migrated ShlinkTableTest to use PHPUnit mocks 2022-10-22 14:40:35 +02:00
Alejandro Celaya
4cb44be9a0 Migrated ProcessRunnerTest to use PHPUnit mocks 2022-10-22 14:37:13 +02:00
Alejandro Celaya
a484455b0b Migrated GeolocationDbUpdaterTest to use PHPUnit mocks 2022-10-22 14:27:07 +02:00
Alejandro Celaya
4b3ed2b7ba Migrated LocateVisitsCommandTest to use PHPUnit mocks 2022-10-22 14:16:42 +02:00
Alejandro Celaya
e2986a7b4c Migrated GetOrphanVisitsCommandTest to use PHPUnit mocks 2022-10-22 14:06:54 +02:00
Alejandro Celaya
82e04800aa Migrated GetNonOrphanVisitsCommandTest to use PHPUnit mocks 2022-10-22 14:06:00 +02:00
Alejandro Celaya
5d367da626 Migrated DownloadGeoLiteDbCommandTest to use PHPUnit mocks 2022-10-22 14:02:38 +02:00
Alejandro Celaya
59de5a5f55 Migrated RenameTagCommandTest to use PHPUnit mocks 2022-10-22 13:53:45 +02:00
Alejandro Celaya
0855104068 Migrated ListTagsCommandTest to use PHPUnit mocks 2022-10-22 13:49:11 +02:00
Alejandro Celaya
8c6f97c4e2 Migrated GetTagVisitsCommandTest to use PHPUnit mocks 2022-10-22 13:47:28 +02:00
Alejandro Celaya
2d16856582 Migrated DeleteTagsCommandTest to use PHPUnit mocks 2022-10-22 13:45:11 +02:00
Alejandro Celaya
41e903cf26 Migrated ResolveUrlCommandTest to use PHPUnit mocks 2022-10-22 13:44:10 +02:00
Alejandro Celaya
4872bd3a92 Migrated ListShortUrlsCommandTest to use PHPUnit mocks 2022-10-22 13:42:46 +02:00
Alejandro Celaya
8b675f55cc Migrated GetShortUrlVisitsCommandTest to use PHPUnit mocks 2022-10-22 13:38:46 +02:00
Alejandro Celaya
acda7f02c6 Migrated DeleteShortUrlCommandTest to use PHPUnit mocks 2022-10-22 13:36:33 +02:00
Alejandro Celaya
184ff90b9f Migrated CreateShortUrlCommandTest to use PHPUnit mocks 2022-10-22 13:27:48 +02:00
Alejandro Celaya
d8be3c28cb Migrated ListDomainsCommandTest to use PHPUnit mocks 2022-10-22 13:21:54 +02:00
Alejandro Celaya
3d358ab046 Migrated GetDomainVisitsCommandTest to use PHPUnit mocks 2022-10-22 13:21:00 +02:00
Alejandro Celaya
960bdfc232 Migrated DomainRedirectsCommandTest to use PHPUnit mocks 2022-10-22 13:17:12 +02:00
Alejandro Celaya
101b4daff4 Migrated MigrateDatabaseCommandTest to use PHPUnit mocks 2022-10-22 13:08:05 +02:00
Alejandro Celaya
13431ff8cf Migrated CreateDatabaseCommandTest to use PHPUnit mocks 2022-10-22 13:05:36 +02:00
Alejandro Celaya
4cdcad29df Migrated ListKeysCommandTest to use PHPUnit mocks 2022-10-22 12:53:28 +02:00
Alejandro Celaya
a4c34ff7be Migrated GenerateKeyCommandTest to use PHPUnit mocks 2022-10-22 12:52:11 +02:00
Alejandro Celaya
2b7b5e9a8f Migrated DisableKeyCommandTest to use PHPUnit mocks 2022-10-22 12:48:17 +02:00
Alejandro Celaya
58db902084 Migrated CliTestUtilsTrait to use PHPUnit mocks 2022-10-22 12:46:16 +02:00
Alejandro Celaya
983e3c9eaa Merge pull request #1582 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-22 10:11:30 +02:00
Alejandro Celaya
dbe35cf567 Fixed coding styles 2022-10-22 10:03:28 +02:00
Alejandro Celaya
8298f9d491 Migrated NotifyVisitToMercureTest to use PHPUnit mocks 2022-10-22 10:03:05 +02:00
Alejandro Celaya
16a951b938 Migrated NotifyNewShortUrlToMercureTest to use PHPUnit mocks 2022-10-22 09:50:12 +02:00
Alejandro Celaya
51fcbfb3c2 Migrated UpdateGeoLiteDbTest to use PHPUnit mocks 2022-10-22 09:42:21 +02:00
Alejandro Celaya
e01e370d16 Migrated NotifyVisitToWebHooksTest to use PHPUnit mocks 2022-10-22 08:08:49 +02:00
Alejandro Celaya
736ac8ba90 Migrated LocateVisitTest to use PHPUnit mocks 2022-10-22 07:54:57 +02:00
Alejandro Celaya
d07104b8d9 Migrated LocateUnlocatedVisitsTest to use PHPUnit mocks 2022-10-22 07:34:38 +02:00
Alejandro Celaya
cad53e397a Migrated CloseDbConnectionEventListenerTest to use PHPUnit mocks 2022-10-22 07:32:37 +02:00
Alejandro Celaya
3608a6d068 Migrated CloseDbConnectionEventListenerDelegatorTest to use PHPUnit mocks 2022-10-22 07:28:15 +02:00
Alejandro Celaya
92ddd2eebe Merge pull request #1581 from acelaya-forks/feature/phpunit-mocks
Feature/phpunit mocks
2022-10-21 19:42:58 +02:00
Alejandro Celaya
bf0b58b344 Migrated NotFoundTypeResolverMiddlewareTest to use PHPUnit mocks 2022-10-21 19:32:25 +02:00
Alejandro Celaya
ff543b151c Migrated NotFoundTrackerMiddlewareTest to use PHPUnit mocks 2022-10-21 19:29:02 +02:00
Alejandro Celaya
d842025835 Migrated NotFoundTemplateHandlerTest to use PHPUnit mocks 2022-10-21 19:25:29 +02:00
Alejandro Celaya
230e56370a Migrated NotFoundRedirectHandlerTest to use PHPUnit mocks 2022-10-21 19:24:39 +02:00
Alejandro Celaya
a8514a9ae4 Migrated DomainServiceTest to use PHPUnit mocks 2022-10-21 19:01:41 +02:00
Alejandro Celaya
148f7a9cfe Migrated CrawlingHelperTest to use PHPUnit mocks 2022-10-21 18:49:47 +02:00
Alejandro Celaya
29d50cabc2 Migrated NotFoundRedirectResolverTest to use PHPUnit mocks 2022-10-21 18:47:10 +02:00
Alejandro Celaya
a8f8297131 Migrated RedirectActionTest to use PHPUnit mocks 2022-10-21 18:44:55 +02:00
Alejandro Celaya
cd4b632d75 Migrated QrActionTest to use PHPUnit mocks 2022-10-21 18:39:22 +02:00
Alejandro Celaya
843754b7e7 Migrated PixelActionTest to use PHPUnit mocks 2022-10-21 18:32:34 +02:00
Alejandro Celaya
847cc2bc50 Updated shlink-config 2022-10-19 14:19:03 +02:00
Alejandro Celaya
751bd15785 Fixed merge conflicts 2022-10-18 19:08:20 +02:00
Alejandro Celaya
c12db7567e Merge pull request #1577 from acelaya-forks/feature/fix-enum-hydration
Feature/fix enum hydration
2022-10-18 19:05:07 +02:00
Alejandro Celaya
e8069a10ba Updated changelog 2022-10-18 18:49:52 +02:00
Alejandro Celaya
9742bf13e4 Upgraded to latest doctrine/orm 2022-10-18 18:48:35 +02:00
Alejandro Celaya
6441707c76 Merge branch 'develop' of github.com:shlinkio/shlink into develop 2022-10-18 18:32:02 +02:00
Alejandro Celaya
23bcba4fd9 Updated shlink-ip-geolocation 2022-10-12 19:07:05 +02:00
Alejandro Celaya
9049a205b7 Merge pull request #1570 from acelaya-forks/feature/phpunit-mocks
Migrated to PHPUnit mocks in RobotsActionTest
2022-10-12 18:56:24 +02:00
Alejandro Celaya
8cfa0b595c Migrated to PHPUnit mocks in RobotsActionTest 2022-10-12 18:23:36 +02:00
Alejandro Celaya
4b958e8b87 Merge pull request #1568 from acelaya-forks/feature/phpunit-mocks-experiment
Used PHPUnit mocks in RoleResolverTest instead of prophezy
2022-10-12 12:55:34 +02:00
Alejandro Celaya
bcd5d2848d Used PHPUnit mocks in RoleResolverTest instead of prophezy 2022-10-12 12:47:58 +02:00
Alejandro Celaya
b59cbeceac Updated deps 2022-10-12 08:49:58 +02:00
Alejandro Celaya
46f948a584 Merge pull request #1565 from acelaya-forks/feature/command-reusable-args
Feature/command reusable args
2022-10-06 21:38:19 +02:00
Alejandro Celaya
14bf3a134b Updated changelog 2022-10-06 21:30:23 +02:00
Alejandro Celaya
1557438fdf Moved logic to reuse command options to option classes instead of base abstract command classes 2022-10-06 21:29:27 +02:00
Alejandro Celaya
27b680e0cd Created CLI test for short URLs list 2022-10-06 21:01:11 +02:00
Alejandro Celaya
14314ef939 Updated shlink deps 2022-10-06 19:49:32 +02:00
Alejandro Celaya
bf5c168d7d Merge pull request #1560 from acelaya-forks/feature/openswoole-4.12
Updated to openswoole 4.12
2022-10-03 20:26:25 +02:00
Alejandro Celaya
1e0791416d Downgraded openswoole ide helper 2022-10-03 20:05:43 +02:00
Alejandro Celaya
ab8d42b609 Updated to openswoole 4.12 in main Dockerfile 2022-10-03 20:01:46 +02:00
Alejandro Celaya
96dbdbe7c9 Updated to openswoole 4.12 2022-10-03 20:00:31 +02:00
Alejandro Celaya
6f135ad6ab Fixed typo 2022-09-30 17:45:36 +02:00
Alejandro Celaya
5b9a1e1978 Merge pull request #1559 from shlinkio/develop
Release 3.3.1
2022-09-30 17:37:29 +02:00
Alejandro Celaya
4ba3522e79 Merge pull request #1558 from acelaya-forks/feature/multisegment-trailing-slash
Feature/multisegment trailing slash
2022-09-30 17:35:01 +02:00
Alejandro Celaya
d3faa22b78 Fixed usage of enum where the enum's value should be used 2022-09-30 17:26:22 +02:00
Alejandro Celaya
1daad334a5 Updated changelog 2022-09-30 17:21:27 +02:00
Alejandro Celaya
3dda49dab4 Created middleware which ensures trailing slash and multi-segment features work properly together 2022-09-30 17:19:07 +02:00
Alejandro Celaya
c6c4e5580b Merge pull request #1554 from acelaya-forks/feature/php-8.2
Added PHP 8.2 to build matrixes
2022-09-24 08:26:54 +02:00
Alejandro Celaya
3f808e3813 Updated changelog 2022-09-24 08:17:14 +02:00
Alejandro Celaya
e5107c40f9 Ignored platform req during roadrunner API tests in CI workflow when using PHP 8.2 2022-09-24 08:14:59 +02:00
Alejandro Celaya
0871ca884e Fixed typo 2022-09-24 08:06:41 +02:00
Alejandro Celaya
62ce9311bf Added PHP 8.2 to build matrixes 2022-09-24 08:03:38 +02:00
Alejandro Celaya
70b15a7ab0 Merge pull request #1553 from acelaya-forks/feature/organize-namespaces
Feature/organize namespaces
2022-09-24 07:35:53 +02:00
Alejandro Celaya
708bff20f0 Updated changelog 2022-09-23 19:09:38 +02:00
Alejandro Celaya
369628ee95 Migrated infection config files to json5 2022-09-23 19:08:54 +02:00
Alejandro Celaya
0c6f8f1136 Refactored global entities into their own proper namespaces 2022-09-23 19:03:32 +02:00
Alejandro Celaya
9f9d011d46 Moved ShortCodeUniquenessHelper to ShortUrl\Helper namespace 2022-09-23 18:46:51 +02:00
Alejandro Celaya
e28b73c130 Refactored global services into their own proper namespaces 2022-09-23 18:42:38 +02:00
Alejandro Celaya
56f953ab2f Refactored global validations into their own proper namespaces 2022-09-23 18:30:07 +02:00
Alejandro Celaya
3ad8be175c Refactored global repositories into their own proper namespaces 2022-09-23 18:24:14 +02:00
Alejandro Celaya
f5f990511c Refactored global models into their own proper namespaces 2022-09-23 18:05:17 +02:00
Alejandro Celaya
1e3ccba503 Merge pull request #1552 from acelaya-forks/feature/visit-geolocation-namespace
Feature/visit geolocation namespace
2022-09-23 15:07:42 +02:00
Alejandro Celaya
a842b5b7cd Updated changelog 2022-09-23 14:58:00 +02:00
Alejandro Celaya
909e42b0be Moved services related to geolocating visits to the Visit\Geolocation namespace 2022-09-23 14:50:26 +02:00
Alejandro Celaya
c8acb5de68 Merge pull request #1549 from shlinkio/develop
Release 3.3.0
2022-09-18 19:36:55 +02:00
Alejandro Celaya
53b9e3ddc1 Merge pull request #1548 from acelaya-forks/feature/deferred-geolite-download
Feature/deferred geolite download
2022-09-18 19:35:00 +02:00
Alejandro Celaya
68e1c61e7f Removed unnecessary ADR entry 2022-09-18 19:28:14 +02:00
Alejandro Celaya
8605b35b57 Removed unneeded injected dependency 2022-09-18 19:22:57 +02:00
Alejandro Celaya
36680e82aa Reduced duplication in LocateVisitsCommand by reusing VisitToLocationHelper 2022-09-18 19:21:59 +02:00
Alejandro Celaya
83b7d5a5f1 Extracted logic to geolocate a visit, handling possible domain errors 2022-09-18 18:44:01 +02:00
Alejandro Celaya
fe41e9d573 Updated changelog 2022-09-18 17:12:21 +02:00
Alejandro Celaya
d76e6647d2 Added real version for composer dependencies 2022-09-18 17:10:11 +02:00
Alejandro Celaya
6f17f70137 Allowed to delay GeoLite2 db download on docker images 2022-09-18 17:00:03 +02:00
Alejandro Celaya
ef01754ad5 Added event dispatching to UpdateGeoLiteDb dispatcher so that it locates visits when file has just been created 2022-09-18 11:17:17 +02:00
Alejandro Celaya
eab9347522 Created enum to determine what was the result of updating a geolite DB 2022-09-18 10:31:14 +02:00
Alejandro Celaya
59bcd62717 Moved Geolocation services to its own namespace inside CLI module 2022-09-18 10:01:22 +02:00
Alejandro Celaya
3f01fad12f Ensured empty initial PAI keys are discarded 2022-09-18 09:29:38 +02:00
Alejandro Celaya
c7f0d14c1b Merge pull request #1546 from acelaya-forks/feature/immutable-options
Feature/immutable options
2022-09-17 16:02:36 +02:00
Alejandro Celaya
2408829627 Updated changelog 2022-09-17 15:55:54 +02:00
Alejandro Celaya
8d244c8d34 Migrated UrlShortenerOptions to immutable object 2022-09-17 15:54:43 +02:00
Alejandro Celaya
42af057316 Migrated RedirectOptions to immutable object 2022-09-17 15:36:40 +02:00
Alejandro Celaya
8f68078835 Migrated RabbitMqOptions to immutable object 2022-09-17 13:56:59 +02:00
Alejandro Celaya
0c34032fd3 Migrated QrCodeOptions to immutable object 2022-09-17 13:45:09 +02:00
Alejandro Celaya
20f457a3e9 Migrated NotFoundRedirectOptions to immutable object 2022-09-17 13:32:40 +02:00
Alejandro Celaya
39693ca1fe Added --thread=max to infection command 2022-09-17 13:19:17 +02:00
Alejandro Celaya
784908420e Migrated DeleteShortUrlsOptions to immutable object 2022-09-17 13:04:49 +02:00
Alejandro Celaya
9685929824 Migrated AppOptions to immutable object 2022-09-17 13:01:28 +02:00
Alejandro Celaya
fe4b2c4ae4 Migrated TrackingOptions to immutable object 2022-09-17 12:57:04 +02:00
Alejandro Celaya
5f87bb13f8 Fixed tracking config 2022-09-17 11:27:56 +02:00
Alejandro Celaya
a87f6c6709 Merge pull request #1541 from acelaya-forks/feature/initial-api-key
Feature/initial api key
2022-09-11 13:23:44 +02:00
Alejandro Celaya
da3ee6b65e Updated installer with support for API key generation 2022-09-11 13:14:36 +02:00
Alejandro Celaya
c5eda37bda Updated changelog 2022-09-11 12:36:47 +02:00
Alejandro Celaya
1966367caf Fixed ApiKeyRepository for MS and Postgres 2022-09-11 12:33:28 +02:00
Alejandro Celaya
eed7b6e565 Added db test for ApiKeyRepository 2022-09-11 12:18:04 +02:00
Alejandro Celaya
0e54ed691d Created InitialApiKeyDelegatorTest 2022-09-11 12:11:39 +02:00
Alejandro Celaya
997289da02 Changed all public setUp methods in tests to be protected 2022-09-11 12:02:49 +02:00
Alejandro Celaya
c841e57db5 Reduced duplication in ApiKeyRepository 2022-09-11 11:59:49 +02:00
Alejandro Celaya
f5138385be Created new env var to programatically provide an initial API key 2022-09-11 10:45:03 +02:00
Alejandro Celaya
63ceba199d Removed mention to improvement on mutation tests in changelog 2022-09-11 09:03:25 +02:00
Alejandro Celaya
e6ee4ceae2 Simplified mapping of TagInfo objects 2022-09-08 20:50:11 +02:00
Alejandro Celaya
19a9d815eb Merge pull request #1538 from acelaya-forks/feature/doctrine-cli
Feature/doctrine cli
2022-09-08 17:42:38 +02:00
Alejandro Celaya
5b78b363f0 Updated changelog 2022-09-08 14:11:01 +02:00
Alejandro Celaya
b078c00492 Migrated to custom doctrine cli entry point, as the built-in is deprecated 2022-09-08 14:10:09 +02:00
Alejandro Celaya
e712efd008 Simplified exception 2022-09-06 21:56:18 +02:00
Alejandro Celaya
ab27c0ce53 Merge pull request #1532 from acelaya-forks/feature/trailing-slash-support
Feature/trailing slash support
2022-09-05 21:21:09 +02:00
Alejandro Celaya
d97cabbe79 Updated changelog 2022-09-05 21:14:53 +02:00
Alejandro Celaya
c3c7ffad25 Updated to installer supporting trailing slash option 2022-09-05 21:12:05 +02:00
Alejandro Celaya
fe4329d730 Allowed trailing slashes support to be enabled for the short URLs route 2022-09-05 20:59:16 +02:00
Alejandro Celaya
c53ba7b119 Exported defaults for env vars in docker only when the runtime is RoadRunner 2022-09-03 17:02:57 +02:00
Alejandro Celaya
025eec6c70 Merge remote-tracking branch 'upstream/develop' into develop 2022-08-28 10:20:26 +02:00
Alejandro Celaya
40e1670314 Fixed default port in docker entry point 2022-08-28 10:18:02 +02:00
Alejandro Celaya
2bca260627 What're RoadRunner docker images is not tried to build for arm/v7 2022-08-27 21:49:20 +02:00
Alejandro Celaya
463d8e8950 Updated changelog 2022-08-27 19:51:59 +02:00
Alejandro Celaya
e2eed8a728 Merge pull request #1523 from acelaya-forks/feature/roadrunner-support
Feature/roadrunner support
2022-08-27 19:48:48 +02:00
Alejandro Celaya
f97effcfe0 Fixed rr E2E tests 2022-08-27 19:40:52 +02:00
Alejandro Celaya
2cf21ab3bd Fixed openswoole E2E tests 2022-08-27 19:38:05 +02:00
Alejandro Celaya
7daa602630 Removed accidental flag in build script 2022-08-27 17:51:14 +02:00
Alejandro Celaya
7b637d6a61 Ensured RoadRunner deps are removed when building openswoole dist file 2022-08-27 17:48:59 +02:00
Alejandro Celaya
a4f979be08 Enabled support for static files from public dir via RoadRunner 2022-08-27 17:27:54 +02:00
Alejandro Celaya
8852739111 Ensured some dynamic RR config for prod env, based on env vars 2022-08-27 17:17:37 +02:00
Alejandro Celaya
2099ea16ec Added stage to build docker images for roadrunner 2022-08-27 13:14:27 +02:00
Alejandro Celaya
a739eb6d60 Added support to build the docker image with RoadRunner instead of openswoole 2022-08-27 13:01:38 +02:00
Alejandro Celaya
529ddacafe Removed usage of bash again from tests in CI, as it does nothing really 2022-08-27 09:54:15 +02:00
Alejandro Celaya
f71c95b74a Another attempt to make API tests script sh compatible 2022-08-27 09:49:32 +02:00
Alejandro Celaya
8260a0843b Undone changes for sh on API tests 2022-08-27 09:43:20 +02:00
Alejandro Celaya
bfbeb7b1fb Improved run-api-tests.sh script to make it compatible with sh 2022-08-27 09:36:37 +02:00
Alejandro Celaya
df70810aa6 Ensured tests are run in bash in CI 2022-08-27 09:23:45 +02:00
Alejandro Celaya
aca5804f98 Fixed usage of inputs instead of matrix on CI workflow 2022-08-27 09:21:17 +02:00
Alejandro Celaya
b7f7288a4b Fixed reference to unknown job in CI workflow 2022-08-27 09:19:55 +02:00
Alejandro Celaya
d54a2bde0f Fixed reference to unknown job in CI workflow 2022-08-27 09:18:46 +02:00
Alejandro Celaya
679bb8d357 Added API tests over roadrunner on CI 2022-08-27 09:15:58 +02:00
Alejandro Celaya
ca515998e4 Added support to run API tests on roadrunner 2022-08-27 09:09:14 +02:00
Alejandro Celaya
c5b6d203f5 Simplified RoadRunner worker, and fixed RoadRunner reloading config 2022-08-27 08:01:57 +02:00
Alejandro Celaya
86159c5d86 Updated to latest event dispatcher lib 2022-08-26 19:17:10 +02:00
Alejandro Celaya
846802c003 Slight improvements on RoadRunner config 2022-08-26 17:58:25 +02:00
Alejandro Celaya
e9ec32b3c3 Added support to dispatch async event listeners as RoadRunner jobs 2022-08-26 14:59:27 +02:00
Alejandro Celaya
4882bec118 Added roadrunner to the project 2022-08-21 13:19:27 +02:00
Alejandro Celaya
89ff259be0 Merge pull request #1517 from acelaya-forks/feature/reusable-docker-build
Moved to docker build on reusable workflow
2022-08-19 15:18:20 +02:00
Alejandro Celaya
60ece7fbf7 Moved to docker build on reusable workflow 2022-08-19 15:11:46 +02:00
Alejandro Celaya
0c110f574a Merge pull request #1516 from acelaya-forks/feature/reduce-ci-artifact-download
Ensured every mutation test job only downloads the specific coverage …
2022-08-17 19:27:52 +02:00
Alejandro Celaya
dbca5b2a7e Ensured every mutation test job only downloads the specific coverage report 2022-08-17 19:16:33 +02:00
Alejandro Celaya
3088298e6b Merge pull request #1515 from acelaya-forks/feature/reusable-docker-build
Migrated docker build to a reusable workflow
2022-08-14 18:35:59 +02:00
Alejandro Celaya
a9c6a12182 Migrated docker build to a reusable workflow 2022-08-14 17:36:58 +02:00
Alejandro Celaya
fa5b512629 Merge pull request #1514 from acelaya-forks/feature/ghcr-support
Feature/ghcr support
2022-08-14 17:12:56 +02:00
Alejandro Celaya
5c2061a6e6 Updated changelog 2022-08-14 17:07:07 +02:00
Alejandro Celaya
cf0fc956c9 Added publishing of the docker image in GHCR 2022-08-14 17:05:13 +02:00
Alejandro Celaya
a0517dfbeb Merge pull request #1512 from acelaya-forks/feature/api-v3
Feature/api v3
2022-08-14 14:07:32 +02:00
Alejandro Celaya
39c71638e6 Updated changelog 2022-08-14 14:02:09 +02:00
Alejandro Celaya
672b728379 Updated swagger docs, with new API v3 error types 2022-08-14 13:55:43 +02:00
Alejandro Celaya
750a546faf Disabled mutation tests filtering until it properly works 2022-08-14 13:18:29 +02:00
Alejandro Celaya
a41835573b Centralized prefix for problem detail types 2022-08-14 13:12:10 +02:00
Alejandro Celaya
2650cb89b5 Created BackwardsCompatibleProblemDetailsExceptionTest 2022-08-14 12:39:05 +02:00
Alejandro Celaya
4a122e0209 Added remaining API tests covering error type convertions 2022-08-14 10:51:12 +02:00
Alejandro Celaya
ce4bf62d75 Added more granular resolution of arguments for infection based on branch 2022-08-14 10:34:27 +02:00
Alejandro Celaya
40bbcb3250 Added some API tests for v3 API errors 2022-08-13 17:49:00 +02:00
Alejandro Celaya
905f51fbd0 Added logic to properly map all existing errors from v3 to v2 in the API 2022-08-13 17:15:04 +02:00
Alejandro Celaya
cd4fe4362b Created middleware to keep backwards compatibility on errors when using v1 and 2 of the API 2022-08-13 16:50:19 +02:00
Alejandro Celaya
ed7be6eb99 Updated changelog 2022-08-13 12:37:15 +02:00
Alejandro Celaya
555007ab16 Merge pull request #1511 from acelaya-forks/feature/only-changed-mutants
Ensured only mutants for changed lines are executed in CI mutation tests
2022-08-13 12:34:52 +02:00
Alejandro Celaya
bd31b99324 Ensured only mutants for changed lines are executed in CI mutation tests 2022-08-13 12:31:12 +02:00
Alejandro Celaya
60237c3c0b Merge pull request #1509 from acelaya-forks/feature/local-composed-action
Extracted all steps for setting up to a reusable action
2022-08-13 12:02:28 +02:00
Alejandro Celaya
eb21833d94 Used ci-setup composite action as much as possible in ci workflow 2022-08-13 11:56:46 +02:00
Alejandro Celaya
763002ae14 Fixed typo when reading etxnesions input on ci-setup action 2022-08-13 11:18:50 +02:00
Alejandro Celaya
ae2dc39a78 Fixed ci-setup local composite action 2022-08-13 11:16:33 +02:00
Alejandro Celaya
fe4ced2709 Moved checkout step back to workflow 2022-08-13 11:06:41 +02:00
Alejandro Celaya
9075d68b7c Fixed reference to local composed action 2022-08-13 11:03:40 +02:00
Alejandro Celaya
759c0ea957 Extracted all steps for setting up to a reusable action 2022-08-13 10:53:24 +02:00
Alejandro Celaya
67b393d4a3 Merge pull request #1508 from acelaya-forks/feature/improve-cache-key-ci
Improved cache keys for extensions in CI workflow to support several …
2022-08-13 10:27:13 +02:00
Alejandro Celaya
de71821759 Updated to latest actions/checkout version 2022-08-13 10:19:38 +02:00
Alejandro Celaya
0c2bcaee34 Fixed typo 2022-08-13 10:12:52 +02:00
Alejandro Celaya
1613975e0e Improved cache keys for extensions in CI workflow to support several PHP versions when needed 2022-08-13 10:11:41 +02:00
Alejandro Celaya
be82204df2 Merge pull request #1507 from acelaya-forks/feature/improve-ci-uploads
Feature/improve ci uploads
2022-08-12 20:52:50 +02:00
Alejandro Celaya
14c2ff5545 Ensured unique cache key 2022-08-12 20:35:59 +02:00
Alejandro Celaya
d7d0e11f2c Added cache for PHP extensions in CI pipeline 2022-08-12 20:32:16 +02:00
Alejandro Celaya
6654f45cb8 Updated upload/download artifact actions 2022-08-12 18:19:12 +02:00
Alejandro Celaya
23f92179ad Optimized how and when code coverage reports are generated for different types of tests 2022-08-12 18:10:45 +02:00
Alejandro Celaya
7377917642 Merge pull request #1506 from acelaya-forks/feature/local-reusable-workflows
Extracted definition of unit tests job to local reusable workflow
2022-08-12 09:52:01 +02:00
Alejandro Celaya
0f796859f2 Fixed typo in ci workflow 2022-08-12 09:32:30 +02:00
Alejandro Celaya
6383230678 Extracted DB tests and mutation tests to reusable workflows 2022-08-12 09:30:52 +02:00
Alejandro Celaya
51536f8746 Moved reusable ci tests workflow to workflows folder 2022-08-12 09:13:04 +02:00
Alejandro Celaya
e3b6c061c4 Extracted definition of unit tests job to local reusable workflow 2022-08-12 08:35:10 +02:00
Alejandro Celaya
4bd3fa74d1 Merge pull request #1502 from acelaya-forks/feature/cli-tests
Feature/cli tests
2022-08-10 17:39:27 +02:00
Alejandro Celaya
71553988d5 Added cli mutation tests to pipeline, and referenced CLI tests in CONTRIBUTING file 2022-08-10 17:21:55 +02:00
Alejandro Celaya
761b24e614 Added CLI tests to to CI pipeline 2022-08-10 17:13:21 +02:00
Alejandro Celaya
10974902b5 Updated changelog 2022-08-10 17:09:54 +02:00
Alejandro Celaya
474407dbc2 Ensured proper coverage is generated during CLI tests 2022-08-10 17:08:42 +02:00
Alejandro Celaya
95d84f354d Simplified tests config 2022-08-09 19:48:43 +02:00
Alejandro Celaya
db47a9a253 Added mutation tests for CLI E2E tests 2022-08-09 19:15:49 +02:00
Alejandro Celaya
709a4639b3 Fixed merge conflicts 2022-08-09 18:59:55 +02:00
Alejandro Celaya
28b9cd02ef Merge pull request #1501 from shlinkio/develop
Release 3.2.1
2022-08-08 19:51:00 +02:00
Alejandro Celaya
af9ea13933 Merge pull request #1500 from acelaya-forks/feature/fix-env-var-loading
Feature/fix env var loading
2022-08-08 19:46:53 +02:00
Alejandro Celaya
bd2cd18916 Tagged stable releases for all shlink teps 2022-08-08 19:33:59 +02:00
Alejandro Celaya
23138dc0b4 Updated changelog 2022-08-08 19:24:51 +02:00
Alejandro Celaya
a2f9742cfc Fix loading of config options as env vars 2022-08-08 19:23:16 +02:00
Alejandro Celaya
6378e614b0 Merge pull request #1498 from acelaya-forks/feature/update-shlink-deps
Feature/update shlink deps
2022-08-07 10:04:23 +02:00
Alejandro Celaya
b116a57aa7 Updated changelog 2022-08-07 09:37:49 +02:00
Alejandro Celaya
a03f32f521 Updated to latest shlink dependencies 2022-08-07 09:36:51 +02:00
Alejandro Celaya
b9180be685 Merge pull request #1496 from acelaya-forks/feature/centralize-multi-segment
Feature/centralize multi segment
2022-08-06 09:54:09 +02:00
Alejandro Celaya
334aee64ad Updated changelog 2022-08-06 09:37:15 +02:00
Alejandro Celaya
16bd368a58 Centralized how routes are configured to support multi-segment slugs 2022-08-06 09:30:13 +02:00
Alejandro Celaya
3266a0f85c Merge pull request #1494 from shlinkio/develop
Release 3.2.0
2022-08-05 19:04:45 +02:00
Alejandro Celaya
4629f1b03f Merge pull request #1493 from acelaya-forks/feature/update-deps
Updated to latest PHP version and native dependencies
2022-08-05 16:44:29 +02:00
Alejandro Celaya
fbd0c6cbea Merge pull request #1491 from acelaya-forks/feature/multi-segment-slugs
Feature/multi segment slugs
2022-08-05 16:31:38 +02:00
Alejandro Celaya
8260051c30 Updated to latest PHP version and native dependencies 2022-08-05 16:31:15 +02:00
Alejandro Celaya
c061c9c3ff Added v3.2.0 to changelog 2022-08-05 16:19:40 +02:00
Alejandro Celaya
8961191b2e Documented ADR for multi-segment slugs 2022-08-05 16:18:53 +02:00
Alejandro Celaya
fc0d99be41 Ensure filtering of custom-slug is different depending on the multi-sement lugsfeature flag 2022-08-05 08:38:05 +02:00
Alejandro Celaya
6834e72c4a Updated changelog 2022-08-04 17:15:35 +02:00
Alejandro Celaya
efe655f880 Enhanced ExtraPathRedirectMiddleware so that it supports multi-segment slugs 2022-08-04 17:03:08 +02:00
Alejandro Celaya
3d5ddce621 Ensured multi-segment feature flag affects how append_extra_path is checked 2022-08-04 16:10:54 +02:00
Alejandro Celaya
a3de3e15cb Updated installer with support for multi-segment slugs flag 2022-08-04 13:00:09 +02:00
Alejandro Celaya
619999d4f8 Added feature flag to enable/disable multi-segment support 2022-08-04 11:49:33 +02:00
Alejandro Celaya
7acf27dd38 Replaced usage of deprecated methods in DateRange class 2022-08-04 11:27:33 +02:00
Alejandro Celaya
ba517eeeb5 Moved routes config together, and ensure they are loaded last 2022-08-04 11:14:26 +02:00
Alejandro Celaya
fdd3e24967 Added support for multi-segment slugs 2022-08-03 19:32:59 +02:00
Alejandro Celaya
a570ce202a Updated to latest common 2022-08-03 12:59:09 +02:00
Alejandro Celaya
0a220bbc7a Allowed slashes on custom slugs during short URL creation 2022-08-01 17:32:54 +02:00
Alejandro Celaya
e0e511f56d Some improvements and comments in preparation of multi-segment slugs 2022-08-01 17:32:54 +02:00
Alejandro Celaya
d375dece0e Updated required deps 2022-08-01 17:32:54 +02:00
Alejandro Celaya
f801f265ed Added comments on places to change 2022-08-01 17:32:54 +02:00
Alejandro Celaya
1b4fc89b07 Merge pull request #1490 from acelaya-forks/feature/ci-composer-cache
Added cache for composer dependencies during CI
2022-08-01 17:32:07 +02:00
Alejandro Celaya
3ac2b77bf0 Removed composer cache due to a bug in github runner making it fail 2022-08-01 17:23:51 +02:00
Alejandro Celaya
b2ca4ad66b Migrated all workflows to ubuntu-22.04 2022-08-01 17:13:34 +02:00
Alejandro Celaya
25a7c7bc7f Added cache for composer dependencies during CI 2022-08-01 16:56:25 +02:00
Alejandro Celaya
6b009a4de4 Merge pull request #1489 from acelaya-forks/feature/command-error
Feature/command error
2022-08-01 12:25:05 +02:00
Alejandro Celaya
0b80a86e88 Updated changelog 2022-08-01 12:07:50 +02:00
Alejandro Celaya
b03f24d59a Ensured no arguments are passed form locate visits command to download geolite command, is it does not expect any 2022-08-01 12:06:38 +02:00
Alejandro Celaya
78ea13d366 Merge pull request #1488 from acelaya-forks/feature/redis-pub-sub
Feature/redis pub sub
2022-07-28 11:04:19 +02:00
Alejandro Celaya
8c2bdfba1c Refactored match to ifs with eary returns 2022-07-28 10:51:48 +02:00
Alejandro Celaya
3289968a93 Updated changelog 2022-07-28 10:46:24 +02:00
Alejandro Celaya
73ae754aa7 Created NotifyVisitToRedisTest 2022-07-28 10:36:52 +02:00
Alejandro Celaya
20a6e7e210 Created NotifyNewShortUrlToRedisTest 2022-07-28 10:33:26 +02:00
Alejandro Celaya
4cf433a994 Defined enum with supported remote systems 2022-07-28 10:25:55 +02:00
Alejandro Celaya
e36c4d397c Moved duplicated code in visit listeners to an abstract class 2022-07-27 18:18:36 +02:00
Alejandro Celaya
26037327f9 Moved duplicated code in short URL listeners to an abstract class 2022-07-27 18:06:47 +02:00
Alejandro Celaya
da6aa1d697 Integrated PublishUpdatesGenerator in NotifyVisitToRabbitMq listener 2022-07-27 17:41:48 +02:00
Alejandro Celaya
dada6aa3d1 Integrated PublishUpdatesGenerator in NotifyVisitToRedis listener 2022-07-27 16:55:19 +02:00
Alejandro Celaya
fa5ebb1677 Integrated PublishUpdatesGenerator in NotifyNewShortUrlToRedis listener 2022-07-27 16:47:21 +02:00
Alejandro Celaya
f071df325d Fixed NotifyNewShortUrlToRabbitMqTest 2022-07-27 10:26:18 +02:00
Alejandro Celaya
3c042c4011 Integrated PublishUpdatesGenerator in NotifyNewShortUrlToRabbitMq listener 2022-07-27 10:18:28 +02:00
Alejandro Celaya
7e8109caa3 Renamed MercureUpdatesGenerator to PublishingUpdatesGenerator to make it general purpose 2022-07-27 09:38:47 +02:00
Alejandro Celaya
d3add6d8e4 Added TODO 2022-07-26 12:18:58 +02:00
Alejandro Celaya
1b089749c0 Migrated mercure event listeners to use new publishing helper from shlink-common 2022-07-26 12:17:37 +02:00
Alejandro Celaya
791d6b7e57 Updated to latest common, with unified publishing API 2022-07-26 12:07:27 +02:00
Alejandro Celaya
233bb603cf Updated local redis config 2022-07-26 10:25:16 +02:00
Alejandro Celaya
db8a816524 Implemented redis pub/sub listeners 2022-07-26 10:17:50 +02:00
Alejandro Celaya
eff50ca202 Created new event listeners to send events to redis pub/sub 2022-07-25 18:23:13 +02:00
Alejandro Celaya
ceabb5ab2c Merge pull request #1486 from acelaya-forks/feature/backwards-compatible-rabbit-mq
Feature/backwards compatible rabbit mq
2022-07-25 12:55:28 +02:00
Alejandro Celaya
122c2fd5e6 Updated changelog 2022-07-25 12:34:40 +02:00
Alejandro Celaya
cd27a72982 Reduced duplicated code in NotifyNewShortUrlToRabbitMqTest 2022-07-25 12:31:32 +02:00
Alejandro Celaya
19b0f0d7dc Extended NotifyVisitToRabbitMqTest covering legacy and non-legacy use-cases 2022-07-25 12:30:28 +02:00
Alejandro Celaya
6ce2049935 Added support for legacy and new publishing of visits in RabbitMQ 2022-07-25 12:08:22 +02:00
Alejandro Celaya
53b937be63 Updated coding standard 2022-07-25 09:49:14 +02:00
Alejandro Celaya
71c8f99dab Merge pull request #1484 from acelaya-forks/feature/short-url-created-event
Feature/short url created event
2022-07-25 09:48:44 +02:00
Alejandro Celaya
9eb3fca726 Updated changelog 2022-07-25 09:32:09 +02:00
Alejandro Celaya
019bd4dec8 Created NotifyNewShortUrlToMercureTest 2022-07-25 09:30:25 +02:00
Alejandro Celaya
be1ce06c00 Updated asyn API spec 2022-07-25 09:04:15 +02:00
Alejandro Celaya
074bfe3db2 Updated MercureUpdatesGeneratorTest 2022-07-25 09:02:05 +02:00
Alejandro Celaya
34e72b42dc Implemented listener to publish new short URL events in Mercure 2022-07-24 19:00:48 +02:00
Alejandro Celaya
97d24d76d8 Fixed new short URL event payload to RabbitMQ, and started to add logic for Mercure 2022-07-24 12:37:57 +02:00
Alejandro Celaya
4d1af867a4 Extracted real-time update topic names to an enum 2022-07-24 12:06:00 +02:00
Alejandro Celaya
fc6b4c12b2 Configured publishing of new short URL events in RabbitMQ 2022-07-24 11:07:20 +02:00
Alejandro Celaya
405c6de591 Created NotifyNewShortUrlToRabbitMq test 2022-07-24 10:53:42 +02:00
Alejandro Celaya
47bfa5fcc0 Simplified NotifyNewShortUrlToRabbitMq 2022-07-24 10:18:19 +02:00
Alejandro Celaya
67d91d5fc5 Migrated rabbit integration to RabbitMqPublishingHelper from shlink-common 2022-07-24 10:12:26 +02:00
Alejandro Celaya
f832c56adb Moved Mercure and RabbitMq event listeners to their own subnamespaces 2022-07-21 20:07:28 +02:00
Alejandro Celaya
1aa9ae680e Merge pull request #1479 from acelaya-forks/feature/unknown-visits
Added missing implements JsonSerializable on VisitLocation that got l…
2022-07-18 20:43:02 +02:00
Alejandro Celaya
c4b30db82d Added missing implements JsonSerializable on VisitLocation that got lost when VisitLocationInterface was removed 2022-07-18 20:23:27 +02:00
Alejandro Celaya
abd9f3c6be Removed style checks disabling due to bug on php code sniffer 2022-07-04 17:12:38 +02:00
Alejandro Celaya
3de3594282 Merge pull request #1465 from jsoref/spelling
Spelling
2022-06-08 07:31:25 +02:00
Alejandro Celaya
ed5816d464 Fixed merge conflicts 2022-06-04 11:43:02 +02:00
Alejandro Celaya
3d43bdbb49 Merge pull request #1462 from acelaya-forks/feature/search-with-all-tags
Fixed error when filtering short URLs by ALL tags and search term
2022-06-04 11:37:14 +02:00
Alejandro Celaya
1ab492ce5b Added missing test case 2022-06-04 11:22:10 +02:00
Alejandro Celaya
de30c6ad79 Fixed error when filtering short URLs by ALL tags and search term 2022-06-04 11:20:08 +02:00
Alejandro Celaya
f5a48ff98d Merge pull request #1460 from acelaya-forks/feature/monolog3
Feature/monolog3
2022-06-04 09:11:31 +02:00
Alejandro Celaya
8493ee5b83 Updated changelog 2022-06-04 09:00:00 +02:00
Alejandro Celaya
52a6d55e5d Updated to monolog 3 2022-06-04 08:59:17 +02:00
Josh Soref
7142295aa5 spelling: urls
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
8b65be26a6 spelling: the
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
60f5deb494 spelling: received
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
0fc09e6dd3 spelling: monolog
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
0c4ccf4e3e spelling: middleware
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
a0e79bf446 spelling: microsoft
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
aa356ad7c7 spelling: github
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 23:36:42 -04:00
Josh Soref
9e0e384d46 spelling: campaign
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-05-30 22:39:08 -04:00
Alejandro Celaya
a20b99e643 Merge pull request #1451 from acelaya-forks/feature/missing-visits-commands
Feature/missing visits commands
2022-05-24 18:44:56 +02:00
Alejandro Celaya
fe4237b2b1 Updated changelog 2022-05-24 18:00:17 +02:00
Alejandro Celaya
4146835f6f Created GetOrhanVisitsCommand test 2022-05-24 17:59:06 +02:00
Alejandro Celaya
5201ea4516 Created tests for short-url-visits commands 2022-05-24 17:54:44 +02:00
Alejandro Celaya
fba7b36245 Improved GetShortUrlVisitsCommand test 2022-05-24 17:44:12 +02:00
Alejandro Celaya
353ac0fc0c Added logic to resolve extra columns on visits commands 2022-05-23 21:19:59 +02:00
Alejandro Celaya
00002b1e24 Renamed some visits commands 2022-05-23 20:47:37 +02:00
Alejandro Celaya
aa32830671 Added note to readme 2022-05-23 07:55:33 +02:00
Alejandro Celaya
12b8100d89 Created visits commands for orphan, non-orphan and domain 2022-05-22 19:34:08 +02:00
Alejandro Celaya
72e56d271d Created tags visits command, with abstract class wrapping common logic for visits lists commands 2022-05-22 19:22:29 +02:00
Alejandro Celaya
2b69f5eff4 Merge pull request #1449 from acelaya-forks/feature/title-html-entities
Feature/title html entities
2022-05-22 10:12:54 +02:00
Alejandro Celaya
f224bb98c4 Updated changelog 2022-05-22 08:30:46 +02:00
Alejandro Celaya
ec17eb3fbc Ensured html entities are parsed when auto-resolving titles 2022-05-22 08:29:26 +02:00
Alejandro Celaya
358b600713 Fixed merge conflicts 2022-05-09 08:21:19 +02:00
Alejandro Celaya
aacb5c39ba Merge pull request #1445 from acelaya-forks/feature/update-openswoole
Updated to openswoole 4.11.1 in docker images
2022-05-09 08:17:01 +02:00
Alejandro Celaya
9ae8804095 Updated to openswoole 4.11.1 in docker images 2022-05-09 08:00:54 +02:00
Alejandro Celaya
2d51bd895d Merge pull request #1440 from acelaya-forks/feature/url-validation-memory-issue
Feature/url validation memory issue
2022-05-01 12:14:52 +02:00
Alejandro Celaya
18f656fed2 Changed logic when resolving the title of a URL, to ensure only html content is tried to be downloaded, and only until the title tag has been parsed 2022-05-01 11:48:20 +02:00
Alejandro Celaya
eea76999b2 Ensured URL validation is doe via HEAD method when the title does not need to be resolved 2022-05-01 09:51:15 +02:00
Alejandro Celaya
bd495adf22 Set SemVer versions for some shlink package versions 2022-05-01 08:40:20 +02:00
Alejandro Celaya
e8c7bee924 Added SemVer constraints for some deps which were left with specific commits by mistake 2022-04-23 19:30:33 +02:00
Alejandro Celaya
24b06c24dc Merge pull request #1434 from acelaya-forks/feature/drop-php-8.0
Feature/drop php 8.0
2022-04-23 19:26:02 +02:00
Alejandro Celaya
6fdd764a35 Updated to phpcov 8.2.1 2022-04-23 19:11:23 +02:00
Alejandro Celaya
2400d1f265 Removed unused method 2022-04-23 19:07:36 +02:00
Alejandro Celaya
cdef430b0b Set ShortUrlIdentifier constructor to private 2022-04-23 19:01:02 +02:00
Alejandro Celaya
6074e4ae2c Updated changelog 2022-04-23 18:57:39 +02:00
Alejandro Celaya
6ada704bc3 Moved TagsMode to its own enum 2022-04-23 18:56:27 +02:00
Alejandro Celaya
e8f7daac6f Converted Role constants to enum 2022-04-23 18:41:16 +02:00
Alejandro Celaya
404455928e Converted visit types into enum 2022-04-23 18:19:16 +02:00
Alejandro Celaya
bca3e62ced Updated to readonly public props on as many models as possible 2022-04-23 14:00:47 +02:00
Alejandro Celaya
e79391907a Added some PHP 8.1 features 2022-04-23 13:08:21 +02:00
Alejandro Celaya
54a23cc7fa Converted EnvVars to enum 2022-04-23 12:44:17 +02:00
Alejandro Celaya
e8ebe77923 Dropped PHP 8.0 support 2022-04-23 12:08:01 +02:00
Alejandro Celaya
68e0aa1ea9 Merge pull request #1433 from shlinkio/develop
Release 3.1.0
2022-04-23 11:39:27 +02:00
Alejandro Celaya
ceaf64c9b3 Fixed typo in changelog 2022-04-23 11:35:55 +02:00
Alejandro Celaya
e015b1bec5 Improved changelog 2022-04-23 11:34:40 +02:00
Alejandro Celaya
ca9726c997 Merge pull request #1432 from acelaya-forks/feature/domain-visits
Feature/domain visits
2022-04-23 11:33:04 +02:00
Alejandro Celaya
85c79abd30 Updated changelog 2022-04-23 11:19:14 +02:00
Alejandro Celaya
54c1c7ad84 Created DomainVisits API test 2022-04-23 11:17:32 +02:00
Alejandro Celaya
af15e31b42 Created DomainVisitsActionTest 2022-04-23 11:07:10 +02:00
Alejandro Celaya
99b4f9f4dd Improved VisitsStatsHelperTest covering visitsForDomain method 2022-04-23 11:02:51 +02:00
Alejandro Celaya
9a0e5ea626 Created method to check if domain exists based on authority and API key 2022-04-23 10:58:33 +02:00
Alejandro Celaya
984205e02c Extended VisitRepositoryTest with domain visits functions 2022-04-23 10:45:42 +02:00
Alejandro Celaya
e11bf6ac67 Created endpoint to get visits for one specific domain 2022-04-23 10:32:07 +02:00
Alejandro Celaya
e029d91544 Documented new domain visits endpoint 2022-04-23 09:27:52 +02:00
Alejandro Celaya
011856cbfa Removed redundant var 2022-04-23 09:15:01 +02:00
Alejandro Celaya
9ce8164013 Merge pull request #1431 from acelaya-forks/feature/update-deps
Updated docker images and dependencies
2022-04-23 09:13:47 +02:00
Alejandro Celaya
dca6b7bbf5 Updated docker images and dependencies 2022-04-23 08:56:25 +02:00
Alejandro Celaya
2511ec3395 Merge pull request #1424 from acelaya-forks/feature/skip-invalid-imports
Added errorhandling for individual imported URLs, so that one failing…
2022-04-23 08:35:21 +02:00
Alejandro Celaya
9f6ffc7186 Added errorhandling for individual imported URLs, so that one failing doe snot make the whole process fail 2022-04-18 14:45:37 +02:00
Alejandro Celaya
622f0217fa Merge pull request #1421 from acelaya-forks/feature/cast-incoming-dates
Feature/cast incoming dates
2022-04-15 20:20:26 +02:00
Alejandro Celaya
09eba49bab Updated changelog 2022-04-15 20:06:51 +02:00
Alejandro Celaya
c20c3801a8 Ensured all input dates are changed to the default timezone before being used on any inner layer 2022-04-15 19:57:27 +02:00
Alejandro Celaya
f8208b7288 Merge pull request #1420 from acelaya-forks/feature/timezone
Feature/timezone
2022-04-15 09:27:17 +02:00
Alejandro Celaya
3db8a65ddb Fixed test 2022-04-14 16:00:15 +02:00
Alejandro Celaya
0495b6f298 Updated changelog 2022-04-14 14:24:01 +02:00
Alejandro Celaya
52c55f385d Added support to set the timezone via config/env vars 2022-04-14 14:22:48 +02:00
Alejandro Celaya
fe28d6fba0 Merge pull request #1417 from acelaya-forks/feature/kutt-import
Updated importer with support for Kutt.it
2022-04-14 12:51:56 +02:00
Alejandro Celaya
0294e49d4a Added dist local config for app options 2022-04-14 11:35:12 +02:00
Alejandro Celaya
cbaf51d3ef Updated importer with support for Kutt.it 2022-04-14 11:31:50 +02:00
Alejandro Celaya
efb604a381 Merge pull request #1415 from acelaya-forks/feature/yourls-domain
Feature/yourls domain
2022-04-13 12:54:12 +02:00
Alejandro Celaya
da87f05126 Updated changelog 2022-04-13 12:41:09 +02:00
Alejandro Celaya
21534b78cb Updated to latest shlink-importer, with support to import on a specific domain for YOURLS 2022-04-13 12:40:21 +02:00
Alejandro Celaya
ab65593f7d Merge pull request #1414 from acelaya-forks/feature/postgres-db-error
Feature/postgres db error
2022-04-12 19:27:35 +02:00
Alejandro Celaya
3a82691503 Small improvements on CreateDatabaseCommand 2022-04-10 19:48:32 +02:00
Alejandro Celaya
430e2ff0b5 Ensured db and api tests can be run without the need of creating the database beforehand 2022-04-09 17:46:13 +02:00
Alejandro Celaya
7d572e7988 Merge pull request #1404 from acelaya-forks/feature/fix-double-paths
Feature/fix double paths
2022-03-14 19:56:58 +01:00
Alejandro Celaya
1449e24b66 Improved some tests 2022-03-14 19:41:33 +01:00
Alejandro Celaya
6a671760da Updated changelog 2022-03-14 19:28:55 +01:00
Alejandro Celaya
613bdd82b0 Ensured base path is not prefixed more than it should 2022-03-14 19:26:02 +01:00
Alejandro Celaya
01bae358f9 Merge pull request #1399 from shlinkio/feature/improve-db-create
Feature/improve db create
2022-03-05 11:03:39 +01:00
Alejandro Celaya
3a8e560dc5 Increased required mutation score for unit tests to 85% 2022-03-05 10:51:48 +01:00
Alejandro Celaya
a0c538d9ee Updated changelog 2022-03-05 10:48:02 +01:00
Alejandro Celaya
07c30f86e9 Excluded migrations table when checking if the database schema exists 2022-03-05 10:41:13 +01:00
Alejandro Celaya
c22e38f9a0 Removed deprecated method call 2022-03-05 10:32:05 +01:00
Alejandro Celaya
4d082a87a1 Added preliminary config to export coverage for CLI tests 2022-02-27 08:11:33 +01:00
Alejandro Celaya
1b6512fc8d Replaced deprecated transactional function with wrapTransaction 2022-02-27 08:10:18 +01:00
Alejandro Celaya
7502e8a1e4 Merge pull request #1386 from acelaya-forks/feature/mercure-error
Feature/mercure error
2022-02-20 15:58:49 +01:00
Alejandro Celaya
5a25211371 Created NotConfiguredMercureErrorHandlerTest 2022-02-20 10:50:21 +01:00
Alejandro Celaya
6983f9b2bf Added middleware that mitigates big error traces being logged for those not using mercure 2022-02-20 10:36:54 +01:00
Alejandro Celaya
5affe64b61 Removed references in CONTRIBUTING.md file to no longer existing assets 2022-02-19 19:55:36 +01:00
Alejandro Celaya
c52f3c396b Fixed merge conflicts 2022-02-19 19:47:34 +01:00
Alejandro Celaya
e1ebbaa52f Merge pull request #1384 from acelaya-forks/feature/default-domain-role
Feature/default domain role
2022-02-19 19:42:12 +01:00
Alejandro Celaya
7abe6af5ec Updated changelog 2022-02-19 19:24:43 +01:00
Alejandro Celaya
c98ea6055b Ensured API keys cannot be generated with domain-only roles linked to default domain 2022-02-19 19:23:36 +01:00
Alejandro Celaya
3e3d255edf Merge pull request #1383 from acelaya-forks/feature/fixes
Updated docker images to PHP 8.1.3
2022-02-19 19:11:30 +01:00
Alejandro Celaya
816d4851e7 Updated docker images to PHP 8.1.3 2022-02-19 18:57:36 +01:00
Alejandro Celaya
9e32886f60 Created first CLI E2E tests 2022-02-13 12:20:02 +01:00
Alejandro Celaya
79af315b9f Fixed merge conflicts 2022-02-10 21:48:21 +01:00
Alejandro Celaya
4110c702c0 Merge pull request #1376 from acelaya-forks/feature/release-3.0.2
Feature/release 3.0.2
2022-02-10 21:44:30 +01:00
Roy-Orbison
57eb29c3c8 Optimise RewriteRules/Conds
From upstream changes on Mezzio Skeleton.

Closes #1369.
2022-02-10 21:31:45 +01:00
Alejandro Celaya
5267c4eee6 Updated changelog 2022-02-10 21:31:30 +01:00
Alejandro Celaya
1453ebe8ca Updated to shlink-installer 7.0.1 2022-02-10 21:29:28 +01:00
Alejandro Celaya
3b5cea5768 Updated changelog 2022-02-07 18:49:22 +01:00
Roy-Orbison
a89f67348d Optimise RewriteRules/Conds
From upstream changes on Mezzio Skeleton.

Closes #1369.
2022-02-07 18:45:27 +01:00
Alejandro Celaya
af1ae0399c Fixed merge conflicts 2022-02-04 18:03:29 +01:00
Alejandro Celaya
5bf84144e7 Tagged v3.0.1 in changelog 2022-02-04 17:53:29 +01:00
Alejandro Celaya
d9adff5749 Merge pull request #1368 from acelaya-forks/feature/stable-pdo-sqlsrv
Updated to stable pdo_sqlsrv in docker images
2022-02-03 22:17:07 +01:00
Alejandro Celaya
a1cd8baf3e Updated to stable pdo_sqlsrv in docker images 2022-02-03 22:03:20 +01:00
Alejandro Celaya
87cadce0ac Merge pull request #1366 from acelaya-forks/feature/fix-autoresolve-titles
Feature/fix autoresolve titles
2022-02-01 20:00:49 +01:00
Alejandro Celaya
f22f50afa2 Updated changelog 2022-02-01 19:46:36 +01:00
Alejandro Celaya
d0fa6f7e03 Added missing test covering URL validation with valid URL but title resolutio is disabled 2022-02-01 19:44:14 +01:00
Alejandro Celaya
d29c58dce5 Unified test:unit:pretty command 2022-02-01 19:25:18 +01:00
Alejandro Celaya
9ea8f3b590 Fixed URL validation still being true by default 2022-02-01 19:12:53 +01:00
Alejandro Celaya
ffffc68144 Updated readme 2022-02-01 07:36:44 +01:00
Alejandro Celaya
086de9f2a0 Merge pull request #1362 from acelaya-forks/feature/deprecate-webhooks
Deprecated webhooks
2022-01-31 12:41:44 +01:00
Alejandro Celaya
1b731aa4a3 Deprecated webhooks 2022-01-31 12:30:29 +01:00
Alejandro Celaya
12913f6b90 Merge pull request #1360 from acelaya-forks/feature/hide-db-commands
Marked database commands as hidden
2022-01-30 13:04:10 +01:00
Alejandro Celaya
1d4186392c Marked database commands as hidden 2022-01-30 12:15:53 +01:00
Alejandro Celaya
48d3ab0cb4 Changed file name used for inlined OAS 2022-01-30 09:37:57 +01:00
Alejandro Celaya
a9d04729eb Merge pull request #1351 from shlinkio/develop
Release 3.0.0
2022-01-28 16:31:55 +01:00
Alejandro Celaya
7adf2292bd Merge pull request #1353 from acelaya-forks/feature/profiling
Feature/profiling
2022-01-28 16:12:27 +01:00
Alejandro Celaya
c8f55f9c05 Added release date for Shlink 3.0.0 2022-01-28 16:00:40 +01:00
Alejandro Celaya
93de62f81d Fixed typo in UPGRADE.md 2022-01-28 13:06:56 +01:00
Alejandro Celaya
9766231d41 Added v3.0.0 to changelog 2022-01-27 20:59:05 +01:00
Alejandro Celaya
9df80e5bec Added explicit versions for shlink dependencies 2022-01-27 20:56:52 +01:00
Alejandro Celaya
81b00e4302 Merge branch 'develop' into feature/profiling 2022-01-27 20:20:15 +01:00
Alejandro Celaya
25ac7c31c4 Minor doc improvements 2022-01-25 20:39:31 +01:00
Alejandro Celaya
11c6c9a2b8 Removed unneeded lines 2022-01-23 18:17:39 +01:00
Alejandro Celaya
066268765a Fixed merge conflicts 2022-01-23 18:17:13 +01:00
Alejandro Celaya
356b33ced0 Merge pull request #1350 from acelaya-forks/feature/fix-memory-leak
Updated to shlink-common 4.4, which no longer uses doctrine/cache
2022-01-23 18:14:00 +01:00
Alejandro Celaya
77088d55f9 Updated to shlink-common 4.4, which no longer uses doctrine/cache 2022-01-23 17:54:49 +01:00
Alejandro Celaya
8d965655a8 Merge pull request #1348 from acelaya-forks/feature/drop-swoole-support
Feature/drop swoole support
2022-01-23 11:52:19 +01:00
Alejandro Celaya
3ace4952e6 Changed swoole with openswoole in issue templates 2022-01-23 11:37:46 +01:00
Alejandro Celaya
299f9f3a10 Documented support on swoole being dropped 2022-01-23 11:36:05 +01:00
Alejandro Celaya
0e6790cdab Replaced references to regular swoole by openswoole 2022-01-23 11:29:53 +01:00
Alejandro Celaya
1f90af3aec Merge pull request #1345 from acelaya-forks/feature/extended-tags-ordering
Feature/extended tags ordering
2022-01-23 11:08:02 +01:00
Alejandro Celaya
cdb18a5baf Documented performance issue when sorting by visits or short URLs count 2022-01-23 10:48:38 +01:00
Alejandro Celaya
8adb6596fb Refactored TagInfo to wrap the raw tag name instead of a Tag entity 2022-01-23 09:37:02 +01:00
Alejandro Celaya
dd6bcd68cc Removed not-needed extra line 2022-01-22 20:36:50 +01:00
Alejandro Celaya
1c9ce0ede0 Fixed default/fallback tags with stats ordering 2022-01-21 22:22:55 +01:00
Alejandro Celaya
6b409b06cc Simplified TagRepository test for tags info list, making it more predictable 2022-01-21 22:04:53 +01:00
Alejandro Celaya
361e864415 Added fallback ordering to tags list 2022-01-21 20:12:16 +01:00
Alejandro Celaya
d5606114cd Documented new ordering fields supported on tags list 2022-01-21 20:02:52 +01:00
Alejandro Celaya
afca66d655 Added tests covering tags info with counted ordering and limit 2022-01-21 19:58:56 +01:00
Alejandro Celaya
33a6c9fda7 Added support to order tags with stats by short URLs or visits count. In a non-performant way 2022-01-21 19:52:25 +01:00
Alejandro Celaya
a198484ab6 Updated test utils lib 2022-01-21 19:21:30 +01:00
Alejandro Celaya
dd5bce9694 Merge pull request #1344 from acelaya-forks/feature/strinct-env-vars
Feature/strinct env vars
2022-01-20 21:08:33 +01:00
Alejandro Celaya
bef17ff76d Fixed inverted condition when determining locks 2022-01-20 20:56:38 +01:00
Alejandro Celaya
7202605fc8 Created EnvVarsTest 2022-01-20 20:40:34 +01:00
Alejandro Celaya
747dac531d Added a more strict way to handle valid and expected env vars 2022-01-20 20:16:37 +01:00
Alejandro Celaya
07d24f70e1 Merge pull request #1343 from acelaya-forks/feature/inline-specs-improvements
Feature/inline specs improvements
2022-01-18 20:27:02 +01:00
Alejandro Celaya
d0546a2ea2 Split spec to join ApiKey spec with short URLs, into inlined and regular versions 2022-01-18 20:14:24 +01:00
Alejandro Celaya
9e9621e7b2 Standardized how inlined or regular specs are applied to query builders 2022-01-18 20:06:32 +01:00
Alejandro Celaya
d39f3b4265 Enhanced TagRepositoryTest and replaced inlined quoting by doctrine connection quoting 2022-01-18 19:50:48 +01:00
Alejandro Celaya
223339cd61 Merge pull request #1337 from acelaya-forks/feature/short-urls-filtering
Feature/short urls filtering
2022-01-17 20:33:40 +01:00
Alejandro Celaya
dc430bae10 Refactored method in ShortUrlsRepository 2022-01-17 20:21:35 +01:00
Alejandro Celaya
661b07e12f Refactored ShortUrlRepository to wrap args into DTOs 2022-01-17 20:10:41 +01:00
Alejandro Celaya
0727c7bdfb Updated readme file 2022-01-17 19:12:50 +01:00
Alejandro Celaya
b4c52116b4 Enabled stryker report for infection 2022-01-17 07:41:33 +01:00
Alejandro Celaya
89dc6108b7 Merge pull request #1334 from acelaya-forks/feature/tackle-todos
Feature/tackle todos
2022-01-16 16:06:21 +01:00
Alejandro Celaya
492eba3a8b Fixed duplicated slashes generated in path when doing not-found redirects with placeholders 2022-01-16 15:54:22 +01:00
Alejandro Celaya
77fee1390f Renamed class to a more appropriate name 2022-01-16 15:41:20 +01:00
Alejandro Celaya
bfb54189b8 Moved some config to the proper namespace, now that config is no longer part of the public contract 2022-01-16 15:34:13 +01:00
Alejandro Celaya
fb43885d85 Merge pull request #1333 from acelaya-forks/feature/all-visits-endpoint
Feature/all visits endpoint
2022-01-16 12:49:01 +01:00
Alejandro Celaya
7c1f705e64 Created NonOrphanVisitsPaginatorAdapter test 2022-01-16 12:29:36 +01:00
Alejandro Celaya
fe1fa7689a Created endpoint to list non-orphan visits 2022-01-16 12:24:02 +01:00
Alejandro Celaya
8b79eee081 Updated changelog 2022-01-16 12:08:11 +01:00
Alejandro Celaya
4a3e04ced9 Added tests covering count non orphan visits with different combinations of filters 2022-01-16 11:44:12 +01:00
Alejandro Celaya
61618250ec Renamed countVisits to countNonOrphanVisits, and updated its signature to expect a VisitsCountFiltering DTO 2022-01-16 11:15:39 +01:00
Alejandro Celaya
60c0ca3ae5 Changed VisitsCountFiltering and VisitsListFiltering so that they encapsulate an ApiKey instead of a Spec 2022-01-16 10:56:37 +01:00
Alejandro Celaya
3436405c55 Merge branch 'develop' into feature/all-visits-endpoint 2022-01-16 10:23:22 +01:00
Alejandro Celaya
d43c3ec865 Merge pull request #1326 from acelaya-forks/feature/high-priority-env-vars
Feature/high priority env vars
2022-01-15 17:46:03 +01:00
Alejandro Celaya
545da96d15 Updated env vars ADR 2022-01-15 17:21:36 +01:00
Alejandro Celaya
f53305c404 Added ADR for the changes to load env vars on top of installer config 2022-01-15 17:17:22 +01:00
Alejandro Celaya
199d976e3d Updated changelog and upgrading doc 2022-01-15 16:55:57 +01:00
Alejandro Celaya
a1366f0ef1 Exposed port 8888 on php container for experimentation 2022-01-15 16:52:48 +01:00
Alejandro Celaya
91192a8a8f Updated to latest shlink-installer and shlink-config, ensuring env vars are properly loaded 2022-01-15 16:06:24 +01:00
Alejandro Celaya
c6f16b0558 Updated to latest installer with support for env vars 2022-01-15 11:34:17 +01:00
Alejandro Celaya
0d37eb65c9 Used PhpFileProvider to load installer generated config 2022-01-13 17:11:23 +01:00
Alejandro Celaya
f7e3a74794 Merge pull request #1323 from acelaya-forks/feature/doctrine-2.11
Updated to doctrine 2.11
2022-01-12 21:03:02 +01:00
Alejandro Celaya
976b07cd61 Updated to doctrine 2.11 2022-01-12 20:48:42 +01:00
Alejandro Celaya
cff9cd5fb8 Documented endpoint to get all non-orphan visits 2022-01-10 22:23:00 +01:00
Alejandro Celaya
f0fd947046 Moved existing paginator adapters that are related with visits to the Visits namespace 2022-01-10 22:16:33 +01:00
Alejandro Celaya
7f4ada9c4b Created method in VisitRepository to fetch all non-orphan visits 2022-01-10 21:43:32 +01:00
Alejandro Celaya
db4ef328b1 Renamed some visits paginator adapters for consistency 2022-01-10 20:26:33 +01:00
Alejandro Celaya
b438802e71 Merge pull request #1321 from acelaya-forks/feature/update-docker-deps
Feature/update docker deps
2022-01-10 17:30:34 +01:00
Alejandro Celaya
632a19ceeb Updated changelog 2022-01-10 17:12:09 +01:00
Alejandro Celaya
629f8ece7a Updated to latest docker images and openswoole 2022-01-10 17:10:36 +01:00
Alejandro Celaya
9215f9beb5 Merge pull request #1320 from acelaya-forks/feature/infection-update
Updated to infection 0.26
2022-01-10 15:37:05 +01:00
Alejandro Celaya
154431e86c Updated to infection 0.26 2022-01-10 15:15:16 +01:00
Alejandro Celaya
8cfb14198b Merge pull request #1319 from acelaya-forks/feature/emoji-support
Feature/emoji support
2022-01-10 14:51:13 +01:00
Alejandro Celaya
2ed475fc76 Ensure database fields are created with proper charset and collation in MySQL 2022-01-10 14:37:44 +01:00
Alejandro Celaya
34512da2fb Fixed indentation 2022-01-10 13:21:12 +01:00
Alejandro Celaya
5b3c6f7752 Fixed charset in local entity manager config 2022-01-10 13:09:24 +01:00
Alejandro Celaya
f4dd27ca3f Updated changelog 2022-01-10 13:05:40 +01:00
Alejandro Celaya
ce47d8c591 Added full support for emojis 2022-01-10 13:04:16 +01:00
Alejandro Celaya
b941ee9aa9 Removed usage of deprecated methods from migrations 2022-01-10 12:05:01 +01:00
Alejandro Celaya
45de3f0128 Ensured emojis in short URLs are not URL-encoded 2022-01-10 11:13:16 +01:00
Alejandro Celaya
41d3826c1a Ensured bars are replaced by dashes in custom slugs 2022-01-10 10:43:20 +01:00
Alejandro Celaya
f2ff6e6a70 Merge pull request #1318 from acelaya-forks/feature/custom-slug-simplification
Simplified how the custom slugs are processed, allowing more characte…
2022-01-10 10:28:17 +01:00
Alejandro Celaya
e47c90c645 Simplified how the custom slugs are processed, allowing more characters in the process 2022-01-09 21:02:23 +01:00
Alejandro Celaya
d2fef20239 Merge pull request #1317 from acelaya-forks/feature/tag-stats-endpoint
Feature/tag stats endpoint
2022-01-09 18:02:03 +01:00
Alejandro Celaya
3b359cfc4f Reduced amount of duplicated code in API tests 2022-01-09 17:47:19 +01:00
Alejandro Celaya
acfc5a4676 Updated changelog 2022-01-09 17:38:45 +01:00
Alejandro Celaya
a6b1647f27 Created TagStatsActionTest 2022-01-09 17:37:00 +01:00
Alejandro Celaya
d5851bbb6a Created TagsStats endpoint 2022-01-09 17:24:07 +01:00
Alejandro Celaya
397bbe2655 Merge pull request #1316 from acelaya-forks/feature/tags-ordering
Feature/tags ordering
2022-01-09 14:10:34 +01:00
Alejandro Celaya
95d8d3ef72 Added ordering by name support for tags list with stats 2022-01-09 13:38:59 +01:00
Alejandro Celaya
1b51a1aedd Added ordering support for tags list when not requesting stats 2022-01-09 13:31:08 +01:00
Alejandro Celaya
ff75b3cd1f Enhanced test covering list short URLs with invalid params 2022-01-09 11:28:32 +01:00
Alejandro Celaya
2abcaf02e2 Standardized ordering field handling and added validation for short URLs list 2022-01-09 11:23:27 +01:00
Alejandro Celaya
d0c9f5a776 Fixed merge conflicts 2022-01-08 17:40:49 +01:00
Alejandro Celaya
a46d510e2b Merge pull request #1314 from acelaya-forks/feature/paginated-tags-performance
Feature/paginated tags performance
2022-01-08 17:37:01 +01:00
Alejandro Celaya
2d861b4077 Improved performance when loading paginated tags, by using an ugly compound of native queries and DQL 2022-01-08 17:25:09 +01:00
Alejandro Celaya
470c62d993 Merge pull request #1313 from acelaya-forks/feature/redis-memory-usage
Added a default lifetime for cache entries when using redis
2022-01-07 21:50:31 +01:00
Alejandro Celaya
364734094b Added a default lifetime for cache entries when using redis 2022-01-07 21:37:24 +01:00
Alejandro Celaya
a667c957ee Added Twitter follow badge to readme 2022-01-07 16:15:47 +01:00
Alejandro Celaya
dc648b0142 Merge pull request #1311 from acelaya-forks/feature/ip-in-logs
Ensured remote IP address is not logged when using swoole/openswoole
2022-01-07 14:44:19 +01:00
Alejandro Celaya
1d14140986 Ensured remote IP address is not logged when using swoole/openswoole 2022-01-07 14:30:06 +01:00
Alejandro Celaya
2b693dc492 Merge pull request #1310 from acelaya-forks/feature/title-max-length
Feature/title max length
2022-01-07 14:24:58 +01:00
Alejandro Celaya
38bea6c086 Added edge case tests for SHortUrlMetaTest on title field 2022-01-07 14:07:07 +01:00
Alejandro Celaya
cbdc5f121e Updated changelog 2022-01-07 14:04:21 +01:00
Alejandro Celaya
562763199a Ensured URL titles are trimmed to avoid error when persisted in database 2022-01-07 13:13:45 +01:00
Alejandro Celaya
107c09604a Fixed performance issues on list tags endpoint when requesting it with stats 2022-01-06 19:01:00 +01:00
Alejandro Celaya
2b0567b368 Fixed typo 2022-01-06 18:35:50 +01:00
Alejandro Celaya
d00a56bec0 Fixed query to count tags when a search term is present 2022-01-06 12:22:05 +01:00
Alejandro Celaya
ead8cc6cec Merge pull request #1302 from acelaya-forks/feature/paginated-tags
Feature/paginated tags
2022-01-06 11:54:30 +01:00
Alejandro Celaya
806ff9daaf Updated changelog 2022-01-06 11:40:20 +01:00
Alejandro Celaya
b3863a3e10 Improved TagServiceTest, covering tagsInfo method with params 2022-01-06 11:36:08 +01:00
Alejandro Celaya
5559107776 Changed namespace for database tests to ShlinkioDbTest 2022-01-06 11:01:21 +01:00
Alejandro Celaya
af1cf806f0 Created tag paginator adapter tests 2022-01-06 10:55:57 +01:00
Alejandro Celaya
0cf33c6119 Added DB test for TagsPaginator 2022-01-06 10:35:01 +01:00
Alejandro Celaya
b38b8a3365 Extended TagRepositoryTest, covering filterings on tags 2022-01-06 10:13:37 +01:00
Alejandro Celaya
e998c8434d Extracted tags filtering params to a DTO 2022-01-06 09:50:43 +01:00
Alejandro Celaya
4b90cf93d3 Created DB-level paginator for tags with stats 2022-01-05 23:44:14 +01:00
Alejandro Celaya
3dd4e33758 Created DB-level paginator for tags without stats 2022-01-05 23:30:35 +01:00
Alejandro Celaya
6caeb11598 Added output logs for swoole during API tests 2022-01-05 22:14:09 +01:00
Alejandro Celaya
11a383b7e5 Extracted common logic from TagService to a private method 2022-01-05 19:25:50 +01:00
Alejandro Celaya
fd2a2530b1 Documented pagination for tags endpoint 2022-01-05 19:21:32 +01:00
Alejandro Celaya
2f42b2d072 Added API tests covering pagination for tags 2022-01-05 19:16:49 +01:00
Alejandro Celaya
775f58f972 Added support for pagination in tags lists 2022-01-05 19:12:08 +01:00
Alejandro Celaya
5c0abb3d96 Created TagsParams class 2022-01-05 18:19:29 +01:00
Alejandro Celaya
3dc46bc5a3 Updated to latest shlink-common and shlink-config 2022-01-05 17:46:38 +01:00
Alejandro Celaya
e2871fc048 Merge pull request #1301 from acelaya-forks/feature/desc-default-order
Changed default ordering of short URLs, returning newest first
2022-01-05 15:15:44 +01:00
Alejandro Celaya
44e3f9b49f Changed default ordering of short URLs, returning newest first 2022-01-05 14:10:24 +01:00
Alejandro Celaya
d3f4263639 Merge pull request #1298 from acelaya-forks/feature/filter-all-tags
Feature/filter all tags
2022-01-04 14:59:22 +01:00
Alejandro Celaya
9dec05f62d Added API test covering invalid tagsMode 2022-01-04 14:42:31 +01:00
Alejandro Celaya
0447aa07fa Added more API tests covering the new tagsMode param on short URLs list 2022-01-04 14:34:31 +01:00
Alejandro Celaya
0e25af790d Updated changelog 2022-01-04 14:28:00 +01:00
Alejandro Celaya
d8484e777f Added logic to actually filter short URLs by any tag or all tags 2022-01-04 14:23:21 +01:00
Alejandro Celaya
665a3dbcbf Documented tagsMode param for short URLs list 2022-01-04 12:22:36 +01:00
Alejandro Celaya
103af2e2c1 Added support for a new tagsMode param when listing short URLs 2022-01-04 12:11:47 +01:00
Alejandro Celaya
d0daeb0078 Merge pull request #1297 from acelaya-forks/feature/docker-image-size
Feature/docker image size
2022-01-03 19:49:12 +01:00
Alejandro Celaya
a9aa49c2e5 Updated changelog 2022-01-03 19:37:05 +01:00
Alejandro Celaya
aad24389a7 Slightly reduced docker image size by merging mssql and openswoole installation steps 2022-01-03 19:34:36 +01:00
Alejandro Celaya
4b4f6f3201 Removed gmp extension as bcmath does the same 2022-01-03 19:10:58 +01:00
Alejandro Celaya
81f82d3b73 Reduced docker image size by ensuring dev native libs are not included in final image 2022-01-03 18:48:08 +01:00
Alejandro Celaya
4103ccf791 Merge pull request #1292 from acelaya-forks/feature/simplify-matches
Simplified some match expressions
2022-01-01 21:15:45 +01:00
Alejandro Celaya
e2ed11f960 Updated installer 2022-01-01 18:43:41 +01:00
Alejandro Celaya
8e1cd67a3d Simplified some match expressions 2022-01-01 18:40:48 +01:00
Alejandro Celaya
18b4caa55e Fixed merge conflicts 2021-12-21 14:48:06 +01:00
Alejandro Celaya
5e781a9010 Merge pull request #1284 from acelaya-forks/feature/visits-threshold-change
Feature/visits threshold change
2021-12-19 09:41:34 +01:00
Alejandro Celaya
277d817429 Removed API test which is no longer relevant 2021-12-18 18:41:11 +01:00
Alejandro Celaya
970f202757 Updated changelog 2021-12-18 18:26:27 +01:00
Alejandro Celaya
2c6b2b47a4 Updated installer 2021-12-18 18:23:27 +01:00
Alejandro Celaya
5c8be4b21f Updated logic to handle visits threshold env var so that it is disabled if not provided 2021-12-18 18:18:30 +01:00
Alejandro Celaya
558a4a2b30 Merge pull request #1281 from acelaya-forks/feature/update-deps
Updated dependencies
2021-12-16 22:08:17 +01:00
Alejandro Celaya
203ad7d594 Updated dependencies 2021-12-16 21:46:52 +01:00
Alejandro Celaya
04cf1aed9c Merge pull request #1279 from acelaya-forks/feature/remove-deprecated-stuff
Feature/remove deprecated stuff
2021-12-14 23:02:38 +01:00
Alejandro Celaya
8c14526f85 Fixed tests and updated changelog 2021-12-14 22:30:09 +01:00
Alejandro Celaya
1ff241411b Removed everything that was deprecated 2021-12-14 22:21:53 +01:00
756 changed files with 23794 additions and 13625 deletions

View File

@@ -1,3 +1,4 @@
bin/rr
config/autoload/*local*
data/infra
data/cache/*
@@ -9,6 +10,7 @@ data/GeoLite2-City*
data/database.sqlite
data/shlink-tests.db
CHANGELOG.md
CONTRIBUTING.md
UPGRADE.md
composer.lock
vendor
@@ -21,4 +23,4 @@ infection*
**/test*
build*
**/.*
bin/helper
!config/roadrunner/.rr.yml

View File

@@ -0,0 +1,51 @@
title: 'Help wanted'
body:
- type: input
validations:
required: true
attributes:
label: Shlink version
placeholder: x.y.z
- type: input
validations:
required: true
attributes:
label: PHP version
placeholder: x.y.z
- type: dropdown
validations:
required: true
attributes:
label: How do you serve Shlink
options:
- Self-hosted Apache
- Self-hosted nginx
- Self-hosted openswoole
- Self-hosted RoadRunner
- Openswoole Docker image
- RoadRunner Docker image
- Other (explain in summary)
- type: dropdown
validations:
required: true
attributes:
label: Database engine
options:
- MySQL
- MariaDB
- PostgreSQL
- MicrosoftSQL
- SQLite
- type: input
validations:
required: true
attributes:
label: Database version
placeholder: x.y.z
- type: textarea
validations:
required: true
attributes:
label: Summary
value: '<!-- Describe your issue, question or request here. -->'

View File

@@ -1,7 +1,7 @@
<!--
Before opening an issue, just take into account that this is a completely free of charge and open source project.
I'm always happy to help and provide support, but some understanding will be expected.
I do this in my own free time, so expect some delays when implementing new features and fixing bugs, and don't take it personal if an issue gets eventually closed.
I do this in my own free time, so expect some delays when implementing new features and fixing bugs, and don't take it personally if an issue gets eventually closed.
You may also be asked to provide tests or ways to reproduce reported bugs.
Try to be polite, and understand it is impossible for an OSS project to cover all use cases.
-->

View File

@@ -1,38 +0,0 @@
---
name: Bug report
about: Something on shlink is broken or not working as documented?
labels: bug
---
<!--
Before opening an issue, just take into account that this is a completely free of charge and open source project.
I'm always happy to help and provide support, but some understanding will be expected.
I do this in my own free time, so expect some delays when implementing new features and fixing bugs, and don't take it personal if an issue gets eventually closed.
You may also be asked to provide tests or ways to reproduce reported bugs.
Try to be polite, and understand it is impossible for an OSS project to cover all use cases.
With that said, please fill in the information requested next. More information might be requested next (like logs or system configs).
-->
#### How Shlink is set-up
* Shlink Version: x.y.z
* PHP Version: x.y.z
* How do you serve Shlink: Self-hosted Apache|Self-hosted nginx|Self-hosted swoole|Docker image
* Database engine used: MySQL|MariaDB|PostgreSQL|MicrosoftSQL|SQLite (x.y.z)
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### Current behavior
<!-- How is it actually behaving (and it shouldn't)? -->
#### Expected behavior
<!-- How did you expected to behave? -->
#### How to reproduce
<!-- Provide steps to reproduce the bug. -->

64
.github/ISSUE_TEMPLATE/Bug.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Bug report
description: Something on Shlink is broken or not working as documented?
labels: ['bug']
body:
- type: input
validations:
required: true
attributes:
label: Shlink version
placeholder: x.y.z
- type: input
validations:
required: true
attributes:
label: PHP version
placeholder: x.y.z
- type: dropdown
validations:
required: true
attributes:
label: How do you serve Shlink
options:
- Self-hosted Apache
- Self-hosted nginx
- Self-hosted openswoole
- Self-hosted RoadRunner
- Openswoole Docker image
- RoadRunner Docker image
- Other (explain in summary)
- type: dropdown
validations:
required: true
attributes:
label: Database engine
options:
- MySQL
- MariaDB
- PostgreSQL
- MicrosoftSQL
- SQLite
- type: input
validations:
required: true
attributes:
label: Database version
placeholder: x.y.z
- type: textarea
validations:
required: true
attributes:
label: Current behavior
value: '<!-- How is it actually behaving (and it should not)? -->'
- type: textarea
validations:
required: true
attributes:
label: Expected behavior
value: '<!-- How did you expect it to behave? -->'
- type: textarea
validations:
required: true
attributes:
label: How to reproduce
value: '<!-- Provide steps to reproduce the bug. -->'

View File

@@ -1,19 +0,0 @@
---
name: Feature request
about: Do you find shlink is missing some important feature that would make it more useful?
labels: feature
---
<!--
Before opening an issue, just take into account that this is a completely free of charge and open source project.
I'm always happy to help and provide support, but some understanding will be expected.
I do this in my own free time, so expect some delays when implementing new features and fixing bugs, and don't take it personal if an issue gets eventually closed.
You may also be asked to provide tests or ways to reproduce reported bugs.
Try to be polite, and understand it is impossible for an OSS project to cover all use cases.
With that said, please fill in the information requested next. More information might be requested next (like logs or system configs).
-->
#### Summary
<!-- Describe the new feature you would like to request. -->

View File

@@ -0,0 +1,16 @@
name: Feature request
description: Do you find Shlink is missing some important feature that would make it more useful?
labels: ['feature']
body:
- type: textarea
validations:
required: true
attributes:
label: Summary
value: '<!-- Describe the new feature you would like to request. -->'
- type: textarea
validations:
required: true
attributes:
label: Use case
value: '<!-- Explain why do you think this feature would be useful, and what problems would it help to solve. -->'

View File

@@ -1,26 +0,0 @@
---
name: Question - Support
about: Do you have a problem setting up or using shlink?
labels: question
---
<!--
Before opening an issue, just take into account that this is a completely free of charge and open source project.
I'm always happy to help and provide support, but some understanding will be expected.
I do this in my own free time, so expect some delays when implementing new features and fixing bugs, and don't take it personal if an issue gets eventually closed.
You may also be asked to provide tests or ways to reproduce reported bugs.
Try to be polite, and understand it is impossible for an OSS project to cover all use cases.
With that said, please fill in the information requested next. More information might be requested next (like logs or system configs).
-->
#### How Shlink is set-up
* Shlink Version: x.y.z
* PHP Version: x.y.z
* How do you serve Shlink: Self-hosted Apache|Self-hosted nginx|Self-hosted swoole|Docker image
* Database engine used: MySQL|MariaDB|PostgreSQL|MicrosoftSQL|SQLite (x.y.z)
#### Summary
<!-- Describe the issue you are facing here. -->

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Question - Support
about: Do you need help setting up or using Shlink?
url: https://github.com/shlinkio/shlink/discussions/new?category=help-wanted

47
.github/actions/ci-setup/action.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: CI setup
description: 'Sets up the environment to run CI actions for Shlink'
inputs:
install-deps:
description: 'Tells if dependencies should be installed with composer. Default value is "yes"'
required: true
default: 'yes'
php-version:
description: 'The PHP version to be setup'
required: true
php-extensions:
description: 'The PHP extensions to install'
required: false
default: ''
extensions-cache-key:
description: 'The key used to cache PHP extensions. If empty value is provided, extension caching is disabled'
required: true
runs:
using: composite
steps:
- name: Setup cache environment
id: extcache
uses: shivammathur/cache-extensions@v1
with:
php-version: ${{ inputs.php-version }}
extensions: ${{ inputs.php-extensions }}
key: ${{ inputs.extensions-cache-key }}
- name: Cache extensions
uses: actions/cache@v3
with:
path: ${{ steps.extcache.outputs.dir }}
key: ${{ steps.extcache.outputs.key }}
restore-keys: ${{ steps.extcache.outputs.key }}
- name: Use PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ inputs.php-version }}
tools: composer
extensions: ${{ inputs.php-extensions }}
coverage: pcov
ini-values: pcov.directory=module
- name: Install dependencies
if: ${{ inputs.install-deps == 'yes' }}
run: composer install --no-interaction --prefer-dist ${{ inputs.php-version == '8.3' && '--ignore-platform-reqs' || '' }}
shell: bash

45
.github/workflows/ci-db-tests.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Database tests
on:
workflow_call:
inputs:
platform:
type: string
required: true
description: One of sqlite:ci, mysql, maria, postgres or ms
jobs:
db-tests:
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.2', '8.3']
continue-on-error: ${{ matrix.php-version == '8.3' }}
env:
LC_ALL: C
steps:
- uses: actions/checkout@v4
- name: Install MSSQL ODBC
if: ${{ inputs.platform == 'ms' }}
run: sudo ./data/infra/ci/install-ms-odbc.sh
- name: Start database server
if: ${{ inputs.platform != 'sqlite:ci' }}
run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_${{ inputs.platform }}
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
php-extensions: openswoole-22.1.0, pdo_sqlsrv-5.11.1
extensions-cache-key: db-tests-extensions-${{ matrix.php-version }}-${{ inputs.platform }}
- name: Create test database
if: ${{ inputs.platform == 'ms' }}
run: docker-compose exec -T shlink_db_ms /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Passw0rd!' -Q "CREATE DATABASE shlink_test;"
- name: Run tests
run: composer test:db:${{ inputs.platform }}
- name: Upload code coverage
uses: actions/upload-artifact@v4
if: ${{ matrix.php-version == '8.2' && inputs.platform == 'sqlite:ci' }}
with:
name: coverage-db
path: |
build/coverage-db
build/coverage-db.cov

View File

@@ -0,0 +1,14 @@
name: Build docker image
on:
pull_request:
paths:
- 'Dockerfile'
jobs:
build-docker-image:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- run: docker build -t shlink-docker-image:temp .

46
.github/workflows/ci-mutation-tests.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: Mutation tests
on:
workflow_call:
inputs:
test-group:
type: string
required: true
description: One of unit, db, api or cli
jobs:
mutation-tests:
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.2', '8.3']
continue-on-error: ${{ matrix.php-version == '8.3' }}
steps:
- uses: actions/checkout@v4
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
php-extensions: openswoole-22.1.0
extensions-cache-key: mutation-tests-extensions-${{ matrix.php-version }}-${{ inputs.test-group }}
- uses: actions/download-artifact@v4
with:
name: coverage-${{ inputs.test-group }}
path: build
- name: Resolve infection args
id: infection_args
run: echo "args=--logger-github=false" >> $GITHUB_OUTPUT
# TODO Try to filter mutation tests to improve execution times. Investigate why --git-diff-lines --git-diff-base=develop does not work
# run: |
# BRANCH="${GITHUB_REF#refs/heads/}" |
# if [[ $BRANCH == 'main' || $BRANCH == 'develop' ]]; then
# echo "args=--logger-github=false" >> $GITHUB_OUTPUT
# else
# echo "args=--logger-github=false --git-diff-lines --git-diff-base=develop" >> $GITHUB_OUTPUT
# fi;
shell: bash
- if: ${{ inputs.test-group == 'unit' }}
run: composer infect:ci:unit -- ${{ steps.infection_args.outputs.args }}
env:
INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }}
- if: ${{ inputs.test-group != 'unit' }}
run: composer infect:ci:${{ inputs.test-group }} -- ${{ steps.infection_args.outputs.args }}

38
.github/workflows/ci-tests.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Tests
on:
workflow_call:
inputs:
test-group:
type: string
required: true
description: One of unit, api or cli
jobs:
tests:
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.2', '8.3']
continue-on-error: ${{ matrix.php-version == '8.3' }}
steps:
- uses: actions/checkout@v4
- name: Start postgres database server
if: ${{ inputs.test-group == 'api' }}
run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_postgres
- name: Start maria database server
if: ${{ inputs.test-group == 'cli' }}
run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_maria
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
php-extensions: openswoole-22.1.0
extensions-cache-key: tests-extensions-${{ matrix.php-version }}-${{ inputs.test-group }}
- run: composer test:${{ inputs.test-group }}:ci
- uses: actions/upload-artifact@v4
if: ${{ matrix.php-version == '8.2' }}
with:
name: coverage-${{ inputs.test-group }}
path: |
build/coverage-${{ inputs.test-group }}
build/coverage-${{ inputs.test-group }}.cov

View File

@@ -1,158 +1,160 @@
name: Continuous integration
on:
pull_request: null
pull_request:
paths-ignore:
- 'LICENSE'
- '.*'
- '*.md'
- '*.xml'
- '*.yml*'
- '*.json5'
- '*.neon'
push:
branches:
- main
- develop
- 2.x
paths-ignore:
- 'LICENSE'
- '.*'
- '*.md'
- '*.xml'
- '*.yml*'
- '*.json5'
- '*.neon'
jobs:
static-analysis:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.0']
php-version: ['8.2']
command: ['cs', 'stan', 'swagger:validate']
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Use PHP
uses: shivammathur/setup-php@v2
- uses: actions/checkout@v4
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1
coverage: none
- run: composer install --no-interaction --prefer-dist
php-extensions: openswoole-22.1.0
extensions-cache-key: tests-extensions-${{ matrix.php-version }}-${{ matrix.command }}
- run: composer ${{ matrix.command }}
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
php-version: ['8.0', '8.1']
test-group: ['unit', 'api']
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Start database server
if: ${{ matrix.test-group == 'api' }}
run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_postgres
- name: Use PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1
coverage: pcov
ini-values: pcov.directory=module
- run: composer install --no-interaction --prefer-dist
- run: composer test:${{ matrix.test-group }}:ci
- uses: actions/upload-artifact@v2
if: ${{ matrix.php-version == '8.0' }}
with:
name: coverage-${{ matrix.test-group }}
path: |
build/coverage-${{ matrix.test-group }}
build/coverage-${{ matrix.test-group }}.cov
unit-tests:
uses: './.github/workflows/ci-tests.yml'
with:
test-group: unit
db-tests:
runs-on: ubuntu-20.04
cli-tests:
uses: './.github/workflows/ci-tests.yml'
with:
test-group: cli
openswoole-api-tests:
uses: './.github/workflows/ci-tests.yml'
with:
test-group: api
roadrunner-api-tests:
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.0', '8.1']
platform: ['sqlite:ci', 'mysql', 'maria', 'postgres', 'ms']
php-version: ['8.2', '8.3']
continue-on-error: ${{ matrix.php-version == '8.3' }}
env:
LC_ALL: C
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # rr get-binary picks this env automatically
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install MSSQL ODBC
if: ${{ matrix.platform == 'ms' }}
run: sudo ./data/infra/ci/install-ms-odbc.sh
- name: Start database server
if: ${{ matrix.platform != 'sqlite:ci' }}
run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_${{ matrix.platform }}
- name: Use PHP
uses: shivammathur/setup-php@v2
- uses: actions/checkout@v4
- run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_postgres
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1, pdo_sqlsrv-5.10.0beta2
coverage: pcov
ini-values: pcov.directory=module
- run: composer install --no-interaction --prefer-dist
- name: Create test database
if: ${{ matrix.platform == 'ms' }}
run: docker-compose exec -T shlink_db_ms /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'Passw0rd!' -Q "CREATE DATABASE shlink_test;"
- name: Run tests
run: composer test:db:${{ matrix.platform }}
- name: Upload code coverage
uses: actions/upload-artifact@v2
if: ${{ matrix.php-version == '8.0' && matrix.platform == 'sqlite:ci' }}
with:
name: coverage-db
path: |
build/coverage-db
build/coverage-db.cov
- run: composer install --no-interaction --prefer-dist --ignore-platform-req=ext-openswoole ${{ matrix.php-version == '8.3' && '--ignore-platform-reqs' || '' }}
- run: ./vendor/bin/rr get --no-interaction --no-config --location bin/ && chmod +x bin/rr
- run: composer test:api:rr
mutation-tests:
sqlite-db-tests:
uses: './.github/workflows/ci-db-tests.yml'
with:
platform: 'sqlite:ci'
mysql-db-tests:
uses: './.github/workflows/ci-db-tests.yml'
with:
platform: 'mysql'
maria-db-tests:
uses: './.github/workflows/ci-db-tests.yml'
with:
platform: 'maria'
postgres-db-tests:
uses: './.github/workflows/ci-db-tests.yml'
with:
platform: 'postgres'
ms-db-tests:
uses: './.github/workflows/ci-db-tests.yml'
with:
platform: 'ms'
unit-mutation-tests:
needs:
- tests
- db-tests
runs-on: ubuntu-20.04
strategy:
matrix:
php-version: ['8.0', '8.1']
test-group: ['unit', 'db', 'api']
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Use PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1
coverage: pcov
ini-values: pcov.directory=module
- run: composer install --no-interaction --prefer-dist
- uses: actions/download-artifact@v2
with:
path: build
- if: ${{ matrix.test-group == 'unit' }}
run: composer infect:ci:unit
env:
INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }}
- if: ${{ matrix.test-group != 'unit' }}
run: composer infect:ci:${{ matrix.test-group }}
- unit-tests
uses: './.github/workflows/ci-mutation-tests.yml'
with:
test-group: unit
db-mutation-tests:
needs:
- sqlite-db-tests
uses: './.github/workflows/ci-mutation-tests.yml'
with:
test-group: db
api-mutation-tests:
needs:
- openswoole-api-tests
uses: './.github/workflows/ci-mutation-tests.yml'
with:
test-group: api
cli-mutation-tests:
needs:
- cli-tests
uses: './.github/workflows/ci-mutation-tests.yml'
with:
test-group: cli
upload-coverage:
needs:
- tests
- db-tests
runs-on: ubuntu-20.04
- unit-tests
- openswoole-api-tests
- cli-tests
- sqlite-db-tests
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.0']
php-version: ['8.2']
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Use PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: pcov
ini-values: pcov.directory=module
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v4
with:
path: build
- run: mv build/coverage-unit/coverage-unit.cov build/coverage-unit.cov
- run: mv build/coverage-db/coverage-db.cov build/coverage-db.cov
- run: mv build/coverage-api/coverage-api.cov build/coverage-api.cov
- run: wget https://phar.phpunit.de/phpcov-8.2.0.phar
- run: php phpcov-8.2.0.phar merge build --clover build/clover.xml
- run: mv build/coverage-cli/coverage-cli.cov build/coverage-cli.cov
- run: wget https://phar.phpunit.de/phpcov-9.0.0.phar
- run: php phpcov-9.0.0.phar merge build --clover build/clover.xml
- name: Publish coverage
uses: codecov/codecov-action@v1
with:
@@ -160,29 +162,14 @@ jobs:
delete-artifacts:
needs:
- mutation-tests
- unit-mutation-tests
- db-mutation-tests
- api-mutation-tests
- cli-mutation-tests
- upload-coverage
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: geekyeggo/delete-artifact@v1
- uses: geekyeggo/delete-artifact@v2
with:
name: |
coverage-unit
coverage-db
coverage-api
build-docker-image:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 100
- uses: marceloprado/has-changed-path@v1
id: changed-dockerfile
with:
paths: ./Dockerfile
- if: ${{ steps.changed-dockerfile.outputs.changed == 'true' }}
run: docker build -t shlink-docker-image:temp .
- if: ${{ steps.changed-dockerfile.outputs.changed != 'true' }}
run: echo "Dockerfile didn't change. Skipped"
coverage-*

View File

@@ -1,28 +0,0 @@
name: Build docker image
on:
push:
branches:
- develop
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
- name: Login to docker hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build the image
run: bash ./docker/build

View File

@@ -0,0 +1,34 @@
name: Build and publish docker image
on:
push:
tags:
- 'v*'
jobs:
build-image:
strategy:
matrix:
include:
- runtime: 'rr'
platforms: 'linux/arm64/v8,linux/amd64'
- runtime: 'rr'
tag-suffix: 'roadrunner'
platforms: 'linux/arm64/v8,linux/amd64'
- runtime: 'openswoole'
tag-suffix: 'openswoole'
platforms: 'linux/arm/v7,linux/arm64/v8,linux/amd64'
- runtime: 'rr'
tag-suffix: 'non-root'
platforms: 'linux/arm64/v8,linux/amd64'
user-id: '1001'
uses: shlinkio/github-actions/.github/workflows/docker-build-and-publish.yml@main
secrets: inherit
with:
image-name: shlinkio/shlink
version-arg-name: SHLINK_VERSION
platforms: ${{ matrix.platforms }}
tags-suffix: ${{ matrix.tag-suffix }}
extra-build-args: |
SHLINK_RUNTIME=${{ matrix.runtime }}
SHLINK_USER_ID=${{ matrix.user-id && matrix.user-id || 'root' }}

View File

@@ -7,36 +7,34 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.0', '8.1']
php-version: ['8.2', '8.3']
swoole: ['yes', 'no']
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Use PHP
uses: shivammathur/setup-php@v2
- uses: actions/checkout@v4
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1
php-extensions: openswoole-22.1.0
extensions-cache-key: publish-swagger-spec-extensions-${{ matrix.php-version }}
install-deps: 'no'
- if: ${{ matrix.swoole == 'yes' }}
run: ./build.sh ${GITHUB_REF#refs/tags/v}
- if: ${{ matrix.swoole == 'no' }}
run: ./build.sh ${GITHUB_REF#refs/tags/v} --no-swoole
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: dist-files-${{ matrix.php-version }}-${{ matrix.swoole }}
path: build
publish:
needs: ['build']
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: actions/download-artifact@v2
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: build
- name: Publish release with assets
@@ -50,12 +48,8 @@ jobs:
delete-artifacts:
needs: ['publish']
runs-on: ubuntu-20.04
strategy:
matrix:
php-version: [ '8.0', '8.1' ]
swoole: [ 'yes', 'no' ]
runs-on: ubuntu-22.04
steps:
- uses: geekyeggo/delete-artifact@v1
- uses: geekyeggo/delete-artifact@v2
with:
name: dist-files-${{ matrix.php-version }}-${{ matrix.swoole }}
name: dist-files-*

View File

@@ -7,30 +7,26 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: ['8.0']
php-version: ['8.2']
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Determine version
id: determine_version
run: echo "::set-output name=version::${GITHUB_REF#refs/tags/}"
run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
shell: bash
- name: Use PHP
uses: shivammathur/setup-php@v2
- uses: './.github/actions/ci-setup'
with:
php-version: ${{ matrix.php-version }}
tools: composer
extensions: openswoole-4.8.1
coverage: none
- run: composer install --no-interaction --prefer-dist
php-extensions: openswoole-22.1.0
extensions-cache-key: publish-swagger-spec-extensions-${{ matrix.php-version }}
- run: composer swagger:inline
- run: mkdir ${{ steps.determine_version.outputs.version }}
- run: mv docs/swagger/swagger-inlined.json ${{ steps.determine_version.outputs.version }}/oas.json
- run: mv docs/swagger/swagger-inlined.json ${{ steps.determine_version.outputs.version }}/open-api-spec.json
- name: Publish spec
uses: JamesIves/github-pages-deploy-action@4.1.7
uses: JamesIves/github-pages-deploy-action@v4
with:
token: ${{ secrets.OAS_PUBLISH_TOKEN }}
repository-name: 'shlinkio/shlink-open-api-specs'

3
.gitignore vendored
View File

@@ -1,4 +1,6 @@
.idea
bin/rr
config/roadrunner/.pid
build
!docker/build
composer.lock
@@ -7,6 +9,7 @@ vendor/
data/database.sqlite
data/shlink-tests.db
data/GeoLite2-City.*
data/infra/matomo
docs/swagger-ui*
docs/mercure.html
docker-compose.override.yml

View File

@@ -4,6 +4,707 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
## [3.7.2] - 2023-12-26
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1960](https://github.com/shlinkio/shlink/issues/1960) Allow QR codes to be optionally resolved even when corresponding short URL is not enabled.
## [3.7.1] - 2023-12-17
### Added
* *Nothing*
### Changed
* Remove dependency on functional-php library
* [#1939](https://github.com/shlinkio/shlink/issues/1939) Fine-tune RoadRunner logs to avoid too many useless info.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1947](https://github.com/shlinkio/shlink/issues/1947) Fix error when importing short URLs while using Postgres.
## [3.7.0] - 2023-11-25
### Added
* [#1798](https://github.com/shlinkio/shlink/issues/1798) Experimental support to send visits to an external Matomo instance.
* [#1780](https://github.com/shlinkio/shlink/issues/1780) Add new `NO_ORPHAN_VISITS` API key role.
Keys with this role will always get `0` when fetching orphan visits.
When trying to delete orphan visits the result will also be `0` and no visits will actually get deleted.
* [#1879](https://github.com/shlinkio/shlink/issues/1879) Cache namespace can now be customized via config option or `CACHE_NAMESPACE` env var.
This is important if you are running multiple Shlink instance on the same server, or they share the same Redis instance (even more so if they are on different versions).
* [#1905](https://github.com/shlinkio/shlink/issues/1905) Add support for PHP 8.3.
* [#1927](https://github.com/shlinkio/shlink/issues/1927) Allow redis credentials be URL-decoded before passing them to connection.
* [#1834](https://github.com/shlinkio/shlink/issues/1834) Add support for redis encrypted connections using SSL/TLS.
Encryption should work out of the box if servers schema is set tp `tls` or `rediss`, including support for self-signed certificates.
This has been tested with AWS ElasticCache using in-transit encryption, and with Digital Ocean Redis database.
* [#1906](https://github.com/shlinkio/shlink/issues/1906) Add support for RabbitMQ encrypted connections using SSL/TLS.
In order to enable SLL, you need to pass `RABBITMQ_USE_SSL=true` or the corresponding config option.
Connections using self-signed certificates should work out of the box.
This has been tested with AWS RabbitMQ using in-transit encryption, and with CloudAMQP.
### Changed
* [#1799](https://github.com/shlinkio/shlink/issues/1799) RoadRunner/openswoole jobs are not run anymore for tasks that are actually disabled.
For example, if you did not enable RabbitMQ real-time updates, instead of triggering a job that ends immediately, the job will not even be enqueued.
* [#1835](https://github.com/shlinkio/shlink/issues/1835) Docker image is now built only when a release is tagged, and new tags are included, for minor and major versions.
* [#1055](https://github.com/shlinkio/shlink/issues/1055) Update OAS definition to v3.1.
* [#1885](https://github.com/shlinkio/shlink/issues/1885) Update to chronos 3.0.
* [#1896](https://github.com/shlinkio/shlink/issues/1896) Requests to health endpoint are no longer logged.
* [#1877](https://github.com/shlinkio/shlink/issues/1877) Print a warning when manually running `visit:download-db` command and a GeoLite2 license was not provided.
### Deprecated
* [#1783](https://github.com/shlinkio/shlink/issues/1783) Deprecated support for openswoole. RoadRunner is the best replacement, with the same capabilities, but much easier and convenient to install and manage.
### Removed
* [#1790](https://github.com/shlinkio/shlink/issues/1790) Drop support for PHP 8.1.
### Fixed
* [#1819](https://github.com/shlinkio/shlink/issues/1819) Fix incorrect timeout when running DB commands during Shlink start-up.
* [#1901](https://github.com/shlinkio/shlink/issues/1901) Do not allow short URLs with custom slugs containing URL-reserved characters, as they will not work at all afterward.
* [#1900](https://github.com/shlinkio/shlink/issues/1900) Fix short URL visits deletion when multi-segment slugs are enabled.
## [3.6.4] - 2023-09-23
### Added
* *Nothing*
### Changed
* [#1866](https://github.com/shlinkio/shlink/issues/1866) The `INITIAL_API_KEY` env var is now only relevant for the official docker image.
Going forward, new non-docker Shlink installations provisioned with env vars that also wish to provide an initial API key, should do it by using the `vendor/bin/shlink-installer init --initial-api-key=%SOME_KEY%` command, instead of using `INITIAL_API_KEY`.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1819](https://github.com/shlinkio/shlink/issues/1819) Fix incorrect timeout when running DB commands during Shlink start-up.
* [#1870](https://github.com/shlinkio/shlink/issues/1870) Make sure shared locks include the cache prefix when using Redis.
* [#1866](https://github.com/shlinkio/shlink/issues/1866) Fix error when starting docker image with `INITIAL_API_KEY` env var.
## [3.6.3] - 2023-06-14
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1817](https://github.com/shlinkio/shlink/issues/1817) Fix Shlink trying to create SQLite database tables even if they already exist.
## [3.6.2] - 2023-06-08
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1808](https://github.com/shlinkio/shlink/issues/1808) Fix `rr` binary downloading during Shlink update.
## [3.6.1] - 2023-06-04
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1413](https://github.com/shlinkio/shlink/issues/1413) Fix error when creating initial DB in Postgres in a cluster where a default `postgres` db does not exist or the credentials do not grant permissions to connect.
* [#1803](https://github.com/shlinkio/shlink/issues/1803) Fix default RoadRunner port when not using docker image.
## [3.6.0] - 2023-05-24
### Added
* [#1148](https://github.com/shlinkio/shlink/issues/1148) Add support to delete short URL visits.
This can be done via `DELETE /short-urls/{shortCode}/visits` REST endpoint or via `short-url:visits-delete` console command.
The CLI command includes a warning and requires the user to confirm before proceeding.
* [#1681](https://github.com/shlinkio/shlink/issues/1681) Add support to delete orphan visits.
This can be done via `DELETE /visits/orphan` REST endpoint or via `visit:orphan-delete` console command.
The CLI command includes a warning and requires the user to confirm before proceeding.
* [#1753](https://github.com/shlinkio/shlink/issues/1753) Add a new `vendor/bin/shlink-installer init` command that can be used to automate Shlink installations.
This command can create the initial database, update it, create proxies, clean cache, download initial GeoLite db files, etc
The official docker image also uses it on its entry point script.
* [#1656](https://github.com/shlinkio/shlink/issues/1656) Add support for openswoole 22
* [#1784](https://github.com/shlinkio/shlink/issues/1784) Add new docker tag where the container runs as a non-root user.
* [#953](https://github.com/shlinkio/shlink/issues/953) Add locks that prevent errors on duplicated keys when creating short URLs in parallel that depend on the same new tag or domain.
### Changed
* [#1755](https://github.com/shlinkio/shlink/issues/1755) Update to roadrunner 2023
* [#1745](https://github.com/shlinkio/shlink/issues/1745) Roadrunner is now the default docker runtime.
There are now three different docker images published:
* Versions without suffix (like `3.6.0`) will contain the default runtime, whichever it is.
* Versions with `-roadrunner` suffix (like `3.6.0-roadrunner`) will always use roadrunner as the runtime, even if default one changes in the future.
* Versions with `-openswoole` suffix (like `3.6.0-openswoole`) will always use openswoole as the runtime, even if default one changes in the future.
### Deprecated
* Deprecated `ENABLE_PERIODIC_VISIT_LOCATE` env var. Use an external mechanism to automate visit locations.
### Removed
* *Nothing*
### Fixed
* [#1760](https://github.com/shlinkio/shlink/issues/1760) Fix domain not being set to null when importing short URLs with default domain.
* [#953](https://github.com/shlinkio/shlink/issues/953) Fix duplicated key errors and short URL creation failing when creating short URLs in parallel that depend on the same new tag or domain.
* [#1741](https://github.com/shlinkio/shlink/issues/1741) Fix randomly using 100% CPU in task workers when trying to download GeoLite DB files.
* Fix Shlink trying to connect to RabbitMQ even if configuration set to not connect.
## [3.5.4] - 2023-04-12
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1742](https://github.com/shlinkio/shlink/issues/1742) Fix URLs using schemas which do not contain `//`, like `mailto:`, to no longer be considered valid.
* [#1743](https://github.com/shlinkio/shlink/issues/1743) Fix Error when trying to create short URLs from CLI on an openswoole context.
Unfortunately the reason are real-time updates do not work with openswoole when outside an openswoole request, so the feature has been disabled for that context.
## [3.5.3] - 2023-03-31
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1715](https://github.com/shlinkio/shlink/issues/1715) Fix short URL creation/edition allowing long URLs without schema. Now a validation error is thrown.
* [#1537](https://github.com/shlinkio/shlink/issues/1537) Fix incorrect list of tags being returned for some author-only API keys.
* [#1738](https://github.com/shlinkio/shlink/issues/1738) Fix memory leak when importing short URLs with many visits.
## [3.5.2] - 2023-02-16
### Added
* *Nothing*
### Changed
* [#1696](https://github.com/shlinkio/shlink/issues/1696) Migrated to PHPUnit 10.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1698](https://github.com/shlinkio/shlink/issues/1698) Fixed error 500 in `robots.txt`.
* [#1688](https://github.com/shlinkio/shlink/issues/1688) Fixed huge performance degradation on `/tags/stats` endpoint.
* [#1693](https://github.com/shlinkio/shlink/issues/1693) Fixed Shlink thinking database already exists if it finds foreign tables.
## [3.5.1] - 2023-02-04
### Added
* *Nothing*
### Changed
* [#1685](https://github.com/shlinkio/shlink/issues/1685) Changed `loosely` mode to `loose`, as it was a typo. The old one keeps working and maps to the new one, but it's considered deprecated.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1682](https://github.com/shlinkio/shlink/issues/1682) Fixed incorrect case-insensitive checks in short URLs when using Microsoft SQL server.
* [#1684](https://github.com/shlinkio/shlink/issues/1684) Fixed entities metadata cache not being cleared at docker container start-up when using redis with replication.
## [3.5.0] - 2023-01-28
### Added
* [#1557](https://github.com/shlinkio/shlink/issues/1557) Added support to dynamically redirect to different long URLs based on the visitor's device type.
For the moment, only `android`, `ios` and `desktop` can have their own specific long URL, and when the visitor cannot be matched against any of them, the regular long URL will be used.
In the future, more granular device types could be added if appropriate (iOS tablet, android table, tablet, mobile phone, Linux, Mac, Windows, etc).
In order to match the visitor's device, the `User-Agent` header is used.
* [#1632](https://github.com/shlinkio/shlink/issues/1632) Added amount of bots, non-bots and total visits to the visits summary endpoint.
* [#1633](https://github.com/shlinkio/shlink/issues/1633) Added amount of bots, non-bots and total visits to the tag stats endpoint.
* [#1653](https://github.com/shlinkio/shlink/issues/1653) Added support for all HTTP methods in short URLs, together with two new redirect status codes, 307 and 308.
Existing Shlink instances will continue to work the same. However, if you decide to set the redirect status codes as 307 or 308, Shlink will also return a redirect for short URLs even when the request method is different from `GET`.
The status 308 is equivalent to 301, and 307 is equivalent to 302. The difference is that the spec requires the client to respect the original HTTP method when performing the redirect. With 301 and 302, some old clients might perform a `GET` request during the redirect, regardless the original request method.
* [#1662](https://github.com/shlinkio/shlink/issues/1662) Added support to provide openswoole-specific config options via env vars prefixed with `OPENSWOOLE_`.
* [#1389](https://github.com/shlinkio/shlink/issues/1389) and [#706](https://github.com/shlinkio/shlink/issues/706) Added support for case-insensitive short URLs.
In order to achieve this, a new env var/config option has been implemented (`SHORT_URL_MODE`), which allows either `strict` or ~~`loosely`~~ `loose`.
Default value is `strict`, but if `loose` is provided, then short URLs will be matched in a case-insensitive way, and new short URLs will be generated with short-codes in lowercase only.
### Changed
* *Nothing*
### Deprecated
* [#1676](https://github.com/shlinkio/shlink/issues/1676) Deprecated `GET /short-urls/shorten` endpoint. Use `POST /short-urls` to create short URLs instead.
* [#1678](https://github.com/shlinkio/shlink/issues/1678) Deprecated `validateUrl` option on URL creation/edition.
### Removed
* *Nothing*
### Fixed
* [#1639](https://github.com/shlinkio/shlink/issues/1639) Fixed 500 error returned when request body is not valid JSON, instead of a proper descriptive error.
## [3.4.0] - 2022-12-16
### Added
* [#1612](https://github.com/shlinkio/shlink/issues/1612) Allowed to filter short URLs out of lists, when `validUntil` date is in the past or have reached their maximum amount of visits.
This can be done by:
* Providing `excludeMaxVisitsReached=true` and/or `excludePastValidUntil=true` to the `GET /short-urls` endpoint.
* Providing `--exclude-max-visits-reached` and/or `--exclude-past-valid-until` to the `short-urls:list` command.
* [#1613](https://github.com/shlinkio/shlink/issues/1613) Added amount of visits coming from bots, non-bots and total to every short URL in the short URLs list.
Additionally, added option to order by non-bot visits, by passing `nonBotVisits-DESC` or `nonBotVisits-ASC`.
* [#1599](https://github.com/shlinkio/shlink/issues/1599) Added support for credentials on redis DSNs, either only password, or both username and password.
* [#1616](https://github.com/shlinkio/shlink/issues/1616) Added support to import orphan visits when importing short URLs from another Shlink instance.
* [#1519](https://github.com/shlinkio/shlink/issues/1519) Allowing to search short URLs by default domain.
* [#1555](https://github.com/shlinkio/shlink/issues/1555) and [#1625](https://github.com/shlinkio/shlink/issues/1625) Added full support for PHP 8.2, updating the docker image to this version.
### Changed
* [#1563](https://github.com/shlinkio/shlink/issues/1563) Moved logic to reuse command options to option classes instead of base abstract command classes.
* [#1569](https://github.com/shlinkio/shlink/issues/1569) Migrated test doubles from phpspec/prophecy to PHPUnit mocks.
* [#1329](https://github.com/shlinkio/shlink/issues/1329) Split some logic from `VisitRepository` and `ShortUrlRepository` into separated repository classes.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1618](https://github.com/shlinkio/shlink/issues/1618) Fixed imported short URLs and visits dates not being set to the target server timezone.
* [#1578](https://github.com/shlinkio/shlink/issues/1578) Fixed short URL allowing an empty string as the domain during creation.
* [#1580](https://github.com/shlinkio/shlink/issues/1580) Fixed `FLUSHDB` being run on Shlink docker start-up when using redis, causing full cache to be flushed.
## [3.3.2] - 2022-10-18
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1576](https://github.com/shlinkio/shlink/issues/1576) Fixed error when trying to retry visits location from CLI.
## [3.3.1] - 2022-09-30
### Added
* *Nothing*
### Changed
* [#1474](https://github.com/shlinkio/shlink/issues/1474) Added preliminary support for PHP 8.2 during CI workflow.
* [#1551](https://github.com/shlinkio/shlink/issues/1551) Moved services related to geolocating visits to the `Visit\Geolocation` namespace.
* [#1550](https://github.com/shlinkio/shlink/issues/1550) Reorganized main namespaces from Core module.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1556](https://github.com/shlinkio/shlink/issues/1556) Fixed trailing slash not working when enabling multi-segment slashes.
## [3.3.0] - 2022-09-18
### Added
* [#1221](https://github.com/shlinkio/shlink/issues/1221) Added experimental support to run Shlink with [RoadRunner](https://roadrunner.dev) instead of openswoole.
* [#1531](https://github.com/shlinkio/shlink/issues/1531) and [#1090](https://github.com/shlinkio/shlink/issues/1090) Added support for trailing slashes in short URLs.
* [#1406](https://github.com/shlinkio/shlink/issues/1406) Added new REST API version 3.
When making requests to the REST API with `/rest/v3/...` and an error occurs, all error types will be different, with the next correlation:
* `INVALID_ARGUMENT` -> `https://shlink.io/api/error/invalid-data`
* `INVALID_SHORT_URL_DELETION` -> `https://shlink.io/api/error/invalid-short-url-deletion`
* `DOMAIN_NOT_FOUND` -> `https://shlink.io/api/error/domain-not-found`
* `FORBIDDEN_OPERATION` -> `https://shlink.io/api/error/forbidden-tag-operation`
* `INVALID_URL` -> `https://shlink.io/api/error/invalid-url`
* `INVALID_SLUG` -> `https://shlink.io/api/error/non-unique-slug`
* `INVALID_SHORTCODE` -> `https://shlink.io/api/error/short-url-not-found`
* `TAG_CONFLICT` -> `https://shlink.io/api/error/tag-conflict`
* `TAG_NOT_FOUND` -> `https://shlink.io/api/error/tag-not-found`
* `MERCURE_NOT_CONFIGURED` -> `https://shlink.io/api/error/mercure-not-configured`
* `INVALID_AUTHORIZATION` -> `https://shlink.io/api/error/missing-authentication`
* `INVALID_API_KEY` -> `https://shlink.io/api/error/invalid-api-key`
If you make a request to the API with v2 or v1, the old error types will be returned, until Shlink 4 is released, when only the new ones will be used.
Non-error responses are not affected.
* [#1513](https://github.com/shlinkio/shlink/issues/1513) Added publishing of the docker image in GHCR.
* [#1114](https://github.com/shlinkio/shlink/issues/1114) Added support to provide an initial API key via `INITIAL_API_KEY` env var, when running Shlink with openswoole or RoadRunner.
Also, the installer tool now allows to generate an initial API key that can be copy-pasted (this tool is run interactively), in case you use php-fpm or you don't want to use env vars.
* [#1528](https://github.com/shlinkio/shlink/issues/1528) Added support to delay when the GeoLite2 DB file is downloaded in docker images, speeding up its startup time.
In order to do it, pass `SKIP_INITIAL_GEOLITE_DOWNLOAD=true` when creating the container.
### Changed
* [#1339](https://github.com/shlinkio/shlink/issues/1339) Added new test suite for CLI E2E tests.
* [#1503](https://github.com/shlinkio/shlink/issues/1503) Drastically improved build time in GitHub Actions, by optimizing parallelization and adding php extensions cache.
* [#1525](https://github.com/shlinkio/shlink/issues/1525) Migrated to custom doctrine CLI entry point.
* [#1492](https://github.com/shlinkio/shlink/issues/1492) Migrated to immutable options objects, mapped with [cuyz/valinor](https://github.com/CuyZ/Valinor).
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* *Nothing*
## [3.2.1] - 2022-08-08
### Added
* *Nothing*
### Changed
* [#1495](https://github.com/shlinkio/shlink/issues/1495) Centralized how routes are configured to support multi-segment slugs.
* [#1497](https://github.com/shlinkio/shlink/issues/1497) Updated to latest shlink dependencies with support for PHP 8.1 only.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1499](https://github.com/shlinkio/shlink/issues/1499) Fixed loading of config options as env vars, which was making all default configurations to be loaded unless env vars were explicitly provided.
## [3.2.0] - 2022-08-05
### Added
* [#854](https://github.com/shlinkio/shlink/issues/854) Added support for multi-segment custom slugs.
The feature is disabled by default, but you can optionally opt in. If you do, you will be able to create short URLs with multiple segments in the custom slug, like `https://example.com/foo/bar/baz`.
* [#1280](https://github.com/shlinkio/shlink/issues/1280) Added missing visit-related commands.
Now you can run `tag:visits`, `domain:visits`, `visit:orphan` or `visit:non-orphan` to get the corresponding list of visits from the command line.
* [#962](https://github.com/shlinkio/shlink/issues/962) Added new real-time update for new short URLs.
You can now subscribe to the `https://shlink.io/new-short-url` topic on any of the supported async updates technologies in order to get notified when a short URL is created.
* [#1367](https://github.com/shlinkio/shlink/issues/1367) Added support to publish real-time updates in redis pub/sub.
The publishing will happen in the same redis instance/cluster configured for caching.
### Changed
* [#1452](https://github.com/shlinkio/shlink/issues/1452) Updated to monolog 3
* [#1485](https://github.com/shlinkio/shlink/issues/1485) Changed payload published in RabbitMQ for all visits events, in order to conform with the Async API spec.
Since this is a breaking change, also provided a new `RABBITMQ_LEGACY_VISITS_PUBLISHING=true` env var that can be provided in order to keep the old payload.
This env var is considered deprecated and will be removed in Shlink 4, when the legacy format will no longer be supported.
### Deprecated
* *Nothing*
### Removed
* [#1280](https://github.com/shlinkio/shlink/issues/1280) Dropped support for PHP 8.0
### Fixed
* [#1471](https://github.com/shlinkio/shlink/issues/1471) Fixed error when running `visit:locate` command with any extra parameter (like `--retry`).
## [3.1.2] - 2022-06-04
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1448](https://github.com/shlinkio/shlink/issues/1448) Fixed HTML entities not being properly parsed when auto-resolving page titles.
* [#1458](https://github.com/shlinkio/shlink/issues/1458) Fixed 500 error when filtering short URLs by ALL tags and search term.
## [3.1.1] - 2022-05-09
### Added
* *Nothing*
### Changed
* [#1444](https://github.com/shlinkio/shlink/issues/1444) Updated docker image to openswoole 4.11.1, in an attempt to fix error.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1439](https://github.com/shlinkio/shlink/issues/1439) Fixed crash when trying to auto-resolve titles for URLs which serve large binary files.
## [3.1.0] - 2022-04-23
### Added
* [#1294](https://github.com/shlinkio/shlink/issues/1294) Allowed to provide a specific domain when importing URLs from YOURLS.
* [#1416](https://github.com/shlinkio/shlink/issues/1416) Added support to import URLs from Kutt.it.
* [#1418](https://github.com/shlinkio/shlink/issues/1418) Added support to customize the timezone used by Shlink, falling back to the default one set in PHP config.
The timezone can be set via the `TIMEZONE` env var, or using the installer tool.
* [#1309](https://github.com/shlinkio/shlink/issues/1309) Improved URL importing, ensuring individual errors do not make the whole process fail, and instead, failing URLs are skipped.
* [#1162](https://github.com/shlinkio/shlink/issues/1162) Added new endpoint to get visits by domain.
The endpoint is `GET /domains/{domain}/visits`, and it has the same capabilities as any other visits endpoint, allowing pagination and filtering.
### Changed
* [#1359](https://github.com/shlinkio/shlink/issues/1359) Hidden database commands.
* [#1385](https://github.com/shlinkio/shlink/issues/1385) Prevented a big error message from being logged when using Shlink without mercure.
* [#1398](https://github.com/shlinkio/shlink/issues/1398) Increased required mutation score for unit tests to 85%.
* [#1419](https://github.com/shlinkio/shlink/issues/1419) Input dates are now parsed to Shlink's configured timezone or default timezone before using them for database queries.
* [#1428](https://github.com/shlinkio/shlink/issues/1428) Updated native dependencies in docker image and base image to PHP v8.1.5.
### Deprecated
* [#1340](https://github.com/shlinkio/shlink/issues/1340) Deprecated webhooks. New events will only be added to other real-time updates approaches, and webhooks will be completely removed in Shlink 4.0.0.
### Removed
* *Nothing*
### Fixed
* [#1397](https://github.com/shlinkio/shlink/issues/1397) Fixed `db:create` command always reporting the schema exists if the `db:migrate` command has been run before by mistake.
* [#1402](https://github.com/shlinkio/shlink/issues/1402) Fixed the base path getting appended with the default domain by mistake, causing multiple side effects in several places.
## [3.0.3] - 2022-02-19
### Added
* *Nothing*
### Changed
* [#1382](https://github.com/shlinkio/shlink/issues/1382) Updated docker image to PHP 8.1.3.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1377](https://github.com/shlinkio/shlink/issues/1377) Fixed installer always setting delete threshold with value 1.
* [#1379](https://github.com/shlinkio/shlink/issues/1379) Ensured API keys cannot be created with a domain-only role linked to default domain.
## [3.0.2] - 2022-02-10
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1373](https://github.com/shlinkio/shlink/issues/1373) Fixed incorrect config import when updating from Shlink 2.x using SQLite.
* [#1369](https://github.com/shlinkio/shlink/issues/1369) Fixed slow regexps in `.htaccess` file.
## [3.0.1] - 2022-02-04
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1363](https://github.com/shlinkio/shlink/issues/1363) Fixed titles being resolved no matter what when `validateUrl` is not set or is explicitly set to true.
* [#1352](https://github.com/shlinkio/shlink/issues/1352) Updated to stable pdo_sqlsrv in docker image.
## [3.0.0] - 2022-01-28
### Added
* [#767](https://github.com/shlinkio/shlink/issues/767) Added full support to use emojis everywhere, whether it is custom slugs, titles, referrers, etc.
* [#1274](https://github.com/shlinkio/shlink/issues/1274) Added support to filter short URLs lists by all provided tags.
The `GET /short-urls` endpoint now accepts a `tagsMode=all` param which will make only short URLs matching **all** the tags in the `tags[]` query param, to be returned.
The `short-urls:list` command now accepts a `-i`/`--including-all-tags` flag which behaves the same.
* [#1273](https://github.com/shlinkio/shlink/issues/1273) Added support for pagination in tags lists, allowing to improve performance by loading subsets of tags.
For backwards compatibility, lists continue returning all items by default, but the `GET /tags` endpoint now supports `page` and `itemsPerPage` query params, to make sure only a subset of the tags is returned.
This is supported both when invoking the endpoint with and without `withStats=true` query param.
Additionally, the endpoint also supports filtering by `searchTerm` query param. When provided, only tags matching it will be returned.
* [#1063](https://github.com/shlinkio/shlink/issues/1063) Added new endpoint that allows fetching all existing non-orphan visits, in case you need a global view of all visits received by your Shlink instance.
This can be achieved using the `GET /visits/non-orphan` endpoint.
### Changed
* [#1277](https://github.com/shlinkio/shlink/issues/1277) Reduced docker image size to 45% of the original size.
* [#1268](https://github.com/shlinkio/shlink/issues/1268) Updated dependencies, including symfony/console 6 and mezzio/mezzio-swoole 4.
* [#1283](https://github.com/shlinkio/shlink/issues/1283) Changed behavior of `DELETE_SHORT_URL_THRESHOLD` env var, disabling the feature if a value was not provided.
* [#1300](https://github.com/shlinkio/shlink/issues/1300) Changed default ordering for short URLs list, returning always from newest to oldest.
* [#1299](https://github.com/shlinkio/shlink/issues/1299) Updated to the latest base docker images, based in PHP 8.1.1, and bumped openswoole to v4.9.1.
* [#1282](https://github.com/shlinkio/shlink/issues/1282) Env vars now have precedence over installer options.
* [#1328](https://github.com/shlinkio/shlink/issues/1328) Refactored ShortUrlsRepository to use DTOs in methods with too many arguments.
### Deprecated
* [#1315](https://github.com/shlinkio/shlink/issues/1315) Deprecated `GET /tags?withStats=true` endpoint. Use `GET /tags/stats` instead.
### Removed
* [#1275](https://github.com/shlinkio/shlink/issues/1275) Removed everything that was deprecated in Shlink 2.x.
See [UPGRADE](UPGRADE.md#from-v2x-to-v3x) doc in order to get details on how to migrate to this version.
* [#1347](https://github.com/shlinkio/shlink/issues/1347) Dropped support for regular swoole in favor of openswoole.
Since openswoole support was introduced in the previous release version, Shlink will still consider the swoole extension as openswoole, as at the moment, functionality hasn't deviated too much, and will simplify migrating to Shlink 3.0.0
However, there's no longer active testing with regular swoole, and it is considered no longer supported. If some incompatibility arises, the only supported solution will be to migrate to openswoole.
### Fixed
* *Nothing*
## [2.10.3] - 2022-01-23
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1349](https://github.com/shlinkio/shlink/issues/1349) Fixed memory leak in cache implementation.
## [2.10.2] - 2022-01-07
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1293](https://github.com/shlinkio/shlink/issues/1293) Fixed error when trying to create/import short URLs with a too long title.
* [#1306](https://github.com/shlinkio/shlink/issues/1306) Ensured remote IP address is not logged when using swoole/openswoole.
* [#1308](https://github.com/shlinkio/shlink/issues/1308) Fixed memory leak when using redis due to the amount of non-expiring keys created by doctrine. Now they have a 24h expiration by default.
## [2.10.1] - 2021-12-21
### Added
* *Nothing*
@@ -401,7 +1102,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* *Nothing*
### Fixed
* [#979](https://github.com/shlinkio/shlink/issues/979) Added missing `itemsPerPage` query param to swagger docs for short RULs list.
* [#979](https://github.com/shlinkio/shlink/issues/979) Added missing `itemsPerPage` query param to swagger docs for short URLs list.
* [#980](https://github.com/shlinkio/shlink/issues/980) Fixed value used for `Access-Control-Allow-Origin`, that could not work as expected when including an IP address.
* [#947](https://github.com/shlinkio/shlink/issues/947) Fixed incorrect value returned in `Access-Control-Allow-Methods` header, which always contained all methods.
@@ -870,7 +1571,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* Preview generation feature completely removed.
* Authentication against REST API using JWT is no longer supported.
See [UPGRADE](UPGRADE.md) doc in order to get details on how to migrate to this version.
See [UPGRADE](UPGRADE.md#from-v1x-to-v2x) doc in order to get details on how to migrate to this version.
### Fixed
* [#600](https://github.com/shlinkio/shlink/issues/600) Fixed health action so that it works with and without version in the path.
@@ -1049,7 +1750,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
Endpoints and commands which create short URLs support providing the `domain` now (via query param or CLI flag). If not provided, the short URLs will still be "attached" to the default domain.
Custom slugs can be created on multiple domains, allowing to share links like `https://doma.in/my-compaign` and `https://example.com/my-campaign`, under the same shlink instance.
Custom slugs can be created on multiple domains, allowing to share links like `https://s.test/my-campaign` and `https://example.com/my-campaign`, under the same shlink instance.
When resolving a short URL to redirect end users, the following rules are applied:
@@ -1299,7 +2000,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Fixed
* [#309](https://github.com/shlinkio/shlink/issues/309) Added missing favicon to prevent 404 errors logged when an error page is loaded in a browser.
* [#310](https://github.com/shlinkio/shlink/issues/310) Fixed execution context not being properly detected, making `CloseDbConnectionMiddlware` to be always piped. Now the check is not even made, which simplifies everything.
* [#310](https://github.com/shlinkio/shlink/issues/310) Fixed execution context not being properly detected, making `CloseDbConnectionMiddleware` to be always piped. Now the check is not even made, which simplifies everything.
## [1.15.0] - 2018-12-02
@@ -1364,7 +2065,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Changed
* [#241](https://github.com/shlinkio/shlink/issues/241) Fixed columns in `visit_locations` table, to be snake_case instead of camelCase.
* [#228](https://github.com/shlinkio/shlink/issues/228) Updated how exceptions are serialized into logs, by using monlog's `PsrLogMessageProcessor`.
* [#228](https://github.com/shlinkio/shlink/issues/228) Updated how exceptions are serialized into logs, by using monolog's `PsrLogMessageProcessor`.
* [#225](https://github.com/shlinkio/shlink/issues/225) Performance and maintainability slightly improved by enforcing via code sniffer that all global namespace classes, functions and constants are explicitly imported.
* [#196](https://github.com/shlinkio/shlink/issues/196) Reduced anemic model in entities, defining more expressive public APIs instead.
* [#249](https://github.com/shlinkio/shlink/issues/249) Added [functional-php](https://github.com/lstrojny/functional-php) to ease collections handling.
@@ -1512,7 +2213,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
```json
{
"shortCode": "12Kb3",
"shortUrl": "https://doma.in/12Kb3",
"shortUrl": "https://s.test/12Kb3",
"longUrl": "https://shlink.io",
"dateCreated": "2016-05-01T20:34:16+02:00",
"visitsCount": 1029,
@@ -1579,7 +2280,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* [#174](https://github.com/shlinkio/shlink/issues/174) Fixed geolocation not working due to a deprecation on used service.
* [#172](https://github.com/shlinkio/shlink/issues/172) Documented missing filtering params for `[GET] /short-codes/{shortCode}/visits` API endpoint, which allow the list to be filtered by date range.
For example: `https://doma.in/rest/v1/short-urls/abc123/visits?startDate=2017-05-23&endDate=2017-10-05`
For example: `https://s.test/rest/v1/short-urls/abc123/visits?startDate=2017-05-23&endDate=2017-10-05`
* [#169](https://github.com/shlinkio/shlink/issues/169) Fixed unhandled error when parsing `ShortUrlMeta` and date fields are already `DateTime` instances.
@@ -1651,7 +2352,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
This eases integration with third party services.
With this feature, a simple request to a URL like `https://doma.in/rest/v1/short-codes/shorten?apiKey=[YOUR_API_KEY]&longUrl=[URL_TO_BE_SHORTENED]` would return the shortened one in JSON or plain text format.
With this feature, a simple request to a URL like `https://s.test/rest/v1/short-codes/shorten?apiKey=[YOUR_API_KEY]&longUrl=[URL_TO_BE_SHORTENED]` would return the shortened one in JSON or plain text format.
### Changed
* *Nothing*
@@ -1687,7 +2388,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Added
* [#125](https://github.com/shlinkio/shlink/issues/125) Implemented a path which returns a 1px image instead of a redirection.
Useful to track emails. Just add an image pointing to a URL like `https://doma.in/abc123/track` to any email and an invisible image will be generated tracking every time the email is opened.
Useful to track emails. Just add an image pointing to a URL like `https://s.test/abc123/track` to any email and an invisible image will be generated tracking every time the email is opened.
* [#132](https://github.com/shlinkio/shlink/issues/132) Added infection to improve tests
@@ -1968,7 +2669,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Added
* [#46](https://github.com/shlinkio/shlink/issues/46) Defined a route that returns a QR code representing the shortened URL.
In order to get the QR code URL, use a pattern like `https://doma.in/abc123/qr-code`
In order to get the QR code URL, use a pattern like `https://s.test/abc123/qr-code`
* [#32](https://github.com/shlinkio/shlink/issues/32) Added support for other cache adapters by improving the Cache factory
* [#14](https://github.com/shlinkio/shlink/issues/14) Added logger and enabled errors logging

View File

@@ -6,9 +6,9 @@ You will also see how to ensure the code fulfills the expected code checks, and
## System dependencies
The project provides all its dependencies as docker containers through a docker-compose configuration.
The project provides all its dependencies as docker containers through a `docker compose` configuration.
Because of this, the only actual dependencies are [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/).
Because of this, the only actual dependencies are [docker](https://docs.docker.com/get-docker/) and [docker compose](https://docs.docker.com/compose/install/).
## Setting up the project
@@ -21,7 +21,7 @@ Then you will have to follow these steps:
For example the `common.local.php.dist` file should be copied as `common.local.php`.
* Copy the file `docker-compose.override.yml.dist` by also removing the `dist` extension.
* Start-up the project by running `docker-compose up`.
* Start-up the project by running `docker compose up`.
The first time this command is run, it will create several containers that are used during development, so it may take some time.
@@ -31,7 +31,7 @@ Then you will have to follow these steps:
* Run `./indocker bin/cli db:migrate` to get database migrations up to date.
* Run `./indocker bin/cli api-key:generate` to get your first API key generated.
Once you finish this, you will have the project exposed in ports `8000` through nginx+php-fpm and `8080` through swoole.
Once you finish this, you will have the project exposed in ports `8800` through RoadRunner, `8080` through openswoole and `8000` through nginx+php-fpm.
> Note: The `indocker` shell script is a helper tool used to run commands inside the main docker container.
@@ -46,9 +46,7 @@ This is a simplified version of the project structure:
```
shlink
├── bin
── cli
│ ├── install
│ └── update
── cli
├── config
│ ├── autoload
│ ├── params
@@ -75,12 +73,12 @@ shlink
The purposes of every folder are:
* `bin`: It contains the CLI tools. The `cli` one is the main entry point to run shlink from the command line, while `install` and `update` are helper tools used to install and update shlink when not using the docker image.
* `bin`: It contains the CLI tools. The `cli` one is the main entry point to run Shlink from the command line.
* `config`: Contains application-wide configurations, which are later merged with the ones provided by every module.
* `data`: Common runtime-generated git-ignored assets, like logs, caches, etc.
* `docs`: Any project documentation is stored here, like API spec definitions or architectural decision records.
* `module`: Contains a subfolder for every module in the project. Modules contain the source code, tests and configurations for every context in the project.
* `public`: Few assets (like `favicon.ico` or `robots.txt`) and the web entry point are stored here. This web entry point is not used when serving the app with swoole.
* `module`: Contains a sub-folder for every module in the project. Modules contain the source code, tests and configurations for every context in the project.
* `public`: Few assets (like `favicon.ico` or `robots.txt`) and the web entry point are stored here. This web entry point is not used when serving the app with RoadRunner or openswoole.
## Project tests
@@ -96,7 +94,7 @@ In order to ensure stability and no regressions are introduced while developing
The project provides some tooling to run them against any of the supported database engines.
* **API tests**: These are E2E tests that spin up an instance of the app with swoole, and test it from the outside by interacting with the REST API.
* **API tests**: These are E2E tests that spin up an instance of the app with RoadRunner or openswoole, and test it from the outside by interacting with the REST API.
These are the best tests to catch regressions, and to verify everything behaves as expected.
@@ -104,7 +102,9 @@ In order to ensure stability and no regressions are introduced while developing
Since the app instance is run on a process different from the one running the tests, when a test fails it might not be obvious why. To help debugging that, the app will dump all its logs inside `data/log/api-tests`, where you will find the `shlink.log` and `access.log` files.
* **CLI tests**: *TBD. Once included, its purpose will be the same as API tests, but running through the command line*
* **CLI tests**: These are E2E tests too, but they test console commands instead of REST endpoints.
They use Maria DB as the database engine, and include the same fixtures as the API tests, that ensure the same data exists at the beginning of the execution.
Depending on the kind of contribution, maybe not all kinds of tests are needed, but the more you provide, the better.
@@ -121,15 +121,15 @@ Depending on the kind of contribution, maybe not all kinds of tests are needed,
For example, `test:db:postgres`.
* Run `./indocker composer test:api` to run API E2E tests. For these, the Postgres database engine is used.
* Run `./indocker composer test:cli` to run CLI E2E tests. For these, the Maria DB database engine is used.
* Run `./indocker composer infect:test` to run both unit and database tests (over sqlite) and then apply mutations to them with [infection](https://infection.github.io/).
* Run `./indocker composer ci` to run all previous commands together. This command is run during the project's continuous integration.
* Run `./indocker composer ci:parallel` to do the same as in previous case, but parallelizing non-conflicting tasks as much as possible.
* Run `./indocker composer ci` to run all previous commands together, parallelizing non-conflicting tasks as much as possible.
> Note: Due to some limitations in the tooling used by shlink, the testing databases need to exist beforehand, both for db and api tests (except sqlite).
>
> However, they just need to be created empty, with no tables. Also, once created, they are automatically reset before every new execution.
>
> The testing database is always called `shlink_test`. You can create it using the database client of your choice. [DBeaver](https://dbeaver.io/) is a good multi-platform desktop database client which supports all the engines supported by shlink.
## Testing endpoints
The project provides a Swagger UI container for dev envs, which can be accessed in http://localhost:8005.
It will automatically load the contents of `docs/swagger`, so you can make any updates and they will get reflected.
## Pull request process
@@ -141,7 +141,7 @@ Once everything is clear, to provide a pull request to this project, you should
The base branch should always be `develop`, and the target branch for the pull request should also be `develop`.
Before your branch can be merged, all the checks described in [Running code checks](#running-code-checks) have to be passing. You can verify that manually by running `./indocker composer ci:parallel`, or wait for the build to be run automatically after the pull request is created.
Before your branch can be merged, all the checks described in [Running code checks](#running-code-checks) have to be passing. You can verify that manually by running `./indocker composer ci`, or wait for the build to be run automatically after the pull request is created.
## Architectural Decision Records

View File

@@ -1,58 +1,60 @@
FROM php:8.1.0-alpine3.15 as base
FROM php:8.2-alpine3.17 as base
ARG SHLINK_VERSION=latest
ENV SHLINK_VERSION ${SHLINK_VERSION}
ENV OPENSWOOLE_VERSION 4.8.1
ENV PDO_SQLSRV_VERSION 5.10.0beta2
ENV MS_ODBC_SQL_VERSION 17.5.2.2
ENV LC_ALL "C"
ARG SHLINK_RUNTIME=rr
ENV SHLINK_RUNTIME ${SHLINK_RUNTIME}
ARG SHLINK_USER_ID='root'
ENV SHLINK_USER_ID ${SHLINK_USER_ID}
ENV OPENSWOOLE_VERSION 22.1.0
ENV PDO_SQLSRV_VERSION 5.11.1
ENV MS_ODBC_DOWNLOAD 'b/9/f/b9f3cce4-3925-46d4-9f46-da08869c6486'
ENV MS_ODBC_SQL_VERSION 18_18.1.1.1
ENV LC_ALL 'C'
WORKDIR /etc/shlink
# Install required PHP extensions
RUN \
# Install extensions with no extra dependencies
docker-php-ext-install -j"$(nproc)" pdo_mysql calendar sockets bcmath && \
# Install sqlite
apk add --no-cache sqlite-libs sqlite-dev && \
# Temp install dev dependencies needed to compile the extensions
apk add --no-cache --virtual .dev-deps sqlite-dev postgresql-dev icu-dev libzip-dev zlib-dev libpng-dev linux-headers && \
docker-php-ext-install -j"$(nproc)" pdo_mysql pdo_pgsql intl calendar sockets bcmath zip gd && \
apk add --no-cache sqlite-libs && \
docker-php-ext-install -j"$(nproc)" pdo_sqlite && \
# Install postgres
apk add --no-cache postgresql-dev && \
docker-php-ext-install -j"$(nproc)" pdo_pgsql && \
# Install intl
apk add --no-cache icu-dev && \
docker-php-ext-install -j"$(nproc)" intl && \
# Install zip and gd
apk add --no-cache libzip-dev zlib-dev libpng-dev && \
docker-php-ext-install -j"$(nproc)" zip gd && \
# Install gmp
apk add --no-cache gmp-dev && \
docker-php-ext-install -j"$(nproc)" gmp
# Remove temp dev extensions, and install prod equivalents that are required at runtime
apk del .dev-deps && \
apk add --no-cache postgresql icu libzip libpng
# Install sqlsrv driver
RUN if [ $(uname -m) == "x86_64" ]; then \
wget https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --no-cache --virtual .phpize-deps ${PHPIZE_DEPS} unixodbc-dev && \
# Install openswoole and sqlsrv driver for x86_64 builds
RUN apk add --no-cache --virtual .phpize-deps ${PHPIZE_DEPS} unixodbc-dev && \
if [ "$SHLINK_RUNTIME" == 'openswoole' ]; then \
# Openswoole is deprecated. Remove in v4.0.0
pecl install openswoole-${OPENSWOOLE_VERSION} && \
docker-php-ext-enable openswoole ; \
fi; \
if [ $(uname -m) == "x86_64" ]; then \
wget https://download.microsoft.com/download/${MS_ODBC_DOWNLOAD}/msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
pecl install pdo_sqlsrv-${PDO_SQLSRV_VERSION} && \
docker-php-ext-enable pdo_sqlsrv && \
apk del .phpize-deps && \
rm msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk ; \
fi
# Install openswoole
RUN apk add --no-cache --virtual .phpize-deps ${PHPIZE_DEPS} && \
pecl install openswoole-${OPENSWOOLE_VERSION} && \
docker-php-ext-enable openswoole && \
rm msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk ; \
fi; \
apk del .phpize-deps
# Install shlink
FROM base as builder
COPY . .
COPY --from=composer:2 /usr/bin/composer ./composer.phar
RUN apk add --no-cache git && \
php composer.phar install --no-dev --optimize-autoloader --prefer-dist --no-progress --no-interaction && \
# FIXME Ignoring ext-openswoole platform req, as it makes install fail with roadrunner, even though it's a dev dependency and we are passing --no-dev
php composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-progress --no-interaction --ignore-platform-req=ext-openswoole && \
if [ "$SHLINK_RUNTIME" == 'openswoole' ]; then \
# Openswoole is deprecated. Remove in v4.0.0
php composer.phar remove spiral/roadrunner spiral/roadrunner-jobs spiral/roadrunner-cli spiral/roadrunner-http --with-all-dependencies --update-no-dev --optimize-autoloader --no-progress --no-interaction ; \
elif [ "$SHLINK_RUNTIME" == 'rr' ]; then \
php composer.phar remove mezzio/mezzio-swoole --with-all-dependencies --update-no-dev --optimize-autoloader --no-progress --no-interaction --ignore-platform-req=ext-openswoole ; \
fi; \
php composer.phar clear-cache && \
rm -r docker composer.* && \
sed -i "s/%SHLINK_VERSION%/${SHLINK_VERSION}/g" config/autoload/app_options.global.php
@@ -62,10 +64,13 @@ RUN apk add --no-cache git && \
FROM base
LABEL maintainer="Alejandro Celaya <alejandro@alejandrocelaya.com>"
COPY --from=builder /etc/shlink .
RUN ln -s /etc/shlink/bin/cli /usr/local/bin/shlink
COPY --from=builder --chown=${SHLINK_USER_ID} /etc/shlink .
RUN ln -s /etc/shlink/bin/cli /usr/local/bin/shlink && \
if [ "$SHLINK_RUNTIME" == 'rr' ]; then \
php ./vendor/bin/rr get --no-interaction --no-config --location bin/ && chmod +x bin/rr ; \
fi;
# Expose default openswoole port
# Expose default port
EXPOSE 8080
# Copy config specific for the image
@@ -73,14 +78,6 @@ COPY docker/docker-entrypoint.sh docker-entrypoint.sh
COPY docker/config/shlink_in_docker.local.php config/autoload/shlink_in_docker.local.php
COPY docker/config/php.ini ${PHP_INI_DIR}/conf.d/
# Change the ownership of /etc/shlink/data to be writable, then change the user to non-root
# FIXME Disabled for now, as it conflicts with ENABLE_PERIODIC_VISIT_LOCATE, which is used to configure a cron as root.
# Ref: https://github.com/shlinkio/shlink/issues/1132
#RUN chown 1001 /etc/shlink/data
#RUN chown 1001 /etc/shlink/data/locks
#RUN chown 1001 /etc/shlink/data/proxies
#RUN chown 1001 /etc/shlink/data/cache
#RUN chown 1001 /etc/shlink/data/log
#USER 1001
USER ${SHLINK_USER_ID}
ENTRYPOINT ["/bin/sh", "./docker-entrypoint.sh"]

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016-2021 Alejandro Celaya
Copyright (c) 2016-2023 Alejandro Celaya
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,20 +1,22 @@
![Shlink](https://raw.githubusercontent.com/shlinkio/shlink.io/main/public/images/shlink-hero.png)
[![Build Status](https://img.shields.io/github/workflow/status/shlinkio/shlink/Continuous%20integration/develop?logo=github&style=flat-square)](https://github.com/shlinkio/shlink/actions?query=workflow%3A%22Continuous+integration%22)
[![Build Status](https://img.shields.io/github/actions/workflow/status/shlinkio/shlink/ci.yml?branch=develop&logo=github&style=flat-square)](https://github.com/shlinkio/shlink/actions/workflows/ci.yml?query=workflow%3A%22Continuous+integration%22)
[![Code Coverage](https://img.shields.io/codecov/c/gh/shlinkio/shlink/develop?style=flat-square)](https://app.codecov.io/gh/shlinkio/shlink)
[![Infection MSI](https://img.shields.io/endpoint?style=flat-square&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fshlinkio%2Fshlink%2Fdevelop)](https://dashboard.stryker-mutator.io/reports/github.com/shlinkio/shlink/develop)
[![Latest Stable Version](https://img.shields.io/github/release/shlinkio/shlink.svg?style=flat-square)](https://packagist.org/packages/shlinkio/shlink)
[![Docker pulls](https://img.shields.io/docker/pulls/shlinkio/shlink.svg?logo=docker&style=flat-square)](https://hub.docker.com/r/shlinkio/shlink/)
[![License](https://img.shields.io/github/license/shlinkio/shlink.svg?style=flat-square)](https://github.com/shlinkio/shlink/blob/main/LICENSE)
[![Twitter](https://img.shields.io/badge/follow-shlinkio-blue.svg?style=flat-square&logo=x&color=black)](https://twitter.com/shlinkio)
[![Mastodon](https://img.shields.io/mastodon/follow/109329425426175098?color=%236364ff&domain=https%3A%2F%2Ffosstodon.org&label=follow&logo=mastodon&logoColor=white&style=flat-square)](https://fosstodon.org/@shlinkio)
[![Paypal donate](https://img.shields.io/badge/Donate-paypal-blue.svg?style=flat-square&logo=paypal&colorA=aaaaaa)](https://slnk.to/donate)
A PHP-based self-hosted URL shortener that can be used to serve shortened URLs under your own custom domain.
A PHP-based self-hosted URL shortener that can be used to serve shortened URLs under your own domain.
## Table of Contents
- [Full documentation](#full-documentation)
- [Docker image](#docker-image)
- [Self hosted](#self-hosted)
- [Self-hosted](#self-hosted)
- [Download](#download)
- [Configure](#configure)
- [Using shlink](#using-shlink)
@@ -26,21 +28,22 @@ This document contains the very basics to get started with Shlink. If you want t
## Docker image
Starting with version 1.15.0, an official docker image is provided. You can learn how to use it by reading [the docs](https://shlink.io/documentation/install-docker-image/).
You can learn how to use the official docker image by reading [the docs](https://shlink.io/documentation/install-docker-image/).
The idea is that you can just generate a container using the image and provide the custom config via env vars.
## Self hosted
## Self-hosted
First, make sure the host where you are going to run shlink fulfills these requirements:
* PHP 8.0 or 8.1
* The next PHP extensions: json, curl, pdo, intl, gd and gmp.
* apcu extension is recommended if you don't plan to use swoole or openswoole.
* PHP 8.2 or 8.3
* The next PHP extensions: json, curl, pdo, intl, gd and gmp/bcmath.
* apcu extension is recommended if you don't plan to use openswoole.
* xml extension is required if you want to generate QR codes in svg format.
* sockets and bcmath extensions are required if you want to integrate with a RabbitMQ instance.
* MySQL, MariaDB, PostgreSQL, Microsoft SQL Server or SQLite.
* The web server of your choice with PHP integration (Apache or Nginx recommended).
* MySQL, MariaDB, PostgreSQL, MicrosoftSQL or SQLite.
* You will also need the corresponding pdo variation for the database you are planning to use: `pdo_mysql`, `pdo_pgsql`, `pdo_sqlsrv` or `pdo_sqlite`.
* The [openswoole](https://openswoole.com/) PHP extension (if you plan to serve Shlink with openswoole) or the web server of your choice with PHP integration (like Apache or Nginx).
### Download
@@ -50,7 +53,7 @@ In order to run Shlink, you will need a built version of the project. There are
The easiest way to install shlink is by using one of the pre-bundled distributable packages.
Go to the [latest version](https://github.com/shlinkio/shlink/releases/latest) and download the `shlink*_dist.zip` file that suits your needs. You will find one for every supported PHP version and with/without swoole/openswoole integration.
Go to the [latest version](https://github.com/shlinkio/shlink/releases/latest) and download the `shlink*_dist.zip` file that suits your needs. You will find one for every supported PHP version and with/without openswoole integration.
Finally, decompress the file in the location of your choice.
@@ -60,11 +63,13 @@ In order to run Shlink, you will need a built version of the project. There are
* Clone the project with git (`git clone https://github.com/shlinkio/shlink.git`), or download it by clicking the **Clone or download** green button.
* Download the [Composer](https://getcomposer.org/download/) PHP package manager inside the project folder.
* Run `./build.sh 1.0.0`, replacing the version with the version number you are going to build (the version number is used as part of the generated dist file name, and to set the value returned when running `shlink -V` from the command line).
* Run `./build.sh 3.0.0`, replacing the version with the version number you are going to build (the version number is used as part of the generated dist file name, and to set the value returned when running `shlink -V` from the command line).
After that, you will have a dist file inside the `build` directory, that you need to decompress in the location of your choice.
> This is the process used when releasing new shlink versions. After tagging the new version with git, the Github release is automatically created by a [GitHub workflow](https://github.com/shlinkio/shlink/actions?query=workflow%3A%22Publish+release%22), attaching the generated dist file to it.
> **Note**
>
> This is the process used when releasing new Shlink versions. After tagging the new version with git, the GitHub release is automatically created by a [GitHub workflow](https://github.com/shlinkio/shlink/actions?query=workflow%3A%22Publish+release%22), attaching the generated dist file to it.
### Configure
@@ -72,24 +77,24 @@ Despite how you built the project, you now need to configure it, by following th
* If you are going to use MySQL, MariaDB, PostgreSQL or Microsoft SQL Server, create an empty database with the name of your choice.
* Recursively grant write permissions to the `data` directory. Shlink uses it to cache some information.
* Setup the application by running the `bin/install` script. It is a command line tool that will guide you through the installation process. **Take into account that this tool has to be run directly on the server where you plan to host Shlink. Do not run it before uploading/moving it there.**
* Generate your first API key by running `bin/cli api-key:generate`. You will need the key in order to interact with shlink's API.
* Set up the application by running the `vendor/bin/shlink-installer install` script. It is a command line tool that will guide you through the installation process. **Take into account that this tool has to be run directly on the server where you plan to host Shlink. Do not run it before uploading/moving it there.**
* Generate your first API key by running `bin/cli api-key:generate`. You will need the key in order to interact with Shlink's API.
## Using shlink
Once shlink is installed, there are two main ways to interact with it:
* **The command line**. Try running `bin/cli` and see all the [available commands](#shlink-cli-help).
* **The command line**: Try running `bin/cli` to see all the available commands.
All of those commands can be run with the `--help`/`-h` flag in order to see how to use them and all the available options.
All of them can be run with the `--help`/`-h` flag in order to see how to use them and all the available options.
It is probably a good idea to symlink the CLI entry point (`bin/cli`) to somewhere in your path, so that you can run shlink from any directory.
* **The REST API**. The complete docs on how to use the API can be found [here](https://shlink.io/documentation/api-docs), and a sandbox which also documents every endpoint can be found in the [API Spec](https://api-spec.shlink.io/) portal.
* **The REST API**: The complete docs on how to use the API can be found [here](https://shlink.io/documentation/api-docs), and a sandbox which also documents every endpoint can be found in the [API Spec](https://api-spec.shlink.io/) portal.
However, you probably don't want to consume the raw API yourself. That's why a nice [web client](https://github.com/shlinkio/shlink-web-client) is provided that can be directly used from [https://app.shlink.io](https://app.shlink.io), or hosted by yourself.
Both the API and CLI allow you to do the same operations, except for API key management, which can be done from the command line interface only.
Both the API and CLI allow you to do mostly the same operations, except for API key management, which can be done from the command line interface only.
## Contributing

View File

@@ -1,5 +1,53 @@
# Upgrading
## From v2.x to v3.x
### Changes in REST API
* The `type` property returned when trying to delete a URL that reached the visits threshold, when using the `DELETE /short-urls/{shortCode}` endpoint, is now `INVALID_SHORT_URL_DELETION` instead of `INVALID_SHORTCODE_DELETION`.
* The `INVALID_AUTHORIZATION` error no longer includes the `expectedTypes` property. Use `expectedHeaders` one instead.
* The `GET /rest/v2/short-urls` endpoint no longer allows ordering by `visitsCount`, `visitCount` or `originalUrl`. Use `visits` instead of the first two, and `longUrl` instead of the last one.
* The `GET /rest/v2/short-urls` endpoint no longer allows providing the ordering params with array notation, as in `/shortUrls?orderBy[longUrl]=DESC`. Instead, use the following notation `/shortUrls?orderBy=longUrl-DESC`.
* The `GET /rest/v2/short-urls` endpoint now has a default ordering of newest-to-oldest. Use `/shortUrls?orderBy=dateCreated-ASC` in order to keep the oldest-to-newest behavior.
* Requests expecting a body no longer support url-encoded payloads. Instead, always use JSON bodies with `Content-Type: application/json`.
* The next endpoints have been removed:
* `PUT /rest/v2/short-urls/{shortCode}/tags`: Use the `PATCH /rest/v2/short-urls/{shortCode}` endpoint to set the short URL tags.
* `POST /rest/v2/tags`: Use `POST /rest/v2/short-urls` or `PATCH /rest/v2/short-urls/{shortCodes}` to create new tags already attached to a short URL. Creating orphan tags makes no sense.
### Changes in CLI
* The next commands have been removed:
* `short-url:generate`: Use `short-url:create` instead.
* `tag:create`: Creating orphan tags makes no sense.
* Params in camelCase format are no longer supported. They all have an equivalent kebab-case replacement. (for example, from `--startDate` to `--start-date`).
* The `short-url:create` command no longer accepts the `--no-validate-url` flag. Now URLs are never validated, unless `--validate-url` is passed.
* The CLI installer tool entry-points have changed.
* `bin/install`: replaced by `vendor/bin/shlink-installer install`
* `bin/update`: replaced by `vendor/bin/shlink-installer update`
* `bin/set-option`: replaced by `vendor/bin/shlink-installer set-option`
### Changes in config
* The next env vars have been removed:
* `INVALID_SHORT_URL_REDIRECT_TO`: Replaced by `DEFAULT_INVALID_SHORT_URL_REDIRECT`.
* `REGULAR_404_REDIRECT_TO`: Replaced by `DEFAULT_REGULAR_404_REDIRECT`.
* `BASE_URL_REDIRECT_TO`: Replaced by `DEFAULT_BASE_URL_REDIRECT`.
* `SHORT_DOMAIN_HOST`: Replaced by `DEFAULT_DOMAIN`.
* `SHORT_DOMAIN_SCHEMA`: Replaced by `IS_HTTPS_ENABLED`.
* `USE_HTTPS`: Replaced by `IS_HTTPS_ENABLED`.
* `VALIDATE_URLS`: There's no replacement. URLs are not validated, unless explicitly requested during creation or edition.
* The next env vars behavior has changed:
* `DELETE_SHORT_URL_THRESHOLD`: Now, if this env var is not provided, the "visits threshold" won't be checked at all when deleting short URLs. Make sure you explicitly provide a value if you want to enable this feature.
* Environment variables now have precedence over configuration set via the installer tool.
### Other changes
* A default GeoLite2 license key is no longer provided. If you don't provide your own as explained in [the docs](https://shlink.io/documentation/geolite-license-key/), Shlink will not try to update the file anymore.
* The docker image no longer accepts providing configuration via json files mounted in the `config/params` folder. Only env vars are supported now.
* If you were manually serving Shlink with swoole, the entry script has to be changed from `/path/to/shlink/vendor/bin/mezzio-swoole start` to `/path/to/shlink/vendor/bin/laminas mezzio:swoole:start`
* The `GET /{shortCode}/qr-code/{size}` url has been removed. Use `GET /{shortCode}/qr-code?size={size}` instead.
* Regular swoole extension is no longer supported. Use openswoole instead, as a direct replacement. In most of the cases you just need to uninstall one and install the other, the rest is transparent.
## From v1.x to v2.x
### PHP 7.4 required
@@ -28,7 +76,7 @@ These routes have been removed, but have a direct replacement:
* `/qr/{shortCode}[/{size}]` -> `/{shortCode}/qr-code[/{size}]`
* `PUT /rest/v{version}/short-urls/{shortCode}` -> `PATCH /rest/v{version}/short-urls/{shortCode}`
When using the old ones, a 404 status will me returned now.
When using the old ones, a 404 status will be returned now.
### Removed command and route aliases

12
bin/doctrine Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
/** @var EntityManager $app */
$em = require __DIR__ . '/../config/entity-manager.php';
ConsoleRunner::run(new SingleManagerProvider($em));

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env php
<?php
/**
* @deprecated To be removed with Shlink 3.0.0
* This script is provided to keep backwards compatibility on how to run shlink with swoole while being still able to
* update to mezzio/mezzio-swoole 3.x
*/
declare(strict_types=1);
namespace Mezzio\Swoole\Command;
use Laminas\ServiceManager\ServiceManager;
use PackageVersions\Versions;
use Symfony\Component\Console\Application as CommandLine;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use function explode;
use function Functional\filter;
use function str_starts_with;
use function strstr;
/** @var ServiceManager $container */
$container = require __DIR__ . '/../../config/container.php';
$version = strstr(Versions::getVersion('mezzio/mezzio-swoole'), '@', true);
$commandsPrefix = 'mezzio:swoole:';
$commands = filter(
$container->get('config')['laminas-cli']['commands'] ?? [],
fn ($c, string $command) => str_starts_with($command, $commandsPrefix),
);
$registeredCommands = [];
foreach ($commands as $newName => $commandServiceName) {
[, $oldName] = explode($commandsPrefix, $newName);
$registeredCommands[$oldName] = $commandServiceName;
$container->addDelegator($commandServiceName, static function ($c, $n, callable $factory) use ($oldName) {
/** @var Command $command */
$command = $factory();
$command->setAliases([$oldName]);
return $command;
});
}
$commandLine = new CommandLine('Mezzio web server', $version);
$commandLine->setAutoExit(true);
$commandLine->setCommandLoader(new ContainerCommandLoader($container, $registeredCommands));
$commandLine->run();

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink;
use function chdir;
use function dirname;
chdir(dirname(__DIR__));
[$install] = require __DIR__ . '/../vendor/shlinkio/shlink-installer/bin/run.php';
$install();

32
bin/roadrunner-worker.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
use Mezzio\Application;
use Psr\Container\ContainerInterface;
use Shlinkio\Shlink\EventDispatcher\RoadRunner\RoadRunnerTaskConsumerToListener;
use Spiral\RoadRunner\Http\PSR7Worker;
use function Shlinkio\Shlink\Config\env;
(static function (): void {
/** @var ContainerInterface $container */
$container = include __DIR__ . '/../config/container.php';
$rrMode = env('RR_MODE');
if ($rrMode === 'http') {
// This was spin-up as a web worker
$app = $container->get(Application::class);
$worker = $container->get(PSR7Worker::class);
while ($req = $worker->waitRequest()) {
try {
$worker->respond($app->handle($req));
} catch (Throwable $e) {
$worker->getWorker()->error((string) $e);
}
}
} else {
$container->get(RoadRunnerTaskConsumerToListener::class)->listenForTasks();
}
})();

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink;
use Shlinkio\Shlink\Installer\Command\SetOptionCommand;
use function chdir;
use function dirname;
chdir(dirname(__DIR__));
[,, $installer] = require __DIR__ . '/../vendor/shlinkio/shlink-installer/bin/run.php';
$installer(SetOptionCommand::NAME);

View File

@@ -1,22 +1,38 @@
#!/usr/bin/env sh
export APP_ENV=test
export DB_DRIVER=postgres
export TEST_ENV=api
export GENERATE_COVERAGE=${GENERATE_COVERAGE:-"no"}
export APP_ENV=test
export TEST_ENV=api
export TEST_RUNTIME="${TEST_RUNTIME:-"openswoole"}" # Openswoole is deprecated. Remove in v4.0.0
export DB_DRIVER="${DB_DRIVER:-"postgres"}"
export GENERATE_COVERAGE="${GENERATE_COVERAGE:-"no"}"
# Reset logs
OUTPUT_LOGS=data/log/api-tests/output.log
rm -rf data/log/api-tests
mkdir data/log/api-tests
touch $OUTPUT_LOGS
# Try to stop server just in case it hanged in last execution
vendor/bin/laminas mezzio:swoole:stop
[ "$TEST_RUNTIME" = 'openswoole' ] && vendor/bin/laminas mezzio:swoole:stop
[ "$TEST_RUNTIME" = 'rr' ] && bin/rr stop -f
echo 'Starting server...'
vendor/bin/laminas mezzio:swoole:start -d
sleep 2
[ "$TEST_RUNTIME" = 'openswoole' ] && vendor/bin/laminas mezzio:swoole:start -d
[ "$TEST_RUNTIME" = 'rr' ] && bin/rr serve -p -c=config/roadrunner/.rr.dev.yml \
-o=http.address=0.0.0.0:9999 \
-o=logs.encoding=json \
-o=logs.channels.http.encoding=json \
-o=logs.channels.server.encoding=json \
-o=logs.output="${PWD}/${OUTPUT_LOGS}" \
-o=logs.channels.http.output="${PWD}/${OUTPUT_LOGS}" \
-o=logs.channels.server.output="${PWD}/${OUTPUT_LOGS}" &
sleep 2 # Let's give the server a couple of seconds to start
vendor/bin/phpunit --order-by=random -c phpunit-api.xml --testdox --colors=always --log-junit=build/coverage-api/junit.xml $*
testsExitCode=$?
vendor/bin/laminas mezzio:swoole:stop
[ "$TEST_RUNTIME" = 'openswoole' ] && vendor/bin/laminas mezzio:swoole:stop
[ "$TEST_RUNTIME" = 'rr' ] && bin/rr stop -c config/roadrunner/.rr.dev.yml -o=http.address=0.0.0.0:9999
# Exit this script with the same code as the tests. If tests failed, this script has to fail
exit $testsExitCode

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env php
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink;
use function chdir;
use function dirname;
chdir(dirname(__DIR__));
[, $update] = require __DIR__ . '/../vendor/shlinkio/shlink-installer/bin/run.php';
$update();

View File

@@ -10,7 +10,8 @@ fi
version=$1
noSwoole=$2
phpVersion=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
[[ $noSwoole ]] && swooleSuffix="" || swooleSuffix="_swoole"
# Openswoole is deprecated. Remove in v4.0.0
[[ $noSwoole ]] && swooleSuffix="" || swooleSuffix="_openswoole"
distId="shlink${version}_php${phpVersion}${swooleSuffix}_dist"
builtContent="./build/${distId}"
projectdir=$(pwd)
@@ -24,28 +25,31 @@ rsync -av * "${builtContent}" \
--exclude=*docker* \
--exclude=Dockerfile \
--include=.htaccess \
--include=config/roadrunner/.rr.yml \
--exclude-from=./.dockerignore
cd "${builtContent}"
# Install dependencies
echo "Installing dependencies with $composerBin..."
composerFlags="--optimize-autoloader --no-progress --no-interaction"
# Deprecated. Do not ignore PHP platform req for Shlink v4.0.0
composerFlags="--optimize-autoloader --no-progress --no-interaction --ignore-platform-req=php+"
${composerBin} self-update
${composerBin} install --no-dev --prefer-dist $composerFlags
if [[ $noSwoole ]]; then
# If generating a dist not for swoole, uninstall mezzio-swoole
# If generating a dist not for openswoole, uninstall mezzio-swoole
${composerBin} remove mezzio/mezzio-swoole --with-all-dependencies --update-no-dev $composerFlags
else
# Copy mezzio helper script to vendor (deprecated - Remove with Shlink 3.0.0)
cp "${projectdir}/bin/helper/mezzio-swoole" "./vendor/bin"
# Deprecated. Remove in Shlink v4.0.0
# If generating a dist for openswoole, uninstall RoadRunner
${composerBin} remove spiral/roadrunner spiral/roadrunner-jobs spiral/roadrunner-cli spiral/roadrunner-http --with-all-dependencies --update-no-dev $composerFlags
fi
# Delete development files
echo 'Deleting dev files...'
rm composer.*
# Update shlink version in config
# Update Shlink version in config
sed -i "s/%SHLINK_VERSION%/${version}/g" config/autoload/app_options.global.php
# Compressing file

View File

@@ -12,72 +12,75 @@
}
],
"require": {
"php": "^8.0",
"php": "^8.2",
"ext-curl": "*",
"ext-gd": "*",
"ext-json": "*",
"ext-pdo": "*",
"akrabat/ip-address-middleware": "^2.1",
"cakephp/chronos": "^2.3",
"cocur/slugify": "^4.0",
"doctrine/migrations": "^3.3",
"doctrine/orm": "^2.10",
"endroid/qr-code": "^4.4",
"geoip2/geoip2": "^2.12",
"guzzlehttp/guzzle": "^7.4",
"cakephp/chronos": "^3.0.2",
"doctrine/migrations": "^3.6",
"doctrine/orm": "^2.16",
"endroid/qr-code": "^4.8",
"friendsofphp/proxy-manager-lts": "^1.0",
"geoip2/geoip2": "^3.0",
"guzzlehttp/guzzle": "^7.5",
"happyr/doctrine-specification": "^2.0",
"jaybizzle/crawler-detect": "^1.2.110",
"laminas/laminas-config": "^3.7",
"laminas/laminas-config-aggregator": "^1.7",
"laminas/laminas-diactoros": "^2.8",
"laminas/laminas-inputfilter": "^2.13",
"laminas/laminas-servicemanager": "^3.10",
"laminas/laminas-stdlib": "^3.6",
"lcobucci/jwt": "^4.1",
"league/uri": "^6.4",
"lstrojny/functional-php": "^1.17",
"mezzio/mezzio": "^3.7",
"mezzio/mezzio-fastroute": "^3.3",
"mezzio/mezzio-problem-details": "^1.5",
"mezzio/mezzio-swoole": "^3.5",
"mlocati/ip-lib": "^1.17",
"monolog/monolog": "^2.3",
"nikolaposa/monolog-factory": "^3.1",
"ocramius/proxy-manager": "^2.11",
"pagerfanta/core": "^3.5",
"php-amqplib/php-amqplib": "^3.1",
"jaybizzle/crawler-detect": "^1.2.116",
"laminas/laminas-config": "^3.8",
"laminas/laminas-config-aggregator": "^1.13",
"laminas/laminas-diactoros": "^3.3",
"laminas/laminas-inputfilter": "^2.27",
"laminas/laminas-servicemanager": "^3.21",
"laminas/laminas-stdlib": "^3.17",
"league/uri": "^6.8",
"matomo/matomo-php-tracker": "^3.2",
"mezzio/mezzio": "^3.17",
"mezzio/mezzio-fastroute": "^3.10",
"mezzio/mezzio-problem-details": "^1.13",
"mezzio/mezzio-swoole": "^4.7",
"mlocati/ip-lib": "^1.18",
"mobiledetect/mobiledetectlib": "^4.8",
"pagerfanta/core": "^3.8",
"php-middleware/request-id": "^4.1",
"predis/predis": "^1.1",
"pugx/shortid-php": "^1.0",
"ramsey/uuid": "^4.2",
"shlinkio/shlink-common": "^4.2.1",
"shlinkio/shlink-config": "^1.4",
"shlinkio/shlink-event-dispatcher": "^2.3",
"shlinkio/shlink-importer": "^2.5",
"shlinkio/shlink-installer": "^6.3",
"shlinkio/shlink-ip-geolocation": "^2.2",
"symfony/console": "^5.4",
"symfony/filesystem": "^6.0 || ^5.4",
"symfony/lock": "^6.0 || ^5.4",
"symfony/mercure": "^0.6",
"symfony/process": "^6.0 || ^5.4",
"symfony/string": "^6.0 || ^5.4"
"pugx/shortid-php": "^1.1",
"ramsey/uuid": "^4.7",
"shlinkio/shlink-common": "^5.7.1",
"shlinkio/shlink-config": "^2.5",
"shlinkio/shlink-event-dispatcher": "^3.1",
"shlinkio/shlink-importer": "^5.2.1",
"shlinkio/shlink-installer": "^8.7",
"shlinkio/shlink-ip-geolocation": "^3.4",
"shlinkio/shlink-json": "^1.1",
"spiral/roadrunner": "^2023.2",
"spiral/roadrunner-cli": "^2.5",
"spiral/roadrunner-http": "^3.1",
"spiral/roadrunner-jobs": "^4.0",
"symfony/console": "^6.3",
"symfony/filesystem": "^6.3",
"symfony/lock": "^6.3",
"symfony/process": "^6.3",
"symfony/string": "^6.3"
},
"require-dev": {
"cebe/php-openapi": "^1.5",
"devizzent/cebe-php-openapi": "^1.0.1",
"devster/ubench": "^2.1",
"dms/phpunit-arraysubset-asserts": "^0.3.0",
"eaglewu/swoole-ide-helper": "dev-master",
"infection/infection": "^0.25.4",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/phpstan": "^1.2",
"phpstan/phpstan-doctrine": "^1.0",
"phpstan/phpstan-symfony": "^1.0",
"phpunit/php-code-coverage": "^9.2",
"phpunit/phpunit": "^9.5",
"infection/infection": "^0.27",
"openswoole/ide-helper": "~22.0.0",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-doctrine": "^1.3",
"phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan-symfony": "^1.3",
"phpunit/php-code-coverage": "^10.1",
"phpunit/phpunit": "^10.4",
"roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.2.0",
"shlinkio/shlink-test-utils": "^2.5",
"symfony/var-dumper": "^6.0",
"veewee/composer-run-parallel": "^1.1"
"shlinkio/php-coding-standard": "~2.3.0",
"shlinkio/shlink-test-utils": "^3.8",
"symfony/var-dumper": "^6.3",
"veewee/composer-run-parallel": "^1.3"
},
"conflict": {
"symfony/var-exporter": ">=6.3.9,<=6.4.0"
},
"autoload": {
"psr-4": {
@@ -87,18 +90,20 @@
},
"files": [
"config/constants.php",
"module/Core/functions/array-utils.php",
"module/Core/functions/functions.php"
]
},
"autoload-dev": {
"psr-4": {
"ShlinkioTest\\Shlink\\CLI\\": "module/CLI/test",
"ShlinkioCliTest\\Shlink\\CLI\\": "module/CLI/test-cli",
"ShlinkioTest\\Shlink\\Rest\\": "module/Rest/test",
"ShlinkioApiTest\\Shlink\\Rest\\": "module/Rest/test-api",
"ShlinkioTest\\Shlink\\Core\\": [
"module/Core/test",
"module/Core/test-db"
]
"ShlinkioDbTest\\Shlink\\Rest\\": "module/Rest/test-db",
"ShlinkioTest\\Shlink\\Core\\": "module/Core/test",
"ShlinkioDbTest\\Shlink\\Core\\": "module/Core/test-db",
"ShlinkioApiTest\\Shlink\\Core\\": "module/Core/test-api"
},
"files": [
"config/test/constants.php"
@@ -106,32 +111,19 @@
},
"scripts": {
"ci": [
"@cs",
"@stan",
"@swagger:validate",
"@test:ci",
"@infect:ci"
],
"ci:parallel": [
"@parallel cs stan swagger:validate test:unit:ci test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms",
"@parallel infect:test:api infect:ci:unit infect:ci:db"
"@parallel infect:test:api infect:test:cli infect:ci:unit infect:ci:db"
],
"cs": "phpcs",
"cs": "phpcs -s",
"cs:fix": "phpcbf",
"stan": "APP_ENV=test php vendor/bin/phpstan analyse module/*/src module/*/config config docker/config data/migrations --level=8",
"stan": "APP_ENV=test php vendor/bin/phpstan analyse module/*/src module/*/test* module/*/config config docker/config data/migrations --level=8",
"test": [
"@test:unit",
"@test:db",
"@test:api"
"@parallel test:unit test:db",
"@parallel test:api test:cli"
],
"test:ci": [
"@test:unit:ci",
"@test:db",
"@test:api:ci"
],
"test:unit": "@php vendor/bin/phpunit --order-by=random --colors=always --coverage-php build/coverage-unit.cov --testdox",
"test:unit:ci": "@test:unit --coverage-xml=build/coverage-unit/coverage-xml --log-junit=build/coverage-unit/junit.xml",
"test:unit:pretty": "@php vendor/bin/phpunit --order-by=random --colors=always --coverage-html build/coverage-unit/coverage-html",
"test:unit": "@php vendor/bin/phpunit --order-by=random --colors=always --testdox",
"test:unit:ci": "@test:unit --coverage-php=build/coverage-unit.cov --coverage-xml=build/coverage-unit/coverage-xml --log-junit=build/coverage-unit/junit.xml",
"test:unit:pretty": "@test:unit --coverage-html build/coverage-unit/coverage-html",
"test:db": "@parallel test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms",
"test:db:sqlite": "APP_ENV=test php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-db.xml",
"test:db:sqlite:ci": "@test:db:sqlite --coverage-php build/coverage-db.cov --coverage-xml=build/coverage-db/coverage-xml --log-junit=build/coverage-db/junit.xml",
@@ -140,12 +132,18 @@
"test:db:postgres": "DB_DRIVER=postgres composer test:db:sqlite",
"test:db:ms": "DB_DRIVER=mssql composer test:db:sqlite",
"test:api": "bin/test/run-api-tests.sh",
"test:api:rr": "TEST_RUNTIME=rr bin/test/run-api-tests.sh",
"test:api:ci": "GENERATE_COVERAGE=yes composer test:api",
"infect:ci:base": "infection --threads=4 --log-verbosity=default --only-covered --only-covering-test-cases --skip-initial-tests",
"test:api:pretty": "GENERATE_COVERAGE=pretty composer test:api",
"test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml --log-junit=build/coverage-cli/junit.xml",
"test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli",
"test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli",
"infect:ci:base": "infection --threads=max --only-covered --skip-initial-tests",
"infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=80",
"infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json",
"infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json",
"infect:ci": "@parallel infect:ci:unit infect:ci:db infect:ci:api",
"infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json5",
"infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=95 --configuration=infection-api.json5",
"infect:ci:cli": "@infect:ci:base --coverage=build/coverage-cli --min-msi=90 --configuration=infection-cli.json5",
"infect:ci": "@parallel infect:ci:unit infect:ci:db infect:ci:api infect:ci:cli",
"infect:test": [
"@parallel test:unit:ci test:db:sqlite:ci test:api:ci",
"@infect:ci"
@@ -154,22 +152,28 @@
"@test:unit:ci",
"@infect:ci:unit"
],
"infect:test:db": [
"@test:db:sqlite:ci",
"@infect:ci:db"
],
"infect:test:api": [
"@test:api:ci",
"@infect:ci:api"
],
"infect:test:cli": [
"@test:cli:ci",
"@infect:ci:cli"
],
"swagger:validate": "php-openapi validate docs/swagger/swagger.json",
"swagger:inline": "php-openapi inline docs/swagger/swagger.json docs/swagger/swagger-inlined.json",
"clean:dev": "rm -f data/database.sqlite && rm -f config/params/generated_config.php"
},
"scripts-descriptions": {
"ci": "<fg=blue;options=bold>Alias for \"cs\", \"stan\", \"swagger:validate\", \"test:ci\" and \"infect:ci\"</>",
"ci:parallel": "<fg=blue;options=bold>Same as \"ci\", but parallelizing tasks as much as possible</>",
"cs": "<fg=blue;options=bold>Checks coding styles</>",
"cs:fix": "<fg=blue;options=bold>Fixes coding styles, when possible</>",
"stan": "<fg=blue;options=bold>Inspects code with phpstan</>",
"test": "<fg=blue;options=bold>Runs all test suites</>",
"test:ci": "<fg=blue;options=bold>Runs all test suites, generating all needed reports and logs for CI envs</>",
"test:unit": "<fg=blue;options=bold>Runs unit test suites</>",
"test:unit:ci": "<fg=blue;options=bold>Runs unit test suites, generating all needed reports and logs for CI envs</>",
"test:unit:pretty": "<fg=blue;options=bold>Runs unit test suites and generates an HTML code coverage report</>",
@@ -179,9 +183,13 @@
"test:db:mysql": "<fg=blue;options=bold>Runs database test suites on a MySQL database</>",
"test:db:maria": "<fg=blue;options=bold>Runs database test suites on a MariaDB database</>",
"test:db:postgres": "<fg=blue;options=bold>Runs database test suites on a PostgreSQL database</>",
"test:db:ms": "<fg=blue;options=bold>Runs database test suites on a Miscrosoft SQL Server database</>",
"test:db:ms": "<fg=blue;options=bold>Runs database test suites on a Microsoft SQL Server database</>",
"test:api": "<fg=blue;options=bold>Runs API test suites</>",
"test:api:ci": "<fg=blue;options=bold>Runs API test suites, and generates code coverage reports</>",
"test:api:ci": "<fg=blue;options=bold>Runs API test suites, and generates code coverage for CI</>",
"test:api:pretty": "<fg=blue;options=bold>Runs API test suites, and generates code coverage in HTML format</>",
"test:cli": "<fg=blue;options=bold>Runs CLI test suites</>",
"test:cli:ci": "<fg=blue;options=bold>Runs CLI test suites, and generates code coverage for CI</>",
"test:cli:pretty": "<fg=blue;options=bold>Runs CLI test suites, and generates code coverage in HTML format</>",
"infect:ci": "<fg=blue;options=bold>Checks unit and db tests quality applying mutation testing with existing reports and logs</>",
"infect:ci:unit": "<fg=blue;options=bold>Checks unit tests quality applying mutation testing with existing reports and logs</>",
"infect:ci:db": "<fg=blue;options=bold>Checks db tests quality applying mutation testing with existing reports and logs</>",
@@ -192,6 +200,12 @@
},
"config": {
"sort-packages": true,
"platform-check": false
"platform-check": false,
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"infection/extension-installer": true,
"veewee/composer-run-parallel": true
}
}
}

View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
return [
'app_options' => [
'version' => 'latest',
],
];

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
use Shlinkio\Shlink\Core\Config\EnvVars;
return (static function (): array {
$redisServers = EnvVars::REDIS_SERVERS->loadFromEnv();
$redis = ['pub_sub_enabled' => $redisServers !== null && EnvVars::REDIS_PUB_SUB_ENABLED->loadFromEnv(false)];
$cacheRedisBlock = $redisServers === null ? [] : [
'redis' => [
'servers' => $redisServers,
'sentinel_service' => EnvVars::REDIS_SENTINEL_SERVICE->loadFromEnv(),
'decode_credentials' => (bool) EnvVars::REDIS_DECODE_CREDENTIALS->loadFromEnv(false),
],
];
return [
'cache' => [
'namespace' => EnvVars::CACHE_NAMESPACE->loadFromEnv('Shlink'),
...$cacheRedisBlock,
],
'redis' => $redis,
];
})();

View File

@@ -8,8 +8,8 @@ return [
'debug' => false,
// Disabling config cache for cli, ensures it's never used for swoole and also that console commands don't generate
// a cache file that's then used by non-swoole web executions
// Disabling config cache for cli, ensures it's never used for openswoole/RoadRunner, and also that console
// commands don't generate a cache file that's then used by php-fpm web executions
ConfigAggregator::ENABLE_CACHE => PHP_SAPI !== 'cli',
];

View File

@@ -4,15 +4,17 @@ declare(strict_types=1);
namespace Shlinkio\Shlink;
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
use const Shlinkio\Shlink\DEFAULT_DELETE_SHORT_URL_THRESHOLD;
return (static function (): array {
$threshold = EnvVars::DELETE_SHORT_URL_THRESHOLD->loadFromEnv();
return [
return [
'delete_short_urls' => [
'check_visits_threshold' => true,
'visits_threshold' => (int) env('DELETE_SHORT_URL_THRESHOLD', DEFAULT_DELETE_SHORT_URL_THRESHOLD),
],
'delete_short_urls' => [
'check_visits_threshold' => $threshold !== null,
'visits_threshold' => (int) ($threshold ?? DEFAULT_DELETE_SHORT_URL_THRESHOLD),
],
];
];
})();

View File

@@ -3,14 +3,25 @@
declare(strict_types=1);
use GuzzleHttp\Client;
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Mezzio\Application;
use Mezzio\Container;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Spiral\RoadRunner\Http\PSR7Worker;
use Spiral\RoadRunner\WorkerInterface;
return [
'dependencies' => [
'factories' => [
PSR7Worker::class => ConfigAbstractFactory::class,
],
'delegators' => [
Mezzio\Application::class => [
Application::class => [
Container\ApplicationConfigInjectionDelegator::class,
],
],
@@ -26,4 +37,13 @@ return [
],
],
ConfigAbstractFactory::class => [
PSR7Worker::class => [
WorkerInterface::class,
ServerRequestFactoryInterface::class,
StreamFactoryInterface::class,
UploadedFileFactoryInterface::class,
],
],
];

View File

@@ -3,13 +3,13 @@
declare(strict_types=1);
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
use Shlinkio\Shlink\Core\Config\EnvVars;
use function Functional\contains;
use function Shlinkio\Shlink\Common\env;
use function Shlinkio\Shlink\Core\ArrayUtils\contains;
return (static function (): array {
$driver = env('DB_DRIVER');
$isMysqlCompatible = contains(['maria', 'mysql'], $driver);
$driver = EnvVars::DB_DRIVER->loadFromEnv();
$isMysqlCompatible = contains($driver, ['maria', 'mysql']);
$resolveDriver = static fn () => match ($driver) {
'postgres' => 'pdo_pgsql',
@@ -21,20 +21,30 @@ return (static function (): array {
'mssql' => '1433',
default => '3306',
};
$resolveConnection = static fn () => match (true) {
$driver === null || $driver === 'sqlite' => [
$resolveCharset = static fn () => match ($driver) {
// This does not determine charsets or collations in tables or columns, but the charset used in the data
// flowing in the connection, so it has to match what has been set in the database.
'maria', 'mysql' => 'utf8mb4',
'postgres' => 'utf8',
default => null,
};
$resolveConnection = static fn () => match ($driver) {
null, 'sqlite' => [
'driver' => 'pdo_sqlite',
'path' => 'data/database.sqlite',
],
default => [
'driver' => $resolveDriver(),
'dbname' => env('DB_NAME', 'shlink'),
'user' => env('DB_USER'),
'password' => env('DB_PASSWORD'),
'host' => env('DB_HOST', $driver === 'postgres' ? env('DB_UNIX_SOCKET') : null),
'port' => env('DB_PORT', $resolveDefaultPort()),
'unix_socket' => $isMysqlCompatible ? env('DB_UNIX_SOCKET') : null,
'charset' => 'utf8',
'dbname' => EnvVars::DB_NAME->loadFromEnv('shlink'),
'user' => EnvVars::DB_USER->loadFromEnv(),
'password' => EnvVars::DB_PASSWORD->loadFromEnv(),
'host' => EnvVars::DB_HOST->loadFromEnv(EnvVars::DB_UNIX_SOCKET->loadFromEnv()),
'port' => EnvVars::DB_PORT->loadFromEnv($resolveDefaultPort()),
'unix_socket' => $isMysqlCompatible ? EnvVars::DB_UNIX_SOCKET->loadFromEnv() : null,
'charset' => $resolveCharset(),
'driverOptions' => $driver !== 'mssql' ? [] : [
'TrustServerCertificate' => 'true',
],
],
};

View File

@@ -6,12 +6,40 @@ return [
'entity_manager' => [
'connection' => [
// MySQL
'user' => 'root',
'password' => 'root',
'driver' => 'pdo_mysql',
'host' => 'shlink_db_mysql',
'dbname' => 'shlink',
'charset' => 'utf8',
// 'dbname' => 'shlink_foo',
'charset' => 'utf8mb4',
// MariaDB
// 'user' => 'root',
// 'password' => 'root',
// 'driver' => 'pdo_mysql',
// 'host' => 'shlink_db_maria',
// 'dbname' => 'shlink_foo',
// 'charset' => 'utf8mb4',
// Postgres
// 'user' => 'postgres',
// 'password' => 'root',
// 'driver' => 'pdo_pgsql',
// 'host' => 'shlink_db_postgres',
// 'dbname' => 'shlink_foo',
// 'charset' => 'utf8',
// MSSQL
// 'user' => 'sa',
// 'password' => 'Passw0rd!',
// 'driver' => 'pdo_sqlsrv',
// 'host' => 'shlink_db_ms',
// 'dbname' => 'shlink_foo',
// 'driverOptions' => [
// 'TrustServerCertificate' => 'true',
// ],
],
],

View File

@@ -6,12 +6,14 @@ use Laminas\Stratigility\Middleware\ErrorHandler;
use Mezzio\ProblemDetails\ProblemDetailsMiddleware;
use Shlinkio\Shlink\Common\Logger;
use function Shlinkio\Shlink\Core\toProblemDetailsType;
return [
'problem-details' => [
'default_types_map' => [
404 => 'NOT_FOUND',
500 => 'INTERNAL_SERVER_ERROR',
404 => toProblemDetailsType('not-found'),
500 => toProblemDetailsType('internal-server-error'),
],
],

View File

@@ -2,14 +2,14 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'geolite2' => [
'db_location' => __DIR__ . '/../../data/GeoLite2-City.mmdb',
'temp_dir' => __DIR__ . '/../../data',
'license_key' => env('GEOLITE_LICENSE_KEY', 'G4Lm0C60yJsnkdPi'), // Deprecated. Remove hardcoded license on v3
'license_key' => EnvVars::GEOLITE_LICENSE_KEY->loadFromEnv(),
],
];

View File

@@ -11,6 +11,7 @@ return [
'installer' => [
'enabled_options' => [
Option\Server\RuntimeConfigOption::class,
Option\Database\DatabaseDriverConfigOption::class,
Option\Database\DatabaseNameConfigOption::class,
Option\Database\DatabaseHostConfigOption::class,
@@ -18,22 +19,23 @@ return [
Option\Database\DatabaseUserConfigOption::class,
Option\Database\DatabasePasswordConfigOption::class,
Option\Database\DatabaseUnixSocketConfigOption::class,
Option\Database\DatabaseSqlitePathConfigOption::class,
Option\Database\DatabaseMySqlOptionsConfigOption::class,
Option\UrlShortener\ShortDomainHostConfigOption::class,
Option\UrlShortener\ShortDomainSchemaConfigOption::class,
Option\UrlShortener\ValidateUrlConfigOption::class,
Option\Visit\VisitsWebhooksConfigOption::class,
Option\Visit\OrphanVisitsWebhooksConfigOption::class,
Option\Redirect\BaseUrlRedirectConfigOption::class,
Option\Redirect\InvalidShortUrlRedirectConfigOption::class,
Option\Redirect\Regular404RedirectConfigOption::class,
Option\Visit\CheckVisitsThresholdConfigOption::class,
Option\Visit\VisitsThresholdConfigOption::class,
Option\BasePathConfigOption::class,
Option\TimezoneConfigOption::class,
Option\Cache\CacheNamespaceConfigOption::class,
Option\Worker\TaskWorkerNumConfigOption::class,
Option\Worker\WebWorkerNumConfigOption::class,
Option\RedisServersConfigOption::class,
Option\Redis\RedisServersConfigOption::class,
Option\Redis\RedisDecodeCredentialsConfigOption::class,
Option\Redis\RedisSentinelServiceConfigOption::class,
Option\Redis\RedisPubSubConfigOption::class,
Option\UrlShortener\ShortCodeLengthOption::class,
Option\Mercure\EnableMercureConfigOption::class,
Option\Mercure\MercurePublicUrlConfigOption::class,
@@ -44,6 +46,9 @@ return [
Option\UrlShortener\RedirectCacheLifeTimeConfigOption::class,
Option\UrlShortener\AutoResolveTitlesConfigOption::class,
Option\UrlShortener\AppendExtraPathConfigOption::class,
Option\UrlShortener\EnableMultiSegmentSlugsConfigOption::class,
Option\UrlShortener\EnableTrailingSlashConfigOption::class,
Option\UrlShortener\ShortUrlModeConfigOption::class,
Option\Tracking\IpAnonymizationConfigOption::class,
Option\Tracking\OrphanVisitsTrackingConfigOption::class,
Option\Tracking\DisableTrackParamConfigOption::class,
@@ -57,24 +62,42 @@ return [
Option\QrCode\DefaultFormatConfigOption::class,
Option\QrCode\DefaultErrorCorrectionConfigOption::class,
Option\QrCode\DefaultRoundBlockSizeConfigOption::class,
Option\QrCode\EnabledForDisabledShortUrlsConfigOption::class,
Option\RabbitMq\RabbitMqEnabledConfigOption::class,
Option\RabbitMq\RabbitMqHostConfigOption::class,
Option\RabbitMq\RabbitMqUseSslConfigOption::class,
Option\RabbitMq\RabbitMqPortConfigOption::class,
Option\RabbitMq\RabbitMqUserConfigOption::class,
Option\RabbitMq\RabbitMqPasswordConfigOption::class,
Option\RabbitMq\RabbitMqVhostConfigOption::class,
Option\Matomo\MatomoEnabledConfigOption::class,
Option\Matomo\MatomoBaseUrlConfigOption::class,
Option\Matomo\MatomoSiteIdConfigOption::class,
Option\Matomo\MatomoApiTokenConfigOption::class,
],
'installation_commands' => [
InstallationCommand::DB_CREATE_SCHEMA => [
InstallationCommand::DB_CREATE_SCHEMA->value => [
'command' => 'bin/cli ' . Command\Db\CreateDatabaseCommand::NAME,
],
InstallationCommand::DB_MIGRATE => [
InstallationCommand::DB_MIGRATE->value => [
'command' => 'bin/cli ' . Command\Db\MigrateDatabaseCommand::NAME,
],
InstallationCommand::GEOLITE_DOWNLOAD_DB => [
InstallationCommand::ORM_PROXIES->value => [
'command' => 'bin/doctrine orm:generate-proxies',
],
InstallationCommand::ORM_CLEAR_CACHE->value => [
'command' => 'bin/doctrine orm:clear-cache:metadata',
],
InstallationCommand::GEOLITE_DOWNLOAD_DB->value => [
'command' => 'bin/cli ' . Command\Visit\DownloadGeoLiteDbCommand::NAME,
],
InstallationCommand::API_KEY_GENERATE->value => [
'command' => 'bin/cli ' . Command\Api\GenerateKeyCommand::NAME,
],
InstallationCommand::API_KEY_CREATE->value => [
'command' => 'bin/cli ' . Command\Api\InitialApiKeyCommand::NAME,
],
],
],

View File

@@ -3,12 +3,12 @@
declare(strict_types=1);
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Predis\ClientInterface as PredisClient;
use Shlinkio\Shlink\Common\Cache\RedisFactory;
use Shlinkio\Shlink\Common\Lock\NamespacedStore;
use Shlinkio\Shlink\Common\Logger\LoggerAwareDelegatorFactory;
use Shlinkio\Shlink\Core\Config\EnvVars;
use Symfony\Component\Lock;
use function Shlinkio\Shlink\Common\env;
use const Shlinkio\Shlink\LOCAL_LOCK_FACTORY;
return [
@@ -23,11 +23,12 @@ return [
Lock\Store\RedisStore::class => ConfigAbstractFactory::class,
Lock\LockFactory::class => ConfigAbstractFactory::class,
LOCAL_LOCK_FACTORY => ConfigAbstractFactory::class,
NamespacedStore::class => ConfigAbstractFactory::class,
],
'aliases' => [
'lock_store' => env('REDIS_SERVERS') === null ? 'local_lock_store' : 'redis_lock_store',
'lock_store' => EnvVars::REDIS_SERVERS->existsInEnv() ? 'redis_lock_store' : 'local_lock_store',
'redis_lock_store' => Lock\Store\RedisStore::class,
'redis_lock_store' => NamespacedStore::class,
'local_lock_store' => Lock\Store\FlockStore::class,
],
'delegators' => [
@@ -39,7 +40,9 @@ return [
ConfigAbstractFactory::class => [
Lock\Store\FlockStore::class => ['config.locks.locks_dir'],
Lock\Store\RedisStore::class => [PredisClient::class],
Lock\Store\RedisStore::class => [RedisFactory::SERVICE_NAME],
NamespacedStore::class => [Lock\Store\RedisStore::class, 'config.cache.namespace'],
Lock\LockFactory::class => ['lock_store'],
LOCAL_LOCK_FACTORY => ['local_lock_store'],
],

View File

@@ -4,87 +4,64 @@ declare(strict_types=1);
namespace Shlinkio\Shlink;
use Monolog\Formatter;
use Monolog\Handler;
use Laminas\ServiceManager\Factory\InvokableFactory;
use Monolog\Level;
use Monolog\Logger;
use Monolog\Processor;
use MonologFactory\DiContainerLoggerFactory;
use PhpMiddleware\RequestId;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Shlinkio\Shlink\Common\Logger\LoggerFactory;
use Shlinkio\Shlink\Common\Logger\LoggerType;
use Shlinkio\Shlink\Common\Middleware\AccessLogMiddleware;
use const PHP_EOL;
use function Shlinkio\Shlink\Config\runningInRoadRunner;
$processors = [
'exception_with_new_line' => [
'name' => Common\Logger\Processor\ExceptionWithNewLineProcessor::class,
],
'psr3' => [
'name' => Processor\PsrLogMessageProcessor::class,
],
'request_id' => RequestId\MonologProcessor::class,
];
$formatter = [
'name' => Formatter\LineFormatter::class,
'params' => [
'format' => '[%datetime%] [%extra.request_id%] %channel%.%level_name% - %message%' . PHP_EOL,
'allow_inline_line_breaks' => true,
],
];
return (static function (): array {
$common = [
'level' => Level::Info->value,
'processors' => [RequestId\MonologProcessor::class],
'line_format' => '[%datetime%] [%extra.request_id%] %channel%.%level_name% - %message%',
];
return [
return [
'logger' => [
'Shlink' => [
'name' => 'Shlink',
'handlers' => [
'shlink_handler' => [
'name' => Handler\RotatingFileHandler::class,
'params' => [
'level' => Logger::INFO,
'filename' => 'data/log/shlink_log.log',
'max_files' => 30,
'file_permission' => 0666,
],
'formatter' => $formatter,
'logger' => [
'Shlink' => [
'type' => LoggerType::FILE->value,
...$common,
],
'Access' => [
'type' => LoggerType::STREAM->value,
'destination' => 'php://stderr',
'add_new_line' => ! runningInRoadRunner(),
...$common,
],
],
'dependencies' => [
'factories' => [
'Logger_Shlink' => [LoggerFactory::class, 'Shlink'],
'Logger_Access' => [LoggerFactory::class, 'Access'],
NullLogger::class => InvokableFactory::class,
],
'aliases' => [
'logger' => 'Logger_Shlink',
Logger::class => 'Logger_Shlink',
LoggerInterface::class => 'Logger_Shlink',
AccessLogMiddleware::LOGGER_SERVICE_NAME => 'Logger_Access',
],
],
// Deprecated. Remove in Shlink 4.0.0
'mezzio-swoole' => [
'swoole-http-server' => [
'logger' => [
// Let's disable mezio-swoole access logging, so that we can provide our own implementation,
// consistent for roadrunner and openswoole
'logger-name' => NullLogger::class,
],
],
'processors' => $processors,
],
'Access' => [
'name' => 'Access',
'handlers' => [
'access_handler' => [
'name' => Handler\StreamHandler::class,
'params' => [
'level' => Logger::INFO,
'stream' => 'php://stdout',
],
'formatter' => $formatter,
],
],
'processors' => $processors,
],
],
'dependencies' => [
'factories' => [
'Logger_Shlink' => [DiContainerLoggerFactory::class, 'Shlink'],
'Logger_Access' => [DiContainerLoggerFactory::class, 'Access'],
],
'aliases' => [
'logger' => 'Logger_Shlink',
Logger::class => 'Logger_Shlink',
LoggerInterface::class => 'Logger_Shlink',
],
],
'mezzio-swoole' => [
'swoole-http-server' => [
'logger' => [
'logger-name' => 'Logger_Access',
'format' => '%h %l %u "%r" %>s %b',
],
],
],
];
];
})();

View File

@@ -2,33 +2,16 @@
declare(strict_types=1);
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
$isSwoole = extension_loaded('openswoole');
// For swoole, send logs to standard output
$handler = $isSwoole
? [
'name' => StreamHandler::class,
'params' => [
'level' => Logger::DEBUG,
'stream' => 'php://stdout',
],
]
: [
'params' => [
'level' => Logger::DEBUG,
],
];
use Monolog\Level;
use Shlinkio\Shlink\Common\Logger\LoggerType;
return [
'logger' => [
'Shlink' => [
'handlers' => [
'shlink_handler' => $handler,
],
'type' => LoggerType::STREAM->value,
'destination' => 'php://stderr',
'level' => Level::Debug->value,
],
],

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'matomo' => [
'enabled' => (bool) EnvVars::MATOMO_ENABLED->loadFromEnv(false),
'base_url' => EnvVars::MATOMO_BASE_URL->loadFromEnv(),
'site_id' => EnvVars::MATOMO_SITE_ID->loadFromEnv(),
'api_token' => EnvVars::MATOMO_API_TOKEN->loadFromEnv(),
],
];

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
/*
* Dev matomo instance needs to be manually configured once before enabling the configuration below.
*
* 1. Go to http://localhost:8003 and follow the installation instructions.
* 2. Open data/infra/matomo/config/config.ini.php and replace `trusted_hosts[] = "localhost"` with
* `trusted_hosts[] = "localhost:8003"` (see https://github.com/matomo-org/matomo/issues/9549)
* 3. Go to http://localhost:8003/index.php?module=SitesManager&action=index and paste the ID for the site you just
* created into the `site_id` field below.
* 4. Go to http://localhost:8003/index.php?module=UsersManager&action=userSecurity, scroll down, click
* "Create new token" and once generated, paste the token into the `api_token` field below.
*/
return [
'matomo' => [
// 'enabled' => true,
// 'base_url' => 'http://shlink_matomo',
// 'site_id' => '...',
// 'api_token' => '...',
],
];

View File

@@ -4,20 +4,19 @@ declare(strict_types=1);
use Laminas\ServiceManager\Proxy\LazyServiceFactory;
use Shlinkio\Shlink\Common\Mercure\LcobucciJwtProvider;
use Shlinkio\Shlink\Core\Config\EnvVars;
use Symfony\Component\Mercure\Hub;
use Symfony\Component\Mercure\HubInterface;
use function Shlinkio\Shlink\Common\env;
return (static function (): array {
$publicUrl = env('MERCURE_PUBLIC_HUB_URL');
$publicUrl = EnvVars::MERCURE_PUBLIC_HUB_URL->loadFromEnv();
return [
'mercure' => [
'public_hub_url' => $publicUrl,
'internal_hub_url' => env('MERCURE_INTERNAL_HUB_URL', $publicUrl),
'jwt_secret' => env('MERCURE_JWT_SECRET'),
'internal_hub_url' => EnvVars::MERCURE_INTERNAL_HUB_URL->loadFromEnv($publicUrl),
'jwt_secret' => EnvVars::MERCURE_JWT_SECRET->loadFromEnv(),
'jwt_issuer' => 'Shlink',
],

View File

@@ -7,7 +7,7 @@ return [
'mercure' => [
'public_hub_url' => 'http://localhost:8001',
'internal_hub_url' => 'http://shlink_mercure_proxy',
'jwt_secret' => 'mercure_jwt_key',
'jwt_secret' => 'mercure_jwt_key_long_enough_to_avoid_error',
],
];

View File

@@ -9,6 +9,7 @@ use Mezzio\ProblemDetails;
use Mezzio\Router;
use PhpMiddleware\RequestId\RequestIdMiddleware;
use RKA\Middleware\IpAddress;
use Shlinkio\Shlink\Common\Middleware\AccessLogMiddleware;
use Shlinkio\Shlink\Common\Middleware\ContentLengthMiddleware;
return [
@@ -16,6 +17,7 @@ return [
'middleware_pipeline' => [
'error-handler' => [
'middleware' => [
AccessLogMiddleware::class,
ContentLengthMiddleware::class,
RequestIdMiddleware::class,
ErrorHandler::class,
@@ -45,6 +47,7 @@ return [
'rest' => [
'path' => '/rest',
'middleware' => [
Rest\Middleware\ErrorHandler\BackwardsCompatibleProblemDetailsHandler::class,
Router\Middleware\ImplicitOptionsMiddleware::class,
Rest\Middleware\BodyParserMiddleware::class,
Rest\Middleware\AuthenticationMiddleware::class,

View File

@@ -2,8 +2,9 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_ERROR_CORRECTION;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_FORMAT;
use const Shlinkio\Shlink\DEFAULT_QR_CODE_MARGIN;
@@ -13,11 +14,18 @@ use const Shlinkio\Shlink\DEFAULT_QR_CODE_SIZE;
return [
'qr_codes' => [
'size' => (int) env('DEFAULT_QR_CODE_SIZE', DEFAULT_QR_CODE_SIZE),
'margin' => (int) env('DEFAULT_QR_CODE_MARGIN', DEFAULT_QR_CODE_MARGIN),
'format' => env('DEFAULT_QR_CODE_FORMAT', DEFAULT_QR_CODE_FORMAT),
'error_correction' => env('DEFAULT_QR_CODE_ERROR_CORRECTION', DEFAULT_QR_CODE_ERROR_CORRECTION),
'round_block_size' => (bool) env('DEFAULT_QR_CODE_ROUND_BLOCK_SIZE', DEFAULT_QR_CODE_ROUND_BLOCK_SIZE),
'size' => (int) EnvVars::DEFAULT_QR_CODE_SIZE->loadFromEnv(DEFAULT_QR_CODE_SIZE),
'margin' => (int) EnvVars::DEFAULT_QR_CODE_MARGIN->loadFromEnv(DEFAULT_QR_CODE_MARGIN),
'format' => EnvVars::DEFAULT_QR_CODE_FORMAT->loadFromEnv(DEFAULT_QR_CODE_FORMAT),
'error_correction' => EnvVars::DEFAULT_QR_CODE_ERROR_CORRECTION->loadFromEnv(
DEFAULT_QR_CODE_ERROR_CORRECTION,
),
'round_block_size' => (bool) EnvVars::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE->loadFromEnv(
DEFAULT_QR_CODE_ROUND_BLOCK_SIZE,
),
'enabled_for_disabled_short_urls' => (bool) EnvVars::QR_CODE_FOR_DISABLED_SHORT_URLS->loadFromEnv(
DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS,
),
],
];

View File

@@ -2,47 +2,21 @@
declare(strict_types=1);
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Laminas\ServiceManager\Proxy\LazyServiceFactory;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'rabbitmq' => [
'enabled' => (bool) env('RABBITMQ_ENABLED', false),
'host' => env('RABBITMQ_HOST'),
'port' => (int) env('RABBITMQ_PORT', '5672'),
'user' => env('RABBITMQ_USER'),
'password' => env('RABBITMQ_PASSWORD'),
'vhost' => env('RABBITMQ_VHOST', '/'),
],
'enabled' => (bool) EnvVars::RABBITMQ_ENABLED->loadFromEnv(false),
'host' => EnvVars::RABBITMQ_HOST->loadFromEnv(),
'use_ssl' => (bool) EnvVars::RABBITMQ_USE_SSL->loadFromEnv(false),
'port' => (int) EnvVars::RABBITMQ_PORT->loadFromEnv('5672'),
'user' => EnvVars::RABBITMQ_USER->loadFromEnv(),
'password' => EnvVars::RABBITMQ_PASSWORD->loadFromEnv(),
'vhost' => EnvVars::RABBITMQ_VHOST->loadFromEnv('/'),
'dependencies' => [
'factories' => [
AMQPStreamConnection::class => ConfigAbstractFactory::class,
],
'delegators' => [
AMQPStreamConnection::class => [
LazyServiceFactory::class,
],
],
'lazy_services' => [
'class_map' => [
AMQPStreamConnection::class => AMQPStreamConnection::class,
],
],
],
ConfigAbstractFactory::class => [
AMQPStreamConnection::class => [
'config.rabbitmq.host',
'config.rabbitmq.port',
'config.rabbitmq.user',
'config.rabbitmq.password',
'config.rabbitmq.vhost',
],
// Deprecated
'legacy_visits_publishing' => (bool) EnvVars::RABBITMQ_LEGACY_VISITS_PUBLISHING->loadFromEnv(false),
],
];

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_CACHE_LIFETIME;
use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE;
@@ -10,16 +10,16 @@ use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE;
return [
'not_found_redirects' => [
// Deprecated env vars
'invalid_short_url' => env('DEFAULT_INVALID_SHORT_URL_REDIRECT', env('INVALID_SHORT_URL_REDIRECT_TO')),
'regular_404' => env('DEFAULT_REGULAR_404_REDIRECT', env('REGULAR_404_REDIRECT_TO')),
'base_url' => env('DEFAULT_BASE_URL_REDIRECT', env('BASE_URL_REDIRECT_TO')),
'invalid_short_url' => EnvVars::DEFAULT_INVALID_SHORT_URL_REDIRECT->loadFromEnv(),
'regular_404' => EnvVars::DEFAULT_REGULAR_404_REDIRECT->loadFromEnv(),
'base_url' => EnvVars::DEFAULT_BASE_URL_REDIRECT->loadFromEnv(),
],
'url_shortener' => [
// TODO Move these options to their own config namespace. Maybe "redirects".
'redirect_status_code' => (int) env('REDIRECT_STATUS_CODE', DEFAULT_REDIRECT_STATUS_CODE),
'redirect_cache_lifetime' => (int) env('REDIRECT_CACHE_LIFETIME', DEFAULT_REDIRECT_CACHE_LIFETIME),
'redirects' => [
'redirect_status_code' => (int) EnvVars::REDIRECT_STATUS_CODE->loadFromEnv(DEFAULT_REDIRECT_STATUS_CODE->value),
'redirect_cache_lifetime' => (int) EnvVars::REDIRECT_CACHE_LIFETIME->loadFromEnv(
DEFAULT_REDIRECT_CACHE_LIFETIME,
),
],
];

View File

@@ -1,21 +0,0 @@
<?php
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
return (static function (): array {
$redisServers = env('REDIS_SERVERS');
return match (true) {
$redisServers === null => [],
default => [
'cache' => [
'redis' => [
'servers' => $redisServers,
'sentinel_service' => env('REDIS_SENTINEL_SERVICE'),
],
],
],
};
})();

View File

@@ -7,12 +7,15 @@ return [
'cache' => [
'redis' => [
'servers' => 'tcp://shlink_redis:6379',
// 'servers' => [
// 'tcp://shlink_redis:6379',
// ],
// 'servers' => 'tcp://barbar@shlink_redis_acl:6379',
// 'servers' => 'tcp://foo:bar@shlink_redis_acl:6379',
],
],
'redis' => [
'pub_sub_enabled' => true,
],
'dependencies' => [
'aliases' => [
// With this config, a user could alias 'lock_store' => 'redis_lock_store' to override the default

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Laminas\ServiceManager\Factory\InvokableFactory;
use PhpMiddleware\RequestId;
use Shlinkio\Shlink\Common\Logger\Processor\BackwardsCompatibleMonologProcessorDelegator;
return [
@@ -20,6 +21,11 @@ return [
RequestId\RequestIdMiddleware::class => ConfigAbstractFactory::class,
RequestId\MonologProcessor::class => ConfigAbstractFactory::class,
],
'delegators' => [
RequestId\MonologProcessor::class => [
BackwardsCompatibleMonologProcessorDelegator::class,
],
],
],
ConfigAbstractFactory::class => [

View File

@@ -3,13 +3,12 @@
declare(strict_types=1);
use Mezzio\Router\FastRouteRouter;
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
return [
'router' => [
'base_path' => env('BASE_PATH', ''),
'base_path' => EnvVars::BASE_PATH->loadFromEnv(''),
'fastroute' => [
FastRouteRouter::CONFIG_CACHE_ENABLED => true,

View File

@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink;
use Fig\Http\Message\RequestMethodInterface;
use RKA\Middleware\IpAddress;
use Shlinkio\Shlink\Core\Action as CoreAction;
use Shlinkio\Shlink\Core\Config\EnvVars;
use Shlinkio\Shlink\Core\ShortUrl\Middleware\TrimTrailingSlashMiddleware;
use Shlinkio\Shlink\Rest\Action;
use Shlinkio\Shlink\Rest\ConfigProvider;
use Shlinkio\Shlink\Rest\Middleware;
use Shlinkio\Shlink\Rest\Middleware\Mercure\NotConfiguredMercureErrorHandler;
use function sprintf;
return (static function (): array {
$contentNegotiationMiddleware = Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class;
$dropDomainMiddleware = Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class;
$overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class;
// TODO This should be based on config, not the env var
$shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false) ? '[/]' : '';
return [
// The order of the routes defined here matters. Changing it might cause path conflicts
'routes' => [
// Rest
...ConfigProvider::applyRoutesPrefix([
Action\HealthAction::getRouteDef(),
// Visits.
// These routes must go first, as they have a more specific path, otherwise, when multi-segment slugs
// are enabled, routes with a less-specific path might match first
Action\Visit\ShortUrlVisitsAction::getRouteDef([$dropDomainMiddleware]),
Action\ShortUrl\DeleteShortUrlVisitsAction::getRouteDef([$dropDomainMiddleware]),
Action\Visit\TagVisitsAction::getRouteDef(),
Action\Visit\DomainVisitsAction::getRouteDef(),
Action\Visit\GlobalVisitsAction::getRouteDef(),
Action\Visit\OrphanVisitsAction::getRouteDef(),
Action\Visit\DeleteOrphanVisitsAction::getRouteDef(),
Action\Visit\NonOrphanVisitsAction::getRouteDef(),
// Short URLs
Action\ShortUrl\CreateShortUrlAction::getRouteDef([
$contentNegotiationMiddleware,
$dropDomainMiddleware,
$overrideDomainMiddleware,
Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class,
]),
Action\ShortUrl\SingleStepCreateShortUrlAction::getRouteDef([
$contentNegotiationMiddleware,
$overrideDomainMiddleware,
]),
Action\ShortUrl\EditShortUrlAction::getRouteDef([$dropDomainMiddleware]),
Action\ShortUrl\DeleteShortUrlAction::getRouteDef([$dropDomainMiddleware]),
Action\ShortUrl\ResolveShortUrlAction::getRouteDef([$dropDomainMiddleware]),
Action\ShortUrl\ListShortUrlsAction::getRouteDef(),
// Tags
Action\Tag\ListTagsAction::getRouteDef(),
Action\Tag\TagsStatsAction::getRouteDef(),
Action\Tag\DeleteTagsAction::getRouteDef(),
Action\Tag\UpdateTagAction::getRouteDef(),
// Domains
Action\Domain\ListDomainsAction::getRouteDef(),
Action\Domain\DomainRedirectsAction::getRouteDef(),
Action\MercureInfoAction::getRouteDef([NotConfiguredMercureErrorHandler::class]),
]),
// Non-rest
[
'name' => CoreAction\RobotsAction::class,
'path' => '/robots.txt',
'middleware' => [
CoreAction\RobotsAction::class,
],
'allowed_methods' => [RequestMethodInterface::METHOD_GET],
],
[
'name' => CoreAction\PixelAction::class,
'path' => '/{shortCode}/track',
'middleware' => [
IpAddress::class,
CoreAction\PixelAction::class,
],
'allowed_methods' => [RequestMethodInterface::METHOD_GET],
],
[
'name' => CoreAction\QrCodeAction::class,
'path' => '/{shortCode}/qr-code',
'middleware' => [
CoreAction\QrCodeAction::class,
],
'allowed_methods' => [RequestMethodInterface::METHOD_GET],
],
[
'name' => CoreAction\RedirectAction::class,
'path' => sprintf('/{shortCode}%s', $shortUrlRouteSuffix),
'middleware' => [
IpAddress::class,
TrimTrailingSlashMiddleware::class,
CoreAction\RedirectAction::class,
],
'allowed_methods' => [RequestMethodInterface::METHOD_GET],
],
],
];
})();

View File

@@ -2,12 +2,14 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
use function Shlinkio\Shlink\Config\getOpenswooleConfigFromEnv;
use const Shlinkio\Shlink\MIN_TASK_WORKERS;
return (static function () {
$taskWorkers = (int) env('TASK_WORKER_NUM', 16);
return (static function (): array {
$taskWorkers = (int) EnvVars::TASK_WORKER_NUM->loadFromEnv(16);
return [
@@ -17,11 +19,12 @@ return (static function () {
'swoole-http-server' => [
'host' => '0.0.0.0',
'port' => (int) env('PORT', 8080),
'port' => (int) EnvVars::PORT->loadFromEnv(8080),
'process-name' => 'shlink',
'options' => [
'worker_num' => (int) env('WEB_WORKER_NUM', 16),
...getOpenswooleConfigFromEnv(),
'worker_num' => (int) EnvVars::WEB_WORKER_NUM->loadFromEnv(16),
'task_worker_num' => max($taskWorkers, MIN_TASK_WORKERS),
],
],

View File

@@ -2,35 +2,42 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
return [
return (static function (): array {
/** @var string|null $disableTrackingFrom */
$disableTrackingFrom = EnvVars::DISABLE_TRACKING_FROM->loadFromEnv();
'tracking' => [
// Tells if IP addresses should be anonymized before persisting, to fulfil data protection regulations
// This applies only if IP address tracking is enabled
'anonymize_remote_addr' => (bool) env('ANONYMIZE_REMOTE_ADDR', true),
return [
// Tells if visits to not-found URLs should be tracked. The disable_tracking option takes precedence
'track_orphan_visits' => (bool) env('TRACK_ORPHAN_VISITS', true),
'tracking' => [
// Tells if IP addresses should be anonymized before persisting, to fulfil data protection regulations
// This applies only if IP address tracking is enabled
'anonymize_remote_addr' => (bool) EnvVars::ANONYMIZE_REMOTE_ADDR->loadFromEnv(true),
// A query param that, if provided, will disable tracking of one particular visit. Always takes precedence
'disable_track_param' => env('DISABLE_TRACK_PARAM'),
// Tells if visits to not-found URLs should be tracked. The disable_tracking option takes precedence
'track_orphan_visits' => (bool) EnvVars::TRACK_ORPHAN_VISITS->loadFromEnv(true),
// If true, visits will not be tracked at all
'disable_tracking' => (bool) env('DISABLE_TRACKING', false),
// A query param that, if provided, will disable tracking of one particular visit. Always takes precedence
'disable_track_param' => EnvVars::DISABLE_TRACK_PARAM->loadFromEnv(),
// If true, visits will be tracked, but neither the IP address, nor the location will be resolved
'disable_ip_tracking' => (bool) env('DISABLE_IP_TRACKING', false),
// If true, visits will not be tracked at all
'disable_tracking' => (bool) EnvVars::DISABLE_TRACKING->loadFromEnv(false),
// If true, the referrer will not be tracked
'disable_referrer_tracking' => (bool) env('DISABLE_REFERRER_TRACKING', false),
// If true, visits will be tracked, but neither the IP address, nor the location will be resolved
'disable_ip_tracking' => (bool) EnvVars::DISABLE_IP_TRACKING->loadFromEnv(false),
// If true, the user agent will not be tracked
'disable_ua_tracking' => (bool) env('DISABLE_UA_TRACKING', false),
// If true, the referrer will not be tracked
'disable_referrer_tracking' => (bool) EnvVars::DISABLE_REFERRER_TRACKING->loadFromEnv(false),
// A list of IP addresses, patterns or CIDR blocks from which tracking is disabled by default
'disable_tracking_from' => env('DISABLE_TRACKING_FROM'),
],
// If true, the user agent will not be tracked
'disable_ua_tracking' => (bool) EnvVars::DISABLE_UA_TRACKING->loadFromEnv(false),
];
// A list of IP addresses, patterns or CIDR blocks from which tracking is disabled by default
'disable_tracking_from' => $disableTrackingFrom === null
? []
: array_map(trim(...), explode(',', $disableTrackingFrom)),
],
];
})();

View File

@@ -2,40 +2,33 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode;
use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH;
use const Shlinkio\Shlink\MIN_SHORT_CODES_LENGTH;
return (static function (): array {
$shortCodesLength = max(
(int) env('DEFAULT_SHORT_CODES_LENGTH', DEFAULT_SHORT_CODES_LENGTH),
(int) EnvVars::DEFAULT_SHORT_CODES_LENGTH->loadFromEnv(DEFAULT_SHORT_CODES_LENGTH),
MIN_SHORT_CODES_LENGTH,
);
$resolveSchema = static function (): string {
// Deprecated. For v3, IS_HTTPS_ENABLED should be true by default, instead of null
// return ((bool) env('IS_HTTPS_ENABLED', true)) ? 'https' : 'http';
$isHttpsEnabled = env('IS_HTTPS_ENABLED', env('USE_HTTPS'));
if ($isHttpsEnabled !== null) {
$boolIsHttpsEnabled = (bool) $isHttpsEnabled;
return $boolIsHttpsEnabled ? 'https' : 'http';
}
return env('SHORT_DOMAIN_SCHEMA', 'http');
};
$modeFromEnv = EnvVars::SHORT_URL_MODE->loadFromEnv(ShortUrlMode::STRICT->value);
$mode = ShortUrlMode::tryDeprecated($modeFromEnv) ?? ShortUrlMode::STRICT;
return [
'url_shortener' => [
'domain' => [
// Deprecated SHORT_DOMAIN_* env vars
'schema' => $resolveSchema(),
'hostname' => env('DEFAULT_DOMAIN', env('SHORT_DOMAIN_HOST', '')),
'domain' => [ // TODO Refactor this structure to url_shortener.schema and url_shortener.default_domain
'schema' => ((bool) EnvVars::IS_HTTPS_ENABLED->loadFromEnv(true)) ? 'https' : 'http',
'hostname' => EnvVars::DEFAULT_DOMAIN->loadFromEnv(''),
],
'validate_url' => (bool) env('VALIDATE_URLS', false), // Deprecated
'default_short_codes_length' => $shortCodesLength,
'auto_resolve_titles' => (bool) env('AUTO_RESOLVE_TITLES', false),
'append_extra_path' => (bool) env('REDIRECT_APPEND_EXTRA_PATH', false),
'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(false),
'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(false),
'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(false),
'trailing_slash_enabled' => (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false),
'mode' => $mode,
],
];

View File

@@ -2,16 +2,23 @@
declare(strict_types=1);
$isSwoole = extension_loaded('openswoole');
use function Shlinkio\Shlink\Config\runningInOpenswoole;
use function Shlinkio\Shlink\Config\runningInRoadRunner;
return [
'url_shortener' => [
'domain' => [
'schema' => 'http',
'hostname' => sprintf('localhost:%s', $isSwoole ? '8080' : '8000'),
'hostname' => sprintf('localhost:%s', match (true) {
runningInRoadRunner() => '8800',
runningInOpenswoole() => '8080',
default => '8000',
}),
],
'auto_resolve_titles' => true,
// 'multi_segment_slugs_enabled' => true,
// 'trailing_slash_enabled' => true,
],
];

View File

@@ -2,17 +2,18 @@
declare(strict_types=1);
use function Shlinkio\Shlink\Common\env;
use Shlinkio\Shlink\Core\Config\EnvVars;
// Deprecated. Webhooks are no longer supported. To be removed in Shlink 4.0.0
return (static function (): array {
$webhooks = env('VISITS_WEBHOOKS');
$webhooks = EnvVars::VISITS_WEBHOOKS->loadFromEnv();
return [
'url_shortener' => [
// TODO Move these options to their own config namespace
'visits_webhooks' => $webhooks === null ? [] : explode(',', $webhooks),
'notify_orphan_visits_to_webhooks' => (bool) env('NOTIFY_ORPHAN_VISITS_TO_WEBHOOKS', false),
'visits_webhooks' => [
'webhooks' => $webhooks === null ? [] : explode(',', $webhooks),
'notify_orphan_visits_to_webhooks' =>
(bool) EnvVars::NOTIFY_ORPHAN_VISITS_TO_WEBHOOKS->loadFromEnv(false),
],
];

View File

@@ -5,7 +5,7 @@ declare(strict_types=1);
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Application as CliApp;
return (static function () {
return (static function (): CliApp {
/** @var ContainerInterface $container */
$container = include __DIR__ . '/container.php';
return $container->get(CliApp::class);

View File

@@ -2,11 +2,26 @@
declare(strict_types=1);
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager;
use Doctrine\Migrations\Configuration\Migration\ConfigurationArray;
use Doctrine\Migrations\DependencyFactory;
// This file is currently used by doctrine migrations only
return (static function () {
/** @var EntityManager $em */
$migrationsConfig = [
'migrations_paths' => [
'ShlinkMigrations' => 'data/migrations',
],
'table_storage' => [
'table_name' => 'migrations',
],
'custom_template' => 'data/migrations_template.txt',
];
$em = include __DIR__ . '/entity-manager.php';
return ConsoleRunner::createHelperSet($em);
return DependencyFactory::fromEntityManager(
new ConfigurationArray($migrationsConfig),
new ExistingEntityManager($em),
);
})();

View File

@@ -9,38 +9,52 @@ use Laminas\Diactoros;
use Mezzio;
use Mezzio\ProblemDetails;
use Mezzio\Swoole;
use Shlinkio\Shlink\Config\ConfigAggregator\EnvVarLoaderProvider;
use function class_exists;
use function Shlinkio\Shlink\Common\env;
use function Shlinkio\Shlink\Config\env;
use function Shlinkio\Shlink\Config\openswooleIsInstalled;
use function Shlinkio\Shlink\Config\runningInRoadRunner;
use function Shlinkio\Shlink\Core\enumValues;
use const PHP_SAPI;
$isCli = PHP_SAPI === 'cli';
$isTestEnv = env('APP_ENV') === 'test';
$enableSwoole = PHP_SAPI === 'cli' && openswooleIsInstalled() && ! runningInRoadRunner();
return (new ConfigAggregator\ConfigAggregator([
Mezzio\ConfigProvider::class,
Mezzio\Router\ConfigProvider::class,
Mezzio\Router\FastRouteRouter\ConfigProvider::class,
$isCli && class_exists(Swoole\ConfigProvider::class)
? Swoole\ConfigProvider::class
: new ConfigAggregator\ArrayProvider([]),
ProblemDetails\ConfigProvider::class,
Diactoros\ConfigProvider::class,
Common\ConfigProvider::class,
Config\ConfigProvider::class,
Importer\ConfigProvider::class,
IpGeolocation\ConfigProvider::class,
EventDispatcher\ConfigProvider::class,
Core\ConfigProvider::class,
CLI\ConfigProvider::class,
Rest\ConfigProvider::class,
new ConfigAggregator\PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
env('APP_ENV') === 'test'
? new ConfigAggregator\PhpFileProvider('config/test/*.global.php')
// Deprecated. When the SimplifiedConfigParser is removed, load only generated_config.php here
: new ConfigAggregator\LaminasConfigProvider('config/params/{generated_config.php,*.config.{php,json}}'),
], 'data/cache/app_config.php', [
Core\Config\SimplifiedConfigParser::class,
Core\Config\BasePathPrefixer::class,
Core\Config\DeprecatedConfigParser::class,
]))->getMergedConfig();
return (new ConfigAggregator\ConfigAggregator(
providers: [
! $isTestEnv
? new EnvVarLoaderProvider('config/params/generated_config.php', enumValues(Core\Config\EnvVars::class))
: new ConfigAggregator\ArrayProvider([]),
Mezzio\ConfigProvider::class,
Mezzio\Router\ConfigProvider::class,
Mezzio\Router\FastRouteRouter\ConfigProvider::class,
$enableSwoole && class_exists(Swoole\ConfigProvider::class)
? Swoole\ConfigProvider::class
: new ConfigAggregator\ArrayProvider([]),
ProblemDetails\ConfigProvider::class,
Diactoros\ConfigProvider::class,
Common\ConfigProvider::class,
Config\ConfigProvider::class,
Importer\ConfigProvider::class,
IpGeolocation\ConfigProvider::class,
EventDispatcher\ConfigProvider::class,
Core\ConfigProvider::class,
CLI\ConfigProvider::class,
Rest\ConfigProvider::class,
new ConfigAggregator\PhpFileProvider('config/autoload/{,*.}global.php'),
// Local config should not be loaded during tests, whereas test config should be loaded ONLY during tests
new ConfigAggregator\PhpFileProvider(
$isTestEnv ? 'config/test/*.global.php' : 'config/autoload/{,*.}local.php',
),
// Routes have to be loaded last
new ConfigAggregator\PhpFileProvider('config/autoload/routes.config.php'),
],
cachedConfigFile: 'data/cache/app_config.php',
postProcessors: [
Core\Config\PostProcessor\BasePathPrefixer::class,
Core\Config\PostProcessor\MultiSegmentSlugProcessor::class,
Core\Config\PostProcessor\ShortUrlMethodsProcessor::class,
],
))->getMergedConfig();

View File

@@ -4,19 +4,21 @@ declare(strict_types=1);
namespace Shlinkio\Shlink;
use Fig\Http\Message\StatusCodeInterface;
use Shlinkio\Shlink\Core\Util\RedirectStatus;
const DEFAULT_DELETE_SHORT_URL_THRESHOLD = 15;
const DEFAULT_SHORT_CODES_LENGTH = 5;
const MIN_SHORT_CODES_LENGTH = 4;
const DEFAULT_REDIRECT_STATUS_CODE = StatusCodeInterface::STATUS_FOUND;
const DEFAULT_REDIRECT_STATUS_CODE = RedirectStatus::STATUS_302; // Deprecated. Default to 307 for Shlink v4
const DEFAULT_REDIRECT_CACHE_LIFETIME = 30;
const LOCAL_LOCK_FACTORY = 'Shlinkio\Shlink\LocalLockFactory';
const CUSTOM_SLUGS_REGEXP = '/[^\pL\pN._~]/u'; // Any unicode letter or number, plus ".", "_" and "~" chars
const TITLE_TAG_VALUE = '/<title[^>]*>(.*?)<\/title>/i'; // Matches the value inside an html title tag
const TITLE_TAG_VALUE = '/<title[^>]*>(.*?)<\/title>/i'; // Matches the value inside a html title tag
const LOOSE_URI_MATCHER = '/(.+)\:(.+)/i'; // Matches anything starting with a schema.
const DEFAULT_QR_CODE_SIZE = 300;
const DEFAULT_QR_CODE_MARGIN = 0;
const DEFAULT_QR_CODE_FORMAT = 'png';
const DEFAULT_QR_CODE_ERROR_CORRECTION = 'l';
const DEFAULT_QR_CODE_ROUND_BLOCK_SIZE = true;
// Deprecated. Shlink 4.0.0 should change default value to `true`
const DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS = false;
const MIN_TASK_WORKERS = 4;

View File

@@ -3,6 +3,7 @@
declare(strict_types=1);
use Laminas\ServiceManager\ServiceManager;
use Shlinkio\Shlink\Core\Config\EnvVars;
use Symfony\Component\Lock;
use const Shlinkio\Shlink\LOCAL_LOCK_FACTORY;
@@ -11,14 +12,27 @@ chdir(dirname(__DIR__));
require 'vendor/autoload.php';
// Workaround to make this compatible with both openswoole 22 and earlier versions.
// Openswoole support is deprecated. Remove in v4.0.0
if (! function_exists('swoole_set_process_name')) {
// phpcs:disable
function swoole_set_process_name(string $name): void
{
OpenSwoole\Util::setProcessName($name);
}
// phpcs:enable
}
// This is one of the first files loaded. Configure the timezone here
date_default_timezone_set(EnvVars::TIMEZONE->loadFromEnv(date_default_timezone_get()));
// This class alias tricks the ConfigAbstractFactory to return Lock\Factory instances even with a different service name
// It needs to be placed here as individual config files will not be loaded once config is cached
if (! class_exists(LOCAL_LOCK_FACTORY)) {
class_alias(Lock\LockFactory::class, LOCAL_LOCK_FACTORY);
}
// Build container
return (function () {
return (static function (): ServiceManager {
$config = require __DIR__ . '/config.php';
$container = new ServiceManager($config['dependencies']);
$container->setService('config', $config);

View File

@@ -3,9 +3,10 @@
declare(strict_types=1);
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Container\ContainerInterface;
return (static function () {
return (static function (): EntityManagerInterface {
/** @var ContainerInterface $container */
$container = include __DIR__ . '/container.php';
return $container->get(EntityManager::class);

View File

@@ -0,0 +1,42 @@
version: '3'
rpc:
listen: tcp://127.0.0.1:6001
server:
command: 'php ../../bin/roadrunner-worker.php'
http:
address: '0.0.0.0:8080'
middleware: ['static']
static:
dir: '../../public'
forbid: ['.php', '.htaccess']
pool:
num_workers: 1
debug: true
jobs:
pool:
num_workers: 1
debug: true
timeout: 300
consume: ['shlink']
pipelines:
shlink:
driver: memory
config:
priority: 10
prefetch: 10
logs:
mode: development
channels:
http:
mode: 'off' # Disable logging as Shlink handles it internally
server:
level: info
metrics:
level: debug
jobs:
level: debug

38
config/roadrunner/.rr.yml Normal file
View File

@@ -0,0 +1,38 @@
version: '3'
rpc:
listen: tcp://127.0.0.1:6001
server:
command: 'php -dopcache.enable_cli=1 -dopcache.validate_timestamps=0 ../../bin/roadrunner-worker.php'
http:
address: '0.0.0.0:${PORT:-8080}'
middleware: ['static']
static:
dir: '../../public'
forbid: ['.php', '.htaccess']
pool:
num_workers: ${WEB_WORKER_NUM:-0}
jobs:
timeout: 300 # 5 minutes
pool:
num_workers: ${TASK_WORKER_NUM:-0}
consume: ['shlink']
pipelines:
shlink:
driver: memory
config:
priority: 10
prefetch: 10
logs:
mode: production
channels:
http:
mode: 'off' # Disable logging as Shlink handles it internally
server:
level: info
jobs:
level: debug

View File

@@ -10,8 +10,8 @@ use Psr\Container\ContainerInterface;
use function register_shutdown_function;
use function sprintf;
use const ShlinkioTest\Shlink\SWOOLE_TESTING_HOST;
use const ShlinkioTest\Shlink\SWOOLE_TESTING_PORT;
use const ShlinkioTest\Shlink\API_TESTS_HOST;
use const ShlinkioTest\Shlink\API_TESTS_PORT;
/** @var ContainerInterface $container */
$container = require __DIR__ . '/../container.php';
@@ -24,10 +24,15 @@ $httpClient = $container->get('shlink_test_api_client');
register_shutdown_function(function () use ($httpClient): void {
$httpClient->request(
'GET',
sprintf('http://%s:%s/api-tests/stop-coverage', SWOOLE_TESTING_HOST, SWOOLE_TESTING_PORT),
sprintf('http://%s:%s/api-tests/stop-coverage', API_TESTS_HOST, API_TESTS_PORT),
);
});
$testHelper->createTestDb(['bin/cli', 'db:create'], ['bin/cli', 'db:migrate']);
$testHelper->createTestDb(
['bin/cli', 'db:create'],
['bin/cli', 'db:migrate'],
['bin/doctrine', 'orm:schema-tool:drop'],
['bin/doctrine', 'dbal:run-sql'],
);
ApiTest\ApiTestCase::setApiClient($httpClient);
ApiTest\ApiTestCase::setSeedFixturesCallback(fn () => $testHelper->seedFixtures($em, $config['data_fixtures'] ?? []));

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\TestUtils;
use Doctrine\ORM\EntityManager;
use Psr\Container\ContainerInterface;
use function file_exists;
use function unlink;
/** @var ContainerInterface $container */
$container = require __DIR__ . '/../container.php';
$testHelper = $container->get(Helper\TestHelper::class);
$config = $container->get('config');
$em = $container->get(EntityManager::class);
// Delete old coverage in PHP, to avoid merging older executions with current one
$covFile = __DIR__ . '/../../build/coverage-cli.cov';
if (file_exists($covFile)) {
unlink($covFile);
}
$testHelper->createTestDb(
createDbCommand: ['bin/cli', 'db:create'],
migrateDbCommand: ['bin/cli', 'db:migrate'],
dropSchemaCommand: ['bin/doctrine', 'orm:schema-tool:drop'],
runSqlCommand: ['bin/doctrine', 'dbal:run-sql'],
);
CliTest\CliTestCase::setSeedFixturesCallback(
static fn () => $testHelper->seedFixtures($em, $config['data_fixtures'] ?? []),
);

View File

@@ -8,5 +8,10 @@ use Psr\Container\ContainerInterface;
/** @var ContainerInterface $container */
$container = require __DIR__ . '/../container.php';
$container->get(Helper\TestHelper::class)->createTestDb();
$container->get(Helper\TestHelper::class)->createTestDb(
['bin/cli', 'db:create'],
['bin/cli', 'db:migrate'],
['bin/doctrine', 'orm:schema-tool:drop'],
['bin/doctrine', 'dbal:run-sql'],
);
DbTest\DatabaseTestCase::setEntityManager($container->get('em'));

View File

@@ -4,5 +4,12 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink;
const SWOOLE_TESTING_HOST = '127.0.0.1';
const SWOOLE_TESTING_PORT = 9999;
const API_TESTS_HOST = '127.0.0.1';
const API_TESTS_PORT = 9999;
const ANDROID_USER_AGENT = 'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) '
. 'Chrome/109.0.5414.86 Mobile Safari/537.36';
const IOS_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 '
. '(KHTML, like Gecko) FxiOS/109.0 Mobile/15E148 Safari/605.1.15';
const DESKTOP_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like '
. 'Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.61';

View File

@@ -8,9 +8,10 @@ use GuzzleHttp\Client;
use Laminas\ConfigAggregator\ConfigAggregator;
use Laminas\Diactoros\Response\EmptyResponse;
use Laminas\ServiceManager\Factory\InvokableFactory;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use League\Event\EventDispatcher;
use Monolog\Level;
use PHPUnit\Runner\Version;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
@@ -20,24 +21,61 @@ use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\Report\Html\Facade as Html;
use SebastianBergmann\CodeCoverage\Report\PHP;
use SebastianBergmann\CodeCoverage\Report\Xml\Facade as Xml;
use Shlinkio\Shlink\Common\Logger\LoggerType;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use function file_exists;
use function Laminas\Stratigility\middleware;
use function Shlinkio\Shlink\Common\env;
use function Shlinkio\Shlink\Config\env;
use function Shlinkio\Shlink\Core\ArrayUtils\contains;
use function sprintf;
use function sys_get_temp_dir;
use const ShlinkioTest\Shlink\SWOOLE_TESTING_HOST;
use const ShlinkioTest\Shlink\SWOOLE_TESTING_PORT;
use const ShlinkioTest\Shlink\API_TESTS_HOST;
use const ShlinkioTest\Shlink\API_TESTS_PORT;
$isApiTest = env('TEST_ENV') === 'api';
$generateCoverage = env('GENERATE_COVERAGE') === 'yes';
if ($isApiTest && $generateCoverage) {
$isCliTest = env('TEST_ENV') === 'cli';
$isE2eTest = $isApiTest || $isCliTest;
$coverageType = env('GENERATE_COVERAGE');
$generateCoverage = contains($coverageType, ['yes', 'pretty']);
$coverage = null;
if ($isE2eTest && $generateCoverage) {
$filter = new Filter();
$filter->includeDirectory(__DIR__ . '/../../module/Core/src');
$filter->includeDirectory(__DIR__ . '/../../module/Rest/src');
$filter->includeDirectory(__DIR__ . '/../../module/' . ($isApiTest ? 'Rest' : 'CLI') . '/src');
$coverage = new CodeCoverage((new Selector())->forLineCoverage($filter), $filter);
}
/**
* @param 'api'|'cli' $type
*/
$exportCoverage = static function (string $type = 'api') use (&$coverage, $coverageType): void {
if ($coverage === null) {
return;
}
$basePath = __DIR__ . '/../../build/coverage-' . $type;
$covPath = $basePath . '.cov';
// Every CLI test runs on its own process and dumps the coverage afterwards.
// Try to load it and merge it, so that we end up with the whole coverage at the end.
if ($type === 'cli' && file_exists($covPath)) {
$coverage->merge(require $covPath);
}
if ($coverageType === 'pretty') {
(new Html())->process($coverage, $basePath . '/coverage-html');
} else {
(new PHP())->process($coverage, $covPath);
(new Xml(Version::getVersionString()))->process($coverage, $basePath . '/coverage-xml');
}
};
$buildDbConnection = static function (): array {
$driver = env('DB_DRIVER', 'sqlite');
$isCi = env('CI', false);
@@ -46,7 +84,7 @@ $buildDbConnection = static function (): array {
return match ($driver) {
'sqlite' => [
'driver' => 'pdo_sqlite',
'path' => sys_get_temp_dir() . '/shlink-tests.db',
'memory' => true,
],
'postgres' => [
'driver' => 'pdo_pgsql',
@@ -63,6 +101,9 @@ $buildDbConnection = static function (): array {
'user' => 'sa',
'password' => 'Passw0rd!',
'dbname' => 'shlink_test',
'driverOptions' => [
'TrustServerCertificate' => 'true',
],
],
default => [ // mysql and maria
'driver' => 'pdo_mysql',
@@ -71,21 +112,16 @@ $buildDbConnection = static function (): array {
'user' => 'root',
'password' => 'root',
'dbname' => 'shlink_test',
'charset' => 'utf8',
'charset' => 'utf8mb4',
],
};
};
$buildTestLoggerConfig = fn (string $handlerName, string $filename) => [
'handlers' => [
$handlerName => [
'name' => StreamHandler::class,
'params' => [
'level' => Logger::DEBUG,
'stream' => sprintf('data/log/api-tests/%s', $filename),
],
],
],
$buildTestLoggerConfig = static fn (string $filename) => [
'level' => Level::Debug->value,
'type' => LoggerType::STREAM->value,
'destination' => sprintf('data/log/api-tests/%s', $filename),
'add_new_line' => true,
];
return [
@@ -96,19 +132,19 @@ return [
'url_shortener' => [
'domain' => [
'schema' => 'http',
'hostname' => 'doma.in',
'hostname' => 's.test',
],
'validate_url' => true,
],
'mezzio-swoole' => [
'enable_coroutine' => false,
'swoole-http-server' => [
'host' => SWOOLE_TESTING_HOST,
'port' => SWOOLE_TESTING_PORT,
'host' => API_TESTS_HOST,
'port' => API_TESTS_PORT,
'process-name' => 'shlink_test',
'options' => [
'pid_file' => sys_get_temp_dir() . '/shlink-test-swoole.pid',
'log_file' => __DIR__ . '/../../data/log/api-tests/output.log',
'enable_coroutine' => false,
],
],
@@ -118,17 +154,10 @@ return [
[
'name' => 'dump_coverage',
'path' => '/api-tests/stop-coverage',
'middleware' => middleware(static function () use (&$coverage) {
'middleware' => middleware(static function () use ($exportCoverage) {
// TODO I have tried moving this block to a listener so that it's invoked automatically,
// but then the coverage is generated empty ¯\_(ツ)_/¯
if ($coverage) { // @phpstan-ignore-line
$basePath = __DIR__ . '/../../build/coverage-api';
(new PHP())->process($coverage, $basePath . '.cov');
(new Xml(Version::getVersionString()))->process($coverage, $basePath . '/coverage-xml');
(new Html())->process($coverage, $basePath . '/coverage-html');
}
$exportCoverage();
return new EmptyResponse();
}),
'allowed_methods' => ['GET'],
@@ -162,13 +191,69 @@ return [
'dependencies' => [
'services' => [
'shlink_test_api_client' => new Client([
'base_uri' => sprintf('http://%s:%s/', SWOOLE_TESTING_HOST, SWOOLE_TESTING_PORT),
'base_uri' => sprintf('http://%s:%s/', API_TESTS_HOST, API_TESTS_PORT),
'http_errors' => false,
]),
],
'factories' => [
TestUtils\Helper\TestHelper::class => InvokableFactory::class,
],
'delegators' => $isCliTest ? [
Application::class => [
static function (
ContainerInterface $c,
string $serviceName,
callable $callback,
) use (
&$coverage,
$exportCoverage,
) {
/** @var Application $app */
$app = $callback();
$wrappedEventDispatcher = new EventDispatcher();
// When the command starts, start collecting coverage
$wrappedEventDispatcher->subscribeTo(
ConsoleCommandEvent::class,
static function () use (&$coverage): void {
$id = env('COVERAGE_ID');
if ($id === null) {
return;
}
$coverage?->start($id);
},
);
// When the command ends, stop collecting coverage
$wrappedEventDispatcher->subscribeTo(
ConsoleTerminateEvent::class,
static function () use (&$coverage, $exportCoverage): void {
$id = env('COVERAGE_ID');
if ($id === null) {
return;
}
$coverage?->stop();
$exportCoverage('cli');
},
);
$app->setDispatcher(new class ($wrappedEventDispatcher) implements EventDispatcherInterface {
public function __construct(private EventDispatcher $wrappedDispatcher)
{
}
public function dispatch(object $event, ?string $eventName = null): object
{
$this->wrappedDispatcher->dispatch($event);
return $event;
}
});
return $app;
},
],
] : [],
],
'entity_manager' => [
@@ -177,13 +262,14 @@ return [
'data_fixtures' => [
'paths' => [
// TODO These are used for CLI tests too, so maybe should be somewhere else
__DIR__ . '/../../module/Rest/test-api/Fixtures',
],
],
'logger' => [
'Shlink' => $buildTestLoggerConfig('shlink_handler', 'shlink.log'),
'Access' => $buildTestLoggerConfig('access_handler', 'access.log'),
'Shlink' => $buildTestLoggerConfig('shlink.log'),
'Access' => $buildTestLoggerConfig('access.log'),
],
];

View File

@@ -3,7 +3,7 @@
set -ex
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
apt-get update
ACCEPT_EULA=Y apt-get install msodbcsql17
apt-get install unixodbc-dev
ACCEPT_EULA=Y apt-get install msodbcsql18
# apt-get install unixodbc-dev

View File

@@ -1,5 +1,5 @@
<VirtualHost *:80>
ServerName doma.in
ServerName s.test
DocumentRoot "/path/to/shlink/public"
<Directory "/path/to/shlink/public">

View File

@@ -1,5 +1,5 @@
server {
server_name doma.in;
server_name s.test;
listen 80;
root /path/to/shlink/public;
index index.php;
@@ -11,7 +11,7 @@ server {
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}

View File

@@ -1,4 +1,4 @@
/var/log/shlink/shlink_swoole.log {
/var/log/shlink/shlink_openswoole.log {
su root root
daily
missingok
@@ -8,6 +8,6 @@
notifempty
create 0640 root root
postrotate
/etc/init.d/shlink_swoole restart
/etc/init.d/shlink_openswoole restart
endscript
}

View File

@@ -1,26 +1,26 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: shlink_swoole
# Provides: shlink_openswoole
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Shlink non-blocking server with swoole
# Description: Shlink non-blocking server with openswoole
### END INIT INFO
SCRIPT=/path/to/shlink/vendor/bin/laminas\ mezzio:swoole:start
RUNAS=root
PIDFILE=/var/run/shlink_swoole.pid
PIDFILE=/var/run/shlink_openswoole.pid
LOGDIR=/var/log/shlink
LOGFILE=${LOGDIR}/shlink_swoole.log
LOGFILE=${LOGDIR}/shlink_openswoole.log
start() {
if [[ -f "$PIDFILE" ]] && kill -0 $(cat "$PIDFILE"); then
echo 'Shlink with swoole already running' >&2
echo 'Shlink with openswoole already running' >&2
return 1
fi
echo 'Starting shlink with swoole' >&2
echo 'Starting shlink with openswoole' >&2
mkdir -p "$LOGDIR"
touch "$LOGFILE"
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
@@ -30,10 +30,10 @@ start() {
stop() {
if [[ ! -f "$PIDFILE" ]] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Shlink with swoole not running' >&2
echo 'Shlink with openswoole not running' >&2
return 1
fi
echo 'Stopping shlink with swoole' >&2
echo 'Stopping shlink with openswoole' >&2
kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
echo 'Shlink stopped' >&2
}

View File

@@ -1,15 +1,15 @@
FROM php:8.1.0-fpm-alpine3.15
FROM php:8.2-fpm-alpine3.17
MAINTAINER Alejandro Celaya <alejandro@alejandrocelaya.com>
ENV APCU_VERSION 5.1.21
ENV PDO_SQLSRV_VERSION 5.10.0beta2
ENV MS_ODBC_SQL_VERSION 17.5.2.2
ENV PDO_SQLSRV_VERSION 5.11.1
ENV MS_ODBC_DOWNLOAD 'b/9/f/b9f3cce4-3925-46d4-9f46-da08869c6486'
ENV MS_ODBC_SQL_VERSION 18_18.1.1.1
RUN apk update
# Install common php extensions
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install iconv
RUN docker-php-ext-install calendar
RUN apk add --no-cache oniguruma-dev
@@ -31,10 +31,9 @@ RUN docker-php-ext-install gd
RUN apk add --no-cache postgresql-dev
RUN docker-php-ext-install pdo_pgsql
RUN apk add --no-cache gmp-dev
RUN docker-php-ext-install gmp
RUN docker-php-ext-install sockets
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS linux-headers && \
docker-php-ext-install sockets && \
apk del .phpize-deps
RUN docker-php-ext-install bcmath
# Install APCu extension
@@ -48,13 +47,13 @@ RUN mkdir -p /usr/src/php/ext/apcu \
&& echo extension=apcu.so > /usr/local/etc/php/conf.d/20-php-ext-apcu.ini
# Install pcov and sqlsrv driver
RUN wget https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
RUN wget https://download.microsoft.com/download/${MS_ODBC_DOWNLOAD}/msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc-dev && \
pecl install pdo_sqlsrv-${PDO_SQLSRV_VERSION} pcov && \
docker-php-ext-enable pdo_sqlsrv pcov && \
apk del .phpize-deps && \
rm msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk
rm msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk
# Install composer
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer

View File

@@ -0,0 +1,2 @@
user foo allcommands allkeys on >bar
requirepass barbar

View File

@@ -0,0 +1,76 @@
FROM php:8.2-alpine3.17
MAINTAINER Alejandro Celaya <alejandro@alejandrocelaya.com>
ENV APCU_VERSION 5.1.21
ENV PDO_SQLSRV_VERSION 5.11.1
ENV MS_ODBC_DOWNLOAD 'b/9/f/b9f3cce4-3925-46d4-9f46-da08869c6486'
ENV MS_ODBC_SQL_VERSION 18_18.1.1.1
RUN apk update
# Install common php extensions
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install calendar
RUN apk add --no-cache oniguruma-dev
RUN docker-php-ext-install mbstring
RUN apk add --no-cache sqlite-libs
RUN apk add --no-cache sqlite-dev
RUN docker-php-ext-install pdo_sqlite
RUN apk add --no-cache icu-dev
RUN docker-php-ext-install intl
RUN apk add --no-cache libzip-dev zlib-dev
RUN docker-php-ext-install zip
RUN apk add --no-cache libpng-dev
RUN docker-php-ext-install gd
RUN apk add --no-cache postgresql-dev
RUN docker-php-ext-install pdo_pgsql
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS linux-headers && \
docker-php-ext-install sockets && \
apk del .phpize-deps
RUN docker-php-ext-install bcmath
# Install APCu extension
ADD https://pecl.php.net/get/apcu-$APCU_VERSION.tgz /tmp/apcu.tar.gz
RUN mkdir -p /usr/src/php/ext/apcu \
&& tar xf /tmp/apcu.tar.gz -C /usr/src/php/ext/apcu --strip-components=1 \
&& docker-php-ext-configure apcu \
&& docker-php-ext-install apcu \
&& rm /tmp/apcu.tar.gz \
&& rm /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini \
&& echo extension=apcu.so > /usr/local/etc/php/conf.d/20-php-ext-apcu.ini
# Install pcov and sqlsrv driver
RUN wget https://download.microsoft.com/download/${MS_ODBC_DOWNLOAD}/msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc-dev && \
pecl install pdo_sqlsrv-${PDO_SQLSRV_VERSION} pcov && \
docker-php-ext-enable pdo_sqlsrv pcov && \
apk del .phpize-deps && \
rm msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk
# Install composer
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
# Make home directory writable by anyone
RUN chmod 777 /home
VOLUME /home/shlink
WORKDIR /home/shlink
# Expose roadrunner port
EXPOSE 8080
CMD \
# Install dependencies if the vendor dir does not exist
if [[ ! -d "./vendor" ]]; then /usr/local/bin/composer install ; fi && \
# Download roadrunner binary
if [[ ! -f "./bin/rr" ]]; then ./vendor/bin/rr get --no-interaction --no-config --location bin/ && chmod +x bin/rr ; fi && \
# This forces the app to be started every second until the exit code is 0
until ./bin/rr serve -c config/roadrunner/.rr.dev.yml; do sleep 1 ; done

View File

@@ -1,17 +1,17 @@
FROM php:8.1.0-alpine3.15
FROM php:8.2-alpine3.17
MAINTAINER Alejandro Celaya <alejandro@alejandrocelaya.com>
ENV APCU_VERSION 5.1.21
ENV INOTIFY_VERSION 3.0.0
ENV OPENSWOOLE_VERSION 4.8.1
ENV PDO_SQLSRV_VERSION 5.10.0beta2
ENV MS_ODBC_SQL_VERSION 17.5.2.2
ENV OPENSWOOLE_VERSION 22.1.0
ENV PDO_SQLSRV_VERSION 5.11.1
ENV MS_ODBC_DOWNLOAD 'b/9/f/b9f3cce4-3925-46d4-9f46-da08869c6486'
ENV MS_ODBC_SQL_VERSION 18_18.1.1.1
RUN apk update
# Install common php extensions
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install iconv
RUN docker-php-ext-install calendar
RUN apk add --no-cache oniguruma-dev
@@ -33,10 +33,9 @@ RUN docker-php-ext-install gd
RUN apk add --no-cache postgresql-dev
RUN docker-php-ext-install pdo_pgsql
RUN apk add --no-cache gmp-dev
RUN docker-php-ext-install gmp
RUN docker-php-ext-install sockets
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS linux-headers && \
docker-php-ext-install sockets && \
apk del .phpize-deps
RUN docker-php-ext-install bcmath
# Install APCu extension
@@ -58,13 +57,13 @@ RUN mkdir -p /usr/src/php/ext/inotify \
&& rm /tmp/inotify.tar.gz
# Install openswoole, pcov and mssql driver
RUN wget https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
RUN wget https://download.microsoft.com/download/${MS_ODBC_DOWNLOAD}/msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --allow-untrusted msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc-dev && \
pecl install openswoole-${OPENSWOOLE_VERSION} pdo_sqlsrv-${PDO_SQLSRV_VERSION} pcov && \
docker-php-ext-enable openswoole pdo_sqlsrv pcov && \
apk del .phpize-deps && \
rm msodbcsql17_${MS_ODBC_SQL_VERSION}-1_amd64.apk
rm msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk
# Install composer
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer

View File

@@ -5,45 +5,45 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Migrations\AbstractMigration;
use function is_subclass_of;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20160819142757 extends AbstractMigration
{
private const MYSQL = 'mysql';
private const SQLITE = 'sqlite';
/**
* @throws Exception
* @throws SchemaException
*/
public function up(Schema $schema): void
{
$db = $this->connection->getDatabasePlatform()->getName();
$platformClass = $this->connection->getDatabasePlatform();
$table = $schema->getTable('short_urls');
$column = $table->getColumn('short_code');
if ($db === self::MYSQL) {
$column->setPlatformOption('collation', 'utf8_bin');
} elseif ($db === self::SQLITE) {
$column->setPlatformOption('collate', 'BINARY');
}
match (true) {
is_subclass_of($platformClass, MySQLPlatform::class) => $column
->setPlatformOption('charset', 'utf8mb4')
->setPlatformOption('collation', 'utf8mb4_bin'),
is_subclass_of($platformClass, SqlitePlatform::class) => $column->setPlatformOption('collate', 'BINARY'),
default => null,
};
}
/**
* @throws Exception
*/
public function down(Schema $schema): void
{
$this->connection->getDatabasePlatform()->getName();
// Nothing to roll back
}
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;
@@ -76,6 +77,6 @@ class Version20160820191203 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Types;
@@ -48,6 +49,6 @@ class Version20171021093246 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Types;
@@ -45,6 +46,6 @@ class Version20171022064541 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Migrations\AbstractMigration;
@@ -42,6 +43,6 @@ final class Version20180801183328 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
use PDO;
@@ -69,6 +70,6 @@ final class Version20180913205455 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Migrations\AbstractMigration;
@@ -50,6 +51,6 @@ final class Version20180915110857 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Table;
@@ -58,7 +59,7 @@ final class Version20181020060559 extends AbstractMigration
foreach (self::COLUMNS as $camelCaseName => $snakeCaseName) {
$qb->set($snakeCaseName, $camelCaseName);
}
$qb->execute();
$qb->executeStatement();
}
public function down(Schema $schema): void
@@ -68,6 +69,6 @@ final class Version20181020060559 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Migrations\AbstractMigration;
@@ -41,6 +42,6 @@ final class Version20181020065148 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
@@ -37,6 +38,6 @@ final class Version20181110175521 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
@@ -37,6 +38,6 @@ final class Version20190824075137 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Types;
@@ -55,6 +56,6 @@ final class Version20190930165521 extends AbstractMigration
public function isTransactional(): bool
{
return $this->connection->getDatabasePlatform()->getName() !== 'mysql';
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

Some files were not shown because too many files have changed in this diff Show More