one-click-accessibility/classes/database/entry.php
VasylD beb8deda2e
[APP-907] Accessibility assistant (#326)
* PHPCS and remediation POC WIP

* WIP Wizard module

* Added scanner module

* [APP-929][APP-930] Add initial setup for wizard, added btn to the topbar (#230)

* [APP-929][APP-930]

* [APP-929][APP-930]

* update logic

* update init app

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

* change return of load

* add header

* Move into shadow dom, add context, add headers components

* add UI components

* add UI components

* add UI components

* merge current develop

* merge current develop

* Add AltText Form

* Add scroll to current element

* Align with current design, add loader, added preview for svg

* Align with current design, add loader, added preview for svg

* Resolve comments

* Resolve comments

* Resolve comments

* [APP-934] add submit logic (#259)

* [APP-934] add submit logic

* [APP-934] add submit logic

* [APP-934] add submit logic

* [APP-934] add submit logic

* Added replace remediation action

* Add submit logic

* Add submit alt text logic, generate AI alt text

* Add AI generate request, add convert from SVG to png base64, added manual fix block

* Add AI generate request, add convert from SVG to png base64, added manual fix block

* Add texts, add remediation submit, fix logic to store remediation

* Add texts, add remediation submit, fix logic to store remediation

* Add texts, add remediation submit, fix logic to store remediation

* Add texts, add remediation submit, fix logic to store remediation

* Add texts, add remediation submit, fix logic to store remediation

* Add texts, add remediation submit, fix logic to store remediation

---------

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

* Add texts, add remediation submit, fix logic to store remediation

* [APP-0000] add store request to the Service API (#268)

* [APP-0000] add store request to the Service API

* [APP-0000] add store request to the Service API

* [APP-0000] add store request to the Service API

* [APP-0000] add store request to the Service API

* [APP-0000] add request to store scanner summary

* [APP-0000] add request to store scanner summary

* [APP-0000] add request to store scanner summary

* [APP-1432] fix with AI flow (#275)

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1432] fix with AI flow

* [APP-1446] sidebar menu update (#276)

* update: simplify menu

* add: headings and scanner menu options

* [APP-945] add column for tables (#282)

* [APP-945] add column for tables

* [APP-945] add column for tables

* [APP-945] add column for tables

* [APP-945] add column for tables

* [APP-1447] Updated quota bar designs (#278)

* update: quota bar designs

* fix: the popover was partially visible

* update: AI credits name

* update: usage calculation logic

* add: quota indicators

* update: quotas tooltip text

* update: quotas notices text

* update: make toggle icon dynamic

* fix: @elementor/ui imports

* Update modules/settings/assets/js/layouts/quota-bar.js

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

* update: styling of component

---------

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

* [APP-1507] add UI changes (#286)

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1507] add UI changes

* [APP-1387] add mixpanel events (#288)

* [APP-1387] add mixpanel events

* [APP-1387] add mixpanel events

* New: Add the a11y assistant dashboard's UI [APP-1445] (#289)

* [APP-1513] add disconnected msg (#290)

* [APP-1513] add disconnected msg

* [APP-1513] add disconnected msg

* [APP-1513] add disconnected msg

* [APP-1547][APP-1548][APP-948] update alt text view, fix list issues (#291)

* [APP-1547][APP-1548][APP-948] update alt text view, fix list issues, add rest route for update status

* [APP-1547][APP-1548][APP-948] update alt text view, fix list issues, add rest route for update status

* fix: infotip icon padding and font style (#293)

* fix: infotip icon padding and font style

* fix: infotip icon padding and font style

* update: caniuse database

* [APP-1525] add edit mode (#294)

* [APP-1525] add edit mode

* [APP-1525] add edit mode

* [APP-1525] add edit mode

* Bug/app 1544 (#295)

* Fix: Resolve QA comments [APP-1544]

* New: Add beta tags [APP-1555]

* New: Add the "no results" state [APP-1544]

* [APP-1554] rename violations (#297)

* [APP-1512] add backend logic for remediation management (#298)

* [APP-1512] add backend logic for remediation management

* [APP-1512] add backend logic for remediation management

* Update modules/remediation/database/remediation-entry.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* Update modules/remediation/rest/items.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* [APP-1512] add backend logic for remediation management

---------

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* Fix: Resolve QA comments [n/a] (#299)

* [APP-1512] add FE remediation management (#300)

* [APP-1512] add backend logic for remediation management

* [APP-1512] add backend logic for remediation management

* Update modules/remediation/database/remediation-entry.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* Update modules/remediation/rest/items.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* [APP-1512] add backend logic for remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

* [APP-1512] add FE remediation management

---------

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* [APP-1609] fix tooltip

* [APP-1609] fix resolved btn click

* [APP-1401] clear cache on update (#302)

* [APP-1401] clear cache on update

* [APP-1401] clear cache on update

* [APP-1401] clear cache on update

* [APP-1401] clear cache on update

* [APP-1401] clear cache on update

* update with latest develop branch

* fix copies

* [APP-1619] add mixpanel event (#303)

* [APP-1619] add mixpanel event

* [APP-1619] add mixpanel event

* [APP-1593] Add locked variant for quota bar (#301)

* update: add locked version of quota status bar

* fix: text color for infotip

* fix: width issues

* fix: add check for 0

* [APP-1637][APP-1643] add UI fixes, add excluded rules array (#307)

* fix: make sidebar collapsible (#306)

* Merge current dev

* [APP-1603] Add dashboard menu (#309)

* [APP-1603] Add dashboard menu

* [APP-1603] Add dashboard menu

* [APP-1603] Add dashboard menu

* [APP-1603] Add dashboard menu

* Bug/app 1607 (#311)

* Fix: Update stats calculation logic [APP-1607]

* Fix: Set fixed width for the results table [APP-1650]

* Fix: Update filter rules [APP-1634]

* New: Add the no search results state [APP-1651]

* Fix: Convert indents [n/a]

* [APP-1670] add menu on Manage Fixes (#315)

* [APP-1670] add menu on Manage Fixes

* [APP-1670] update menu

* [APP-1611] fix comments

* fix: direction of snippet (#313)

* [APP-1561] New menu layout (#308)

* update: app menu and layout

* merge: latest changes from feature/remediation

* add: alert indicator to the closed sidebar

* fix: page layout for statement page

* update: menu display names

* fix: topbar menu layout

* update: sidebar menu width

* update: sidebar menu width

* fix: popup menu layout

* add: hover action to the toggle button

* update: my account menu

* fix: quota indicator for closed sidebar

* fix: icon alignments

* fix: scroll behaviour

* fix: page scroll behaviour

* fix: popup menu hover state

* update: quota bar and group layouts

* add: tooltips to the menu items

* update: make scans page fixed height and scrollable

* update: styles with theme references and added new styled components

* fix: make sidebar smoother

* update: accessibility page heading

* Merge latest develop

* [APP-1611] trigger save entry for clean cache (#314)

* [APP-1611] trigger save entry for clean cache

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-0000] call trigger save async (#319)

* [APP-1611] trigger save entry for clean cache

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-0000] call trigger save async

* fix: scrollbar issues (#318)

* [APP-1615] add remediation for wp image (#321)

* POC - FrontEnd remediations to handle Dynamic Data [APP-1644] (#312)

* POC - FrontEnd remediations to handle Dynamic Data

* Update modules/remediation/components/remediation-runner.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* added MutationObserver to cover elements that are added later on the page

runs until remediations are all done, and disconnect

* added $use_frontend flag instead of using "false"

* Update modules/remediation/components/remediation-runner.php

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* WIP on poc/fe-remediations

* [APP-0000] call trigger save async

* [APP-1644] apply FE remediation

* [APP-1644] apply FE remediation

* [APP-1644] apply FE remediation

* Add timeout (wait for FE remediation timeout)

* Add timeout (wait for FE remediation timeout)

* Add timeout (wait for FE remediation timeout)

* Add timeout (wait for FE remediation timeout)

* Add timeout (wait for FE remediation timeout)

* Small fixes

* Small fixes

* Small fixes

* Small fixes

---------

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>
Co-authored-by: vasyldinets <vasyld@elementor.red>

* [APP-1611] Fix cache issue (#324)

* [APP-1611] trigger save entry for clean cache

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-1611] fix comments

* [APP-0000] call trigger save async

* [APP-1611] clear cache

* [APP-1657] upgrade cta (#323)

* update: added logic to show button based on plan

* Update modules/settings/assets/js/components/quota-bar/quota-bar-group.js

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* fix: eslint error

---------

Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>

* [APP-1658] Update accessibility admin column design (#322)

* update: wpadmin column layout

* update: move icon to assets

* Fix: Resolve remediation encoding issue [APP-1646] (#325)

---------

Co-authored-by: Ohad <ohad@elementor.com>
Co-authored-by: Raz Ohad <admin@bainternet.info>
Co-authored-by: Nirbhay Singh <121793120+nirbhayel@users.noreply.github.com>
Co-authored-by: Pavlo Kniazevych <139438463+pkniazevych@users.noreply.github.com>
Co-authored-by: gitstream-cm[bot] <111687743+gitstream-cm[bot]@users.noreply.github.com>
2025-07-07 16:25:11 +07:00

402 lines
12 KiB
PHP

<?php
namespace EA11y\Classes\Database;
use EA11y\Classes\Database\Exceptions\Missing_Table_Exception;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Class DB_Entry_Base
* This class represents a single row (or part of a record) from a database table
* @property int|mixed|null id
*/
class Entry {
/**
* @var Table $db_table
*/
public $db_table = null;
protected $entry_data = [];
/**
* This class should return the name of the /Table/ derivative class representing the database table holding this
* entry
* @return string - name of the class
*/
protected static function get_helper_class(): string {
return '';
}
/**
* init_by
*
* Return the entry representing the first row in the table that satisfies the conditions set by the parameters
* and its associated data.
*
* @param string $by The name of the field to compare the value parameter to in case the
* /value/ parameter is a string, otherwise, ignored.
* @param string|array $value If a string, the value to compare against the column specified
* by the /by/ parameter.
* If an array, can be either a list of column => value entries for direct comparison
* joined with the AND logical operator, or in the format of column => [column =>
* string, value =>string|int|array<string|array>, comparison operator => string,
* relation_before=>string, optional, relation_after=>string, optional].
*
* @return Entry Returns the entry with the data found.
*/
private function init_by( string $by, $value ) : Entry {
$data = static::get_by( $by, $value );
return $this->init_by_data( $data );
}
/**
* get_by
*
* Returns the first row in the table that satisfies the conditions set by the parameters.
*
* @param string $by The name of the field to compare the value parameter to in case the
* /value/ parameter is a string.
* Optional.
* Defaults to an empty string.
* @param array|string $value If a string, the value to compare against the column specified
* by the /by/ parameter.
* If an array, can be either a list of column => value entries for direct comparison
* joined with the AND logical operator, or in the format of column => [column =>
* string, value =>string|int|array<string|array>, comparison operator => string,
* relation_before=>string, optional, relation_after=>string, optional]. Optional.
* Defaults to an empty string.
*
* @return mixed|\stdClass|null An object representing the row or NULL in case of an error.
*/
protected function get_by( string $by = '', $value = '' ) {
$fields = '*';
$where = is_array( $value ) ? $value : [ $by => $value ];
return $this->db_table::first( $fields, $where );
}
/**
* init_by_data
*
* Returns an Entry object with its data set to the data passed by the /data/ parameter.
*
* @param array|object $data The data to set the entry with.
*
* @return $this Returns an entry loaded with the data passes in the parameter, or en Empty entry (representing
* null) on error
*/
protected function init_by_data( $data ) : Entry {
if ( ! $data || is_wp_error( $data ) ) {
return $this->return_empty();
}
return $this->set_data( $data );
}
/**
* return_empty
*
* Returns an empty entry project, representing an empty set/null.
*
* NOTE: An empty entry cannot be saved in the database unless you either unset the
* /id/ field or set it for a valid value for an update.
*
* @return Entry Returns the object back
*/
private function return_empty() : Entry {
$this->set_data( [] );
return $this->set( 'id', 0 );
}
/**
* set_data
*
* Sets the data of this entry object
*
* @param array|object $data The data to set in the current object in the format of key => value
*
* @return $this Returns the object back
*/
public function set_data( $data ) : Entry {
$this->entry_data = (array) $data;
return $this;
}
/**
* init_by_id
*
* Loads the Entry with data from the database fetched by the /id/ column compared to the value passed with the
* /id/ parameter.
*
* @param string $id The value of the /id/ field
*
* @return $this The Entry loaded with the data gotten from the database by the specified ID.
*/
protected function init_by_id( $id ) : Entry {
$data = static::get_by( 'id', $id );
return $this->init_by_data( $data );
}
/**
* __get
* magic get properties
*
* Returns an Entry's data field by key name
*
* @param string $name The name of the field to return
*
* @return mixed|null The value of the field or null if it doesn't exist'
*/
public function __get( $name ) {
return $this->entry_data[ $name ] ?? null;
}
/**
* __set
* magic set properties
*
* Sets an Entry's data field value by the specified key
*
* @param string $name The key of the field being set
* @param mixed $value The new value for the field
*
* @return $this Returns the current object back
*/
public function __set( string $name, $value ) {
return $this->set( $name, $value );
}
/**
* set
*
* Sets and entry data field value by the specified key
*
* @param string $name The key of the field being set
* @param mixed $value The new value for the field
*
* @return $this Returns the current object back
*/
public function set( string $name, $value ) : Entry {
$this->entry_data[ $name ] = $value;
return $this;
}
/**
* class_short_name
*
* Returns just the name of the class, without its namespace. Used for hooks.
* Taken from https://coderwall.com/p/cpxxxw/php-get-class-name-without-namespace
*
* NOTE: Called on a class without a namespace will return the name of the class
* without the first letter in the name
* @return string The name of the current class
*/
private function class_short_name(): string {
$class_name = get_called_class();
return ( substr( $class_name, strrpos( $class_name, '\\' ) + 1 ) );
}
/**
* trigger_change
*
* Raises action hooks following the create, delete and update operations.
* Raises the hook [ea11y/db/class_name>/change]. If the /event/
* parameter is not null, then it also raises the hook [ea11y/db/class_name/event].
*
* The parameters sent to both hooks is a reference to the current object and the value of the /data/ parameter.
*
* @param int|bool $data Numbers of rows changed or FALSE on database action failure
* @param string|null $event The name of the custom event hook to raise in addition to the /changed/ event hook
* Optional.
* Defaults to null. In this case, will raise only the defaults /changed/ event.
*/
private function trigger_change( $data, string $event = null ) : void {
if ( $event ) {
/**
* event specific
* @var Entry $this
* @var false|int $data
*/
do_action( 'ea11y/db/' . $this->class_short_name() . '/' . $event, $this, $data );
}
/**
* entity change
* @var Entry $this
* @var false|int $data
*/
do_action( 'ea11y/db/' . $this->class_short_name() . '/change', $this, $data );
}
/**
* save
*
* Writes the entry to the database.
* If the entry has a field called /id/ set, will
* perform an update, if it doesn't, will perform an insert.
* Update and create function triggers the change action hooks and the respective custom event
* @return false|int The number of rows inserted or FALSE on error.
*/
public function save() {
if ( isset( $this->entry_data['id'] ) ) {
return $this->update( [ 'id' => $this->entry_data['id'] ] );
}
return $this->create();
}
/**
* delete
*
* Delete entries from the table.
* Bases on the field specified by the /by/ parameter and its current value.
* Triggers change action hooks and raises the /delete/ custom event.
*
* @param string $by The field name to delete by.
* Optional.
* Defaults to 'id'.
*
* @return false|int The number of rows deleted or false on error.
*/
public function delete( string $by = 'id' ) {
$results = $this->db_table::delete( [ $by => $this->{$by} ] );
$this->trigger_change( $results, 'delete' );
return $results;
}
/**
* update
*
* Updates the database with the data of this entry based on the conditions passed
* by the /where/ parameter.
* Triggers change action hooks and raises the /update/ custom event.
*
* NOTE: If no conditions are supplied, the update is going to be performed on all rows,
*
* @param array $where Array of column => (raw) values as a group of AND WHERE conditionals for the UPDATE
* statement. Optional. Defaults to an empty array.
*
* @return false|int The number of rows updated or false on error.
*/
public function update( array $where = [] ) {
$results = $this->db_table::update( $this->entry_data, $where );
$this->trigger_change( $results, 'update' );
return $results;
}
/**
* create
*
* Inserts the entry to the database table.
* Trigger change action hooks and raises the /create/ custom event,
*
* @param string $id On successful insertion, will set the field passes in the /id/ parameter
* ot the value of the last inserted ID as returned from the database.
* Optional.
* Defaults to 'id'
*
* @return false|int The numbers of rows affected or FALSE on error
*/
public function create( string $id = 'id' ) {
$results = $this->db_table::insert( $this->entry_data );
if ( $results ) {
// Set row id once created
$this->set( $id, $this->db_table::db()->insert_id );
}
$this->trigger_change( $results, 'create' );
return $results;
}
/**
* reset
*
* Clears all of this entry's data.
*/
public function reset(): void {
$this->entry_data = [];
}
/**
* @return bool
*/
public function exists(): bool {
return isset( $this->entry_data['id'] ) && 0 < $this->entry_data['id'];
}
/**
* to_json
* @return string
*/
public function to_json() : string {
return json_encode( $this->entry_data );
}
public function get_data() {
return $this->entry_data;
}
public function to_array() {
return $this->get_data();
}
/**
* DB_Entry_Base constructor.
* Uses the passed on arguments to initialize/set the Entry.
* Will through an exception in case the Entry's table property is not set correctly, and the /Table/ class
* linking this entry to a database table is not found.
*
* @param array $args The arguments to set this Entry by.
* If arguments /by/ and /value/ are set,
* will fetch the data according to the column name specified by /by/ and the value(s) specified
* by /value/. See doc for /init_by/ for details.
*
* if argument /data/ is set, will set the Entry's data with the data specified.
* See doc for /init_by_data/ for details.
*
* if argument /id/ is specified, will load the data of the row whose /id/ column has the value specified by the
* argument.
*
* Optional.
* Defaults to an empty array which will make this entry as the Empty Entry representing null,
* which cannot be saved unless properly modified to a non-null entry.
*
* @throws Missing_Table_Exception If the Entry table property is not found.
*/
public function __construct( array $args = [] ) {
$this->db_table = static::get_helper_class();
if ( empty( $this->db_table ) ) {
throw new Missing_Table_Exception();
}
if ( isset( $args['by'] ) && isset( $args['value'] ) ) {
return $this->init_by( $args['by'], $args['value'] );
}
if ( isset( $args['data'] ) ) {
return $this->init_by_data( $args['data'] );
}
if ( isset( $args['id'] ) ) {
return $this->init_by_id( $args['id'] );
}
return $this->return_empty();
}
}