Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
cce6e71
refactor: remove deprecated mode, prepend, append parameters from xl(…
Copilot Dec 22, 2025
7f09099
refactor(library/date_functions.php): replace switch with match and a…
Copilot Dec 23, 2025
866b839
Fix deprecated PHP prpperty_exist error in portal (#9964)
sjpadgett Dec 23, 2025
951aa4b
fix: undefined $filename breaks extension detection in download_templ…
Copilot Dec 23, 2025
2fd01e8
refactor(patient_file): file type lookup in download_template (#9970)
kojiromike Dec 23, 2025
5e1886e
perf: add composite index on lang_definitions for translation lookups…
kojiromike Dec 24, 2025
972a912
feat: add configuration option to disable translation engine (#9976)
kojiromike Dec 24, 2025
4a9c835
chore: update changelog for 7.0.4 (#9973)
bradymiller Dec 24, 2025
c4d1835
Refactor Portal CCDA actions (#9950)
sjpadgett Dec 25, 2025
d3b253d
fix: current user dropdown hover state persisting (#9989)
stephenwaite Dec 26, 2025
8ef2793
Remove dead code from verysimple library - 22 unused files (#9771)
Copilot Dec 28, 2025
1057b54
refactor(php): no call_user_func* (#9767)
kojiromike Dec 28, 2025
7eee204
perf: persist lang_definitions index in language translation tools (#…
kojiromike Dec 28, 2025
081ed85
perf: add in-memory translation cache (#9978)
kojiromike Dec 29, 2025
f2f253f
Fix Context Manager (#9998)
sjpadgett Dec 29, 2025
91067c1
Inventory and other bug fixes (#9994)
sjpadgett Dec 29, 2025
2eb5728
chore(deps-dev): bump phpunit/php-code-coverage in the development gr…
dependabot[bot] Dec 29, 2025
ea072b9
chore(deps): bump vlucas/phpdotenv from 5.6.2 to 5.6.3 (#10002)
dependabot[bot] Dec 29, 2025
de2a4ee
chore(deps-dev): bump stylelint-scss in the build-tools group (#10004)
dependabot[bot] Dec 29, 2025
6dca30d
chore(deps): bump league/csv from 9.27.1 to 9.28.0 (#10005)
dependabot[bot] Dec 29, 2025
b40c192
chore(deps-dev): bump rector/rector from 2.2.14 to 2.3.0 (#10003)
dependabot[bot] Dec 29, 2025
6667188
Remove deprecated xls() function, replace with xlj() (#10007) (#10008)
kojiromike Dec 29, 2025
c11c7a6
fix(ci): correct dclint argument order and run on all PRs (#9959) (#1…
kojiromike Dec 29, 2025
2af5122
fix(sql): aggregate uuid in care_teams migration GROUP BY (#10011)
kojiromike Dec 29, 2025
e139541
fix: fatal error rendering allergies (#10010)
stephenwaite Dec 30, 2025
5f20b75
Merge commit from fork
kojiromike Dec 30, 2025
a024f46
fix(oehttpkernel): eventdispatcherinterface type inconsistency (#10016)
Copilot Dec 30, 2025
78b3058
fix(ci): update PHPStan baselines to reflect codebase changes (#10018)
kojiromike Dec 30, 2025
6a4e18c
Extend URLSearchParams refactoring to remaining first-party files (#9…
Copilot Dec 30, 2025
09390de
fax service and eRx titles (#9874)
juggernautsei Dec 31, 2025
f17e557
fix: use js_escape instead of attr_js in URLSearchParams within scrip…
kojiromike Dec 31, 2025
4b01593
refactor(Twig): use first-class callables for filters (#10025)
kojiromike Dec 31, 2025
544d287
feat: add xlx() translation function for XML contexts (#10026)
kojiromike Jan 1, 2026
f6303dc
chore: change next planned version from 7.0.5 to 8.0.0 (#10030)
bradymiller Jan 1, 2026
66fcce1
chore: update production docker compose to use current production ver…
bradymiller Jan 1, 2026
b1e3fe8
Merge commit from fork
kojiromike Jan 2, 2026
fb58d68
Composer | Fixed validation warning for academe/omnipay-authorizenetapi
igormukhingmailcom Dec 12, 2025
e7a5f46
Composer | Fixed validation warning for adodb/adodb-php
igormukhingmailcom Dec 10, 2025
789b118
Composer | Fixed validation warning for aranyasen/hl7
igormukhingmailcom Dec 10, 2025
22f6a16
Composer | Fixed validation warning for bacon/bacon-qr-code
igormukhingmailcom Dec 10, 2025
48b17eb
Composer | Fixed validation warning for digitickets/lalit
igormukhingmailcom Dec 10, 2025
8686ae0
Composer | Fixed validation warning for dompdf/dompdf
igormukhingmailcom Dec 10, 2025
430d4e6
Composer | Fixed validation warning for ezyang/htmlpurifier
igormukhingmailcom Dec 10, 2025
619c5aa
Composer | Fixed validation warning for google/apiclient
igormukhingmailcom Dec 10, 2025
f8aa82b
Composer | Fixed validation warning for guzzlehttp/guzzle
igormukhingmailcom Dec 10, 2025
b93a99b
Composer | Fixed validation warning for html2text/html2text
igormukhingmailcom Dec 10, 2025
3f3c8c4
Composer | Fixed validation warning for kamermans/guzzle-oauth2-subsc…
igormukhingmailcom Dec 10, 2025
f34ed85
Composer | Fixed validation warning for knplabs/knp-snappy
igormukhingmailcom Dec 10, 2025
66b7e28
Composer | Fixed validation warning for laminas/laminas-config
igormukhingmailcom Dec 10, 2025
42eaf6d
Composer | Fixed validation warning for laminas/laminas-db
igormukhingmailcom Dec 10, 2025
2f1babe
Composer | Fixed validation warning for laminas/laminas-escaper
igormukhingmailcom Dec 10, 2025
43c0c8b
Composer | Fixed validation warning for laminas/laminas-eventmanager
igormukhingmailcom Dec 10, 2025
136c9a3
Composer | Fixed validation warning for laminas/laminas-filter
igormukhingmailcom Dec 10, 2025
78adf9c
Composer | Fixed validation warning for laminas/laminas-form
igormukhingmailcom Dec 10, 2025
5e44cd7
Composer | Fixed validation warning for laminas/laminas-inputfilter
igormukhingmailcom Dec 10, 2025
7b97056
Composer | Fixed validation warning for laminas/laminas-json
igormukhingmailcom Dec 10, 2025
c47176e
Composer | Fixed validation warning for laminas/laminas-json-server
igormukhingmailcom Dec 10, 2025
2f6a0d4
Composer | Fixed validation warning for laminas/laminas-loader
igormukhingmailcom Dec 10, 2025
915e78f
Composer | Fixed validation warning for laminas/laminas-mvc
igormukhingmailcom Dec 10, 2025
156caff
Composer | Fixed validation warning for laminas/laminas-mvc-i18n
igormukhingmailcom Dec 10, 2025
fbf9cee
Composer | Fixed validation warning for laminas/laminas-servicemanager
igormukhingmailcom Dec 10, 2025
a09841f
Composer | Fixed validation warning for laminas/laminas-soap
igormukhingmailcom Dec 10, 2025
c340f70
Composer | Fixed validation warning for laminas/laminas-stdlib
igormukhingmailcom Dec 10, 2025
54351e7
Composer | Fixed validation warning for laminas/laminas-xmlrpc
igormukhingmailcom Dec 10, 2025
84b6be6
Composer | Fixed validation warning for lcobucci/jwt
igormukhingmailcom Dec 10, 2025
4307a2d
Composer | Fixed validation warning for league/csv
igormukhingmailcom Dec 10, 2025
eba0d2a
Composer | Fixed validation warning for league/omnipay
igormukhingmailcom Dec 10, 2025
85ce9e0
Composer | Fixed validation warning for mobiledetect/mobiledetectlib
igormukhingmailcom Dec 10, 2025
5367ca1
Composer | Fixed validation warning for monolog/monolog
igormukhingmailcom Dec 10, 2025
6112329
Composer | Fixed validation warning for mpdf/mpdf
igormukhingmailcom Dec 10, 2025
8ba5d37
Composer | Fixed validation warning for nyholm/psr7
igormukhingmailcom Dec 10, 2025
769b8b4
Composer | Fixed validation warning for nyholm/psr7-server
igormukhingmailcom Dec 10, 2025
7d879bc
Composer | Fixed validation warning for omnipay/stripe
igormukhingmailcom Dec 10, 2025
a703b3f
Composer | Fixed validation warning for openemr/mustache
igormukhingmailcom Dec 10, 2025
5b04921
Composer | Fixed validation warning for particle/validator
igormukhingmailcom Dec 17, 2025
8a3268b
Composer | Fixed validation warning for pear/archive_tar
igormukhingmailcom Dec 10, 2025
1e7b69c
Composer | Fixed validation warning for php-http/discovery
igormukhingmailcom Dec 10, 2025
633c3c6
Composer | Fixed validation warning for php81_bc/strftime
igormukhingmailcom Dec 10, 2025
f2e9e1f
Composer | Fixed validation warning for phpmailer/phpmailer
igormukhingmailcom Dec 10, 2025
99aade3
Composer | Fixed validation warning for phpoffice/phpspreadsheet
igormukhingmailcom Dec 10, 2025
c54acf4
Composer | Fixed validation warning for phpseclib/phpseclib
igormukhingmailcom Dec 10, 2025
9eb2447
Composer | Fixed validation warning for predis/predis
igormukhingmailcom Dec 10, 2025
70d1fda
Composer | Fixed validation warning for psr/log
igormukhingmailcom Dec 10, 2025
b991639
Composer | Fixed validation warning for ramsey/uuid
igormukhingmailcom Dec 10, 2025
745dfa1
Composer | Fixed validation warning for ringcentral/ringcentral-php
igormukhingmailcom Dec 10, 2025
c527c63
Composer | Fixed validation warning for robthree/twofactorauth
igormukhingmailcom Dec 10, 2025
5857db8
Composer | Fixed validation warning for rospdf/pdf-php
igormukhingmailcom Dec 10, 2025
65e0b96
Composer | Fixed validation warning for smarty/smarty
igormukhingmailcom Dec 10, 2025
c716970
Composer | Fixed validation warning for steverhoades/oauth2-openid-co…
igormukhingmailcom Dec 10, 2025
cadb1af
Composer | Fixed validation warning for stripe/stripe-php
igormukhingmailcom Dec 10, 2025
8922e5f
Composer | Fixed validation warning for twig/twig
igormukhingmailcom Dec 10, 2025
7f65304
Composer | Fixed validation warning for twilio/sdk
igormukhingmailcom Dec 10, 2025
aa9eda3
Composer | Fixed validation warning for vlucas/phpdotenv
igormukhingmailcom Dec 10, 2025
8b50595
Composer | Fixed validation warning for waryway/php-traits-library
igormukhingmailcom Jan 2, 2026
55ddb76
Composer | Fixed validation warning for yubico/u2flib-server
igormukhingmailcom Dec 10, 2025
0c10c21
Composer | Updated composer.lock
igormukhingmailcom Jan 2, 2026
8574170
fix(phpstan): fix class name casing issues and reorganize baselines (…
kojiromike Jan 3, 2026
d2b51ea
Fix preg_match return value misuse in MedEx icon translation (#10043)
Copilot Jan 3, 2026
0bedcf1
revert: remove type declarations from translation functions (#10040)
kojiromike Jan 3, 2026
9225d9b
fix(xl): fix passing null to `xl` function instead of string (#10039)
zmilan Jan 3, 2026
52bd52d
fix(phpstan): add missing static properties to FaxSMS AuthenticateTra…
kojiromike Jan 3, 2026
7ba5986
fix(calendar): synchronize after importing holidays (#9993)
jeevanism Jan 3, 2026
551a758
chore(composer): tools for local QA (#10055)
kojiromike Jan 3, 2026
96279e4
fix(phpstan): resolve phpunit.mockMethod findings in EventAuditLogger…
kojiromike Jan 3, 2026
2bdf844
fix(phpstan): make eye_mag display functions return strings (#10049)
kojiromike Jan 3, 2026
6ae11cc
fix(phpstan): resolve fileNotFound findings via include path config (…
kojiromike Jan 3, 2026
39b4b7d
fix: remove dead MockRestConfig (#10064)
igormukhingmailcom Jan 3, 2026
b70507c
chore: add pre-commit config for local QA tooling (#9740)
Copilot Jan 3, 2026
a33e4cb
Remove unnecessary xl() call on numeric amount in ReminderIntervalDet…
Copilot Jan 3, 2026
03787ac
feat(ApplicationHealthProbe): application health probes (#8796)
kojiromike Jan 3, 2026
eb8e162
fix(composer): memory limit to be 4g for composer code quality script…
igormukhingmailcom Jan 3, 2026
e5154d6
fix(composer): version warning fix during composer validation (#10065)
igormukhingmailcom Jan 3, 2026
9454bb7
chore(deps): remove waryway/php-traits-library (#9759)
igormukhingmailcom Jan 4, 2026
db6ec66
fix: development environment fixes and a ci fix (#10075)
bradymiller Jan 5, 2026
0f54fbf
chore(deps): bump the symfony group with 6 updates (#10088)
dependabot[bot] Jan 5, 2026
5f48663
chore(deps): bump laminas/laminas-loader in the laminas group (#10089)
dependabot[bot] Jan 5, 2026
0d6cfdb
chore(deps): bump league/oauth2-server from 8.4.3 to 8.5.5 (#10090)
dependabot[bot] Jan 5, 2026
387d678
feat(api): added PATCH requests support (#10081)
igormukhingmailcom Jan 5, 2026
d198173
fix(phpstan): indent size for neon files at editorconfig (#10072)
igormukhingmailcom Jan 5, 2026
2f1c7b4
fix(composer): normalize to be consistently strict (#10100)
igormukhingmailcom Jan 5, 2026
35f4468
chore: upgrade lcobucci jwt to 4.3.0, steverhoades/oauth2-openid-con…
stephenwaite Jan 5, 2026
06e10dd
fix(pre-commit): exclude vendored third-party bundles from hooks (#10…
kojiromike Jan 5, 2026
ededbd7
chore(deps): bump monolog/monolog from 3.9.0 to 3.10.0 (#10091)
dependabot[bot] Jan 5, 2026
e516e6d
feat(phpstan): openemr-related rules baselines update script (#10099)
igormukhingmailcom Jan 5, 2026
f0b2ab9
style(whitespace): consistent whitespace (#10103)
kojiromike Jan 5, 2026
d1203b7
fix(phpstan): resolve class name collision between Procedure classes …
kojiromike Jan 6, 2026
4d8df08
fix(phpstan): resolve staticMethod.notFound via @method annotations (…
kojiromike Jan 6, 2026
82c5343
fix(health): skip auth for readyz endpoint to prevent login redirect …
kojiromike Jan 6, 2026
991ec1e
chore: peer true removed from package-lock.json after building with e…
stephenwaite Jan 6, 2026
cdaaa7e
fix(phpstan): resolve constructor.unusedParameter findings (#10062)
kojiromike Jan 6, 2026
98670af
Replace $GLOBALS with OEGlobalsBag in Portal (#9868)
zmilan Jan 6, 2026
4c5c27f
fix(phpstan): resolve return.missing findings (#10069)
kojiromike Jan 6, 2026
cfa14c9
test(js): add jsPDF integration tests for Fax/SMS module (#10120)
kojiromike Jan 6, 2026
6d7c425
Update node versions php-fpm dockers Fixes #10022 (#10118)
adunsulag Jan 6, 2026
619b973
Fixes #9877 adding ccda to phpunit tests
adunsulag Dec 15, 2025
b66a380
Fix inferno node version
adunsulag Dec 15, 2025
f04d91b
Fix test cases, enable ccda for ci engine
adunsulag Dec 23, 2025
19f40d8
Fix global settings for ci engine
adunsulag Dec 30, 2025
69c377e
cleanup line endings on xml file
adunsulag Jan 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"BillingExport",
"C_Document",
"Carecoordination\\Model\\CarecoordinationTable",
"Carecoordination\\Model\\CcdaGenerator",
"Carecoordination\\Model\\EncounterccdadispatchTable",
"FPDF_FONTPATH",
"GenericProductRegistrationException",
"IS_WINDOWS",
Expand All @@ -27,6 +29,7 @@
"areCredentialsCreated",
"buildTemplate",
"checkUserSetting",
"check_code_set_filters",
"csv_like_join",
"display_layout_tabs",
"display_layout_tabs_data",
Expand Down
2 changes: 1 addition & 1 deletion .dclintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rules:
service-image-require-explicit-tag: 0
no-unbound-port-interfaces: 0
require-quotes-in-ports: 0

# Alphabetical ordering rules are kept as warnings
services-alphabetical-order: 1
service-ports-alphabetical-order: 1
Expand Down
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.{json,jsn,sh,yaml,yml}]
[*.{json,jsn,sh,yaml,yml,neon,neon.dist}]
indent_size = 2

[composer.{json,lock}]
Expand Down
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ["https://www.open-emr.org/donate/"]
#bitcoin: 3GCNLbiZmHP26fA77NkLgY4tKdEts3ADQg
#ethereum: 0xcD7542b2DcF41072aC7783C7cbc31B0f1E257E80
#ethereum: 0xcD7542b2DcF41072aC7783C7cbc31B0f1E257E80
2 changes: 0 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,3 @@ Steps to reproduce the behavior:

<!-- Love openemr? Please consider supporting our project:
👉 https://github.com/sponsors/openemr -->


2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--Thanks for sending a pull request!
<!--Thanks for sending a pull request!
Please create an issue at https://github.com/openemr/openemr/issues/new/choose and then
-->

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/composer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
run: composer install --prefer-dist --no-progress

- name: "Validate Composer"
run: composer validate
run: composer validate --strict

- name: "Check Composer Normalized"
run: composer normalize --dry-run
24 changes: 7 additions & 17 deletions .github/workflows/docker-compose-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,10 @@ on:
branches:
- master
- rel-*
paths:
- '**/*compose*.yml'
- '**/*compose*.yaml'
- '.github/workflows/docker-compose-lint.yml'
- '.dclintrc.yaml'
pull_request:
branches:
- master
- rel-*
paths:
- '**/*compose*.yml'
- '**/*compose*.yaml'
- '.github/workflows/docker-compose-lint.yml'
- '.dclintrc.yaml'

permissions:
contents: read
Expand All @@ -34,7 +24,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Get changed docker compose files
id: changed-files
continue-on-error: true
Expand All @@ -45,12 +35,12 @@ jobs:
**/*compose*.yaml
files_ignore: |
.github/**

- name: Determine files to check
id: files-to-check
run: |
set -x

# If the changed-files step failed or returned empty,
# use find to locate all docker compose files in the repo.
if [[ "${{ steps.changed-files.outcome }}" = success && "${{ steps.changed-files.outputs.any_changed }}" = true ]]; then
Expand All @@ -63,13 +53,13 @@ jobs:
# Use recursive mode in dclint to find all compose files
echo "mode=recursive" >> "$GITHUB_OUTPUT"
fi

- name: Run dclint on changed files
if: steps.files-to-check.outputs.mode == 'files'
run: |
docker run --rm --volume "$PWD:$PWD" --workdir "$PWD" zavoloklom/dclint:3.1.0 --exclude .github ${{ steps.files-to-check.outputs.files }}
docker run --rm --volume "$PWD:$PWD" --workdir "$PWD" zavoloklom/dclint:3.1.0 ${{ steps.files-to-check.outputs.files }} --exclude .github

- name: Run dclint recursively
if: steps.files-to-check.outputs.mode == 'recursive'
run: |
docker run --rm --volume "$PWD:$PWD" --workdir "$PWD" zavoloklom/dclint:3.1.0 --exclude .github --recursive ci/ docker/
docker run --rm --volume "$PWD:$PWD" --workdir "$PWD" zavoloklom/dclint:3.1.0 ci/ docker/ --recursive --exclude .github
8 changes: 4 additions & 4 deletions .github/workflows/hadolint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Get changed Dockerfile files
id: changed-files
# We run hadolint on all Dockerfiles in the repo
Expand All @@ -43,7 +43,7 @@ jobs:
with:
files: |
**/Dockerfile*

- name: Run hadolint on changed files
if: ${{ steps.changed-files.outcome == 'success' && steps.changed-files.outputs.any_changed == 'true' }}
env:
Expand All @@ -52,14 +52,14 @@ jobs:
# Safely handle changed files list using environment variable
# Convert space-separated list to newline-separated for safe parsing
mapfile -t files < <(echo "$CHANGED_FILES" | tr ' ' '\n')

echo "Linting ${#files[@]} changed Dockerfile(s)..."
for file in "${files[@]}"; do
[[ -n "$file" ]] || continue
echo "Checking: $file"
docker run --rm -i -v "$(pwd)/.hadolint.yaml:/.config/hadolint.yaml" hadolint/hadolint < "$file"
done

- name: Run hadolint on all files
if: ${{ steps.changed-files.outcome != 'success' || steps.changed-files.outputs.any_changed != 'true' }}
run: |
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/phpstan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,14 @@ jobs:
# Generate baseline only if analyze step failed
- name: PHPStan Baseline
if: steps.phpstan-analyze.outcome == 'failure'
run: vendor/bin/phpstan --memory-limit=8G --generate-baseline=baseline.neon
run: composer run phpstan-baseline
continue-on-error: true
# Upload baseline only if baseline.neon file exists
- name: Upload PHPStan Baseline
if: hashFiles('baseline.neon') != ''
if: steps.phpstan-analyze.outcome == 'failure'
uses: actions/upload-artifact@v6
with:
name: phpstan-baseline-php${{ matrix.php-version }}
path: baseline.neon
path: .phpstan/phpstan-*-baseline.neon
continue-on-error: true
- name: Check PHPStan Results
if: steps.phpstan-analyze.outcome == 'failure'
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/whitespace.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Whitespace

on:
push:
branches:
- master
- rel-*
pull_request:
branches:
- master
- rel-*

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'pull_request' && github.event.number || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:

whitespace:
runs-on: ubuntu-24.04
name: Check whitespace
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install pre-commit
run: pip install pre-commit
- name: Get changed files (PR only)
if: github.event_name == 'pull_request'
id: changed-files
uses: tj-actions/changed-files@v47
- name: Run whitespace hooks (PR - changed files only)
if: github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true'
run: |
pre-commit run trailing-whitespace --files ${{ steps.changed-files.outputs.all_changed_files }}
pre-commit run end-of-file-fixer --files ${{ steps.changed-files.outputs.all_changed_files }}
pre-commit run mixed-line-ending --files ${{ steps.changed-files.outputs.all_changed_files }}
- name: Run whitespace hooks (push - all files)
if: github.event_name == 'push'
run: |
pre-commit run --all-files trailing-whitespace
pre-commit run --all-files end-of-file-fixer
pre-commit run --all-files mixed-line-ending
16 changes: 8 additions & 8 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,35 @@ ignored:
# DL3003: Use WORKDIR to switch to a directory
# Many of our existing Dockerfiles use cd in RUN commands for complex build processes
- DL3003

# DL3006: Always tag the version of an image explicitly
# Some base images (osixia/openldap, nginx) are intentionally using latest
- DL3006

# DL3008: Pin versions in apt-get install
# Pinning apt versions can make maintenance difficult and break builds
- DL3008

# DL3009: Delete the apt lists after installing something
# Some Dockerfiles deliberately keep apt lists for development purposes
- DL3009

# DL3015: Avoid additional packages by specifying --no-install-recommends
# Some builds intentionally include recommended packages
- DL3015

# DL4006: Set the SHELL option -o pipefail before RUN with a pipe
# Adding pipefail to all existing RUN commands would be intrusive
- DL4006

# SC2086: Double quote to prevent globbing and word splitting
# Many existing scripts use intentional word splitting
- SC2086

# SC2046: Quote this to prevent word splitting
# Many existing scripts use intentional word splitting
- SC2046

# DL3020: Use COPY instead of ADD for files and folders
# Some existing Dockerfiles use ADD for local files
- DL3020
Expand Down
20 changes: 17 additions & 3 deletions .phpstan/ForbiddenFunctionsRule.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php

/**
* Custom PHPStan Rule to Forbid Legacy SQL Functions in Modern Code
* Custom PHPStan Rule to Forbid Legacy Functions in Modern Code
*
* This rule prevents use of legacy sql.inc.php functions in the src/ directory.
* Contributors should use QueryUtils or DatabaseQueryTrait instead.
* This rule prevents use of:
* - Legacy sql.inc.php functions (use QueryUtils or DatabaseQueryTrait instead)
* - Legacy call_user_func and call_user_func_array (use modern PHP syntax instead)
*
* @package OpenEMR
* @author Michael A. Smith <michael@opencoreemr.com>
Expand Down Expand Up @@ -42,6 +43,8 @@ class ForbiddenFunctionsRule implements Rule
'sqlStatementNoLog' => 'Use QueryUtils::fetchRecordsNoLog() instead of sqlStatementNoLog().',
'sqlStatementThrowException' => 'Use QueryUtils::sqlStatementThrowException() instead of global sqlStatementThrowException().',
'sqlQueryNoLog' => 'Use QueryUtils::querySingleRow() instead of sqlQueryNoLog().',
'call_user_func' => 'Use uniform variable syntax $callable(...$args) or the argument unpacking operator instead of call_user_func().',
'call_user_func_array' => 'Use uniform variable syntax $callable(...$args) or the argument unpacking operator instead of call_user_func_array().',
];

public function getNodeType(): string
Expand All @@ -68,6 +71,17 @@ public function processNode(Node $node, Scope $scope): array

$message = self::FORBIDDEN_FUNCTIONS[$functionName];

// Determine error identifier and tip based on function type
if (in_array($functionName, ['call_user_func', 'call_user_func_array'])) {
return [
RuleErrorBuilder::message($message)
->identifier('openemr.legacyCallUserFunc')
->tip('Example: $myFunction(...$args) or [$object, \'method\'](...$args)')
->build()
];
}

// Default for SQL functions
return [
RuleErrorBuilder::message($message)
->identifier('openemr.deprecatedSqlFunction')
Expand Down
6 changes: 3 additions & 3 deletions .phpstan/MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ use OpenEMR\Core\OEGlobalsBag;
class MyService
{
private OEGlobalsBag $globals;

public function __construct(OEGlobalsBag $globals)
{
$this->globals = $globals;
}

public function doSomething(): void
{
$setting = $this->globals->get('some_setting');
Expand Down Expand Up @@ -209,7 +209,7 @@ class MyServiceTest extends TestCase
'some_setting' => 'test value',
'timeout' => 60
]);

$service = new MyService($testGlobals);
// Test your service
}
Expand Down
4 changes: 2 additions & 2 deletions .phpstan/MIGRATION_GUIDE_CURL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ try {
$response = $client->request('POST', 'https://api.example.com/endpoint', [
'json' => $data // Automatically sets Content-Type and encodes JSON
]);

$result = json_decode($response->getBody()->getContents(), true);
} catch (GuzzleException $e) {
error_log("HTTP Error: " . $e->getMessage());
Expand Down Expand Up @@ -163,7 +163,7 @@ try {
'Authorization' => 'Bearer ' . $token
]
]);

$data = json_decode($response->getBody()->getContents(), true);
} catch (\Exception $e) {
error_log("HTTP request failed: " . $e->getMessage());
Expand Down
Loading
Loading