one-click-accessibility/modules/core/classes/svg-sanitizer.php
Raz Ohad 3497463785
Release/v3.3.0 (#272)
* Bump WP version

* ♻️ Initial Refactor commit [APP-687] (#109)

* Initial refactor commit

*  Added build and tests CI/CD

* PR Rejects

* Rejects leftover

* Setup base (#110)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: settings variable

* update: removed duplicate css import

* Update modules/settings/assets/js/api/index.js

Co-authored-by: VasylD <vasyld@elementor.red>

---------

Co-authored-by: Ohad <ohad@elementor.com>
Co-authored-by: VasylD <vasyld@elementor.red>

* [Infra]  updated Github actions (#114)

* updated github actions

* removed composer github auth

* PHPCS

* removed package-lock.json from ignore to allow `npm ci`

* added missing husky

* ignore legacy

* removed unused non existing import

* Add connect modal (#111)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: add rule to move jsx props to multiline imporving readability

* add: connect modal

* update: hooks import for better readability

* update: replace functions with hooks

* fix: alignment and style

* update: imports

* update: removed conflicting imports

* fix: add compatibility for mobile devices

---------

Co-authored-by: Ohad <ohad@elementor.com>

* [APP 705] add connect module, settings and notification component (#112)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: add rule to move jsx props to multiline imporving readability

* add: connect modal

* update: hooks import for better readability

* update: replace functions with hooks

* add: connect module

* add: settings and get settings route

* add: hooks and contexts to get settings

* add: hooks

* add: notification component

* add: data api

* add: settings provider and connect settings

* add: husky

* fix: formatting and text-domain

* update: filter names

* fix: hook import

* add: set function for settings

* add: prop-types package

* update: refactor notification component and context

* update: remove filter for authorize url

* update: imports and exports of hooks

* update: plugin settings context filename and relevant imports

---------

Co-authored-by: Ohad <ohad@elementor.com>

* [APP 707] general setting components (#113)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: add rule to move jsx props to multiline imporving readability

* add: connect modal

* update: hooks import for better readability

* update: replace functions with hooks

* add: connect module

* add: settings and get settings route

* add: hooks and contexts to get settings

* add: hooks

* add: notification component

* add: data api

* add: settings provider and connect settings

* add: husky

* add: icon size control

* fix: icon size control labels

* add: icon select component

* add: color picker component

* add: accessibility icons

* add: icon export

* update: add icons to the component

* fix: styling for the icon select control

* update: color picker with react-colorful component

* update: icon size component with live icon design

* fix: styling of radio boxes

* add: icon design settings layout

* add: position settings layout

* add: layout exports

* add: alignment matrix and position control components

* add: position settings  & position settings for mobile layout

* fix: formatting and text-domain

* update: filter names

* fix: hook import

* add: set function for settings

* add: prop-types package

* update: refactor notification component and context

* update: remove filter for authorize url

* Update modules/settings/assets/js/components/color-picker/style.css

Co-authored-by: Raz Ohad <admin@bainternet.info>

* update: color picker class name

---------

Co-authored-by: Ohad <ohad@elementor.com>
Co-authored-by: Raz Ohad <admin@bainternet.info>

* [App 780] Navigation Sidebar (#115)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: add rule to move jsx props to multiline imporving readability

* add: connect modal

* update: hooks import for better readability

* update: replace functions with hooks

* add: connect module

* add: settings and get settings route

* add: hooks and contexts to get settings

* add: hooks

* add: notification component

* add: data api

* add: settings provider and connect settings

* add: husky

* fix: formatting and text-domain

* update: filter names

* fix: hook import

* add: set function for settings

* add: prop-types package

* update: refactor notification component and context

* update: remove filter for authorize url

* update: imports and exports of hooks

* update: plugin settings context filename and relevant imports

* update: icons and icon imports

* add: sidebar(wip)

* update: fix width of connect screen on mobile

* update: sidebar layout

* add: credit card and user arrow icons

* update: hidden wpfooter and fixed sidebar height

* update: sidebar layout

* add: basic page layouts

* update: sidebar layout

* add: sidebar menu, sidebar app bar and my account menu components

* update: add sidebar and menu settings

* update: add page layouts

* update: admin top bar

* add: bottom bar

* add: bottom bar and top bar

* add: bottom bar and top bar

* update: page content styling

* fix: styling

* fix: styling

* update: text domain

* update: added translations

* fix: admin top bar layout

* update: exports of icons

* update: exports of components

* add: aliases for imports and fix exports

* fix: height and styling of the layout

* fix: unhide wp footer

* update: keep widget menu open on page load (default)

* update: linter rules to move first prop to new line

* update: linter rules to move first prop to new line

---------

Co-authored-by: Ohad <ohad@elementor.com>

* Fix error on install plugin, add prettier (#116)

* Feature/app 810 assemble icon settings page (#117)

* Initial refactor commit

*  Added build and tests CI/CD

* update: add src for admin settings

* update: incorrect constant names

* update: namespace

* add: accessibility settings

* update: webpack to output files inside a folder

* update: build output folders

* update: removed commented code

* update: npm scripts

* add: webpack config

* add: hooks

* update: move admin setting to the module folder

* update: assets loading logic

* update: add rule to move jsx props to multiline imporving readability

* add: connect modal

* update: hooks import for better readability

* update: replace functions with hooks

* add: connect module

* add: settings and get settings route

* add: hooks and contexts to get settings

* add: hooks

* add: notification component

* add: data api

* add: settings provider and connect settings

* add: husky

* add: icon size control

* fix: icon size control labels

* add: icon select component

* add: color picker component

* add: accessibility icons

* add: icon export

* update: add icons to the component

* fix: styling for the icon select control

* update: color picker with react-colorful component

* update: icon size component with live icon design

* fix: styling of radio boxes

* add: icon design settings layout

* add: position settings layout

* add: layout exports

* add: alignment matrix and position control components

* add: position settings  & position settings for mobile layout

* fix: formatting and text-domain

* update: filter names

* fix: hook import

* add: set function for settings

* add: prop-types package

* update: refactor notification component and context

* update: remove filter for authorize url

* update: imports and exports of hooks

* update: plugin settings context filename and relevant imports

* update: icons and icon imports

* add: sidebar(wip)

* update: fix width of connect screen on mobile

* update: sidebar layout

* Update modules/settings/assets/js/components/color-picker/style.css

Co-authored-by: Raz Ohad <admin@bainternet.info>

* update: color picker class name

* add: credit card and user arrow icons

* update: hidden wpfooter and fixed sidebar height

* update: sidebar layout

* add: basic page layouts

* update: sidebar layout

* add: sidebar menu, sidebar app bar and my account menu components

* update: add sidebar and menu settings

* update: add page layouts

* update: admin top bar

* add: bottom bar

* add: bottom bar and top bar

* add: bottom bar and top bar

* update: page content styling

* fix: styling

* fix: styling

* update: text domain

* add: props to wrapper

* add: icon design and position setting layouts

* add: in page scroll behaviour to the settings

* add: widget icons and getter function

* update: icon design settings getter and setter functions

* update: imports

* add: mobile layout for position settings

* add: icon position settings

* add: icon position settings hooks and handlers

* fix: alignment of controls in AlignmentMatrixControl

* update: useSettings and usePositionSetting hooks and relevant functions

* fix: colors of AlignmentMatrixControl

* fix: styling of components and layouts

* add: aliases

* add: container wrapper to page

* update: accessibility options rendering logic

* fix: order of the icons

* add: aliases for components and hooks imports

* fix: styling of settings panel

* fix: container height for settings page

* update: toggle control states

* add: widget icon settings

* add: load saved widget icon settings

* update: move layout to page for different designs per page

* update: add changes tracking and disable button logic

* add: async/await to save settings

* update: convert options to array of objects

* Update modules/settings/assets/js/components/bottom-bar/index.js

Co-authored-by: VasylD <vasyld@elementor.red>

* Update modules/settings/assets/js/app.js

Co-authored-by: VasylD <vasyld@elementor.red>

* fix: remove duplicate entries

---------

Co-authored-by: Ohad <ohad@elementor.com>
Co-authored-by: Raz Ohad <admin@bainternet.info>
Co-authored-by: VasylD <vasyld@elementor.red>

* Feature/app 708 widget menu settings (#118)

* add: icons for menu settings

* add: placeholder layout for widget preview in menu settings

* update: load saved settings and updated imports

* add: logics for handling and saving menu settings

* add: useSavedSettings hook

* update: set export as default for Sidebar layout

* add: widget menu settings layout and settings

* update: add widget menu settings and widget preview layouts

* add: hide/show minimum option alert notification

* update: styling of the save button

* update: save settings logic to use async/await

* fix: accessibility text icon

* update: app type (#119)

* [APP-834] Update account menu buttons (#121)

* update: account menu buttons

* update: billing link

* add: error handling for switch account

* [APP-835] add service data (#122)

* add: client functions

* add: site register and site info endpoints

* update: add plan data settings

* update: add support for 201 response code

* update: add plan data key

* update: store the plan data on the once the site is registered

* update: add filter for client url

* add: retry registering in there is any error after connect

* update: setting prefix

* add: plan data

* update: add account details to menu

* fix: lint issues

* update: add data checkbox support (#123)

* [APP-928] Settings pointer (#125)

* add: settings pointer

* update: add alias for the settings

* [APP-837] Add post connect modal (#120)

* add: post connect modal

* update: settings prefix

* fix: connect modal design

* update: connect modal text

* add: connect modal graphics

* update: connect modal icon

* update: post connect modal

* update: sidebar menu text

* update: text of icon settings

* update: text

* update: php compatibility with return types

* add: accessibility statement page structure (#126)

* [APP-721] Render widget and global settings (#124)

* add: webhook endpoint

* add: widget module

* add: default widget settings on successful registration

* update: name of global object to ea11yWidget

* update: remove json encoding to make objects available on the frontend

* update: widget url, filter and enqueuing method

* update: removed obsolete code

* update: enqueue script only when connected

* update: add check for valid plan data and key

* update: conditional check

* update: conditional check

* fix: widget loading error (#128)

* [Legacy] Upgrade To New [APP-949] (#127)

* Added `Notice_Base` and `Notices` component to core module

* Always load core module and load all other modules based on legacy status

* added filter in customizer settings

* added bubble / pimple in admin menu to indicate upgrade

* added `Dismissible_Deprecated_Nag` notice to none legacy pages

* added `Dismissible_Deprecated_Nag` notice to legacy pages

* Added `Upgrade` component to legacy module

includes:
* loading of notices
* introduction modal
* admin menu pimple
* customizer notice
* pointer
* confirmation modal
* upgrade logic and handler

*  Fixed legacy module test

* added `local:quick-run` command to run in browser mode

* update phpunit workflow

* ensure wp.ajax is loaded

* wrong translations

* Updated strings

* added "Equally"

* remove unused test

*  use custom version of wp test library (#129)

*  use custom version of wp test library

* cleanup

* update WP versions for testing

* [APP-711] Widget preview (#130)

* add: dynamic script loader for widget

* update: settings name

* update: settings save function and comments

* update: tools settings object structure

* add: widget preview section

* update: added setting page slug as a constant

* update: enqueue widget for preview in the settings

* add: widget icon assets link

* add: widget icon svgs

* update: store widget url in a constant

* update: store widget url in a constant

* update: trigger widget preview update on menu item changes

* update: remove the icon option from the frontend.

* update: add widget URL

* update: plan data setting type

* update: widget plan url

* update: widget plan url and parse plan data

* fix: phpcs error ext-json missing

* fix: widget url

* fix: save and use plan data as a serialized option

* fix: use template string for widget url

* [APP-908] Accessibility generator (#131)

* add: accessibility statement radio icons

* update: add form group on radio buttons

* add: statement generator

* add: statement generator

* add: accessibility statement data option

* update: create page in WordPress and save it to the option

* update: exclude zip file from the git

* update: render statement page conditionally

* add: statement link layout and settings

* add: preload statement data

* update: publish the created page and add link for it

* update: changed Dynamic Script Loader to WidgetLoader

* add: accessibility statement url

* update: text and styling

* update: styling of the preview text

* update: restructure statement generator

* add: support for dynamic update in statement links

* update: remove index.css file for widget loader

* add: widget styling for settings page

* add: empty link when hide link is enabled

* update: statement page structure and logic

* fix: typo

* update: convert component into a styled component

* fix: styling and layout

* update: icons

* update: convert radio buttons to styled component

* fix: typo and style

* add: fading for the link preview

* update: import

* update: styling and spacing

* fix: sidebar layout

* update: wpcs to latest version

* fix: spacing

* fix: wpcs version

* add: check for valid statement page

* fix: jitters on rendering

* fix: use escape attribute

* update: settings menu slug and plugin name

* fix: menu item rendering

* update: definition of the styled text field

* add: addPage function to the API

* fix: add notification on page creation

* add: copy link icon

* update: optimize SVGs

* [APP-908] Additional fixes (#133)

* fix: text domains

* updated: styled component syntax

* update: use await instead of then

* fix: prevent application crash in case widget fails to load

* add: generated info tip card

* update: refactor function

* Fix: Fix the QA bugs [n/a] (#135)

* [APP-830] Add mixpanel events (#134)

* [APP-830] Add mixpanel events

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* [APP-830] Add user to init Mixpanel (#136)

* [APP-830] Add mixpanel events

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* Merge branch 'develop' into feature/APP-830-add-mixpanel

# Conflicts:
#	.gitignore
#	modules/settings/assets/js/components/sidebar-menu/index.js
#	modules/settings/assets/js/pages/accessibility-statement.js

* [APP-830] Add user to init Mixpanel

* [APP-830] Add user to init Mixpanel

* [APP-830] Add user to init Mixpanel

* [APP-830] rename events (#137)

* Connect and Preview Fixes (#139)

* updated connect admin page

* Use unified widget URL instead of hardcoded Js to support envs

* Removed enqueue of fictional widget.js and reuse settings `admin` handle

* Fix: Fix the QA bugs [n/a] (#138)

* New: Finish the BE integration [n/a]

* Fix: Fix some bugs [n/a]

* upgrade flow UI and design tweaks [app-949] (#141)

* Updated Learn More links with UTM's

* Tweaked Pointer strings Icon and CTA

* dismissible notice strings

* sticky notice strings

* updated upgrade flow design for pointer, notices, introduction modal, and confirmation modal

* added build script

* [APP-979] Update links and plugin name (#140)

* Ensure loading of legacy widget based on any saved data and fixed legacy JS

* Bug/app 1002 (#143)

* Bug: Update the logo in the "Hide Widget" modal [APP-1001]

* Fix: Update the side menu spaces [APP-1002]

* [APP-991] Add translation for statement (#142)

* [APP-979] Update links and plugin name

* [APP-991] Add translation for statement

* Set Prod Widget URL

* [APP-1004][APP-1005][APP-1006] Fix generator UI and logic, fix statement UI, fix copy link (#144)

* [APP-1004] Fix generator UI and logic

* [APP-1005] Fix statement UI

* [APP-1005] Fix statement UI

* Mixpanel record session

* Fix: Enhance position values validation [APP-1009] (#146)

* Bug/app 1003 (#147)

* Fix: Add a border to the preview [n/a]

* Fix: Fix Capabilities screen UI [APP-1003]

* [APP-1020] add missed events (#148)

* [APP-1015] fix switch account (#149)

* [APP-1015] fix switch account (#150)

* [APP-1021] Fix switch modal ui (#151)

* fix: ui issues

* fix: translation strings

* [APP-912] add default settings for RTL (#152)

* [APP-912] add default settings for RTL

* [APP-912] add default settings for RTL

* [APP-912] add default settings for RTL

* [APP-1026] Remove HTML breaking <style> tag & update pointer logic (#153)

* fix: remove extra closing tag

* update: hide settings pointer when plugin settings is opened

* update: remove unused functions

* update: add help text to mobile position settings

* Bug/app 1003 (#157)

* Fix: Add missed translations [n/a]

* Fix: Refresh the plan data on page load [n/a]

* New: Add loader to the settings [n/a]

* update: delete lock key after each check (#160)

* New: Update dashboard icon size [n/a] (#158)

* New: Update dashboard icon size [n/a]

* Fix: Fix widget previews [n/a]

* [APP-1018] Help menu change (#155)

* update: remove accessibility word from menu items

* update: remove top bar

* update: add help button to the sidebar

* update: re-add spacing in styled css code

* update: create styled components

* [APP-973] Add an UTM for users upgrading from one click to the new widget (#165)

* update: ui of the statement preview (#166)

* [APP-1011][APP-1013] focus outline and sitemap settings (#161)

* [APP-1011][APP-1013] focus outline and sitemap settings

* [APP-1011][APP-1013] focus outline and sitemap settings

* [APP-1011][APP-1013] focus outline and sitemap settings

* [APP-1011][APP-1013] focus outline and sitemap settings

* update: video link (#167)

* [APP-1051] Fix layout on the small and medium devices (#156)

* fix: layout on the small and medium devices

* update: change components to styled components

* refactor: position settings wrapper into a separate component

* [APP-1012][APP-1085] Add skip to content settings and event for Mixpanel (#169)

* [APP-1012][APP-1085] Add skip to content settings and event for Mixpanel

* [APP-1012][APP-1085] Add skip to content settings and event for Mixpanel

* [APP-1012][APP-1085] Add skip to content settings and event for Mixpanel

* [APP-1012][APP-1085] Add skip to content settings and event for Mixpanel

* [APP-1048] Add tooltip to accessibility statement (#159)

* add: tooltip to accessibility statement

* update: hide infotip when statement link is set

* update: infotip's text

* fix: infotip naming and logic

* [APP-1049] Add back button accessibility statement (#164)

* add: back button to the statement link section

* add: Edit link button to statement page section

* update: add admin_url and generate query args properly

* update: learn more link for accessibility statement page (#168)

* Fix: Update overlay height [n/a] (#171)

* Fix settings and connect issues (#170)

* fix: token fails to refresh after expiry

* update: add 12 hour time for plan data refresh and fix missing subscription id

* update: add check to refresh plan data

* fix: decoding errors and alignment and add logging for errors

* update: refresh logic and formatting

* Update/app 1029 app name (#173)

* update: plugin name

* update: default menu option

* update: menu structure

* update: add inline checks

* update: reduce padding on app icon in menu

* fix: height of the modal

* update: app menu icon color

* update: menu icon colors

* fix: menu icon size

* update: plugin names

* update: HELP_LINK

* update: app name

* update: icon background color

* update: icon size

* fix: admin icon size

* fix: width of the sidebar

* Fix/toggle not working properly (#174)

* fix: toggles not working properly in some cases

* fix: saving of the settings was not working

* add: missing adminUrl in settings data

* fix: switch was not working properly in some cases (#175)

* Fix/app 1093 incorrect position on default (#176)

* fix: switch was not working properly in some cases

* fix: default setting structure for the icon position

* [APP-1096] Text changes (#177)

* fix: switch was not working properly in some cases

* update: plugin name and action buttons title

* fix: revert change to is_active function

* fix: button color

* New: Add the skip link [APP-1012] (#179)

* [APP-1097] Fix preview load (#178)

* [APP-1097] Fix preview load

* [APP-1097] Fix preview load

* [APP-1097] Fix preview load

* Update modules/settings/assets/js/components/widget-loader/index.js

---------

Co-authored-by: Raz Ohad <ohad@elementor.com>

* [APP-1123] Accessibility statement text (#181)

* fix: switch was not working properly in some cases

* update: accessibility statement content

* [APP-1121] Add support for react-jsx-runtime for older WP versions (#180)

* fix: switch was not working properly in some cases

* update: revert wp-scripts version to 28.0.0 to add support for older WordPress versions

* update: revert wp-scripts to 27.9.0

* add: support for react-jsx-runtime in older versions of WordPress

* update: version to the latest wp-scripts 30.3.0

* update: add lib/ to gitignore

* update: plugin name

* Fix: Fix admin widget previews [n/a] (#183)

* [APP-1061] change mixpanel user id (#184)

* [APP-1129] change toggle_event for mixpanel (#186)

* Remove skip to content btn if anchor does not exist (#187)

* fix: hide wp notices to keep the layout from shifting (#189)

* [APP-1143] fix bug with capability display (#195)

* [APP-1143] fix bug with capability display

* [APP-1143] fix bug with capability display

* [APP-1143] fix bug with capability display

* [APP-1143] fix bug with capability display

* add: loading text to widget preview (#196)

* [APP-1142] add 'appType' super props, change identify key (#191)

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic

* [APP-1142] Add 'appType' super props

* [APP-1144] Accessibility statement tooltip text update (#198)

* update: text

* update: switch design

* Tweak: Update widget loaders [n/a] (#197)

* added images to readme (#172)

* added images to readme

* updated readme

* V3.0.0

* updated readme

* updated tested up to

* Fix: Update the skip link rendering hook [APP-1157] (#203)

* bumped v3.0.1 (#206)

* Fix: Adapt widget preview to smaller height viewports [APP-1130] (#217)

* update: convert menu icon to base64 svg (#199)

* update: convert menu icon to base64 svg

* update: logo to svg logo with base64 encoded

* update: svg app icon

* [APP-1201] Improve admin panel accessibility (#220)

* [APP-1201] add accessibility rules

* [APP-1201] add accessibility rules

* [APP-1210] add prop to Mixpanel, move event names to const (#225)

* [APP-1159] Add mismatch URL flow (#210)

* update: convert imports to named imports

* add: function to check if current screen is settings page

* update: rename elementor logo to app logo

* add: url mismatch flow and components

* update: remove obsolete code

* Update modules/connect/rest/authorize.php

Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>

* Update modules/settings/module.php

Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>

* fix: modal was not closing

* update: remove url mismatch notice

* update: mismatch modal and rendering logic

* add: toast notifications for errors

* update: convert components into styled components

* update: remove bottom border from the dialog

* update: text copy

* fix: logo alignment

* update: renamed styled component

---------

Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic (#190)

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic

* Add nonce to the widget settings

* Update routes and DB table

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* [APP-1101] Move action button to footer (#208)

* update: add save changes footer to the bottom and remove it from capabilities

* add: logic to save settings for skiptocontent using footer

* update: text

* update: convert component to styled component

* [APP-1198] [APP-1199] Quota bar and notices (#219)

* add: quota bar

* add: openLink helper function

* add: styled elements and visits link placeholder

* update: remove hover state from the box

* add: quota notices

* update: quota access and usage calculations

* add: logic to calculate plan usage

* update: move logic to calculate plan usage to hook

* add: todo note

* add: todos

* add: mixpanel events

* fix: hide quota bar when sidebar is minimized

* fix: settings panel was not expanding when sidebar is minimized

* update: text and structure of the bar

* update: quota calculation logic

* update: remove TODOs

* update: text and values

* fix: height of the container for icon settings

* update: golinks

* update: golinks

* fix: prevent icon options from wrapping on smaller screen sizes (#229)

* [APP-1107] Add dashboard for analytics (#204)

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic

* [APP-1108][APP-1109][APP-1110] Add analytics backend logic

* Add nonce to the widget settings

* Update routes and DB table

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* Fix comments

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1107] Add dashboard for analytics

* [APP-1201] add accessibility rules

* [APP-1107] fixed API endpoint

* [APP-1107] fixed API endpoint

* [APP-1107] fixed API endpoint

* [APP-1107] add check for is_active

* update to the latest

* update to the latest

* update to the latest

* fix bugs, add changes

* fix bugs, add changes

* fix bugs, add changes

* fix bugs, add changes

* [APP-1105] Add pro capabilities (#205)

* add: volume and solid crown icon

* add: volume and crown icons to export

* update: refactor menu item to a new component

* add: screen reader to the menu items and reorganize them

* add: pro item infotip content

* add: capabilities item and pro info tip to exports

* update: import ProInfoTip component and change disabled logic

* update: imports

* update: refactor pro item infotip into the separate component

* update: refactor infotip and add comments

* add: custom switch component

* add: logo settings layout

* update: switch component

* add: useToggleSetting hook to manage widget settings.

* update: move pro feature key to a separate constant

* fix: pro icon style

* update: remove branding key

* update: pro enable check structure

* update: pro enabled check structure

* update: key name

* update: update key before checking for it

* fix: null error

* add: update logic to get the tools settings based on plan

* update: exclude remove-elementor-label from the minimum option rule

* update: add formlabel and eventnames

* add: logic to deactivate the features which are disabled for the plan

* fix: PHP warning

* fix: keyword name

* add: GOLINKS

* add: open link function

* fix: PHP warning undefined key

* update: logic to show the icon and added golinks

* [APP-1045] Add billing tab (#223)

* add: plan name and subscription link

* update: refactor my account menu

* update: move truncate email to a helper file

* update: simplify truncation logic

* [APP-1270] Delete transient and force info update (#236)

* add: force update site/info on mismatch url

* update: add a constant for the transient

* add: delete_transient for switch account as well

* add: delete_transient for disconnect as well

* [APP-1267] Quota bar undefined (#234)

* fix: undefined was shown when there is no quota data

* add: preloader

* fix: make bottom bar sticky on the settings pages (#237)

* [APP-1268] Pro tip spacing (#235)

* fix: pro tip spacing

* fix: pro icon

* [APP-1271] Align menu icons (#238)

* update: hide info button on minimized sidebar

* fix: alignment of quota bar icon

* fix: conditional logic

* update: improve sidebar motion

* fix: switch account issue

* update: upgrade link for analytics popup (#239)

* [APP-1281] fix usage percentage formatting (#240)

* fix: format display of percentage correctly.

* update: fraction conversion logic

* Force referer and lower transient time to 15 minutes [APP-1286] (#242)

* reduce transient timeout

* force referrer in script tags

* [APP-1262] Enable routes for get statistic on disabled analytics (#233)

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1262] Enable routes for get statistic on disabled analytics

* [APP-1243] Admin upgrade notices (#241)

* add: admin quota notices

* add: fix function name and phpcs issues

* fix: formatting issues

* [APP-1287] change Mixpanel check for free trial (#243)

* Fix/quota text (#244)

* fix: wp notice close logic plus banner text

* update: banner text

* [APP-1292] missing mixpanel events (#245)

* add: missing mixpanel events

* update: use variable for hardcoded names

* update: use variable for hardcoded names

* [APP-1293] Add additional checks (#246)

* update: add additional check to prevent fatal error

* fix: formatting

* [APP-1312] minimize client css (#252)

* [APP-1168] widget icon radius

* add: icon radius component

* add: icon radius component

* update: add support for widget radius

* fix: minor ui fixes

* fix: resolve comments

* fix: alignment of the icon

* update: add styled components

* add: corner radius mixpanel event

* fix: corner radius should have default values when no value is set based on icon

* fix: icon radius input style

* add: accessibility attributes

* fix: active states color

* add: logic to control invalid inputs

* update: make aria attributes translatable

* update: styled component names

* add: spacing between the components

* [APP-1342] add super props, store plan scope after register/switch (#250)

* [APP-0000] store plan scope after register/switch

* Update modules/settings/module.php

Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>

* remove deprecated method

* remove deprecated method

* [1342] Add super prop to mixpanel

* [1342] Add super prop to mixpanel

* [1342] Add super prop to mixpanel

---------

Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>

* [Legacy] Added strict settings sanitization (#257)

* [Legacy] Added strict settings sanitization

* use correct esc_x method

* hardcoded 6.8.0

* added svn for wp test library

* fix: default border radius (#258)

* fix: default border radius

* add: default corner radius for new users

* update: add support for default values for users with saved style settings

* updated phpunit workflow

* revert to master

* hardcode 6.8.x

* update: default values for existing users

* update: remove saving default corner radius for new users

* fix: update default radius for text icon

* fix: PHPUnit tests for WP 6.8.0

* align with develop

* set to latest

---------

Co-authored-by: Raz Ohad <admin@bainternet.info>
Co-authored-by: Raz Ohad <ohad@elementor.com>

* fix: widget icon spacing (#262)

* Added custom gutenberg link to toggle widget [APP-1306] (#256)

* New: Added Ally Trigger Dynamic Tag for Elementor [APP-1305] (#254)

* New: Added Ally Trigger Dynamic Tag for Elementor [APP-1305]

* typo Update modules/widget/components/ally-trigger.php

* New: Add the what's new functionality [APP-1329] (#264)

* add: statement page selector field (#261)

* add: statement page selector field

* add: updated the statement link button to a search field

* fix: add support for create statement data

* New: Bump the Notifications SDK to 1.2.0 [APP-1427] (#267)

* Fix: Resolve a11y issues [APP-1331] (#269)

* [APP-1417] Add support for custom icon (#270)

* add: media upload button

* add: support for custom icon

* fix: code alignment, phpcs

* fix: code alignment and linting

* add: mixpanel events

* fix: styling of custom svg

* fix: missing variable

* fix: missing variable

* fix: load gutenberg block without css

* fix: icon spacing in preview

* fix: indentation

* fix: indents

* [APP-1440] Fix doing_it_wrong warning for translations (#271)

* fix: doing_it_wrong warning for translations

* update: stop explicitly loading translations

* fix: add package-lock

* fix: add package-lock

* Bumped V3.3.0

* Update manager.php

---------

Co-authored-by: Yakir Sitbon <kingyes1@gmail.com>
Co-authored-by: Nirbhay Singh <121793120+nirbhayel@users.noreply.github.com>
Co-authored-by: VasylD <vasyld@elementor.red>
Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>
2025-05-14 13:37:34 +03:00

798 lines
17 KiB
PHP

<?php
namespace EA11y\Modules\Core\Classes;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* EA11Y SVG Sanitizer.
*
* A class that is responsible for sanitizing SVG files.
*
* @since 3.3.0
*/
class Svg_Sanitizer {
/**
* @var \DOMDocument
*/
private $svg_dom = null;
/**
* Sanitize File
*
* @access public
*
* @param $filename
* @return bool
*/
public function sanitize_file( $filename ) {
$original_content = $this->file_get_contents( $filename );
$is_encoded = $this->is_encoded( $original_content );
if ( $is_encoded ) {
$decoded = $this->decode_svg( $original_content );
if ( false === $decoded ) {
return false;
}
$original_content = $decoded;
}
$valid_svg = $this->sanitize( $original_content );
if ( false === $valid_svg ) {
return false;
}
// If we were gzipped, we need to re-zip
if ( $is_encoded ) {
$valid_svg = $this->encode_svg( $valid_svg );
}
file_put_contents( $filename, $valid_svg );
return true;
}
/**
* Sanitize
*
* @access public
*
* @param $content
* @return bool|string
*/
public function sanitize( $content ) {
// Strip php tags
$content = $this->strip_comments( $content );
$content = $this->strip_php_tags( $content );
$content = $this->strip_line_breaks( $content );
// Find the start and end tags so we can cut out miscellaneous garbage.
$start = strpos( $content, '<svg' );
$end = strrpos( $content, '</svg>' );
if ( false === $start || false === $end ) {
return false;
}
$content = substr( $content, $start, ( $end - $start + 6 ) );
// If the server's PHP version is 8 or up, make sure to Disable the ability to load external entities
$php_version_under_eight = version_compare( PHP_VERSION, '8.0.0', '<' );
if ( $php_version_under_eight ) {
$libxml_disable_entity_loader = libxml_disable_entity_loader( true ); // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
}
// Suppress the errors
$libxml_use_internal_errors = libxml_use_internal_errors( true );
// Create DomDocument instance
$this->svg_dom = new \DOMDocument();
$this->svg_dom->formatOutput = false;
$this->svg_dom->preserveWhiteSpace = false;
$this->svg_dom->strictErrorChecking = false;
$open_svg = $this->svg_dom->loadXML( $content );
if ( ! $open_svg ) {
return false;
}
$this->strip_doctype();
$this->sanitize_elements();
// Export sanitized svg to string
// Using documentElement to strip out <?xml version="1.0" encoding="UTF-8"...
$sanitized = $this->svg_dom->saveXML( $this->svg_dom->documentElement, LIBXML_NOEMPTYTAG );
// Restore defaults
if ( $php_version_under_eight ) {
libxml_disable_entity_loader( $libxml_disable_entity_loader ); // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
}
libxml_use_internal_errors( $libxml_use_internal_errors );
return $sanitized;
}
/**
* Is Encoded
*
* Check if the contents of the SVG file are gzipped
*
* @see http://www.gzip.org/zlib/rfc-gzip.html#member-format
*
* @access private
*
* @param $contents
*
* @return bool
*/
private function is_encoded( $contents ) {
$needle = "\x1f\x8b\x08";
if ( function_exists( 'mb_strpos' ) ) {
return 0 === mb_strpos( $contents, $needle );
} else {
return 0 === strpos( $contents, $needle );
}
}
/**
* Encode SVG
*
* @access private
*
* @param $content
* @return string
*/
private function encode_svg( $content ) {
return gzencode( $content );
}
/**
* Decode SVG
*
* @access private
*
* @param $content
*
* @return string
*/
private function decode_svg( $content ) {
return gzdecode( $content );
}
/**
* Is Allowed Tag
*
* @access private
*
* @param $element
* @return bool
*/
private function is_allowed_tag( $element ) {
static $allowed_tags = false;
if ( false === $allowed_tags ) {
$allowed_tags = $this->get_allowed_elements();
}
$tag_name = $element->tagName; // phpcs:ignore -- php DomDocument
if ( ! in_array( strtolower( $tag_name ), $allowed_tags ) ) {
$this->remove_element( $element );
return false;
}
return true;
}
/**
* Remove Element
*
* Removes the passed element from its DomDocument tree
*
* @access private
*
* @param $element
*/
private function remove_element( $element ) {
$element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomDocument
}
/**
* Is It An Attribute
*
* @access private
*
* @param $name
* @param $check
* @return bool
*/
private function is_a_attribute( $name, $check ) {
return 0 === strpos( $name, $check . '-' );
}
/**
* Is Remote Value
*
* @access private
*
* @param $value
* @return string
*/
private function is_remote_value( $value ) {
$value = trim( preg_replace( '/[^ -~]/xu', '', $value ) );
$wrapped_in_url = preg_match( '~^url\(\s*[\'"]\s*(.*)\s*[\'"]\s*\)$~xi', $value, $match );
if ( ! $wrapped_in_url ) {
return false;
}
$value = trim( $match[1], '\'"' );
return preg_match( '~^((https?|ftp|file):)?//~xi', $value );
}
/**
* Has JS Value
*
* @access private
*
* @param $value
* @return false|int
*/
private function has_js_value( $value ) {
return preg_match( '/base64|data|(?:java)?script|alert\(|window\.|document/i', $value );
}
/**
* Get Allowed Attributes
*
* Returns an array of allowed tag attributes in SVG files.
*
* @access private
*
* @return array
*/
private function get_allowed_attributes() {
$allowed_attributes = [
'accent-height',
'accumulate',
'additivive',
'alignment-baseline',
'aria-hidden',
'aria-controls',
'aria-describedby',
'aria-description',
'aria-expanded',
'aria-haspopup',
'aria-label',
'aria-labelledby',
'aria-roledescription',
'ascent',
'attributename',
'attributetype',
'azimuth',
'basefrequency',
'baseline-shift',
'begin',
'bias',
'by',
'class',
'clip',
'clip-path',
'clip-rule',
'clippathunits',
'color',
'color-interpolation',
'color-interpolation-filters',
'color-profile',
'color-rendering',
'cx',
'cy',
'd',
'dx',
'dy',
'diffuseconstant',
'direction',
'display',
'divisor',
'dominant-baseline',
'dur',
'edgemode',
'elevation',
'end',
'fill',
'fill-opacity',
'fill-rule',
'filter',
'filterres',
'filterunits',
'flood-color',
'flood-opacity',
'font-family',
'font-size',
'font-size-adjust',
'font-stretch',
'font-style',
'font-variant',
'font-weight',
'fx',
'fy',
'g1',
'g2',
'glyph-name',
'glyphref',
'gradienttransform',
'gradientunits',
'height',
'href',
'id',
'image-rendering',
'in',
'in2',
'k',
'k1',
'k2',
'k3',
'k4',
'kerning',
'keypoints',
'keysplines',
'keytimes',
'lang',
'lengthadjust',
'letter-spacing',
'kernelmatrix',
'kernelunitlength',
'lighting-color',
'local',
'marker-end',
'marker-mid',
'marker-start',
'markerheight',
'markerunits',
'markerwidth',
'mask',
'maskcontentunits',
'maskunits',
'max',
'media',
'method',
'mode',
'min',
'name',
'numoctaves',
'offset',
'opacity',
'operator',
'order',
'orient',
'orientation',
'origin',
'overflow',
'paint-order',
'path',
'pathlength',
'patterncontentunits',
'patterntransform',
'patternunits',
'points',
'preservealpha',
'preserveaspectratio',
'primitiveunits',
'r',
'rx',
'ry',
'radius',
'refx',
'refy',
'repeatcount',
'repeatdur',
'requiredfeatures',
'restart',
'result',
'role',
'rotate',
'scale',
'seed',
'shape-rendering',
'spacing',
'specularconstant',
'specularexponent',
'spreadmethod',
'startoffset',
'stddeviation',
'stitchtiles',
'stop-color',
'stop-opacity',
'stroke',
'stroke-dasharray',
'stroke-dashoffset',
'stroke-linecap',
'stroke-linejoin',
'stroke-miterlimit',
'stroke-opacity',
'stroke-width',
'style',
'surfacescale',
'systemlanguage',
'tabindex',
'targetx',
'targety',
'transform',
'transform-origin',
'text-anchor',
'text-decoration',
'text-rendering',
'textlength',
'type',
'u1',
'u2',
'underline-position',
'underline-thickness',
'unicode',
'unicode-bidi',
'values',
'vector-effect',
'vert-adv-y',
'vert-origin-x',
'vert-origin-y',
'viewbox',
'visibility',
'width',
'word-spacing',
'wrap',
'writing-mode',
'x',
'x1',
'x2',
'xchannelselector',
'xlink:href',
'xlink:title',
'xmlns',
'xmlns:se',
'xmlns:xlink',
'xml:lang',
'xml:space',
'y',
'y1',
'y2',
'ychannelselector',
'z',
'zoomandpan',
];
/**
* Allowed attributes in SVG file.
*
* Filters the list of allowed attributes in SVG files.
*
* Since SVG files can run JS code that may inject malicious code, all attributes
* are removed except the allowed attributes.
*
* This hook can be used to manage allowed SVG attributes. To either add new
* attributes or delete existing attributes. To strengthen or weaken site security.
*
* @param array $allowed_attributes A list of allowed attributes.
*/
$allowed_attributes = apply_filters( 'elementor/files/svg/allowed_attributes', $allowed_attributes );
return $allowed_attributes;
}
/**
* Get Allowed Elements
*
* Returns an array of allowed element tags to be in SVG files.
*
* @access private
*
* @return array
*/
private function get_allowed_elements() {
$allowed_elements = [
'a',
'animate',
'animateMotion',
'animateTransform',
'circle',
'clippath',
'defs',
'desc',
'ellipse',
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'feDistantLight',
'feDropShadow',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feImage',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulence',
'filter',
'foreignobject',
'g',
'image',
'line',
'lineargradient',
'marker',
'mask',
'metadata',
'mpath',
'path',
'pattern',
'polygon',
'polyline',
'radialgradient',
'rect',
'set',
'stop',
'style',
'svg',
'switch',
'symbol',
'text',
'textpath',
'title',
'tspan',
'use',
'view',
];
/**
* Allowed elements in SVG file.
*
* Filters the list of allowed elements in SVG files.
*
* Since SVG files can run JS code that may inject malicious code, all elements
* are removed except the allowed elements.
*
* This hook can be used to manage SVG elements. To either add new elements or
* delete existing elements. To strengthen or weaken site security.
*
* @param array $allowed_elements A list of allowed elements.
*/
$allowed_elements = apply_filters( 'elementor/files/svg/allowed_elements', $allowed_elements );
return $allowed_elements;
}
/**
* Validate Allowed Attributes
*
* @access private
*
* @param \DOMElement $element
*/
private function validate_allowed_attributes( $element ) {
static $allowed_attributes = false;
if ( false === $allowed_attributes ) {
$allowed_attributes = $this->get_allowed_attributes();
}
for ( $index = $element->attributes->length - 1; $index >= 0; $index-- ) {
// get attribute name
$attr_name = $element->attributes->item( $index )->name;
$attr_name_lowercase = strtolower( $attr_name );
// Remove attribute if not in whitelist
if ( ! in_array( $attr_name_lowercase, $allowed_attributes ) && ! $this->is_a_attribute( $attr_name_lowercase, 'aria' ) && ! $this->is_a_attribute( $attr_name_lowercase, 'data' ) ) {
$element->removeAttribute( $attr_name );
continue;
}
$attr_value = $element->attributes->item( $index )->value;
// Remove attribute if it has a remote reference or js or data-URI/base64
if ( ! empty( $attr_value ) && ( $this->is_remote_value( $attr_value ) || $this->has_js_value( $attr_value ) ) ) {
$element->removeAttribute( $attr_name );
continue;
}
}
}
/**
* Strip xlinks
*
* @access private
*
* @param \DOMElement $element
*/
private function strip_xlinks( $element ) {
$xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
if ( ! $xlinks ) {
return;
}
if ( ! $this->is_safe_href( $xlinks ) ) {
$element->removeAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
}
}
/**
* @see https://github.com/darylldoyle/svg-sanitizer/blob/2321a914e/src/Sanitizer.php#L454
*/
private function is_safe_href( $value ) {
// Allow empty values.
if ( empty( $value ) ) {
return true;
}
// Allow fragment identifiers.
if ( '#' === substr( $value, 0, 1 ) ) {
return true;
}
// Allow relative URIs.
if ( '/' === substr( $value, 0, 1 ) ) {
return true;
}
// Allow HTTPS domains.
if ( 'https://' === substr( $value, 0, 8 ) ) {
return true;
}
// Allow HTTP domains.
if ( 'http://' === substr( $value, 0, 7 ) ) {
return true;
}
// Allow known data URIs.
if ( in_array( substr( $value, 0, 14 ), [
'data:image/png', // PNG
'data:image/gif', // GIF
'data:image/jpg', // JPG
'data:image/jpe', // JPEG
'data:image/pjp', // PJPEG
], true ) ) {
return true;
}
// Allow known short data URIs.
if ( in_array( substr( $value, 0, 12 ), [
'data:img/png', // PNG
'data:img/gif', // GIF
'data:img/jpg', // JPG
'data:img/jpe', // JPEG
'data:img/pjp', // PJPEG
], true ) ) {
return true;
}
return false;
}
/**
* Validate Use Tag
*
* @access private
*
* @param $element
*/
private function validate_use_tag( $element ) {
$xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
if ( $xlinks && '#' !== substr( $xlinks, 0, 1 ) ) {
$element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomNode
}
}
/**
* Strip Doctype
*
* @access private
*/
private function strip_doctype() {
foreach ( $this->svg_dom->childNodes as $child ) {
if ( XML_DOCUMENT_TYPE_NODE === $child->nodeType ) { // phpcs:ignore -- php DomDocument
$child->parentNode->removeChild( $child ); // phpcs:ignore -- php DomDocument
}
}
}
/**
* Sanitize Elements
*
* @access private
*/
private function sanitize_elements() {
$elements = $this->svg_dom->getElementsByTagName( '*' );
// loop through all elements
// we do this backwards so we don't skip anything if we delete a node
// see comments at: http://php.net/manual/en/class.domnamednodemap.php
for ( $index = $elements->length - 1; $index >= 0; $index-- ) {
/**
* @var \DOMElement $current_element
*/
$current_element = $elements->item( $index );
// If the tag isn't in the whitelist, remove it and continue with next iteration
if ( ! $this->is_allowed_tag( $current_element ) ) {
continue;
}
// validate element attributes
$this->validate_allowed_attributes( $current_element );
$this->strip_xlinks( $current_element );
if ( 'use' === strtolower( $current_element->tagName ) ) { // phpcs:ignore -- php DomDocument
$this->validate_use_tag( $current_element );
}
}
}
/**
* Strip PHP Tags
*
* @access private
*
* @param $string
* @return string
*/
private function strip_php_tags( $string ) {
$string = preg_replace( '/<\?(=|php)(.+?)\?>/i', '', $string );
// Remove XML, ASP, etc.
$string = preg_replace( '/<\?(.*)\?>/Us', '', $string );
$string = preg_replace( '/<\%(.*)\%>/Us', '', $string );
if ( ( false !== strpos( $string, '<?' ) ) || ( false !== strpos( $string, '<%' ) ) ) {
return '';
}
return $string;
}
/**
* Strip Comments
*
* @access private
*
* @param $string
* @return string
*/
private function strip_comments( $string ) {
// Remove comments.
$string = preg_replace( '/<!--(.*)-->/Us', '', $string );
$string = preg_replace( '/\/\*(.*)\*\//Us', '', $string );
if ( ( false !== strpos( $string, '<!--' ) ) || ( false !== strpos( $string, '/*' ) ) ) {
return '';
}
return $string;
}
/**
* Strip Line Breaks
*
* @access private
*
* @param $string
* @return string
*/
private function strip_line_breaks( $string ) {
// Remove line breaks.
return preg_replace( '/\r|\n/', '', $string );
}
/**
* @param string $file
* @param mixed ...$args
* @return false|string
*/
public function file_get_contents( $file, ...$args ) {
if ( ! is_file( $file ) || ! is_readable( $file ) ) {
return false;
}
return file_get_contents( $file, ...$args );
}
}