From 156e5d2556c5025001fc7d0b47466b68ee673efe Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:11:31 -0500 Subject: [PATCH 01/70] Better way to null class. --- authentication/authenticate.php | 63 +++++++++++++++++++++++++++++++++ authentication/index.html | 36 +++++++++++++++++++ authentication/logout.php | 10 ++++++ authentication/signin.css | 39 ++++++++++++++++++++ models/view_components.php | 3 ++ 5 files changed, 151 insertions(+) create mode 100644 authentication/authenticate.php create mode 100644 authentication/index.html create mode 100644 authentication/logout.php create mode 100644 authentication/signin.css diff --git a/authentication/authenticate.php b/authentication/authenticate.php new file mode 100644 index 00000000..bc3b298f --- /dev/null +++ b/authentication/authenticate.php @@ -0,0 +1,63 @@ +prepare('SELECT id, password FROM accounts WHERE username = ?')) { + + // Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s" + $stmt->bind_param('s', $_POST['username']); + $stmt->execute(); + + // Store the result so we can check if the account exists in the database. + $stmt->store_result(); + if ($stmt->num_rows > 0) { + $stmt->bind_result($id, $password); + $stmt->fetch(); + + // Account exists, now we verify the password. + // Note: remember to use password_hash in your registration file to store the hashed passwords. + if (password_verify($_POST['password'], $password)) { + + // Verification success! User has logged-in! + // Create sessions, so we know the user is logged in, they basically act like cookies but remember the data on the server. + session_regenerate_id(); + $_SESSION['loggedin'] = TRUE; + $_SESSION['name'] = $_POST['username']; + $_SESSION['id'] = $id; + header('Location: ../index.php'); + + } else { + // Incorrect password + echo 'Incorrect username and/or password!'; + } + } else { + // Incorrect username + echo 'Incorrect username and/or password!'; + } + + $stmt->close(); +} +?> diff --git a/authentication/index.html b/authentication/index.html new file mode 100644 index 00000000..0e08373d --- /dev/null +++ b/authentication/index.html @@ -0,0 +1,36 @@ + + + + + + + + Equalify | Login + + + + + + + + +
+
+ + + +

Please sign in

+
+ + +
+
+ + +
+ +

Want to try Equalify? Request access.

+
+
+ + diff --git a/authentication/logout.php b/authentication/logout.php new file mode 100644 index 00000000..70b21afd --- /dev/null +++ b/authentication/logout.php @@ -0,0 +1,10 @@ + diff --git a/authentication/signin.css b/authentication/signin.css new file mode 100644 index 00000000..18e10b2b --- /dev/null +++ b/authentication/signin.css @@ -0,0 +1,39 @@ +html, +body { + height: 100%; +} + +body { + display: flex; + align-items: center; + padding-top: 40px; + padding-bottom: 40px; + background-color: #f5f5f5; +} + +.form-signin { + width: 100%; + max-width: 330px; + padding: 15px; + margin: auto; +} + +.form-signin .checkbox { + font-weight: 400; +} + +.form-signin .form-floating:focus-within { + z-index: 2; +} + +.form-signin input[type="email"] { + margin-bottom: -1px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.form-signin input[type="password"] { + margin-bottom: 10px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} \ No newline at end of file diff --git a/models/view_components.php b/models/view_components.php index cbee4886..8e161340 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -73,6 +73,9 @@ function the_integration_activation_button($integration_uri, $integration_status }elseif($integration_status == 'Active'){ $button_class = 'btn btn-outline-danger'; $button_text = 'Disable'; + }else{ + $button_class = NULL; + $button_text = NULL; } echo ''.$button_text.''; From 2cb7c5e0fe87990567611545fa18cdc11c8399aa Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:13:55 -0500 Subject: [PATCH 02/70] Add hook system to resolve #31 - Thanks @ebertucc! --- models/hooks.php | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 models/hooks.php diff --git a/models/hooks.php b/models/hooks.php new file mode 100644 index 00000000..f80477f9 --- /dev/null +++ b/models/hooks.php @@ -0,0 +1,63 @@ +_actions[] = $action; + } + + public function run_hook(string $hook): void { + // filter by hook + $filter = fn(Action $action) => $action->hook === $hook; + // order by priority + $sort = fn($a, $b) => $a->priority <=> $b->priority; + $actions_to_run = array_filter($this->_actions, $filter); + usort($actions_to_run, $sort); + + foreach ($actions_to_run as $action) { + ($action->action)(); + } + + } + +} + +// Initialize hooks. +$hook_system = new HookSystem([ + 'before_content' // everything before the app content +]); + +// Set initial actions for hooks. +$hook_system->add_action( + new Action('before_content', function() { + // This hook has no action...for now. + }) +); \ No newline at end of file From 4dde8449320f7ac4a087f2964da8fc3f668beec7 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:14:44 -0500 Subject: [PATCH 03/70] Add `before_content` hook. --- index.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/index.php b/index.php index f6e4dedd..31aebde0 100644 --- a/index.php +++ b/index.php @@ -22,6 +22,12 @@ + + run_hook('before_content'); + ?> +
From cdfc253b593f1e6558f9cfb27642a86bb08b2cb9 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:16:19 -0500 Subject: [PATCH 04/70] Talk about hooks. --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 04f58ae7..c2068f51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,10 @@ Eventually, I imagine people will want different accounts. Like so many features, we will build an auth system when folks request it. +## Usable hooks and patterns. + +Checkout [/models/hooks.php](/models/hooks.php) and the `_scan` pattern in [/actions/scan_all_pages.php](/actions/scan_all_pages.php). + ## Progress Depends on Bugs I am inspired by the development of [Gutenberg](https://github.com/WordPress/gutenberg). From e8094f65a8b4ff4281fd238f14f2206a9f53a94e Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:18:08 -0500 Subject: [PATCH 05/70] Simplify language. --- CONTRIBUTING.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c2068f51..2eb9d21a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Equalify is in an Alpha MVP "Wild West" phase. The only limits are your imagination. -I know limits will be created eventually. +I know this wild west needs rules eventually. For now, let's hack! @@ -22,7 +22,7 @@ I'm up for any new coding standards! Exceptions allow me to log errors. -**I consider User Errors System Errors. 🚩** +**I consider User Errors System Errors.** What some platforms display a warning for, like "wrong password," I ring alarm bells for. @@ -34,10 +34,6 @@ Users should never hit roadblocks. Equalify is being designed as open as possible. -Eventually, I imagine people will want different accounts. - -Like so many features, we will build an auth system when folks request it. - ## Usable hooks and patterns. Checkout [/models/hooks.php](/models/hooks.php) and the `_scan` pattern in [/actions/scan_all_pages.php](/actions/scan_all_pages.php). @@ -45,7 +41,7 @@ Checkout [/models/hooks.php](/models/hooks.php) and the `_scan` pattern in [/act ## Progress Depends on Bugs I am inspired by the development of [Gutenberg](https://github.com/WordPress/gutenberg). -A community of engaged devs builds the future of WordPress around issues that can be easily reported by any user. +A community of engaged devs builds the future of WordPress around issues that are reported by users. I hope folks, no matter their expertise, contribute to Equalify. From 7448e14ce2a008d0da413a6d9a0b14460b9b6920 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:18:57 -0500 Subject: [PATCH 06/70] requirements.. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3ff3448..df2a14c9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The goal: **Equalify every website.** ## To Start 1. Download or clone [the latest release](https://github.com/bbertucc/equalify/releases). 2. Update `config.php` info. -3. Upload/run on your server. +3. Upload/run on your server (PHP 8 + MySQL required). 4. Report [issues](https://github.com/bbertucc/equalify/issues), questions, and patches. ## Special Thanks From a2c3c8052e28cb38a62a89551d88a35c3490a7eb Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:21:26 -0500 Subject: [PATCH 07/70] Add hooks. --- config.php | 7 ------- index.php | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 config.php diff --git a/config.php b/config.php deleted file mode 100644 index 7405aaea..00000000 --- a/config.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Wed, 11 May 2022 13:22:01 -0500 Subject: [PATCH 08/70] Ignore config and add-ons --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2608ec26..be37893f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .DS_Store -.vscode \ No newline at end of file +.vscode +authentication/ +config.php \ No newline at end of file From 27809ef864d99622cb8231bee2ad60eb967819a0 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:25:19 -0500 Subject: [PATCH 09/70] Move important info up to improve UX. --- views/site_details.php | 88 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/views/site_details.php b/views/site_details.php index 6b37b6c9..0f7b958c 100644 --- a/views/site_details.php +++ b/views/site_details.php @@ -31,7 +31,50 @@
+
+

Alerts

+ + + + + + + + + + + site); + if(count($alerts) > 0 ): + foreach($alerts as $alert): + ?> + + + + + + + + + + + + + + + +
TimePageDetailsActions
time;?>page_id);?>details;?> + + Dismiss + +
No alerts found.
+
-
-

Alerts

- - - - - - - - - - - site); - if(count($alerts) > 0 ): - foreach($alerts as $alert): - ?> - - - - - - - - - - - - - - - - -
TimePageDetailsActions
time;?>page_id);?>details;?> - - Dismiss - -
No alerts found.
-

Options

@@ -181,5 +180,4 @@
-
\ No newline at end of file From c27daee0fabce263108d0b686a2f8a9da15e373d Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:25:59 -0500 Subject: [PATCH 10/70] Alert time distracts from the real message. --- views/site_details.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/views/site_details.php b/views/site_details.php index 0f7b958c..2bb48d5c 100644 --- a/views/site_details.php +++ b/views/site_details.php @@ -36,7 +36,6 @@ - @@ -50,7 +49,6 @@ ?> - - + + @@ -20,7 +21,8 @@ - + + - + @@ -50,7 +50,7 @@ - + - + @@ -52,4 +53,10 @@ ?>
Time Page Details Actions
time;?> page_id);?> details;?> From aa96d0d8999e5b3fdaa8dcbf8b3dbee05f66a6d4 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 13:27:15 -0500 Subject: [PATCH 11/70] Remove site and status column because site is listed on top of the page and status should not be different than site status. --- views/site_details.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/site_details.php b/views/site_details.php index 2bb48d5c..033c555f 100644 --- a/views/site_details.php +++ b/views/site_details.php @@ -95,7 +95,7 @@ // Users don't need to see a few columns // because they cannot act on these or they // are listed elsewhere. - $excluded_columns = array('is_parent', 'type', 'id'); + $excluded_columns = array('is_parent', 'type', 'id', 'site', 'status'); if( !in_array($column->COLUMN_NAME, $excluded_columns )){ // Make column name human readable and formatted @@ -136,7 +136,7 @@ foreach ($columns as $column){ // Limiting columns again. - $excluded_columns = array('is_parent', 'type', 'id'); + $excluded_columns = array('is_parent', 'type', 'id', 'site', 'status'); if( !in_array($column->COLUMN_NAME, $excluded_columns )){ // Make column name human readable. From e9a94e4929b802eae0a6531824b1d0a523c6b7cf Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 11 May 2022 16:59:56 -0500 Subject: [PATCH 12/70] Change the way integrations are activated so we don't rely on unsafe file writing. --- actions/scan_all_pages.php | 34 ++++- actions/toggle_integration_status.php | 46 +++--- actions/update_meta.php | 10 +- index.php | 5 +- integrations/little_forrest/functions.php | 3 +- .../little_forrest_archived.php | 73 --------- integrations/wave/functions.php | 9 +- models/db.php | 139 ++++++++++-------- models/integrations.php | 22 +-- views/integration_settings.php | 8 +- views/integrations.php | 17 ++- 11 files changed, 158 insertions(+), 208 deletions(-) delete mode 100644 integrations/little_forrest/little_forrest_archived.php diff --git a/actions/scan_all_pages.php b/actions/scan_all_pages.php index 34e89557..8b6f922c 100644 --- a/actions/scan_all_pages.php +++ b/actions/scan_all_pages.php @@ -8,7 +8,6 @@ // Setup queries to minize db calls. -$meta = DataAccess::get_meta(); $page_filters = [ array( 'name' => 'status', @@ -36,12 +35,14 @@ // This count helps us know how many pages were scanned. $pages_count = 0; + // Get active integrations. + $active_integrations = unserialize(DataAccess::get_meta_value('active_integrations')); // We're requring active integrations here and not in // the next loop because we don't want to require the // files over and over again. foreach($uploaded_integrations as $uploaded_integration){ - if(is_active_integration($uploaded_integration['uri'])) + if ( array_search($uploaded_integration['uri'], $active_integrations) !== false) require_once '../integrations/'.$uploaded_integration['uri'].'/functions.php'; } @@ -51,7 +52,7 @@ // Run active integration scans. foreach($uploaded_integrations as $uploaded_integration){ - if(is_active_integration($uploaded_integration['uri'])){ + if ( array_search($uploaded_integration['uri'], $active_integrations) !== false){ // Fire the '_scans' function. $integration_scan_function_name = $uploaded_integration['uri'].'_scans'; @@ -59,13 +60,22 @@ // We need to kill the scan if an integration has an error. try { - $integration_scan_function_name($page, $meta); + $integration_scan_function_name($page); } catch (Exception $x) { // We will kill the scan and alert folks of any errors, but // we will also record the successful scans that occured. - DataAccess::update_usage_meta($pages_count); + $existing_usage = DataAccess::get_meta_value('usage'); + if($existing_usage == false){ + + // This might be the first time we run a scan, so + // we need to create the meta field if none exists. + DataAccess::add_meta('usage', $pages_count); + + }else{ + DataAccess::update_meta_value('usage', $pages_count+$existing_usage); + } DataAccess::add_integration_alert($x->getMessage()); DataAccess::update_scan_status('running', 'incomplete'); $scans = DataAccess::get_scans(); @@ -89,7 +99,19 @@ // pages. $pages_count = count($active_page_ids); - DataAccess::update_usage_meta($pages_count); + // We keep track of the amount of pages scanned. + $existing_usage = DataAccess::get_meta_value('usage'); + if($existing_usage == NULL){ + + // This might be the first time we run a scan, so + // we need to create the meta field if none exists. + DataAccess::add_meta('usage', $pages_count); + + }else{ + DataAccess::update_meta_value('usage', $pages_count+$existing_usage); + } + + // Sacn is complete! DataAccess::update_scan_status('running', 'complete'); // Scan info is passed to JSON on the view, so that we can do diff --git a/actions/toggle_integration_status.php b/actions/toggle_integration_status.php index 83ad2da5..2683f20a 100644 --- a/actions/toggle_integration_status.php +++ b/actions/toggle_integration_status.php @@ -5,16 +5,12 @@ require_once '../models/db.php'; // Get URL parameters. -$uri = $_GET['uri']; -if(empty($uri)) +$integration_uri = $_GET['uri']; +if(empty($integration_uri)) throw new Exception('Integration is not specfied'); $old_status = $_GET['old_status']; if(empty($old_status)) - throw new Exception('Status is not specfied for integration "'.$uri.'"'); - -// Integration file is going to be updated. -$integration_path = '../integrations/'.$uri.'/functions.php'; -$integration_contents = file_get_contents($integration_path); + throw new Exception('Old status is not specfied for integration "'.$integration_uri.'"'); // Conditional operations based on status: if($old_status == 'Active'){ @@ -23,21 +19,21 @@ $alerts_filter = [ array( 'name' => 'integration_uri', - 'value' => $uri + 'value' => $integration_uri ) ]; DataAccess::delete_alerts($alerts_filter); // Remove fields. - $integration_fields = get_integration_fields($uri); + $integration_fields = get_integration_fields($integration_uri); if( !empty($integration_fields['db']) ){ $integration_db_fields = $integration_fields['db']; // Delete "meta" fields. if( !empty($integration_db_fields['meta']) ){ foreach($integration_db_fields['meta'] as $integration_meta_field){ - if(DataAccess::db_column_exists('meta', $integration_meta_field['name'])) - DataAccess::delete_db_column('meta', $integration_meta_field['name']); + if(!DataAccess::get_meta_value($integration_meta_field['name'])) + DataAccess::delete_meta($integration_meta_field['name']); } } @@ -51,21 +47,26 @@ } - // Status text. - $new_status = 'Disabled'; + // Remove from "active_integrations" meta field. + $active_integrations = unserialize(DataAccess::get_meta_value('active_integrations')); + if (($key = array_search($integration_uri, $active_integrations)) !== false) { + unset($active_integrations[$key]); + $new_active_integrations = serialize($active_integrations); + DataAccess::update_meta_value('active_integrations', $new_active_integrations); + } }elseif($old_status == 'Disabled'){ // Setup fields. - $integration_fields = get_integration_fields($uri); + $integration_fields = get_integration_fields($integration_uri); if( !empty($integration_fields['db']) ){ $integration_db_fields = $integration_fields['db']; // Setup "meta" fields. if( !empty($integration_db_fields['meta']) ){ foreach($integration_db_fields['meta'] as $integration_meta_field){ - if(!DataAccess::db_column_exists('meta', $integration_meta_field['name'])) - DataAccess::add_db_column('meta', $integration_meta_field['name'], $integration_meta_field['type']); + if(!DataAccess::get_meta_value($integration_meta_field['name'])) + DataAccess::add_meta($integration_meta_field['name'], $integration_meta_field['value']); } } @@ -79,16 +80,15 @@ } - // Status text. - $new_status = 'Active'; + // Add to "active_integrations" meta field. + $active_integrations = unserialize(DataAccess::get_meta_value('active_integrations')); + array_push( $active_integrations, $integration_uri); + $new_active_integrations = serialize($active_integrations); + DataAccess::update_meta_value('active_integrations', $new_active_integrations); }else{ throw new Exception('The status,"'.$old_status.'," is not allowed'); } -// Replace the file contents. -$new_contents = str_replace($old_status, $new_status, $integration_contents); -file_put_contents($integration_path, $new_contents); - // Redirect. -header('Location: ../index.php?view=integrations&id='.$uri.'&status=success'); \ No newline at end of file +header('Location: ../index.php?view=integrations&id='.$integration_uri.'&status=success'); \ No newline at end of file diff --git a/actions/update_meta.php b/actions/update_meta.php index 63eb34c2..8853c8a6 100644 --- a/actions/update_meta.php +++ b/actions/update_meta.php @@ -17,15 +17,7 @@ // set in the integrations file. See Github Issue #12. $account_records = []; if(!empty($_POST['wave_key'])){ - array_push( - $account_records, - array( - 'key' => 'wave_key', - 'value' => $_POST['wave_key'] - ) - ); + DataAccess::update_meta_value('wave_key', $_POST['wave_key']); }; -// Time to update meta and redirect! -DataAccess::update_meta($account_records); header('Location: ../index.php?view='.$last_view.'&status=success'); \ No newline at end of file diff --git a/index.php b/index.php index 10288b9a..170a5be2 100644 --- a/index.php +++ b/index.php @@ -84,12 +84,13 @@ usage)): + $usage_meta = DataAccess::get_meta_value('usage'); + if(!empty($usage_meta)): ?>

- 🎉 usage;?> pages scanned. + 🎉 pages scanned.

diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index bc228e5d..158530cb 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -2,7 +2,6 @@ /** * Name: Little Forrest * Description: Counts WCAG 2.1 errors and links to page reports. - * Status: Active */ /** @@ -35,7 +34,7 @@ function little_forrest_fields(){ /** * little_forrest Scans */ -function little_forrest_scans($page, $meta){ +function little_forrest_scans($page){ // Add DB info and required functions. require_once '../config.php'; diff --git a/integrations/little_forrest/little_forrest_archived.php b/integrations/little_forrest/little_forrest_archived.php deleted file mode 100644 index 21d398dd..00000000 --- a/integrations/little_forrest/little_forrest_archived.php +++ /dev/null @@ -1,73 +0,0 @@ - 'Little Forrest', - - // Description (60 Chararacter Max) - 'tagline' => 'Counts WCAG 2.1 errors and links to reports.', - - ), - array( - - // Toggle functions are . - 'toggle_functions' => array('wcag_2_1_page_error'), - - ) -); - -/** - * Scan pages with LF and return errors - */ -function wcag_2_1_page_error($pages){ - - // Loop $pages - foreach ($pages as &$page): - - // Get Little Forrest data. - $little_forrest_url = 'https://inspector.littleforest.co.uk/InspectorWS/Accessibility?url='.$page['url'].'&level=WCAG2AA'; - $little_forrest_json = file_get_contents($little_forrest_url, false, stream_context_create($override_https)); - - // Fallback if LF scan doesn't work - if(strpos($little_forrest_json, 'NoSuchFileException')) - throw new Exception('Little Forrest error related to page "'.$little_forrest_url.'"'); - - // Decode JSON and count WCAG errors. - $little_forrest_json_decoded = json_decode($little_forrest_json, true); - $little_forrest_errors = count($little_forrest_json_decoded['Errors']); - if($little_forrest_errors == NULL) - $little_forrest_errors = 0; - - // Update post meta. - $page['wcag_errors'] = $little_forrest_errors; - - endforeach; - -} - -/** - * Create Settings View - */ -function settings($pages){ -?> - -

- - little_forrest_wcag_2_1_page_error == true) echo 'checked';?> > - - -
- - [ - // Metas columns. + // Meta values. 'meta' => [ array( 'name' => 'wave_key', - 'type' => 'VARCHAR(20)', + 'value' => '', ) ], @@ -57,7 +56,7 @@ function wave_fields(){ /** * WAVE Scans */ -function wave_scans($page, $meta){ +function wave_scans($page){ // Add DB and required functions. require_once '../config.php'; @@ -70,7 +69,7 @@ function wave_scans($page, $meta){ "verify_peer_name"=> false, ) ); - $wave_url = 'https://wave.webaim.org/api/request?key='.$meta->wave_key.'&url='.$page->url; + $wave_url = 'https://wave.webaim.org/api/request?key='.DataAccess::get_meta_value('wave_key').'&url='.$page->url; $wave_json = file_get_contents($wave_url, false, stream_context_create($override_https)); $wave_json_decoded = json_decode($wave_json, true); diff --git a/models/db.php b/models/db.php index 8507a389..bc4e7580 100644 --- a/models/db.php +++ b/models/db.php @@ -198,19 +198,29 @@ public static function get_alerts_by_site($site){ } /** - * Get Meta + * Get Meta Value */ - public static function get_meta(){ - + public static function get_meta_value($meta_name){ + // SQL - $sql = 'SELECT * FROM meta'; + $sql = 'SELECT * FROM `meta` WHERE `meta_name` = "'.$meta_name.'"'; // Query $data = []; $data = self::connect()->query($sql)->fetch_object(); - - // Result - return $data; + + // Results + if($data == NULL){ + + // Returns "false" if no data exists. + return false; + + }else{ + + // Returns meta_value. + return $data->meta_value; + + } } @@ -442,48 +452,6 @@ public static function add_pages($pages_records){ } - /** - * Update Usage Meta - */ - public static function update_usage_meta($usage){ - - // SQL - $sql = 'UPDATE `meta` SET `usage` = `usage` + '.$usage; - - // Execute Query - $result = self::connect()->query($sql); - - // Result - if(!$result) - throw new Exception('Cannot add "'.$usage.'"'); - } - - /** - * Update Meta - */ - public static function update_meta(array $meta_records){ - - // SQL - $sql = 'UPDATE `meta` SET '; - - // Loop Based on the amount of records updated - $record_count = count($meta_records); - $record_iteration = 0; - foreach ($meta_records as $record){ - $sql.= '`'.$record['key'].'` = "'.$record['value'].'"'; - if(++$record_iteration != $record_count) - $sql.= ","; - } - - // Query - $result = self::connect()->query($sql); - - // Result - if(!$result) - throw new Exception('Cannot update meta: '.$meta_records); - - } - /** * Update Status */ @@ -670,6 +638,7 @@ public static function delete_alerts($filters = []){ // Result if(!$result) throw new Exception('Cannot delete alert using filters "'.$filters.'"'); + } /** @@ -722,22 +691,62 @@ public static function add_integration_alert($details){ /** * Add Meta */ - public static function add_meta($field, $value){ + public static function add_meta($meta_name, $meta_value = ''){ // SQL - $sql = 'INSERT INTO `meta` (`'.$field.'`) VALUES ("'.$value.'");'; + $sql = 'INSERT INTO `meta` (`meta_name`, `meta_value`) VALUES ("'.$meta_name.'", "'.$meta_value.'")'; // Query $result = self::connect()->query($sql); // Fallback if(!$result) - throw new Exception('Cannot add meta field "'.$field.'" and value "'.$value.'"'); + throw new Exception('Cannot add meta field "'.$meta_name.'" and value "'.$meta_value.'"'); // Complete Query return $result; } + + /** + * Delete Meta + */ + public static function delete_meta($meta_name){ + + // SQL + $sql = 'DELETE FROM `meta` WHERE `meta_name` = "'.$meta_name.'"'; + + // Query + $result = self::connect()->query($sql); + + // Result + if(!$result) + throw new Exception('Cannot delete alert using filters "'.$filters.'"'); + + // Complete Query + return $result; + + } + + /** + * Update Meta + */ + public static function update_meta_value($meta_name, $meta_value){ + + // SQL + $sql = "UPDATE `meta` SET `meta_value` = '".$meta_value."' WHERE `meta_name` = '".$meta_name."'"; + + // Query + $result = self::connect()->query($sql); + + // Result + if(!$result) + throw new Exception('Cannot update "'.$meta_name.'" with value "'.$meta_value.'"'); + // Complete Query + return $result; + + } + /** * Create Alerts Table */ @@ -771,15 +780,25 @@ public static function create_alerts_table(){ public static function create_meta_table(){ // SQL - $sql = - 'CREATE TABLE `meta` ( - `usage` bigint(20) DEFAULT NULL, - `wave_key` varchar(20) DEFAULT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'; - - // Query - $result = self::connect()->query($sql); + $sql_1 = + 'CREATE TABLE `meta` ( + `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `meta_name` varchar(191) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT "", + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, + PRIMARY KEY (`meta_id`), + UNIQUE KEY `option_name` (`meta_name`) + ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; + '; + + // Query 1 + $result = self::connect()->query($sql_1); + + $sql_2 = + 'INSERT INTO `meta` (`meta_id`, `meta_name`, `meta_value`) + VALUES (1, "active_integrations", "a:1:{i:0;s:14:\"little_forrest\";}")'; + $result = self::connect()->query($sql_2); + // Fallback if(!$result) throw new Exception('Error creating table: "'.$result->error.'"'); diff --git a/models/integrations.php b/models/integrations.php index bf97530a..8ca1cb1e 100644 --- a/models/integrations.php +++ b/models/integrations.php @@ -44,8 +44,8 @@ function uploaded_integrations($path_to_integrations){ */ function get_integration_meta( $file ) { - // We need to read and write to change the status. - $fp = fopen( $file, 'r+' ); + // We need to read the meta. + $fp = fopen( $file, 'r' ); if ( $fp ) { @@ -95,22 +95,4 @@ function get_integration_fields( $uri ){ false; } -} - -/** - * Is Active Integration - */ -function is_active_integration($uri){ - - // Get integration meta. - $integration_path = __DIR__.'/../integrations/'.$uri.'/functions.php'; - $integration_meta = get_integration_meta($integration_path); - - // Return true if it is active. - if($integration_meta['status'] == 'Active'){ - return true; - }else{ - return false; - } - } \ No newline at end of file diff --git a/views/integration_settings.php b/views/integration_settings.php index bdad6ee6..27de2792 100644 --- a/views/integration_settings.php +++ b/views/integration_settings.php @@ -42,9 +42,6 @@ " value="$name)) - echo $meta->$name + $meta_value = DataAccess::get_meta_value($name); + if($meta_value != false) + echo $meta_value; ?>" class="form-control" > diff --git a/views/integrations.php b/views/integrations.php index 33e994cb..03fa4ba1 100644 --- a/views/integrations.php +++ b/views/integrations.php @@ -4,10 +4,22 @@
@@ -26,7 +38,6 @@ @@ -44,12 +55,12 @@ // Show settings button if integration has settings $integration_fields = get_integration_fields( $integration['uri'] ); if(!empty($integration_fields['settings'])) - the_integration_settings_button($integration['uri'], $meta['status']); + the_integration_settings_button($integration['uri'], $status); ?>
From 66e2ae30d9c5d984e37068a366020130809dbe12 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 12 May 2022 15:49:11 -0500 Subject: [PATCH 13/70] Update config semantics. --- README.md | 2 +- models/db.php | 11 +++-------- sample-config.php | 6 ++++++ 3 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 sample-config.php diff --git a/README.md b/README.md index df2a14c9..eb6cc8aa 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ The goal: **Equalify every website.** ## To Start 1. Download or clone [the latest release](https://github.com/bbertucc/equalify/releases). -2. Update `config.php` info. +2. Change `sample-config.php` to `config.php` and update info. 3. Upload/run on your server (PHP 8 + MySQL required). 4. Report [issues](https://github.com/bbertucc/equalify/issues), questions, and patches. diff --git a/models/db.php b/models/db.php index bc4e7580..3eeee1ea 100644 --- a/models/db.php +++ b/models/db.php @@ -1,18 +1,13 @@ connect_error){ throw new Exception('Cannot connect to database: ' . self::$conn->connect_error); } diff --git a/sample-config.php b/sample-config.php new file mode 100644 index 00000000..0d6861d4 --- /dev/null +++ b/sample-config.php @@ -0,0 +1,6 @@ + Date: Thu, 12 May 2022 15:52:27 -0500 Subject: [PATCH 14/70] Check todos off. --- models/db.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/models/db.php b/models/db.php index 3eeee1ea..7c98b92b 100644 --- a/models/db.php +++ b/models/db.php @@ -398,7 +398,6 @@ public static function add_scan($status, array $pages){ //Fallback if(!$result) - // TODO: Fix this error message throw new Exception('Cannot insert scan with status "'.$status.'" and records "'.$records.'"'); // Complete Query @@ -476,8 +475,7 @@ public static function update_page_scanned_time($id){ // Result if(!$result) - // TODO: Fix this error message - throw new Exception('Cannot update scan status where old status is "'.$old_status.'" and new status is "'.$new_status.'"'); + throw new Exception('Cannot update scan time for scan with id "'.$id.'"'); } /** From a81489d6890d7f9ce9d8af4fa16012978046ddf4 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 12 May 2022 16:17:15 -0500 Subject: [PATCH 15/70] update gitignore and remove old files --- .gitignore | 2 +- authentication/authenticate.php | 63 --------------------------------- authentication/index.html | 36 ------------------- authentication/logout.php | 10 ------ authentication/signin.css | 39 -------------------- 5 files changed, 1 insertion(+), 149 deletions(-) delete mode 100644 authentication/authenticate.php delete mode 100644 authentication/index.html delete mode 100644 authentication/logout.php delete mode 100644 authentication/signin.css diff --git a/.gitignore b/.gitignore index be37893f..2da2b442 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .DS_Store .vscode -authentication/ +login/ config.php \ No newline at end of file diff --git a/authentication/authenticate.php b/authentication/authenticate.php deleted file mode 100644 index bc3b298f..00000000 --- a/authentication/authenticate.php +++ /dev/null @@ -1,63 +0,0 @@ -prepare('SELECT id, password FROM accounts WHERE username = ?')) { - - // Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s" - $stmt->bind_param('s', $_POST['username']); - $stmt->execute(); - - // Store the result so we can check if the account exists in the database. - $stmt->store_result(); - if ($stmt->num_rows > 0) { - $stmt->bind_result($id, $password); - $stmt->fetch(); - - // Account exists, now we verify the password. - // Note: remember to use password_hash in your registration file to store the hashed passwords. - if (password_verify($_POST['password'], $password)) { - - // Verification success! User has logged-in! - // Create sessions, so we know the user is logged in, they basically act like cookies but remember the data on the server. - session_regenerate_id(); - $_SESSION['loggedin'] = TRUE; - $_SESSION['name'] = $_POST['username']; - $_SESSION['id'] = $id; - header('Location: ../index.php'); - - } else { - // Incorrect password - echo 'Incorrect username and/or password!'; - } - } else { - // Incorrect username - echo 'Incorrect username and/or password!'; - } - - $stmt->close(); -} -?> diff --git a/authentication/index.html b/authentication/index.html deleted file mode 100644 index 0e08373d..00000000 --- a/authentication/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - Equalify | Login - - - - - - - - -
-
- - - -

Please sign in

-
- - -
-
- - -
- -

Want to try Equalify? Request access.

-
-
- - diff --git a/authentication/logout.php b/authentication/logout.php deleted file mode 100644 index 70b21afd..00000000 --- a/authentication/logout.php +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/authentication/signin.css b/authentication/signin.css deleted file mode 100644 index 18e10b2b..00000000 --- a/authentication/signin.css +++ /dev/null @@ -1,39 +0,0 @@ -html, -body { - height: 100%; -} - -body { - display: flex; - align-items: center; - padding-top: 40px; - padding-bottom: 40px; - background-color: #f5f5f5; -} - -.form-signin { - width: 100%; - max-width: 330px; - padding: 15px; - margin: auto; -} - -.form-signin .checkbox { - font-weight: 400; -} - -.form-signin .form-floating:focus-within { - z-index: 2; -} - -.form-signin input[type="email"] { - margin-bottom: -1px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.form-signin input[type="password"] { - margin-bottom: 10px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} \ No newline at end of file From 9a7748f9dfbb456fa760c4a4c448b4bf767140d8 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 12 May 2022 18:40:04 -0500 Subject: [PATCH 16/70] =?UTF-8?q?=F0=9F=95=B7=20-=20thanks=20@ebertucc!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- integrations/little_forrest/functions.php | 2 +- models/db.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index 158530cb..df844df3 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -83,5 +83,5 @@ function little_forrest_scans($page){ // Update page data. DataAccess::update_page_data($page->id, 'little_forrest_wcag_2_1_errors', $little_forrest_errors); - + } \ No newline at end of file diff --git a/models/db.php b/models/db.php index 7c98b92b..7be29654 100644 --- a/models/db.php +++ b/models/db.php @@ -312,7 +312,7 @@ public static function get_column_names($table){ // SQL $sql = 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS '; - $sql.= 'WHERE TABLE_NAME = "'.$table.'" AND TABLE_SCHEMA = "'.DB_NAME.'"'; + $sql.= 'WHERE TABLE_NAME = "'.$table.'" AND TABLE_SCHEMA = "'.$GLOBALS['DB_NAME'].'"'; // Query $results = self::connect()->query($sql); @@ -788,7 +788,7 @@ public static function create_meta_table(){ $sql_2 = 'INSERT INTO `meta` (`meta_id`, `meta_name`, `meta_value`) - VALUES (1, "active_integrations", "a:1:{i:0;s:14:\"little_forrest\";}")'; + VALUES (1, "active_integrations", "a:1:{i:0;s:14:\"little_forrest\";}")'; // Little Forrest is activated here. $result = self::connect()->query($sql_2); @@ -803,7 +803,7 @@ public static function create_meta_table(){ */ public static function create_pages_table(){ - // SQL + // SQL $sql = 'CREATE TABLE `pages` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, @@ -813,6 +813,7 @@ public static function create_pages_table(){ `site` text COLLATE utf8mb4_bin, `is_parent` tinyint(1) DEFAULT NULL, `scanned` timestamp NULL DEFAULT NULL, + `little_forrest_wcag_2_1_errors` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT "0", -- Little Forrest is activated here. PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7172 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;'; From 21c25d0b40cfd2c39c872828788c95f2a343e50e Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Tue, 17 May 2022 14:01:45 -0500 Subject: [PATCH 17/70] Update fallback text, related to #32 --- models/adders.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/adders.php b/models/adders.php index 31ec4f09..4c9aa00c 100644 --- a/models/adders.php +++ b/models/adders.php @@ -77,7 +77,7 @@ function wordpress_site_adder($site_url){ // Create JSON. $wp_api_json = json_decode($curled_site['contents'], true); if(empty($wp_api_json[0])) - throw new Exception('The URL "'.$site_url.'" is not valid output'); + throw new Exception('"'.$site_url.'" does not include WordPress functionality that Equalify requires'); // Push JSON to pages array. $pages = []; From 446080ee03c5d3848975ca782689e8ded76eaf04 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Tue, 17 May 2022 14:54:29 -0500 Subject: [PATCH 18/70] set dashboard as default --- index.php | 11 ++++++++++- views/dashboard.php | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 views/dashboard.php diff --git a/index.php b/index.php index 170a5be2..6b0b745f 100644 --- a/index.php +++ b/index.php @@ -38,6 +38,15 @@ Equalify
Time SourceDetailsTypeMessage Actions
time;?> source);?>details;?>type);?>message;?>
PageDetailsMessage Actions
page_id);?>details;?>message;?> Dismiss From 05fc1a1b5ae9a0f2bfcdd9e645d9672bdb612eaf Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 11:58:36 -0500 Subject: [PATCH 21/70] Add [code] shortcode manipulator. --- models/view_components.php | 15 +++++++++++++++ theme.css | 3 +++ views/alerts.php | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/models/view_components.php b/models/view_components.php index 8e161340..5ffb805f 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -138,4 +138,19 @@ function the_scan_rows($scans){ // Clean the buff. echo ob_get_clean(); +} + +/** + * Convert Code Shortcode + */ +function covert_code_shortcode($subject){ + + // Convert text between [code][/code] into styled + // code. + $subject = str_replace('[code]', '
', $subject);
+    $subject = str_replace('[/code]', '
', $subject); + + // [code] is converted! + return $subject; + } \ No newline at end of file diff --git a/theme.css b/theme.css index 20033eaf..85e1f012 100644 --- a/theme.css +++ b/theme.css @@ -38,4 +38,7 @@ main{ .sites tbody tr.parent td{ padding-top: .5rem; +} +pre code{ + white-space: break-spaces; } \ No newline at end of file diff --git a/views/alerts.php b/views/alerts.php index 18fe0467..b66cbfa8 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -22,7 +22,7 @@
time;?> source);?> type);?>message;?>message);?> Date: Thu, 19 May 2022 11:59:53 -0500 Subject: [PATCH 22/70] Update LF message to include code --- integrations/little_forrest/functions.php | 80 +++++++++++++---------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index 692228c8..b4cee96c 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -109,39 +109,53 @@ function little_forrest_scans($page){ } } - // // Add notices. - // if(count($little_forrest_notices) >= 1){ - // foreach($little_forrest_notices as $notice){ - - // // Create Meta - // $meta = array( - // 'guideline' => $notice['Guideline'], - // 'tag' => $notice['Tag'], - // 'code' => $notice['Code'] - // ); - - // // Add notice. - // DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'notice', $notice['Message'], $meta); - - // } - // } - - // // Add warnings. - // if(count($little_forrest_warnings) >= 1){ - // foreach($little_forrest_warnings as $warning){ - - // // Create Meta - // $meta = array( - // 'guideline' => $warning['Guideline'], - // 'tag' => $warning['Tag'], - // 'code' => $warning['Code'] - // ); - - // // Add warning. - // DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'warning', $warning['Message'], $meta); - - // } - // } + // Add notices. + if(count($little_forrest_notices) >= 1){ + foreach($little_forrest_notices as $notice){ + + // Create Meta + $meta = array( + 'guideline' => $notice['Guideline'], + 'tag' => $notice['Tag'] + ); + + // Create message. + if(!empty($error['Code'])){ + $code = htmlentities('[code]'.$error['Code'].'[/code]'); + $message = $code.$error['Message']; + }else{ + $message = $error['Message']; + } + + // Add notice. + DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'notice', $message, $meta); + + } + } + + // Add warnings. + if(count($little_forrest_warnings) >= 1){ + foreach($little_forrest_warnings as $warning){ + + // Create Meta + $meta = array( + 'guideline' => $warning['Guideline'], + 'tag' => $warning['Tag'] + ); + + // Create message. + if(!empty($error['Code'])){ + $code = htmlentities('[code]'.$error['Code'].'[/code]'); + $message = $code.$error['Message']; + }else{ + $message = $error['Message']; + } + + // Add warning. + DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'warning', $message, $meta); + + } + } // Update page data. From 0a7b52f155149bd80859f8c65e4e5ac4d25b859c Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 12:17:58 -0500 Subject: [PATCH 23/70] Update LF to not show null code. --- integrations/little_forrest/functions.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index b4cee96c..bc302579 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -96,7 +96,7 @@ function little_forrest_scans($page){ ); // Create message. - if(!empty($error['Code'])){ + if(!empty($error['Code']) && $error['Code'] != 'null'){ $code = htmlentities('[code]'.$error['Code'].'[/code]'); $message = $code.$error['Message']; }else{ @@ -120,11 +120,11 @@ function little_forrest_scans($page){ ); // Create message. - if(!empty($error['Code'])){ - $code = htmlentities('[code]'.$error['Code'].'[/code]'); - $message = $code.$error['Message']; + if(!empty($notice['Code']) && $notice['Code'] != 'null'){ + $code = htmlentities('[code]'.$notice['Code'].'[/code]'); + $message = $code.$notice['Message']; }else{ - $message = $error['Message']; + $message = $notice['Message']; } // Add notice. @@ -144,11 +144,11 @@ function little_forrest_scans($page){ ); // Create message. - if(!empty($error['Code'])){ - $code = htmlentities('[code]'.$error['Code'].'[/code]'); - $message = $code.$error['Message']; + if(!empty($warning['Code']) && $warning['Code'] != 'null'){ + $code = htmlentities('[code]'.$warning['Code'].'[/code]'); + $message = $code.$warning['Message']; }else{ - $message = $error['Message']; + $message = $warning['Message']; } // Add warning. From afefbedc4e3efa49b66ccf1410a1523b2ac4e9e3 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 12:20:54 -0500 Subject: [PATCH 24/70] preddy code. --- models/view_components.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/view_components.php b/models/view_components.php index 5ffb805f..79439e5e 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -147,7 +147,7 @@ function covert_code_shortcode($subject){ // Convert text between [code][/code] into styled // code. - $subject = str_replace('[code]', '
', $subject);
+    $subject = str_replace('[code]', '
', $subject);
     $subject = str_replace('[/code]', '
', $subject); // [code] is converted! From bb008f98f721b0a955fe644d265967215120d05d Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 14:03:40 -0500 Subject: [PATCH 25/70] minor styling update --- theme.css | 1 + 1 file changed, 1 insertion(+) diff --git a/theme.css b/theme.css index 85e1f012..9802023e 100644 --- a/theme.css +++ b/theme.css @@ -41,4 +41,5 @@ main{ } pre code{ white-space: break-spaces; + word-break: break-word !important; } \ No newline at end of file From 4a7248a4d0cc32322eccbe317c07c06b3277f08b Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 16:09:58 -0500 Subject: [PATCH 26/70] Paginate alerts results. --- models/db.php | 56 ++++++++++++++++---- models/view_components.php | 101 ++++++++++++++++++++++++++++++++++++- views/alerts.php | 11 +++- 3 files changed, 154 insertions(+), 14 deletions(-) diff --git a/models/db.php b/models/db.php index ef2aba90..444b2c68 100644 --- a/models/db.php +++ b/models/db.php @@ -1,6 +1,9 @@ $name, 'value' => $value, 'page' => $page) ] + * @param string page */ - public static function get_alerts(){ + public static function get_alerts($filters = [], $page = 1){ + + // Set alerts per page. + $alerts_per_page = self::ITEMS_PER_PAGE; + $page_offset = ($page-1) * $alerts_per_page; + + // Count the number of items for pagination + $total_pages_sql = "SELECT COUNT(*) FROM `alerts`"; + $total_pages_result = self::connect()->query($total_pages_sql); + $total_pages_rows = mysqli_fetch_array($total_pages_result)[0]; + $total_pages = ceil($total_pages_rows / $alerts_per_page); // SQL - $sql = 'SELECT * FROM `alerts` ORDER BY STR_TO_DATE(`time`,"%Y-%m-%d %H:%i:%s")'; - - // Query - $results = self::connect()->query($sql); + $content_sql = "SELECT * FROM `alerts` LIMIT $page_offset, $alerts_per_page "; - // Result - $data = []; - if($results->num_rows > 0){ - while($row = $results->fetch_object()){ - $data[] = $row; + // Add optional filters + $filter_count = count($filters); + if($filter_count > 0){ + $content_sql.= 'WHERE '; + $filter_iteration = 0; + foreach ($filters as $filter){ + $content_sql.= '`'.$filter['name'].'` = "'.$filter['value'].'"'; + if(++$filter_iteration != $filter_count) + $content_sql.= ' AND '; + + } + } + $content_sql.= ';'; + + // Content Query + $content_results = self::connect()->query($content_sql); + $content = []; + if($content_results->num_rows > 0){ + while($row = $content_results->fetch_object()){ + $content[] = $row; } } + + // Create and return data. + $data = [ + 'total_pages' => $total_pages, + 'content' => $content + ]; return $data; + } /** diff --git a/models/view_components.php b/models/view_components.php index 79439e5e..6c4b1b25 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -153,4 +153,103 @@ function covert_code_shortcode($subject){ // [code] is converted! return $subject; -} \ No newline at end of file +} + +/** + * Get Page Number + */ +function get_current_page_number(){ + + // Pull page number from URL string. + if (isset($_GET['current_page_number'])) { + $current_page_number = $_GET['current_page_number']; + } else { + $current_page_number = 1; + } + + // Return page + return $current_page_number; + +} + +/** + * The Pagination + */ +function the_pagination($total_pages){ + + // Define page number. + $current_page_number = get_current_page_number(); + + // Defined current view + $current_view = $_GET['view']; + + // Set active state as function so we don't have to keep + // writing this condition. + function get_active_state($current_page_number, $item_number){ + if($current_page_number == $item_number){ + return 'active'; + }else{ + return null; + } + } + +?> + + + + \ No newline at end of file diff --git a/views/alerts.php b/views/alerts.php index b66cbfa8..19035fb9 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -14,8 +14,9 @@ 0 ): foreach($alerts as $alert): + $alerts = DataAccess::get_alerts([], get_current_page_number()); + $alerts_content = $alerts['content']; + if(count($alerts_content) > 0 ): foreach($alerts_content as $alert): ?>
+ + + \ No newline at end of file From da3193df8f4dbe9b354504830393d49484c09d7f Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 16:17:21 -0500 Subject: [PATCH 27/70] Add inspiration to pagination. --- models/view_components.php | 1 + 1 file changed, 1 insertion(+) diff --git a/models/view_components.php b/models/view_components.php index 6c4b1b25..eb1f1f40 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -174,6 +174,7 @@ function get_current_page_number(){ /** * The Pagination + * Inspired by https://www.myprogrammingtutorials.com/create-pagination-with-php-and-mysql.html */ function the_pagination($total_pages){ From 679440da3e0fb6b0621b78b8f8045d71e577d48b Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 19 May 2022 17:09:53 -0500 Subject: [PATCH 28/70] minor style changes --- views/alerts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/views/alerts.php b/views/alerts.php index 19035fb9..8ee7841b 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -1,6 +1,7 @@

- All Alerts

+ All Alerts + From 48b8cc43b476e79508540a7ec57fa85a7aa26aa2 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 11:23:57 -0500 Subject: [PATCH 29/70] Add filter placeholders. --- views/alerts.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/views/alerts.php b/views/alerts.php index 8ee7841b..1cc2f105 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -2,6 +2,37 @@

All Alerts

+
+
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+
From 383e6cdfb3567575afdabdb8ae7585466315996a Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 11:50:36 -0500 Subject: [PATCH 30/70] Add function to count alerts so we don't have to pass a giant query. --- index.php | 2 +- integrations/little_forrest/functions.php | 3 ++- models/db.php | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 170a5be2..92c26a3d 100644 --- a/index.php +++ b/index.php @@ -56,7 +56,7 @@ - + diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index bc302579..77e38943 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -159,6 +159,7 @@ function little_forrest_scans($page){ // Update page data. - DataAccess::update_page_data($page->id, 'little_forrest_wcag_2_1_errors', count($little_forrest_errors)); + $total_alerts = count($little_forrest_errors+$little_forrest_notices+$little_forrest_warnings); + DataAccess::update_page_data($page->id, 'little_forrest_wcag_2_1_errors', $total_alerts); } \ No newline at end of file diff --git a/models/db.php b/models/db.php index 444b2c68..f2d65cf0 100644 --- a/models/db.php +++ b/models/db.php @@ -197,6 +197,23 @@ public static function get_alerts($filters = [], $page = 1){ return $data; } + + /** + * Count Alerts + */ + public static function count_alerts(){ + + // SQL + $sql = 'SELECT COUNT(*) AS TOTAL FROM `alerts`'; + + // Query + $data = self::connect()->query($sql)->fetch_object()->TOTAL; + + // Result + return $data; + + } + /** * Get Alerts By Page Site From 9dc11ae449cf2325e93a70638024b982eee3461f Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 12:05:58 -0500 Subject: [PATCH 31/70] Add Bootstrap 5.2.0-beta1 --- index.php | 21 ++++++++++++--------- theme.css | 3 +++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/index.php b/index.php index 92c26a3d..de139b04 100644 --- a/index.php +++ b/index.php @@ -18,9 +18,8 @@ Equalify | WebOps Management - + - @@ -31,23 +30,23 @@
+ + + + \ No newline at end of file diff --git a/theme.css b/theme.css index 9802023e..28151cf5 100644 --- a/theme.css +++ b/theme.css @@ -42,4 +42,7 @@ main{ pre code{ white-space: break-spaces; word-break: break-word !important; +} +.nav-link{ + color: #212529; } \ No newline at end of file From cda4238da33fc0c8073f711d10ed6f8947e0a12d Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 12:06:23 -0500 Subject: [PATCH 32/70] Reformat --- models/db.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/db.php b/models/db.php index f2d65cf0..56821922 100644 --- a/models/db.php +++ b/models/db.php @@ -253,7 +253,7 @@ public static function get_meta_value($meta_name){ // Query $data = []; - $data = self::connect()->query($sql)->fetch_object(); + $data = self::connect()->query($sql)->fetch_object()->meta_value; // Results if($data == NULL){ @@ -264,7 +264,7 @@ public static function get_meta_value($meta_name){ }else{ // Returns meta_value. - return $data->meta_value; + return $data; } From 7177c4eb4b5aa24eae87c0a2e11119e593e111d0 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 17:00:54 -0500 Subject: [PATCH 33/70] Add Filter/View UX for alerts --- actions/save_alert_filters.php | 10 ++++ theme.css | 3 ++ views/alerts.php | 87 ++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 26 deletions(-) create mode 100644 actions/save_alert_filters.php diff --git a/actions/save_alert_filters.php b/actions/save_alert_filters.php new file mode 100644 index 00000000..ea028cb0 --- /dev/null +++ b/actions/save_alert_filters.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/theme.css b/theme.css index 28151cf5..0991afb1 100644 --- a/theme.css +++ b/theme.css @@ -45,4 +45,7 @@ pre code{ } .nav-link{ color: #212529; +} +.fs-7{ + font-size: .9em; } \ No newline at end of file diff --git a/views/alerts.php b/views/alerts.php index 1cc2f105..dfca72fe 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -2,36 +2,71 @@

All Alerts

-
-
- -
- - + + +
+
+
+ +
-
-
-
- - +
+ +
+
+ Showing xx of xxx results. +
From d1e752dc7bc6b706031396d6941baf6ce545fea6 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 23 May 2022 17:26:48 -0500 Subject: [PATCH 34/70] a few more enhancements.. --- views/alerts.php | 69 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/views/alerts.php b/views/alerts.php index dfca72fe..5bef630d 100644 --- a/views/alerts.php +++ b/views/alerts.php @@ -37,23 +37,76 @@
From 66f5e6325ad2c4232fbcb35f2ed94c692386519e Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Fri, 27 May 2022 13:40:09 -0500 Subject: [PATCH 44/70] Pagination now show if no filters are applied. --- models/db.php | 9 ++++++--- models/view_components.php | 25 +++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/models/db.php b/models/db.php index 2177621a..21f41981 100644 --- a/models/db.php +++ b/models/db.php @@ -199,6 +199,7 @@ public static function get_alerts($filters = [], $page = 1){ // Add optional filters to content and total_pages. $filter_count = count($filters); + $filters_sql = ''; if($filter_count > 0){ $filters_sql = ' WHERE '; $filter_iteration = 0; @@ -209,11 +210,13 @@ public static function get_alerts($filters = [], $page = 1){ $filters_sql.= ' AND '; } - $filters_sql.= ' LIMIT '.$page_offset.', '.$alerts_per_page; - $total_pages_sql.= $filters_sql; - $content_sql.= $filters_sql; } + // Add filters and page limit. + $filters_sql.= ' LIMIT '.$page_offset.', '.$alerts_per_page; + $total_pages_sql.= $filters_sql; + $content_sql.= $filters_sql; + // Run 'total_pages' SQL. $total_pages_result = self::query($total_pages_sql, $params, true); $total_pages_rows = $total_pages_result->fetch_array()[0]; diff --git a/models/view_components.php b/models/view_components.php index 0d9243d5..7f3d1f59 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -182,7 +182,7 @@ function the_pagination($total_pages){ $current_page_number = get_current_page_number(); // Defined current view - $current_tab = $_GET['view']; + $current_view = $_GET['view']; // Set active state as function so we don't have to keep // writing this condition. @@ -202,10 +202,10 @@ function get_active_state($current_page_number, $item_number){ @@ -433,8 +433,9 @@ function the_alert_tabs($current_tab_data){ sourceSelect.value = '' alertTabID.value = ''; } -editTabOptionsButton.addEventListener('click', setUpdateTabSaveAction); - +if(editTabOptionsButton){ + editTabOptionsButton.addEventListener('click', setUpdateTabSaveAction); +} Date: Fri, 27 May 2022 14:25:32 -0500 Subject: [PATCH 45/70] Finalize filters. --- models/db.php | 25 ++++++++++++++++++++++--- models/view_components.php | 20 +++++++++----------- views/alerts.php | 12 +++++++----- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/models/db.php b/models/db.php index 21f41981..e202efb3 100644 --- a/models/db.php +++ b/models/db.php @@ -213,9 +213,8 @@ public static function get_alerts($filters = [], $page = 1){ } // Add filters and page limit. - $filters_sql.= ' LIMIT '.$page_offset.', '.$alerts_per_page; $total_pages_sql.= $filters_sql; - $content_sql.= $filters_sql; + $content_sql.= $filters_sql.' LIMIT '.$page_offset.', '.$alerts_per_page; // Run 'total_pages' SQL. $total_pages_result = self::query($total_pages_sql, $params, true); @@ -233,6 +232,7 @@ public static function get_alerts($filters = [], $page = 1){ // Create and return data. $data = [ + 'total_alerts' => $total_pages_rows, 'total_pages' => $total_pages, 'content' => $content ]; @@ -242,13 +242,32 @@ public static function get_alerts($filters = [], $page = 1){ /** * Count Alerts + * @param array filters [ array ('name' => $name, 'value' => $value, 'page' => $page) ] + * @param string page */ - public static function count_alerts(){ + public static function count_alerts($filters = []){ // SQL $sql = 'SELECT COUNT(*) AS TOTAL FROM `alerts`'; $params = array(); + // Add optional filters to content and total_pages. + $filter_count = count($filters); + $filters_sql = ''; + if($filter_count > 0){ + $filters_sql = ' WHERE '; + $filter_iteration = 0; + foreach ($filters as $filter){ + $filters_sql.= '`'.$filter['name'].'` = ?'; + $params[] = $filter['value']; + if(++$filter_iteration != $filter_count) + $filters_sql.= ' AND '; + + } + } + $sql.= $filters_sql; + + // Query $results = self::query($sql, $params, true); diff --git a/models/view_components.php b/models/view_components.php index 7f3d1f59..a5d413dd 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -335,7 +335,7 @@ function the_alert_tabs($current_tab_data){
- + '; tabNameInput.value = ''; - integrationSelect.value = '' - typeSelect.value = '' - sourceSelect.value = '' + integrationSelect.value = ''; + typeSelect.value = ''; + sourceSelect.value = ''; alertTabID.value = ''; } -if(editTabOptionsButton){ - editTabOptionsButton.addEventListener('click', setUpdateTabSaveAction); -} +editTabButton.addEventListener('click', editTabAction); " "> @@ -68,7 +68,8 @@ class="nav-link "
- @@ -107,6 +108,7 @@ class="nav-link " 0 ): foreach($alerts_content as $alert): From d021247884e9f3befe562685b4f1398932ad5a4c Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Fri, 27 May 2022 14:33:07 -0500 Subject: [PATCH 46/70] Add to the insanity of the pagination. --- models/view_components.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/models/view_components.php b/models/view_components.php index a5d413dd..7318faac 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -213,12 +213,12 @@ function get_active_state($current_page_number, $item_number){ // and if there are more than 5 pages and we're not on page 3, // display a disabled elipses so that the user knows to click // 'previous'. - if($current_page_number != 1 && ($total_pages > 3 && $current_page_number != 2) && ($total_pages > 5 && $current_page_number != 3)) + if($current_page_number != 1 && ($total_pages > 3 && $current_page_number != 2) && ($total_pages > 5 && $current_page_number != 3) || ($total_pages == 4 && $current_page_number == 4)) echo '
  • ...
  • '; // If there are more than 5 pages and current page number isn't - // first, second, or last... - if($total_pages > 5 && $current_page_number != 1 && $current_page_number != 2 && $current_page_number != $total_pages) + // first, second, or last or if we're on the third page of 4... + if(($total_pages > 5 && $current_page_number != 1 && $current_page_number != 2 && $current_page_number != $total_pages) || ($total_pages == 4 && $current_page_number == 3)) echo '
  • '.($current_page_number-1).'
  • '; // If there are more than 3 pages and current page number isn't @@ -226,8 +226,8 @@ function get_active_state($current_page_number, $item_number){ if($total_pages > 3 && $current_page_number != 1 && $current_page_number != $total_pages) echo '
  • '.$current_page_number.'
  • '; - // If there are more than 5 pages and current page is the first or second.. - if($total_pages > 5 && ($current_page_number == 1 || $current_page_number == 2)) + // If there are more than 5 pages and current page is the first or second or we're on the second page of fur.. + if(($total_pages > 5 && ($current_page_number == 1 || $current_page_number == 2)) || ($total_pages == 4 && $current_page_number == 2)) echo '
  • '.($current_page_number+1).'
  • '; // If there are more than 5 pages and current page is the last or second to last.. From 11c7e3fd2774a3e2a1d343c894cda56b043e2db5 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Fri, 27 May 2022 15:09:07 -0500 Subject: [PATCH 47/70] Nothing is ever final. --- models/view_components.php | 8 ++++---- views/alerts.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/models/view_components.php b/models/view_components.php index 7318faac..cc91498e 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -262,7 +262,7 @@ function get_active_state($current_page_number, $item_number){ /** * The Alert Tab Options */ -function the_alert_tabs($current_tab_data){ +function the_alert_tab_options($current_tab_data){ // Setup filters array to make it easier to return // filter data. @@ -295,7 +295,7 @@ function the_alert_tabs($current_tab_data){
    -
    From 6da06f7ab536d7e2c819c38214d4a8bf382d9bdc Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Fri, 27 May 2022 17:15:11 -0500 Subject: [PATCH 48/70] Alerts is becoming the "meat and potatoes" --- index.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/index.php b/index.php index de139b04..8ca595e7 100644 --- a/index.php +++ b/index.php @@ -30,21 +30,13 @@
    - + Equalify
    - - - - - - - - - site); - if(count($alerts) > 0 ): - foreach($alerts as $alert): - ?> - - - - - - - - - - - - - - - -
    PageMessageActions
    page_id);?>message;?> - - Dismiss - -
    No alerts found.
    -
    - - - -
    -

    Pages

    - - - - - - - COLUMN_NAME, $excluded_columns )){ - - // Make column name human readable and formatted - // with the various special conditions - $name = $column->COLUMN_NAME; - $name = str_replace('_', ' ', $name); - $name = str_replace('url', 'URL', $name); - $name = str_replace('wcag', 'WCAG', $name); - $name = str_replace('2 1', '2.1', $name); - $name = str_replace('wave', 'WAVE', $name); - $name = ucwords($name); - echo ''; - - } - } - ?> - - - - - - 'site', - 'value' => $page->site - ), - ]; - $site = DataAccess::get_pages($page_filters); - $site_count = count($site); - if($site_count > 0 ): - foreach($site as $page): - echo ''; - - // Again, we need to loop columns so that integrations - // can add columns if they register new DB fields. - foreach ($columns as $column){ - - // Limiting columns again. - $excluded_columns = array('is_parent', 'type', 'id', 'site', 'status'); - if( !in_array($column->COLUMN_NAME, $excluded_columns )){ - - // Make column name human readable. - $text = $column->COLUMN_NAME; - echo ''; - - } -; - } - - // End pages list. - echo ''; - endforeach; - endif; - ?> - - -
    '.$name.'
    '.$page->$text.'
    - - -
    -
    -

    Options

    - - status == 'archived'){ - $button_text = 'Activate Site'; - $button_class = 'btn-outline-success'; - }else{ - $button_text = 'Archive Site and Delete Alerts'; - $button_class = 'btn-outline-danger'; - } - ?> - -
    - - -
    \ No newline at end of file diff --git a/views/sites.php b/views/sites.php index 0a4c064f..01a3d0a8 100644 --- a/views/sites.php +++ b/views/sites.php @@ -39,7 +39,21 @@

    site; ?>

    - View Details + + status == 'archived'){ + $button_text = 'Activate Site'; + $button_class = 'btn-outline-success'; + }else{ + $button_text = 'Archive Site'; + $button_class = 'btn-outline-secondary'; + } + ?> + + + + From 54a4f815d7c227afce3b7c9de049fb6c7e4b05b6 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 6 Jun 2022 12:28:43 -0400 Subject: [PATCH 51/70] Rewrite how the scanner and sites work. --- README.md | 2 +- actions/add_site.php | 81 +---- actions/cue_scan.php | 15 + actions/get_alerts.php | 8 + actions/get_scans.php | 10 + actions/run_scan.php | 271 ++++++++++++++++ actions/scan_all_pages.php | 128 -------- ...page_status.php => toggle_site_status.php} | 11 +- index.php | 2 +- integrations/little_forrest/functions.php | 6 +- integrations/wave/functions.php | 2 +- models/adders.php | 54 +++- models/cron.php | 11 + models/db.php | 294 +++++++++++------- models/hooks.php | 7 +- models/view_components.php | 43 +-- views/alerts.php | 4 +- views/scans.php | 24 +- views/sites.php | 47 ++- 19 files changed, 637 insertions(+), 383 deletions(-) create mode 100644 actions/cue_scan.php create mode 100644 actions/get_alerts.php create mode 100644 actions/get_scans.php create mode 100644 actions/run_scan.php delete mode 100644 actions/scan_all_pages.php rename actions/{toggle_page_status.php => toggle_site_status.php} (70%) create mode 100644 models/cron.php diff --git a/README.md b/README.md index eb6cc8aa..e5c19a82 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ The goal: **Equalify every website.** ## To Start 1. Download or clone [the latest release](https://github.com/bbertucc/equalify/releases). 2. Change `sample-config.php` to `config.php` and update info. -3. Upload/run on your server (PHP 8 + MySQL required). +3. Upload/run on a Linux server (PHP 8 + MySQL required). 4. Report [issues](https://github.com/bbertucc/equalify/issues), questions, and patches. ## Special Thanks diff --git a/actions/add_site.php b/actions/add_site.php index aa2a941e..0b4b2824 100644 --- a/actions/add_site.php +++ b/actions/add_site.php @@ -19,85 +19,20 @@ // Static pages are treated as sites in themselves. if($type == 'single_page' ){ + single_page_adder($site_url); - // The adder cURLs the site to test if the URL can be scanned. - $curled_site = single_page_adder($site_url); +// WordPress sites are added via their API. +}elseif($type == 'wordpress'){ + wordpress_site_adder($site_url); - // Site URL changes to the curled URL. - $site_url = $curled_site['url']; - - // Single pages are saved with the following pramenters - $type = 'single_page'; - $status = 'active'; - $site = $curled_site['url']; - $is_parent = 1; - DataAccess::add_page($site_url, $type, $status, $site, $is_parent ); - -// WordPress and XML deals with adding pages similarly, -// so their functions are wrapped in one condition. -}elseif($type == 'wordpress' || $type == 'xml' ){ - - // WordPress API is queried to create sites. - if($type == 'wordpress' ) - $curled_site = wordpress_site_adder($site_url); - - // .XML adder can create lots of pages. - if($type == 'xml' ) - $curled_site = xml_site_adder($site_url); - - // Both XML and WP deliver similar content. - $pages = $curled_site['contents']; - $site_url = $curled_site['url']; - - // We're setting the status and adding pages here so we - // do not have to call the db inside "models/adders.php", - // keeping each model focused on distinct functions. - $pages_records = []; - foreach ($pages as &$page): - - // Though these variables were set, we must reset them for - // one page, since we have now generated many pages. - if($site_url == $page['url']){ - $is_parent = 1; - - // This will be used later.. - $has_parent = true; - - }else{ - $is_parent = ''; - } - - // Push each page to pages' records. - array_push( - $pages_records, - array( - 'url' => $page['url'], - 'site' => $site_url, - 'is_parent' => $is_parent, - 'status' => 'active', - 'type' => $type - ) - ); - - endforeach; - - // Some newly created record arrays do not have existing sites - // and do not contain a parent because API/XML records contain - // different URLs than the URL where the API/XML exists. In that - // case, the first record, which is often the homepage, becomes - // the parent. - if(!isset($has_parent) && !isset($existing_site)){ - $first_record = &$pages_records[0]; - $first_record['is_parent'] = 1; - } - - // Finalllly, we can add pages to the DB. - DataAccess::add_pages($pages_records); +// .XML sites use the latest version of XML standards. +}elseif($type == 'XML'){ + xml_site_adder($site_url); // Since we're passing type through a URL, we have a fallback // in case someone passes an unsupported 'type'. }else{ - die('"'.$type.'" sites are unsupported.'); + throw new Exception('"'.$type.'" sites are unsupported'); } // Back home we go. diff --git a/actions/cue_scan.php b/actions/cue_scan.php new file mode 100644 index 00000000..5f5b483d --- /dev/null +++ b/actions/cue_scan.php @@ -0,0 +1,15 @@ + $next_scan->time){ + + // Do the next scan. + scan($next_scan->id); + +}else{ + + // This fallback message is for testing purposes. This + // shouldn't be seen because scans are triggered via the + // cron and cron events are only scheduled on times cued. + throw new Exception('No scan scheduled'); + +} + +/** + * Scan + */ +function scan($scan_id){ + + // Change status to 'running'. + DataAccess::update_scan_status($scan_id, 'running'); + + // Setup scanning_process and scanning_page meta here, since integrations + // and the system is going can update the meta value. + $scanning_process_meta_filters = array( + array( + 'name' => 'meta_name', + 'value' => 'scanning_process' + ), + ); + if(empty(DataAccess::get_meta($scanning_process_meta_filters))){ + DataAccess::add_meta('scanning_process'); + } + $scanning_page_meta_filters = array( + array( + 'name' => 'meta_name', + 'value' => 'scanning_page' + ) + ); + if(empty(DataAccess::get_meta($scanning_page_meta_filters))){ + DataAccess::add_meta('scanning_page'); + } + + // We'll start by verifying site urls. + DataAccess::update_meta_value('scanning_process', 'Verify site urls.'); + + // We are only looking at active parents for now because if + // their URLs don't work, their pages wont work. + $filtered_by_active_parents = array( + array( + 'name' => 'is_parent', + 'value' => 1 + ), array( + 'name' => 'status', + 'value' => 'active' + ) + ); + $active_parents = DataAccess::get_pages($filtered_by_active_parents); + if(!empty($active_parents)): + $working_sites = []; + foreach($active_parents as $parent){ + + // Set scanning_page so we can bug check if issues arrise. + DataAccess::update_meta_value('scanning_page', $parent->url); + + // Curl parent to determin if the site exists. + $curl = curl_init($parent->site); + curl_setopt($curl, CURLOPT_URL, $parent->site); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + curl_setopt($curl, CURLOPT_USERAGENT, 'Equalify'); + + // Execute CURL. + $url_contents = curl_exec($curl); + + // Alert folks if site can't be reached. + if($url_contents == false){ + DataAccess::add_alert('system', $parent->id, $parent->site, NULL, 'error', 'Site is unreachable.', NULL); + }else{ + + // Parents that work are saved into a variable we + // use for the next process. + array_push($working_sites, $parent); + + } + + } + endif; + + // Sometimes we're offline or the URLs don't exist, so we need + // to add a condition that skips all the rest of the processes + // in that case. + if(!empty($working_sites)): + + // We need to curl all the working sites to get any new + // pages before we launch into the scan. + DataAccess::update_meta_value('scanning_process', 'Update site pages.'); + foreach ($working_sites as $site){ + + // We need to clear out the scanning_page, since we're not + // currently scanning a page. + DataAccess::update_meta_value('scanning_page', ''); + + // We'll need to delete pages and alerts of a site before + // we re-add the site. + $filtered_by_site = array( + array( + 'name' => 'site', + 'value' => $site->site + ) + ); + DataAccess::delete_pages($filtered_by_site); + DataAccess::delete_alerts($filtered_by_site); + + // Use the adders to generate pages of sites again with + // a fallback if any adder encounters an excemption. + try{ + if($site->type == 'xml'){ + xml_site_adder($site->url); + DataAccess::update_meta_value('scanning_process', 'Adding XML pages.'); + } + if($site->type == 'wordpress'){ + wordpress_site_adder($site->url); + DataAccess::update_meta_value('scanning_process', 'Adding WordPress pages.'); + } + if($site->type == 'single_page'){ + single_page_adder($site->url); + DataAccess::update_meta_value('scanning_process', 'Adding single pages.'); + } + } + catch(Exception $exemption){ + + // Alert every site that cannot be scanned. + DataAccess::add_alert('system', $site->url, $site->parent, NULL, 'error', $exemption->getMessage(), NULL); + DataAccess::update_scan_status($scan_id, 'incomplete'); + die; + + } + + // Now that all the pages are in the system, we can + // create an array of working pages. + $working_urls = []; + $filtered_by_site = array( + array( + 'name' => 'site', + 'value' => $site->site + ) + ); + $pages = DataAccess::get_pages($filtered_by_site); + foreach ($pages as $page){ + + // Now we can log the page url again, since the scanner + // is now directly running on it. + DataAccess::update_meta_value('scanning_page', $page->url); + + // We'll use the $working_urls array later. + array_push($working_urls, $page->url); + + } + + } + + // With our working urls set, we can now run the integrations! + $active_integrations = unserialize(DataAccess::get_meta_value('active_integrations')); + foreach($active_integrations as $integration){ + require_once '../integrations/'.$integration.'/functions.php'; + + // 'scanning_process' keeps track of what integration is running. + DataAccess::update_meta_value('scanning_process', $integration); + + // Run integration scan on every working url. + $pages_count = 0; + foreach ($working_urls as $url){ + $pages_count++; + + // Set scanning_page meta. + DataAccess::update_meta_value('scanning_page', $url); + + // Every integration should use the same pattern to run + // register thier scan functions. + $integration_scan_function_name = $integration.'_scans'; + if(function_exists($integration_scan_function_name)){ + + // We need to kill the scan if there's an error. + try { + $integration_scan_function_name($page); + + } catch (Exception $x) { + + // We will kill the scan and alert folks of any errors, but + // we will also record the successful scans that occured. + $meta_usage_filters = array( + array( + 'name' => 'meta_name', + 'value' => 'usage' + ), + ); + $existing_usage = DataAccess::get_meta($meta_usage_filters); + if(empty($existing_usage)){ + + // This might be the first time we run a scan, so + // we need to create the meta field if none exists. + DataAccess::add_meta('usage', $pages_count); + + }else{ + DataAccess::update_meta_value('usage', $pages_count+$existing_usage); + } + DataAccess::add_alert('system', DataAccess::get_page_id($url), $url, NULL, 'error', $x->getMessage(), NULL); + DataAccess::update_scan_status($scan_id, 'incomplete'); + die; + + } + + } + + // Successfully scanned pages get a timestamp. + DataAccess::update_page_scanned_time($url); + + } + + } + + // We keep track of the amount of pages scanned. + $meta_usage_filters = array( + array( + 'name' => 'meta_name', + 'value' => 'usage' + ) + ); + $existing_usage = DataAccess::get_meta($meta_usage_filters)[0]->meta_value; + if(empty($existing_usage)){ + + // This might be the first time we run a scan, so + // we need to create the meta field if none exists. + DataAccess::add_meta('usage', $pages_count); + + }else{ + DataAccess::update_meta_value('usage', $pages_count+$existing_usage); + } + + // Change status to 'complete'. + DataAccess::update_scan_status($scan_id, 'complete'); + + // End conditions related to working_urls + endif; + + // Change status to 'complete'. + DataAccess::update_scan_status($scan_id, 'complete'); + + // Clear scan process and page after scan is complete. + DataAccess::delete_meta('scanning_process'); + DataAccess::delete_meta('scanning_page'); + +} \ No newline at end of file diff --git a/actions/scan_all_pages.php b/actions/scan_all_pages.php deleted file mode 100644 index 8b6f922c..00000000 --- a/actions/scan_all_pages.php +++ /dev/null @@ -1,128 +0,0 @@ - 'status', - 'value' => 'active' - ), -]; -$active_page_ids = DataAccess::get_page_ids($page_filters); -$active_pages = DataAccess::get_pages($page_filters); -$uploaded_integrations = uploaded_integrations('../integrations'); - -// Make sure there are pages to scan. -if($active_page_ids == NULL) - throw new Exception('You have no active pages to scan'); - -// Adding a scan to display a running task before scans complete. -if( $_GET['action'] == 'add_scan' ){ - DataAccess::add_scan('running', $active_page_ids); - $scans = DataAccess::get_scans(); - the_scan_rows($scans); -} - -// All the scan heavy lifting goes here. -if( $_GET['action'] == 'do_scan' ){ - - // This count helps us know how many pages were scanned. - $pages_count = 0; - - // Get active integrations. - $active_integrations = unserialize(DataAccess::get_meta_value('active_integrations')); - - // We're requring active integrations here and not in - // the next loop because we don't want to require the - // files over and over again. - foreach($uploaded_integrations as $uploaded_integration){ - if ( array_search($uploaded_integration['uri'], $active_integrations) !== false) - require_once '../integrations/'.$uploaded_integration['uri'].'/functions.php'; - } - - // Scan each active page. - foreach ($active_pages as $page){ - $pages_count++; - - // Run active integration scans. - foreach($uploaded_integrations as $uploaded_integration){ - if ( array_search($uploaded_integration['uri'], $active_integrations) !== false){ - - // Fire the '_scans' function. - $integration_scan_function_name = $uploaded_integration['uri'].'_scans'; - if(function_exists($integration_scan_function_name)){ - - // We need to kill the scan if an integration has an error. - try { - $integration_scan_function_name($page); - - } catch (Exception $x) { - - // We will kill the scan and alert folks of any errors, but - // we will also record the successful scans that occured. - $existing_usage = DataAccess::get_meta_value('usage'); - if($existing_usage == false){ - - // This might be the first time we run a scan, so - // we need to create the meta field if none exists. - DataAccess::add_meta('usage', $pages_count); - - }else{ - DataAccess::update_meta_value('usage', $pages_count+$existing_usage); - } - DataAccess::add_integration_alert($x->getMessage()); - DataAccess::update_scan_status('running', 'incomplete'); - $scans = DataAccess::get_scans(); - the_scan_rows($scans); - die; - - } - - } - - } - } - - // Successful scans get a timestamp. - DataAccess::update_page_scanned_time($page->id); - - } - - // We're updating the count at the end of the scan - // because we only want to count succsefully scanned - // pages. - $pages_count = count($active_page_ids); - - // We keep track of the amount of pages scanned. - $existing_usage = DataAccess::get_meta_value('usage'); - if($existing_usage == NULL){ - - // This might be the first time we run a scan, so - // we need to create the meta field if none exists. - DataAccess::add_meta('usage', $pages_count); - - }else{ - DataAccess::update_meta_value('usage', $pages_count+$existing_usage); - } - - // Sacn is complete! - DataAccess::update_scan_status('running', 'complete'); - - // Scan info is passed to JSON on the view, so that we can do - // async scans. - $scans = DataAccess::get_scans(); - the_scan_rows($scans); - -} - -// This changes the little red number asyncronistically with JS -// embedded in the view file. -if( $_GET['action'] == 'get_alerts' ){ - echo count(DataAccess::get_alerts()); -} \ No newline at end of file diff --git a/actions/toggle_page_status.php b/actions/toggle_site_status.php similarity index 70% rename from actions/toggle_page_status.php rename to actions/toggle_site_status.php index 06e303b6..648513fc 100644 --- a/actions/toggle_page_status.php +++ b/actions/toggle_site_status.php @@ -4,15 +4,14 @@ require_once '../models/db.php'; // Get URL variables and fallbacks. -$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); -if(empty($id)) - throw new Exception('ID "'.$id.'" is invalid format.'); +$site = $_GET['site']; +if(empty($site)) + throw new Exception('Site is not specified'); $old_status = $_GET['old_status']; if(empty($old_status)) - throw new Exception('Status is not specfied for page "'.$id.'"'); + throw new Exception('Status is not specfied for "'.$site.'"'); -// Toggle page status. -$site = DataAccess::get_page($id)->site; +// Toggle site status. if($old_status == 'active'){ DataAccess::update_site_status($site, 'archived'); diff --git a/index.php b/index.php index 8ca595e7..a32af0c4 100644 --- a/index.php +++ b/index.php @@ -114,7 +114,7 @@ if(!empty($_GET['view'])){ require_once 'views/'.$_GET['view'].'.php'; }else{ - require_once 'views/alerts.php'; + require_once get_default_view(); } ?> diff --git a/integrations/little_forrest/functions.php b/integrations/little_forrest/functions.php index 77e38943..21ad28e8 100644 --- a/integrations/little_forrest/functions.php +++ b/integrations/little_forrest/functions.php @@ -104,7 +104,7 @@ function little_forrest_scans($page){ } // Add notice. - DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'error', $message, $meta); + DataAccess::add_alert('page', $page->id, $page->site, 'little_forrest', 'error', $message, $meta); } } @@ -128,7 +128,7 @@ function little_forrest_scans($page){ } // Add notice. - DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'notice', $message, $meta); + DataAccess::add_alert('page', $page->id, $page->site, 'little_forrest', 'notice', $message, $meta); } } @@ -152,7 +152,7 @@ function little_forrest_scans($page){ } // Add warning. - DataAccess::add_page_alert($page->id, $page->site,'little_forrest', 'warning', $message, $meta); + DataAccess::add_alert('page', $page->id, $page->site, 'little_forrest', 'warning', $message, $meta); } } diff --git a/integrations/wave/functions.php b/integrations/wave/functions.php index 18328eaf..581d6878 100644 --- a/integrations/wave/functions.php +++ b/integrations/wave/functions.php @@ -97,7 +97,7 @@ function wave_scans($page){ // Set optional alerts. if($wave_errors >= 1) - DataAccess::add_page_alert($page->id, $page->site, 'wave', 'error', 'WCAG 2.1 page errors found! See WAVE report.'); + DataAccess::add_alert('page', $page->id, $page->site, 'wave', 'error', 'WCAG 2.1 page errors found! See WAVE report.'); // Update page data. DataAccess::update_page_data($page->id, 'wave_wcag_2_1_errors', $wave_errors); diff --git a/models/adders.php b/models/adders.php index 4c9aa00c..3372d8c4 100644 --- a/models/adders.php +++ b/models/adders.php @@ -58,7 +58,16 @@ function single_page_adder($site_url){ // Get URL contents so we can make sure URL // can be scanned. - return run_curl($site_url); + $curled_site = run_curl($site_url); + + // Site URL changes to the curled URL. + $site_url = $curled_site['url']; + + // Single pages are saved with the following pramenters + $type = 'single_page'; + $status = 'active'; + $site = $curled_site['url']; + DataAccess::add_page($site_url, $type, $status, $site); } @@ -90,11 +99,14 @@ function wordpress_site_adder($site_url){ // Reformat the curled contents to be an array we can // work with. - return array( + $curled_site = array( 'url' => $clean_curled_url, 'contents' => $pages ); + // Insert site in DB. + add_xml_or_wordpress_site_to_db($curled_site, 'wordpress'); + } /** @@ -123,9 +135,45 @@ function xml_site_adder($site_url){ // Reformat the curled contents to be an array we can // work with. - return array( + $curled_site = array( 'url' => $curled_site['url'], 'contents' => $pages ); + + // Insert site in DB. + add_xml_or_wordpress_site_to_db($curled_site, 'xml'); +} + +/** + * Add XML or WordPress Site to DB + */ +function add_xml_or_wordpress_site_to_db($curled_site, $type){ + + // Both XML and WP deliver similar content. + $pages = $curled_site['contents']; + $site_url = $curled_site['url']; + + // We're setting the status and adding pages here so we + // do not have to call the db inside "models/adders.php", + // keeping each model focused on distinct functions. + $pages_records = []; + foreach ($pages as &$page): + + // Push each page to pages' records. + array_push( + $pages_records, + array( + 'url' => $page['url'], + 'site' => $site_url, + 'status' => 'active', + 'type' => $type + ) + ); + + endforeach; + + // Finalllly, we can add pages to the DB. + DataAccess::add_pages($pages_records); + } \ No newline at end of file diff --git a/models/cron.php b/models/cron.php new file mode 100644 index 00000000..0ddc3710 --- /dev/null +++ b/models/cron.php @@ -0,0 +1,11 @@ +num_rows > 0){ + while($row = $results->fetch_object()){ + $data[] = $row; + } + } + return $data; + + } /** * Get Scans @@ -179,6 +202,34 @@ public static function get_scans($filters = []){ return $data; } + /** + * Get Next Scan + */ + public static function get_next_scan(){ + + // SQL + $sql = 'SELECT * FROM `scans` WHERE status = "cued" ORDER BY `time` ASC LIMIT 1'; + $params = array(); + + // Query + $results = self::query($sql, $params, false); + + // Results + $data = $results->fetch_object(); + if($data == NULL || empty($data)){ + + // Returns "false" if no data exists. + throw new Exception('No cued scans found'); + + }else{ + + // Returns meta_value. + return $data; + + } + + } + /** * Get Alerts * @param array filters [ array ('name' => $name, 'value' => $value, 'page' => $page) ] @@ -302,6 +353,45 @@ public static function get_alerts_by_site($site){ $results->close(); } + + /** + * Get Meta + * @param array filters [ array ('name' => $name, 'value' => $value) ] + */ + public static function get_meta($filters = []){ + + // SQL + $sql = 'SELECT * FROM `meta`'; + $params = array(); + + // Add optional filters + $filter_count = count($filters); + if($filter_count > 0){ + $sql.= ' WHERE '; + + $filter_iteration = 0; + foreach ($filters as $filter){ + $sql.= '`'.$filter['name'].'` = ?'; + $params[] = $filter['value']; + if(++$filter_iteration != $filter_count) + $sql.= ' AND '; + + } + } + $sql.= ';'; + + // Query + $results = self::query($sql, $params, true); + + // Result + $data = []; + if($results->num_rows > 0){ + while($row = $results->fetch_object()){ + $data[] = $row; + } + } + return $data; + } /** * Get Meta Value @@ -386,13 +476,12 @@ public static function get_page_url($id){ } /** - * Get Site Parent Status - * Parent sets the site status. + * Get Site Status */ - public static function get_site_parent_status($site){ + public static function get_site_status($site){ // SQL - $sql = 'SELECT `status` FROM `pages` WHERE `site` = ? AND `is_parent` = 1'; + $sql = 'SELECT `status` FROM `pages` WHERE `site` = ?'; $params = array($site); // Query @@ -403,6 +492,24 @@ public static function get_site_parent_status($site){ return $data; } + + /** + * Get Site Type + */ + public static function get_site_type($site){ + + // SQL + $sql = 'SELECT `type` FROM `pages` WHERE `site` = ?'; + $params = array($site); + + // Query + $results = self::query($sql, $params, true); + + // Result + $data = $results->fetch_object()->type; + return $data; + + } /** * Get Column Names @@ -456,27 +563,19 @@ public static function is_unique_site($site_url){ /** * Add Page */ - public static function add_page($url, $type, $status, $site, $is_parent){ + public static function add_page($url, $type, $status, $site){ // SQL - $sql = 'INSERT INTO `pages` (`url`, `type`, `status`, `is_parent`, `site`) VALUES'; - $sql.= '(?, ?, ?,'; - $params = array($url, $type, $status); - if(empty($is_parent)){ - $sql.= 'NULL,'; - }else{ - $sql.= '?,'; - $params[] = $is_parent; - } - $sql.= '?)'; - $params[] = $site; + $sql = 'INSERT INTO `pages` (`url`, `type`, `status`, `site`) VALUES'; + $sql.= '(?, ?, ?, ?)'; + $params = array($url, $type, $status, $site); // Query $result = self::query($sql, $params, false); //Fallback if(!$result) - throw new Exception('Cannot insert page with values "'.$url.',"'.$url.',"'.$type.',"'.$status.',"'.$site.',"'.$is_parent.'"'); + throw new Exception('Cannot insert page with values "'.$url.',"'.$url.',"'.$type.',"'.$status.',"'.$site.'"'); // Complete Query return $result; @@ -485,22 +584,19 @@ public static function add_page($url, $type, $status, $site, $is_parent){ /** * Add Scan */ - public static function add_scan($status, array $pages){ - - // Serialize pages. - $pages = serialize($pages); + public static function add_scan($status, $time){ // SQL - $sql = 'INSERT INTO `scans` (`status`, `pages`) VALUES'; + $sql = 'INSERT INTO `scans` (`status`, `time`) VALUES'; $sql.= '(?, ?)'; - $params = array($status, $pages); + $params = array($status, $time); // Query $result = self::query($sql, $params, false); //Fallback if(!$result) - throw new Exception('Cannot insert scan with status "'.$status.'" and records "'.$records.'"'); + throw new Exception('Cannot insert scan with status "'.$status.'" and time "'.$time.'"'); // Complete Query return $result; @@ -513,7 +609,7 @@ public static function add_scan($status, array $pages){ public static function add_pages($pages_records){ // SQL - $sql = 'INSERT INTO `pages` (`site`, `url`, `status`, `is_parent`, `type`) VALUES'; + $sql = 'INSERT INTO `pages` (`site`, `url`, `status`, `type`) VALUES'; // Insert Each Record $record_count = count($pages_records); @@ -522,17 +618,10 @@ public static function add_pages($pages_records){ foreach ($pages_records as $record){ // SQL - $sql.= "(?, ?, ?,"; + $sql.= "(?, ?, ?, ?)"; $params[] = $record['site']; $params[] = $record['url']; $params[] = $record['status']; - if(empty($record['is_parent'])){ - $sql.= 'NULL,'; - }else{ - $sql.= '?,'; - $params[] = $record['is_parent']; - } - $sql.= '?)'; $params[] = $record['type']; if(++$record_iteration != $record_count) @@ -549,39 +638,76 @@ public static function add_pages($pages_records){ throw new Exception('Cannot insert page records "'.$pages_records.'"'); } + + /** + * Delete Pages + * @param array filters [ array ('name' => $name, 'value' => $value) ] + */ + public static function delete_pages($filters = []){ + + // SQL + $sql = 'DELETE FROM `pages`'; + $params = array(); + + // Add optional filters + $filter_count = count($filters); + if($filter_count > 0){ + $sql.= 'WHERE '; + + $filter_iteration = 0; + foreach ($filters as $filter){ + $sql.= '`'.$filter['name'].'` = ?'; + $params[] = $filter['value']; + if(++$filter_iteration != $filter_count) + $sql.= ' AND '; + + } + } + $sql.= ';'; + + // Query + $result = self::query($sql, $params, false); + + // Result + if(!$result) + throw new Exception('Cannot delete alert using filters "'.$filters.'"'); + + } /** * Update Status */ - public static function update_scan_status($old_status, $new_status){ + public static function update_scan_status($scan_id, $new_status){ // SQL - $sql = 'UPDATE `scans` SET `status` = ? WHERE `status` = ?'; - $params = array($new_status, $old_status); + $sql = 'UPDATE `scans` SET `status` = ? WHERE `id` = ?'; + $params = array($new_status, $scan_id); // Query $result = self::query($sql, $params, false); // Result if(!$result) - throw new Exception('Cannot update scan status where old status is "'.$old_status.'" and new status is "'.$new_status.'"'); + throw new Exception('Cannot update scan id "'.$scan_id.'" to new status "'.$new_status.'"'); + } /** * Update Page Scanned Time */ - public static function update_page_scanned_time($id){ + public static function update_page_scanned_time($url){ // SQL - $sql = 'UPDATE `pages` SET `scanned` = CURRENT_TIMESTAMP() WHERE `id` = ?'; - $params = array($id); + $sql = 'UPDATE `pages` SET `scanned` = CURRENT_TIMESTAMP() WHERE `url` = ?'; + $params = array($url); // Query $result = self::query($sql, $params, false); // Result if(!$result) - throw new Exception('Cannot update scan time for scan with id "'.$id.'"'); + throw new Exception('Cannot update scan time for scan with url "'.$url.'"'); + } /** @@ -619,39 +745,6 @@ public static function update_page_data($id, $column, $value){ } - /** - * The Page Badge - */ - public static function get_page_badge($page){ - - // Badge info - if($page->status == 'archived'){ - $badge_status = 'bg-dark'; - $badge_content = 'Archived'; - }elseif($page->scanned == NULL){ - $badge_status = 'bg-warning text-dark'; - $badge_content = 'Unscanned'; - }else{ - - // Alerts - $alert_count = count(self::get_alerts_by_site($page->site)); - if($alert_count == 0){ - $badge_status = 'bg-success'; - $badge_content = 'Equalified'; - }else{ - $badge_status = 'bg-danger'; - if($alert_count == 1){ - $badge_content = $alert_count.' Alert'; - }else{ - $badge_content = $alert_count.' Alerts'; - } - }; - - } - return ''.$badge_content.''; - - } - /** * Add DB Column */ @@ -748,52 +841,37 @@ public static function delete_alerts($filters = []){ } /** - * Add Page Alert + * Add Alert */ - public static function add_page_alert($page_id, $site, $integration_uri, $type, $message, $meta = []){ + public static function add_alert($source, $page_id, $site, $integration_uri = NULL, $type = 'error', $message = NULL, $meta = NULL){ // Sanitize items. $message = filter_var($message, FILTER_SANITIZE_STRING); - $meta = filter_var(serialize($meta), FILTER_SANITIZE_STRING); + if(is_array($meta)){ + $meta = filter_var(serialize($meta), FILTER_SANITIZE_STRING); + } // Require certain alert types. $allowed_types = array('error', 'warning', 'notice'); if(!in_array($type, $allowed_types)) throw new Exception('Alert type, "'.$type.'," is not allowed'); + // Require certain alert sources. + $allowed_sources = array('system', 'page'); + if(!in_array($source, $allowed_sources)) + throw new Exception('Alert source, "'.$source.'," is not allowed'); + // SQL $sql = 'INSERT INTO `alerts` (`source`, `page_id`, `site`, `integration_uri`, `type`, `message`, `meta`) VALUES'; $sql.= '(?, ?, ?, ?, ?, ?, ?)'; - $params = array('page', $page_id, $site, $integration_uri, $type, $message, $meta); + $params = array($source, $page_id, $site, $integration_uri, $type, $message, $meta); // Query $result = self::query($sql, $params, false); // Fallback if(!$result) - throw new Exception('Cannot insert integration alert for "'.$page_id.'", "'.$site.'", "'.$integration_uri.'", "'.$type.'", "'.$message.'"'); - - // Complete Query - return $result; - - } - - /** - * Add Integration Alert - */ - public static function add_integration_alert($message){ - - // SQL - $sql = 'INSERT INTO `alerts` (`source`, `message`) VALUES'; - $sql.= '(?, ?)'; - $params = array('integration', $message); - - // Query - $result = self::query($sql, $params, false); - - // Fallback - if(!$result) - throw new Exception('Cannot insert alert "'.$message.'"'); + throw new Exception('Cannot insert alert with the variables "'.$page_id.'", "'.$site.'", "'.$integration_uri.'", "'.$type.'", "'.$message.'", and "'.$meta.'"'); // Complete Query return $result; @@ -803,10 +881,12 @@ public static function add_integration_alert($message){ /** * Add Meta */ - public static function add_meta($meta_name, $meta_value = ''){ + public static function add_meta($meta_name, $meta_value = NULL){ // Serialize meta_value. - $meta_value = serialize($meta_value); + if(is_array($meta_value)){ + $meta_value = serialize($meta_value); + } // SQL $sql = 'INSERT INTO `meta` (`meta_name`, `meta_value`) VALUES (?, ?)'; @@ -935,7 +1015,6 @@ public static function create_pages_table(){ `type` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT "static", `status` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT "active", `site` text COLLATE utf8mb4_bin, - `is_parent` tinyint(1) DEFAULT NULL, `scanned` timestamp NULL DEFAULT NULL, `little_forrest_wcag_2_1_errors` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT "0", -- Little Forrest is activated here. PRIMARY KEY (`id`) @@ -960,11 +1039,10 @@ public static function create_scans_table(){ $sql = 'CREATE TABLE `scans` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `pages` blob, - `status` varchar(20) DEFAULT NULL, + `time` timestamp NULL DEFAULT NULL, + `status` varchar(20) NOT NULL, PRIMARY KEY (`id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;'; + ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;'; $params = array(); // Query diff --git a/models/hooks.php b/models/hooks.php index f80477f9..18aa16dc 100644 --- a/models/hooks.php +++ b/models/hooks.php @@ -58,6 +58,11 @@ public function run_hook(string $hook): void { // Set initial actions for hooks. $hook_system->add_action( new Action('before_content', function() { - // This hook has no action...for now. + + // We trigger scans every time content is loaded to + // avoid the bloat and configuration requirements + // of server crons. NOTE: This is why Linux is + // required. + }) ); \ No newline at end of file diff --git a/models/view_components.php b/models/view_components.php index cc91498e..f2ac9d87 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -1,4 +1,15 @@ ' - .$page_type. - ' Page Type'; - -} - /** * The Integration Status Badge */ @@ -110,15 +106,6 @@ function the_scan_rows($scans){ time;?> status);?> - - - pages); - echo count($page_ids); - ?> - - - No scans found. + No scans found. " Time Source + Site Type Message Actions @@ -117,6 +118,7 @@ class="nav-link " time;?> source);?> + site;?> type);?> message);?> @@ -132,7 +134,7 @@ class="nav-link " ?> - No alerts found. + No alerts found. All Scans
    - + + \ No newline at end of file diff --git a/models/adders.php b/models/adders.php index 3372d8c4..5ac5e940 100644 --- a/models/adders.php +++ b/models/adders.php @@ -23,10 +23,6 @@ function run_curl($site_url, $type = ''){ // Execute CURL $url_contents = curl_exec($curl); - // Add in DB info so we can see if URL is unique. - require_once '../config.php'; - require_once 'db.php'; - // The curled URL is the URL we use as an ID. $curled_url = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); diff --git a/models/db.php b/models/db.php index 9c0e2674..3351aba6 100644 --- a/models/db.php +++ b/models/db.php @@ -188,7 +188,7 @@ public static function get_next_scan(){ if($data == NULL || empty($data)){ // Returns "false" if no data exists. - throw new Exception('No cued scans found'); + return NULL; }else{ diff --git a/views/scans.php b/views/scans.php index 4b08806a..c5073816 100644 --- a/views/scans.php +++ b/views/scans.php @@ -4,62 +4,8 @@

    All Scans

    - -
    From a0e7aa4c817883b957125e31f76daf1b77660ec0 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 8 Jun 2022 14:20:07 -0400 Subject: [PATCH 57/70] Setup kinda janky automated scan --- actions/cue_scan.php | 7 +-- index.php | 136 ++++++++++++++++++++++++++----------------- models/db.php | 3 +- script-old.js | 62 ++++++++++++++++++++ script.js | 105 +++++++++++++++++++++++++++++++++ 5 files changed, 253 insertions(+), 60 deletions(-) create mode 100644 script-old.js create mode 100644 script.js diff --git a/actions/cue_scan.php b/actions/cue_scan.php index 93eadc0d..68347fdf 100644 --- a/actions/cue_scan.php +++ b/actions/cue_scan.php @@ -1,9 +1,8 @@ - - async function refreshAlerts(data) { - if (document.getElementById('alert_count')) - document.getElementById('alert_count').innerHTML = data; - } + + \ No newline at end of file diff --git a/models/db.php b/models/db.php index 3351aba6..54b1767e 100644 --- a/models/db.php +++ b/models/db.php @@ -141,12 +141,13 @@ public static function get_scans($filters = []){ // SQL $sql = 'SELECT * FROM `scans`'; $params = array(); + + // Add optional filters $filter_count = count($filters); if($filter_count > 0){ $sql.= ' WHERE '; - $filter_iteration = 0; foreach ($filters as $filter){ $sql.= '`'.$filter['name'].'` = ?'; diff --git a/script-old.js b/script-old.js new file mode 100644 index 00000000..f37296c8 --- /dev/null +++ b/script-old.js @@ -0,0 +1,62 @@ +// Instead of using cron, we asycronistically run the scan +async function runScan() { + const response = await fetch('actions/run_scan.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); +} + +async function getScans() { + const response = await fetch('actions/get_scans.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); + return response.text(); +} + +async function getAlerts() { + const response = await fetch('actions/get_alerts.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); + return response.text(); +} + +async function refreshAlerts(data) { + if (document.getElementById('alert_count')) + document.getElementById('alert_count').innerHTML = data; +} + +async function refreshScans(data) { + + document.getElementById('the_scans_rows').innerHTML = data; + +} + +const handleCuedScans = () => { + + runScan(); + + + timer = setInterval(function() { + getScans() + .then(refreshScans) + .then(getAlerts) + .then(refreshAlerts); + }, 3000); + +} + +window.onload = function(){ + handleCuedScans(); +}; + diff --git a/script.js b/script.js new file mode 100644 index 00000000..26bfd7e0 --- /dev/null +++ b/script.js @@ -0,0 +1,105 @@ +async function getScans() { + console.log('getScans'); + const response = await fetch('actions/get_scans.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); + return response.text(); + +} + +async function getAlerts() { + console.log('getAlerts'); + + const response = await fetch('actions/get_alerts.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); + return response.text(); +} + +async function runScan() { + console.log('runScan'); + + const response = await fetch('actions/run_scan.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); +} + +async function handleScans(data){ + console.log('handleScans'); + + theScanRows = document.getElementById('the_scans_rows'); + + if(!data.includes('Running') && !data.includes('Cued') && theScanRows){ + console.log('not running and not cued and scan rows'); + + theScanRows.innerHTML = data; + + } + + if(data.includes('Running') && theScanRows){ + console.log('running and scan rows'); + + setTimeout(function(){ + handlePromises(); + theScanRows.innerHTML = data; + }, 1000); + + } + + if(!data.includes('Running') && data.includes('Cued')){ + console.log('not running and cued'); + + runScan(). + then(handlePromises); + + } + + if(!data.includes('Running') && data.includes('Cued') && theScanRows ){ + console.log('not running and cued and scan rows'); + + setTimeout(function(){ + handlePromises(); + theScanRows.innerHTML = data; + }, 1000); + + } + +} + +async function handleAlerts(data) { + console.log('handleAlerts'); + + alertCount = document.getElementById('alert_count'); + + if (alertCount) + alertCount.innerHTML = data; +} + +const handlePromises = () => { + console.log('handlePromises'); + + getScans() + .then(handleScans) + .then(getAlerts) + .then(handleAlerts) + +} + +window.onload = function(){ + console.log('window'); + + handlePromises(); + +} \ No newline at end of file From 604e067e9f1ab17f111997edbd0e26ff1cfca2c6 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 9 Jun 2022 13:48:07 -0400 Subject: [PATCH 58/70] Code clean. --- script.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/script.js b/script.js index 26bfd7e0..49f4d831 100644 --- a/script.js +++ b/script.js @@ -1,5 +1,5 @@ async function getScans() { - console.log('getScans'); + console.log('3. getScans'); const response = await fetch('actions/get_scans.php', { method: 'GET', cache: 'no-cache', @@ -12,7 +12,7 @@ async function getScans() { } async function getAlerts() { - console.log('getAlerts'); + console.log('6. getAlerts'); const response = await fetch('actions/get_alerts.php', { method: 'GET', @@ -25,7 +25,7 @@ async function getAlerts() { } async function runScan() { - console.log('runScan'); + console.log('5b. runScan'); const response = await fetch('actions/run_scan.php', { method: 'GET', @@ -37,29 +37,29 @@ async function runScan() { } async function handleScans(data){ - console.log('handleScans'); + console.log('4. handleScans'); theScanRows = document.getElementById('the_scans_rows'); if(!data.includes('Running') && !data.includes('Cued') && theScanRows){ - console.log('not running and not cued and scan rows'); + console.log('5. not running and not cued and scan rows'); theScanRows.innerHTML = data; } if(data.includes('Running') && theScanRows){ - console.log('running and scan rows'); - setTimeout(function(){ + console.log('5. running and scan rows'); + handlePromises(); theScanRows.innerHTML = data; - }, 1000); + }, 5000); } if(!data.includes('Running') && data.includes('Cued')){ - console.log('not running and cued'); + console.log('5. not running and cued'); runScan(). then(handlePromises); @@ -67,19 +67,20 @@ async function handleScans(data){ } if(!data.includes('Running') && data.includes('Cued') && theScanRows ){ - console.log('not running and cued and scan rows'); setTimeout(function(){ + console.log('5. not running and cued and scan rows'); + handlePromises(); theScanRows.innerHTML = data; - }, 1000); + }, 5000); } } async function handleAlerts(data) { - console.log('handleAlerts'); + console.log('7. handleAlerts'); alertCount = document.getElementById('alert_count'); @@ -88,7 +89,7 @@ async function handleAlerts(data) { } const handlePromises = () => { - console.log('handlePromises'); + console.log('2. handlePromises'); getScans() .then(handleScans) @@ -98,7 +99,7 @@ const handlePromises = () => { } window.onload = function(){ - console.log('window'); + console.log('1. window'); handlePromises(); From 06149c8a5419cbe1b76910803df839efe637eca9 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 9 Jun 2022 13:48:36 -0400 Subject: [PATCH 59/70] Goodbye old stuff. --- script-old.js | 62 --------------------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 script-old.js diff --git a/script-old.js b/script-old.js deleted file mode 100644 index f37296c8..00000000 --- a/script-old.js +++ /dev/null @@ -1,62 +0,0 @@ -// Instead of using cron, we asycronistically run the scan -async function runScan() { - const response = await fetch('actions/run_scan.php', { - method: 'GET', - cache: 'no-cache', - headers: { - 'Content-Type': 'text/html' - } - }); -} - -async function getScans() { - const response = await fetch('actions/get_scans.php', { - method: 'GET', - cache: 'no-cache', - headers: { - 'Content-Type': 'text/html' - } - }); - return response.text(); -} - -async function getAlerts() { - const response = await fetch('actions/get_alerts.php', { - method: 'GET', - cache: 'no-cache', - headers: { - 'Content-Type': 'text/html' - } - }); - return response.text(); -} - -async function refreshAlerts(data) { - if (document.getElementById('alert_count')) - document.getElementById('alert_count').innerHTML = data; -} - -async function refreshScans(data) { - - document.getElementById('the_scans_rows').innerHTML = data; - -} - -const handleCuedScans = () => { - - runScan(); - - - timer = setInterval(function() { - getScans() - .then(refreshScans) - .then(getAlerts) - .then(refreshAlerts); - }, 3000); - -} - -window.onload = function(){ - handleCuedScans(); -}; - From 9c320bc70dd62b85f04fe754be7fce6df9b7aeaa Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 9 Jun 2022 13:59:13 -0400 Subject: [PATCH 60/70] Do not disable integrations in use by alert tabs. --- actions/toggle_integration_status.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/actions/toggle_integration_status.php b/actions/toggle_integration_status.php index 2683f20a..04606094 100644 --- a/actions/toggle_integration_status.php +++ b/actions/toggle_integration_status.php @@ -15,6 +15,12 @@ // Conditional operations based on status: if($old_status == 'Active'){ + // If integration is active on any alert tab, users + // must keep the interagration active. + $alert_tabs = DataAccess::get_meta_value('alert_tabs'); + if(str_contains($alert_tabs, $integration_uri)) + throw new Exception($integration_uri.' is used by an alert tab and this is not allowed'); + // Remove integration-related alerts. $alerts_filter = [ array( From d44b57076ea6c61e7d09bd458a2aed68eb0c4674 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 9 Jun 2022 14:02:38 -0400 Subject: [PATCH 61/70] Remove unused db queries. --- actions/run_scan.php | 49 -------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/actions/run_scan.php b/actions/run_scan.php index 0665dc7c..e79edce0 100644 --- a/actions/run_scan.php +++ b/actions/run_scan.php @@ -35,30 +35,6 @@ function scan($scan_id){ // Change status to 'running'. DataAccess::update_scan_status($scan_id, 'running'); - // Setup scanning_process and scanning_page meta here, since integrations - // and the system is going can update the meta value. - $scanning_process_meta_filters = array( - array( - 'name' => 'meta_name', - 'value' => 'scanning_process' - ), - ); - if(empty(DataAccess::get_meta($scanning_process_meta_filters))){ - DataAccess::add_meta('scanning_process'); - } - $scanning_page_meta_filters = array( - array( - 'name' => 'meta_name', - 'value' => 'scanning_page' - ) - ); - if(empty(DataAccess::get_meta($scanning_page_meta_filters))){ - DataAccess::add_meta('scanning_page'); - } - - // We'll start by verifying site urls. - DataAccess::update_meta_value('scanning_process', 'Verify site urls.'); - // We are only looking at active parents for now because if // their URLs don't work, their pages wont work. $filtered_to_active_sites = array( @@ -72,9 +48,6 @@ function scan($scan_id){ $working_sites = []; foreach($active_sites as $site){ - // Set scanning_page so we can bug check if issues arrise. - DataAccess::update_meta_value('scanning_page', $site); - // Curl parent to determin if the site exists. $curl = curl_init($site); curl_setopt($curl, CURLOPT_URL, $site); @@ -114,13 +87,8 @@ function scan($scan_id){ // We need to curl all the working sites to get any new // pages before we launch into the scan. - DataAccess::update_meta_value('scanning_process', 'Update site pages.'); foreach ($working_sites as $site){ - // We need to clear out the scanning_page, since we're not - // currently scanning a page. - DataAccess::update_meta_value('scanning_page', ''); - // Set type before we delete all the pages. $type = DataAccess::get_site_type($site); @@ -146,15 +114,12 @@ function scan($scan_id){ try{ if($type == 'xml'){ xml_site_adder($site); - DataAccess::update_meta_value('scanning_process', 'Adding XML pages.'); } if($type == 'wordpress'){ wordpress_site_adder($site); - DataAccess::update_meta_value('scanning_process', 'Adding WordPress pages.'); } if($type == 'single_page'){ single_page_adder($site); - DataAccess::update_meta_value('scanning_process', 'Adding single pages.'); } } catch(Exception $exemption){ @@ -177,10 +142,6 @@ function scan($scan_id){ $pages = DataAccess::get_pages($filtered_by_site); foreach ($pages as $page){ - // Now we can log the page url again, since the scanner - // is now directly running on it. - DataAccess::update_meta_value('scanning_page', $page->url); - // We'll use the $working_urls array later. array_push($working_urls, $page->url); @@ -197,16 +158,10 @@ function scan($scan_id){ foreach($active_integrations as $integration){ require_once '../integrations/'.$integration.'/functions.php'; - // 'scanning_process' keeps track of what integration is running. - DataAccess::update_meta_value('scanning_process', $integration); - // Run integration scan on every working url. foreach ($working_urls as $url){ $pages_count++; - // Set scanning_page meta. - DataAccess::update_meta_value('scanning_page', $url); - // Every integration should use the same pattern to run // register thier scan functions. $integration_scan_function_name = $integration.'_scans'; @@ -278,8 +233,4 @@ function scan($scan_id){ // Change status to 'complete'. DataAccess::update_scan_status($scan_id, 'complete'); - // Clear scan process and page after scan is complete. - DataAccess::delete_meta('scanning_process'); - DataAccess::delete_meta('scanning_page'); - } \ No newline at end of file From 51f9e82516a343da02990b711ea5d348c80156d5 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Thu, 9 Jun 2022 15:21:36 -0400 Subject: [PATCH 62/70] Dismiss status message --- actions/delete_alert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/delete_alert.php b/actions/delete_alert.php index 9df2e60e..dbb32e87 100644 --- a/actions/delete_alert.php +++ b/actions/delete_alert.php @@ -16,4 +16,4 @@ DataAccess::delete_alerts($filters); // When the work is done, we can triumphantly go back. -header('Location: ../index.php?view=alerts&status=success'); \ No newline at end of file +header('Location: ../index.php?view=alerts'); \ No newline at end of file From deb1085d499b2f5caa3eec41a6375fea1572c639 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Fri, 10 Jun 2022 12:36:07 -0400 Subject: [PATCH 63/70] Add License to resolve #39 --- index.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/index.php b/index.php index d19002f4..824dfbab 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,29 @@ . + */ + // Add dependencies. require_once 'models/hooks.php'; require_once 'config.php'; From 2407fd43e756614f173dfc84b9097c75c84e11e2 Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Mon, 13 Jun 2022 10:54:31 -0400 Subject: [PATCH 64/70] English is dumb. --- actions/{cue_scan.php => queue_scan.php} | 6 +++--- index.php | 6 +++--- models/db.php | 2 +- script.js | 12 ++++++------ views/scans.php | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename actions/{cue_scan.php => queue_scan.php} (72%) diff --git a/actions/cue_scan.php b/actions/queue_scan.php similarity index 72% rename from actions/cue_scan.php rename to actions/queue_scan.php index 68347fdf..58e44acb 100644 --- a/actions/cue_scan.php +++ b/actions/queue_scan.php @@ -4,10 +4,10 @@ require_once '../models/db.php'; require_once '../models/cron.php'; -// Add scan to cue. +// Add scan to queue. $time = date('Y-m-d H:i:s'); -DataAccess::add_scan('cued', $time); +DataAccess::add_scan('queued', $time); // Return to scan page without 'success' because -// cueing a scan is feedback enough. +// queuing a scan is feedback enough. header('Location: ../index.php?view=scans'); \ No newline at end of file diff --git a/index.php b/index.php index 824dfbab..c4544082 100644 --- a/index.php +++ b/index.php @@ -198,13 +198,13 @@ // } - // const handleCuedScans = () => { + // const handleQueuedScans = () => { // runScan(); // All Scans From 271c9304b46ed1ac4ea90612ceef79f7512e2943 Mon Sep 17 00:00:00 2001 From: Ezra Bertuccelli Date: Mon, 13 Jun 2022 10:29:25 -0700 Subject: [PATCH 65/70] Fix da good shit now. --- actions/run_scan.php | 2 +- models/db.php | 17 +++++++++++------ script.js | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/actions/run_scan.php b/actions/run_scan.php index e79edce0..af071e67 100644 --- a/actions/run_scan.php +++ b/actions/run_scan.php @@ -214,7 +214,7 @@ function scan($scan_id){ ) ); $existing_usage = DataAccess::get_meta($meta_usage_filters)[0]->meta_value; - if(empty($existing_usage)){ + if(empty($existing_usage) && ($existing_usage !== '0')){ // This might be the first time we run a scan, so // we need to create the meta field if none exists. diff --git a/models/db.php b/models/db.php index c0a7d8b2..762d1922 100644 --- a/models/db.php +++ b/models/db.php @@ -1,6 +1,5 @@ num_rows === 1){ return true; }else{ return false; diff --git a/script.js b/script.js index 9303c2f4..99e99a0f 100644 --- a/script.js +++ b/script.js @@ -27,7 +27,7 @@ async function getAlerts() { async function runScan() { console.log('5b. runScan'); - const response = await fetch('actions/run_scan.php', { + const response = await fetch('actions/run_scan.php', { // NOTE: method: 'GET', cache: 'no-cache', headers: { @@ -50,7 +50,7 @@ async function handleScans(data){ if(data.includes('Running') && theScanRows){ setTimeout(function(){ - console.log('5. running and scan rows'); + console.log('5. running and scan rows'); // NOTE: handlePromises(); theScanRows.innerHTML = data; From 656c19159057805b4ef597750d2bf483a811fb2b Mon Sep 17 00:00:00 2001 From: Ezra Bertuccelli Date: Tue, 14 Jun 2022 19:42:20 -0700 Subject: [PATCH 66/70] script.js refactoring + text jitter fix --- script.js | 97 +++++++++++++++++++------------------------------------ 1 file changed, 34 insertions(+), 63 deletions(-) diff --git a/script.js b/script.js index 99e99a0f..f2a5c3be 100644 --- a/script.js +++ b/script.js @@ -1,5 +1,6 @@ async function getScans() { console.log('3. getScans'); + const response = await fetch('actions/get_scans.php', { method: 'GET', cache: 'no-cache', @@ -7,8 +8,36 @@ async function getScans() { 'Content-Type': 'text/html' } }); + return response.text(); +} + +async function handleScans(data){ + console.log('4. handleScans'); + let theScanRows = document.getElementById('the_scans_rows'); + + if (theScanRows) { + theScanRows.innerHTML = data; + } + + const isQueued = data.includes('Queued'); + const isRunning = data.includes('Running'); + + // don't start a new scan if one is already running + if (isQueued && !isRunning) { + console.log('5a. is not running, is queued'); + console.log('5b. runScan'); + + // don't care about the response; just trigger the scan + fetch('actions/run_scan.php', { + method: 'GET', + cache: 'no-cache', + headers: { + 'Content-Type': 'text/html' + } + }); + } } async function getAlerts() { @@ -24,68 +53,14 @@ async function getAlerts() { return response.text(); } -async function runScan() { - console.log('5b. runScan'); - - const response = await fetch('actions/run_scan.php', { // NOTE: - method: 'GET', - cache: 'no-cache', - headers: { - 'Content-Type': 'text/html' - } - }); -} - -async function handleScans(data){ - console.log('4. handleScans'); - - theScanRows = document.getElementById('the_scans_rows'); - - if(!data.includes('Running') && !data.includes('Queued') && theScanRows){ - console.log('5. not running and not queued and scan rows'); - - theScanRows.innerHTML = data; - - } - - if(data.includes('Running') && theScanRows){ - setTimeout(function(){ - console.log('5. running and scan rows'); // NOTE: - - handlePromises(); - theScanRows.innerHTML = data; - }, 5000); - - } - - if(!data.includes('Running') && data.includes('Queued')){ - console.log('5. not running and queued'); - - runScan(). - then(handlePromises); - - } - - if(!data.includes('Running') && data.includes('Queued') && theScanRows ){ - - setTimeout(function(){ - console.log('5. not running and queued and scan rows'); - - handlePromises(); - theScanRows.innerHTML = data; - }, 5000); - - } - -} - async function handleAlerts(data) { console.log('7. handleAlerts'); alertCount = document.getElementById('alert_count'); - if (alertCount) + if (alertCount) { alertCount.innerHTML = data; + } } const handlePromises = () => { @@ -95,12 +70,8 @@ const handlePromises = () => { .then(handleScans) .then(getAlerts) .then(handleAlerts) - + .then(() => setTimeout(handlePromises, 5000)); } -window.onload = function(){ - console.log('1. window'); - - handlePromises(); - -} \ No newline at end of file +console.log('1. window'); +window.addEventListener('load', handlePromises); \ No newline at end of file From e76ad3fe350d962137bfb52c7b8405009d1236c6 Mon Sep 17 00:00:00 2001 From: Ezra Bertuccelli Date: Tue, 14 Jun 2022 19:45:58 -0700 Subject: [PATCH 67/70] space out console logs between promise loop iterations --- script.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script.js b/script.js index f2a5c3be..0b759b96 100644 --- a/script.js +++ b/script.js @@ -64,6 +64,7 @@ async function handleAlerts(data) { } const handlePromises = () => { + console.log(''); // spacing for clarity console.log('2. handlePromises'); getScans() @@ -71,6 +72,7 @@ const handlePromises = () => { .then(getAlerts) .then(handleAlerts) .then(() => setTimeout(handlePromises, 5000)); + } console.log('1. window'); From 2ca86c060abb4fa7ceb001e7e89abe3328df3c2c Mon Sep 17 00:00:00 2001 From: Ezra Bertuccelli Date: Tue, 14 Jun 2022 20:26:24 -0700 Subject: [PATCH 68/70] break promise loop when no scans queued or running --- script.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/script.js b/script.js index 0b759b96..540e3fe2 100644 --- a/script.js +++ b/script.js @@ -38,6 +38,11 @@ async function handleScans(data){ } }); } + + // rejecting here breaks the promise loop and stops pinging the server + if (!isQueued && !isRunning) { + return Promise.reject('No scans queued or running'); + } } async function getAlerts() { @@ -71,7 +76,10 @@ const handlePromises = () => { .then(handleScans) .then(getAlerts) .then(handleAlerts) - .then(() => setTimeout(handlePromises, 5000)); + .then( + () => setTimeout(handlePromises, 5000), + (rejectionReason) => console.log('Loop broken: ' + rejectionReason) + ); } From 80a7132503761941a2210833e7cf32ae228c8b8e Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 15 Jun 2022 12:44:09 -0400 Subject: [PATCH 69/70] Convert entites to html --- models/view_components.php | 1 + 1 file changed, 1 insertion(+) diff --git a/models/view_components.php b/models/view_components.php index f2ac9d87..4e388b39 100644 --- a/models/view_components.php +++ b/models/view_components.php @@ -136,6 +136,7 @@ function covert_code_shortcode($subject){ // code. $subject = str_replace('[code]', '
    ', $subject);
         $subject = str_replace('[/code]', '
    ', $subject); + $subject = html_entity_decode($subject); // [code] is converted! return $subject; From 3a3fd5d812dae266eda7a06428e4995056482b9c Mon Sep 17 00:00:00 2001 From: Blake Bertuccelli Date: Wed, 15 Jun 2022 12:55:51 -0400 Subject: [PATCH 70/70] Brand update. --- index.php | 2 +- theme.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/index.php b/index.php index c4544082..9df0c5da 100644 --- a/index.php +++ b/index.php @@ -59,7 +59,7 @@ - Equalify + Equalify