From 9746bd7308a987dc1b2c7260044e15a5b3f7e040 Mon Sep 17 00:00:00 2001 From: Glynn Quelch Date: Wed, 28 May 2025 22:45:26 +0100 Subject: [PATCH 1/2] Created new dashboard widget with own tempalte file and scss file --- assets/css/build/style-style.scss.css | 2 +- assets/css/src/admin/_dashboard.scss | 123 +++++++++++++++++++++ assets/css/src/admin/_events.scss | 43 ------- assets/css/src/admin/_main.scss | 7 +- assets/css/src/admin/_meta_box_runner.scss | 65 ----------- src/Dashboard/Dashboard_Notifications.php | 121 ++++++++++---------- src/Dashboard/Setup_Wizard.php | 39 ++++--- src/Settings/Settings.php | 2 +- src/Settings/Settings_Page.php | 11 ++ templates/admin/dashboard/widget.php | 121 ++++++++++++++++++++ 10 files changed, 347 insertions(+), 187 deletions(-) create mode 100644 assets/css/src/admin/_dashboard.scss delete mode 100644 assets/css/src/admin/_events.scss delete mode 100644 assets/css/src/admin/_meta_box_runner.scss create mode 100644 templates/admin/dashboard/widget.php diff --git a/assets/css/build/style-style.scss.css b/assets/css/build/style-style.scss.css index 07716752..f8bb0f2b 100644 --- a/assets/css/build/style-style.scss.css +++ b/assets/css/build/style-style.scss.css @@ -1 +1 @@ -.http_100,.http_101,.http_102,.http_103{background-color:#e6f7ff}.http_200,.http_201,.http_202,.http_203,.http_204,.http_205,.http_206,.http_207,.http_208,.http_226{background-color:#e6ffe6}.http_300,.http_301,.http_302,.http_303,.http_304,.http_305,.http_306,.http_307,.http_308{background-color:#fff2e6}.http_400,.http_401,.http_402,.http_403,.http_404,.http_405,.http_406,.http_407,.http_408,.http_409,.http_410,.http_411,.http_412,.http_413,.http_414,.http_415,.http_416,.http_417,.http_418,.http_421,.http_422,.http_423,.http_424,.http_425,.http_426,.http_428,.http_429,.http_431,.http_451{background-color:#ffe6e6}.http_500,.http_501,.http_502,.http_503,.http_504,.http_505,.http_506,.http_507,.http_508,.http_510,.http_511{background-color:#ffe6ff}.http_none{background-color:#e6e6e6}@keyframes pulse{0%{background-color:#ebffff}50%{background-color:#f8ebff}50%{background-color:rgba(255,255,255,0)}}#wlf-meta-box-results h2{padding:0;margin-bottom:1em;font-size:19px;color:#db7093}#wlf-meta-box-results .report{border:1px solid #000;padding:5px 7px}#wlf-meta-box-results .report p{margin-bottom:2px}#wlf-meta-box-results .report a{text-align:center;display:block}#wlf-meta-box-results div{margin-bottom:5px}#wlf-meta-box-results.updated-results{animation:pulse 5s}#wlf-meta-box-runner div{margin-bottom:5px}#wlf-meta-box-runner .checkbox_container{display:flex;align-items:flex-end;justify-content:space-between}#wlf-meta-box-runner .text_container label{line-height:25px}#wlf-meta-box-runner .button_container{text-align:center;padding-top:5px}#wlf-meta-box-results__progress{padding:5px;text-align:center;background-color:#00891d;color:#fff;font-weight:500;margin-top:10px;border-radius:10px}#wlf_excluded_links{padding:5px;border:1px solid #cfcfcf;margin:5px 0}#wlf_excluded_links #wlf_excluded_empty{text-align:center;color:#cfcfcf}#wlf_excluded_links .link,#wlf_excluded_links .new-link{display:flex}#wlf_excluded_links .link input,#wlf_excluded_links .new-link input{max-width:100%;width:-webkit-fill-available}#wlf_excluded_links .new-link{margin-bottom:10px;background-color:#cfcfcf;padding:10px}.wlf_settings_postbox{position:relative;min-width:255px;border:1px solid #c3c4c7;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;margin-bottom:20px;padding-top:0}.wlf_settings_postbox h2{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #c3c4c7;padding:10px;margin:0;font-size:14px;padding:8px 12px;line-height:14px}.wlf_settings_postbox table.form-table th{padding-left:10px;font-size:13px}.wlf_settings_postbox>p.description{padding:10px 15px 5px}.wlf_settings_card{box-shadow:0 4px 12px rgba(0,0,0,.06),0 0 2px rgba(0,0,0,.16);border-radius:8px;overflow:hidden;padding:5px 10px;background-color:#fff;margin-bottom:20px}.wlf_settings_post_types{display:grid;grid-template-columns:auto auto;gap:16px;width:-moz-fit-content;width:fit-content}.wlf_read-only{pointer-events:none;background-color:#f9f9f9}.wlf_toggle_setting__invalid_api_keys input{border-color:#dc3232}#invalid_api_creds{text-align:center}#invalid_api_creds p{color:#dc3232;font-weight:600;margin:0}#wlf-events-trigger{padding:5px;border:1px solid #000;background:#d9d9d9}#wlf-events-trigger h2{margin-top:0}#wlf-events-trigger .wlf-event-trigger-row{padding:2px;margin-bottom:5px}#wlf-events-trigger .wlf-event-trigger-row p{margin:0;margin-top:3px}#wlf-events-trigger .wlf-event-trigger-row p span.description{color:#646970}#wlf-events-trigger .wlf-event-trigger-row input[type=text]{width:100%}#wlf-events-trigger .wlf-event-trigger-row p.with-checkbox input[type=checkbox]{margin-left:5px}#wlf-events-trigger .wlf-event-trigger-row .checkbox-grid{display:flex}#wlf-events-trigger .wlf-event-trigger-row .checkbox-grid label{display:block;padding:5px}#wlf-events-trigger .wlf-event-trigger-row #wlf-event-select2-errors{font-size:medium;text-align:center;color:red;font-weight:700}#wlf-events-trigger .select2-container--default .select2-selection--multiple{padding-bottom:0px}.wp-list-table.reports .column-report-link-archive,.wp-list-table.reports .column-report-is-broken,.wp-list-table.reports .column-report-link-checks,.wp-list-table.reports .column-report-link-exclude{max-width:10%;width:135px;text-align:center}@media(max-width: 1200px){.wp-list-table.reports .column-report-link-archive,.wp-list-table.reports .column-report-is-broken,.wp-list-table.reports .column-report-link-checks,.wp-list-table.reports .column-report-link-exclude{max-width:unset;width:unset}}.wp-list-table.reports .column-report-link-checks-last{max-width:30%;width:240px}@media(max-width: 1200px){.wp-list-table.reports .column-report-link-checks-last{max-width:unset;width:unset}}.wp-list-table.reports .dashicons.dashicons-yes-alt{color:#2271b1}.wp-list-table.reports .report-link-url a:first-of-type{display:inline-block;max-width:calc(100% - 30px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.wp-list-table.reports .report-link-url .dashicons{display:inline-block;vertical-align:middle;margin-left:5px}.contextual-help-tabs-wrap .wlf_help_tab h3{font-size:1.2em;margin-bottom:.25em}.contextual-help-tabs-wrap .wlf_help_tab p{margin:.25em 0}#wlf_help_info_bulk_actions{cursor:pointer}#wlf_wizard{padding:20px 30px;background:#fff;border-radius:10px;width:500px;min-width:250px;max-width:calc(100% - 60px);margin-left:auto;margin-right:auto}#wlf_wizard input[type=checkbox]{-webkit-appearance:none;appearance:none;width:40px;height:20px;background:#ccc;border-radius:20px;position:relative;cursor:pointer;transition:background .3s;margin:inherit}#wlf_wizard input[type=checkbox]::before{content:"";position:absolute;width:16px;height:16px;background:#fff;border-radius:50%;top:1px;left:2px;transition:transform .3s}#wlf_wizard input[type=checkbox]:checked{background:#2271b1}#wlf_wizard input[type=checkbox]:checked::before{transform:translateX(20px);top:4px;left:5px}#wlf_wizard input[type=text],#wlf_wizard input[type=password],#wlf_wizard select{width:100%;padding:10px;font-size:19px;max-width:unset}#wlf_wizard input.invalid{border-color:#dc3232}#wlf-wizard__footer{display:flex;width:100%;align-items:center;justify-content:space-between}.wlf-wizard__footer__progress{flex-grow:1;display:flex;align-items:center;justify-content:center;padding:0 25px;width:100%}@media(max-width: 499px){.wlf-wizard__footer__progress{display:none}}.wlf-wizard__footer__progress__bar{width:100%;justify-content:center;align-items:center;display:inline;text-align:center;position:relative}.wlf-wizard__footer__progress__bar .wlf-wizard__footer__progress__bar__inner{background-color:#2271b1;height:5px;position:relative;z-index:1}.wlf-wizard__footer__progress__bar::before{content:"";position:absolute;bottom:0;left:0;height:5px;background-color:#f5f5f5;width:100%;transition:width .3s ease-in-out;z-index:0}.wlf-wizard__content form{display:flex;flex-direction:column}.wlf-wizard__content__field{display:flex;flex-direction:column;margin-bottom:20px;justify-content:center;align-items:flex-start}.wlf-wizard__content__field.is_optional.disabled{display:none}.wlf-wizard__content__field label{font-size:17px;line-height:20px;margin-bottom:6px;font-weight:400}.wlf-wizard__content__inner-field .inner-spaced-between__list{display:flex;align-items:center;justify-content:space-between;padding:3px 25px}.wlf-wizard__content__inner-field .inner-spaced-between__list:hover{background-color:#f9f9f9}.wlf-wizard__content__inner-field .inner-spaced-between{display:flex;align-items:center;justify-content:space-between;width:100%}.wlf-wizard__content__inner-field.checkbox{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%}.wlf-wizard__content__inner-field.checkbox input{margin:10px}.wlf-wizard__content__inner-field.checkboxes{width:100%}.wlf-wizard__content__inner-field p.description{width:100%} +.http_100,.http_101,.http_102,.http_103{background-color:#e6f7ff}.http_200,.http_201,.http_202,.http_203,.http_204,.http_205,.http_206,.http_207,.http_208,.http_226{background-color:#e6ffe6}.http_300,.http_301,.http_302,.http_303,.http_304,.http_305,.http_306,.http_307,.http_308{background-color:#fff2e6}.http_400,.http_401,.http_402,.http_403,.http_404,.http_405,.http_406,.http_407,.http_408,.http_409,.http_410,.http_411,.http_412,.http_413,.http_414,.http_415,.http_416,.http_417,.http_418,.http_421,.http_422,.http_423,.http_424,.http_425,.http_426,.http_428,.http_429,.http_431,.http_451{background-color:#ffe6e6}.http_500,.http_501,.http_502,.http_503,.http_504,.http_505,.http_506,.http_507,.http_508,.http_510,.http_511{background-color:#ffe6ff}.http_none{background-color:#e6e6e6}#wlf_excluded_links{padding:5px;border:1px solid #cfcfcf;margin:5px 0}#wlf_excluded_links #wlf_excluded_empty{text-align:center;color:#cfcfcf}#wlf_excluded_links .link,#wlf_excluded_links .new-link{display:flex}#wlf_excluded_links .link input,#wlf_excluded_links .new-link input{max-width:100%;width:-webkit-fill-available}#wlf_excluded_links .new-link{margin-bottom:10px;background-color:#cfcfcf;padding:10px}.wlf_settings_postbox{position:relative;min-width:255px;border:1px solid #c3c4c7;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;margin-bottom:20px;padding-top:0}.wlf_settings_postbox h2{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #c3c4c7;padding:10px;margin:0;font-size:14px;padding:8px 12px;line-height:14px}.wlf_settings_postbox table.form-table th{padding-left:10px;font-size:13px}.wlf_settings_postbox>p.description{padding:10px 15px 5px}.wlf_settings_card{box-shadow:0 4px 12px rgba(0,0,0,.06),0 0 2px rgba(0,0,0,.16);border-radius:8px;overflow:hidden;padding:5px 10px;background-color:#fff;margin-bottom:20px}.wlf_settings_post_types{display:grid;grid-template-columns:auto auto;gap:16px;width:-moz-fit-content;width:fit-content}.wlf_read-only{pointer-events:none;background-color:#f9f9f9}.wlf_toggle_setting__invalid_api_keys input{border-color:#dc3232}#invalid_api_creds{text-align:center}#invalid_api_creds p{color:#dc3232;font-weight:600;margin:0}.wp-list-table.reports .column-report-link-archive,.wp-list-table.reports .column-report-is-broken,.wp-list-table.reports .column-report-link-checks,.wp-list-table.reports .column-report-link-exclude{max-width:10%;width:135px;text-align:center}@media(max-width: 1200px){.wp-list-table.reports .column-report-link-archive,.wp-list-table.reports .column-report-is-broken,.wp-list-table.reports .column-report-link-checks,.wp-list-table.reports .column-report-link-exclude{max-width:unset;width:unset}}.wp-list-table.reports .column-report-link-checks-last{max-width:30%;width:240px}@media(max-width: 1200px){.wp-list-table.reports .column-report-link-checks-last{max-width:unset;width:unset}}.wp-list-table.reports .dashicons.dashicons-yes-alt{color:#2271b1}.wp-list-table.reports .report-link-url a:first-of-type{display:inline-block;max-width:calc(100% - 30px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.wp-list-table.reports .report-link-url .dashicons{display:inline-block;vertical-align:middle;margin-left:5px}.contextual-help-tabs-wrap .wlf_help_tab h3{font-size:1.2em;margin-bottom:.25em}.contextual-help-tabs-wrap .wlf_help_tab p{margin:.25em 0}#wlf_help_info_bulk_actions{cursor:pointer}#wlf_wizard{padding:20px 30px;background:#fff;border-radius:10px;width:500px;min-width:250px;max-width:calc(100% - 60px);margin-left:auto;margin-right:auto}#wlf_wizard input[type=checkbox]{-webkit-appearance:none;appearance:none;width:40px;height:20px;background:#ccc;border-radius:20px;position:relative;cursor:pointer;transition:background .3s;margin:inherit}#wlf_wizard input[type=checkbox]::before{content:"";position:absolute;width:16px;height:16px;background:#fff;border-radius:50%;top:1px;left:2px;transition:transform .3s}#wlf_wizard input[type=checkbox]:checked{background:#2271b1}#wlf_wizard input[type=checkbox]:checked::before{transform:translateX(20px);top:4px;left:5px}#wlf_wizard input[type=text],#wlf_wizard input[type=password],#wlf_wizard select{width:100%;padding:10px;font-size:19px;max-width:unset}#wlf_wizard input.invalid{border-color:#dc3232}#wlf-wizard__footer{display:flex;width:100%;align-items:center;justify-content:space-between}.wlf-wizard__footer__progress{flex-grow:1;display:flex;align-items:center;justify-content:center;padding:0 25px;width:100%}@media(max-width: 499px){.wlf-wizard__footer__progress{display:none}}.wlf-wizard__footer__progress__bar{width:100%;justify-content:center;align-items:center;display:inline;text-align:center;position:relative}.wlf-wizard__footer__progress__bar .wlf-wizard__footer__progress__bar__inner{background-color:#2271b1;height:5px;position:relative;z-index:1}.wlf-wizard__footer__progress__bar::before{content:"";position:absolute;bottom:0;left:0;height:5px;background-color:#f5f5f5;width:100%;transition:width .3s ease-in-out;z-index:0}.wlf-wizard__content form{display:flex;flex-direction:column}.wlf-wizard__content__field{display:flex;flex-direction:column;margin-bottom:20px;justify-content:center;align-items:flex-start}.wlf-wizard__content__field.is_optional.disabled{display:none}.wlf-wizard__content__field label{font-size:17px;line-height:20px;margin-bottom:6px;font-weight:400}.wlf-wizard__content__inner-field .inner-spaced-between__list{display:flex;align-items:center;justify-content:space-between;padding:3px 25px}.wlf-wizard__content__inner-field .inner-spaced-between__list:hover{background-color:#f9f9f9}.wlf-wizard__content__inner-field .inner-spaced-between{display:flex;align-items:center;justify-content:space-between;width:100%}.wlf-wizard__content__inner-field.checkbox{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%}.wlf-wizard__content__inner-field.checkbox input{margin:10px}.wlf-wizard__content__inner-field.checkboxes{width:100%}.wlf-wizard__content__inner-field p.description{width:100%}.wlf_dashboard-wrapper{margin:-12px;padding:0}.wlf_dashboard-status-section{padding:12px;border-bottom:1px solid #e5e5e5}.wlf_dashboard-status-section:last-child{border-bottom:none}.wlf_dashboard-status-indicator{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:8px}.wlf_dashboard-status-indicator.online{background-color:#46b450}.wlf_dashboard-status-indicator.offline{background-color:#dc3232}.wlf_dashboard-stats-grid{display:grid;grid-template-columns:repeat(2, 1fr);gap:12px}.wlf_dashboard-stats-box{background:#f8f9fa;padding:12px;border-radius:4px;text-align:center}.wlf_dashboard-stats-number,.wlf_dashboard-stats-ratio{font-size:28px;font-weight:600;color:#1d2327;line-height:1.3}.wlf_dashboard-stats-label{color:#50575e;font-size:13px;margin-top:4px}.wlf_dashboard-section-title{font-size:14px;font-weight:600;color:#1d2327;margin:0 12px 8px;padding-bottom:8px;border-bottom:1px solid #e5e5e5}.wlf_dashboard-features{display:grid;grid-template-columns:repeat(2, 1fr);gap:12px;padding:12px}.wlf_dashboard-features-item{display:flex;align-items:flex-start;gap:8px;padding:8px;background:#f8f9fa;border-radius:4px}.wlf_dashboard-features-content{flex:1}.wlf_dashboard-features-status{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;flex-shrink:0}.wlf_dashboard-features-status.enabled{background:#edfaef;color:#46b450}.wlf_dashboard-features-status.disabled{background:#fef1f1;color:#d63638}.wlf_dashboard-features-label{font-size:13px;color:#50575e}.wlf_dashboard-features-description{font-size:12px;color:#757575;margin-top:2px}.wlf_dashboard-warning{color:#d63638;padding:12px;background:#fcf0f1;border-left:4px solid #d63638;margin:0 0 12px 0}.wlf_dashboard-navigation{padding:12px;background:#f0f0f1;display:flex;gap:10px;justify-content:flex-end}.wlf_dashboard-navigation a{text-decoration:none} diff --git a/assets/css/src/admin/_dashboard.scss b/assets/css/src/admin/_dashboard.scss new file mode 100644 index 00000000..14f59547 --- /dev/null +++ b/assets/css/src/admin/_dashboard.scss @@ -0,0 +1,123 @@ +.wlf_dashboard { + &-wrapper { + margin: -12px; + padding: 0; + } + &-status { + &-section { + padding: 12px; + border-bottom: 1px solid #e5e5e5; + &:last-child { + border-bottom: none; + } + } + &-indicator { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + margin-right: 8px; + &.online { + background-color: #46b450; + } + &.offline { + background-color: #dc3232; + } + } + } + &-stats { + &-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + } + &-box { + background: #f8f9fa; + padding: 12px; + border-radius: 4px; + text-align: center; + } + &-number, + &-ratio { + font-size: 28px; + font-weight: 600; + color: #1d2327; + line-height: 1.3; + } + &-label { + color: #50575e; + font-size: 13px; + margin-top: 4px; + } + } + &-section { + &-title { + font-size: 14px; + font-weight: 600; + color: #1d2327; + margin: 0 12px 8px; + padding-bottom: 8px; + border-bottom: 1px solid #e5e5e5; + } + } + &-features { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + padding: 12px; + &-item { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 8px; + background: #f8f9fa; + border-radius: 4px; + } + &-content { + flex: 1; + } + &-status { + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + border-radius: 50%; + flex-shrink: 0; + &.enabled { + background: #edfaef; + color: #46b450; + } + &.disabled { + background: #fef1f1; + color: #d63638; + } + } + &-label { + font-size: 13px; + color: #50575e; + } + &-description { + font-size: 12px; + color: #757575; + margin-top: 2px; + } + } + &-warning { + color: #d63638; + padding: 12px; + background: #fcf0f1; + border-left: 4px solid #d63638; + margin: 0 0 12px 0; + } + &-navigation { + padding: 12px; + background: #f0f0f1; + display: flex; + gap: 10px; + justify-content: flex-end; + a { + text-decoration: none; + } + } +} \ No newline at end of file diff --git a/assets/css/src/admin/_events.scss b/assets/css/src/admin/_events.scss deleted file mode 100644 index d3599096..00000000 --- a/assets/css/src/admin/_events.scss +++ /dev/null @@ -1,43 +0,0 @@ -#wlf-events-trigger { - padding: 5px; - border: 1px solid black; - background: #d9d9d9; - h2 { - margin-top: 0; - } - .wlf-event-trigger-row { - padding: 2px; - margin-bottom: 5px; - p { - margin: 0; - margin-top: 3px; - span.description { - color: #646970; - } - } - input[type="text"] { - width: 100%; - } - p.with-checkbox { - input[type="checkbox"] { - margin-left: 5px; - } - } - .checkbox-grid { - display: flex; - label { - display: block; - padding: 5px; - } - } - #wlf-event-select2-errors { - font-size: medium; - text-align: center; - color: red; - font-weight: 700; - } - } - .select2-container--default .select2-selection--multiple { - padding-bottom: 0px; - } -} \ No newline at end of file diff --git a/assets/css/src/admin/_main.scss b/assets/css/src/admin/_main.scss index 8ecbf4e9..6c22bedd 100644 --- a/assets/css/src/admin/_main.scss +++ b/assets/css/src/admin/_main.scss @@ -81,9 +81,8 @@ background-color: #e6e6e6; } -// Create css colours for each http code. -@import "meta_box_runner.scss"; +// Import admin styles @import "settings.scss"; -@import "events.scss"; @import "report_list.scss"; -@import "wizard.scss"; \ No newline at end of file +@import "wizard.scss"; +@import "dashboard"; \ No newline at end of file diff --git a/assets/css/src/admin/_meta_box_runner.scss b/assets/css/src/admin/_meta_box_runner.scss deleted file mode 100644 index ec01cc70..00000000 --- a/assets/css/src/admin/_meta_box_runner.scss +++ /dev/null @@ -1,65 +0,0 @@ -@keyframes pulse { - 0% { - background-color: #ebffff; - } - 50% { - background-color: #f8ebff; - } - 50% { - background-color: #ffffff00; - } -} - -#wlf-meta-box-results { - h2 { - padding: 0; - margin-bottom: 1em; - font-size: 19px; - color: palevioletred; - } - .report { - border: 1px solid black; - padding: 5px 7px; - p { - margin-bottom: 2px; - } - a { - text-align: center; - display: block; - } - } - div { - margin-bottom: 5px; - } - &.updated-results { - animation: pulse 5s; - } -} - -#wlf-meta-box-runner { - div { - margin-bottom: 5px; - } - .checkbox_container { - display: flex; - align-items: flex-end; - justify-content: space-between; - } - .text_container label { - line-height: 25px; - } - .button_container { - text-align: center; - padding-top: 5px; - } -} - -#wlf-meta-box-results__progress { - padding: 5px; - text-align: center; - background-color: #00891d; - color: white; - font-weight: 500; - margin-top: 10px; - border-radius: 10px; -} \ No newline at end of file diff --git a/src/Dashboard/Dashboard_Notifications.php b/src/Dashboard/Dashboard_Notifications.php index dfd5bd80..ed534a13 100644 --- a/src/Dashboard/Dashboard_Notifications.php +++ b/src/Dashboard/Dashboard_Notifications.php @@ -11,6 +11,9 @@ namespace WPCOMSpecialProjects\Wayback_Link_Fixer\Dashboard; use WPCOMSpecialProjects\Wayback_Link_Fixer\Settings\Settings; +use WPCOMSpecialProjects\Wayback_Link_Fixer\Report\Report_Page; +use WPCOMSpecialProjects\Wayback_Link_Fixer\Link\Link_Repository; +use WPCOMSpecialProjects\Wayback_Link_Fixer\Settings\Settings_Page; defined( 'ABSPATH' ) || exit; @@ -19,6 +22,11 @@ */ class Dashboard_Notifications { + /** + * The page slug. + */ + const PAGE_SLUG = 'wayback_link_fixer_dashboard'; + /** * Initialize the dashboard notifications. * @@ -26,6 +34,24 @@ class Dashboard_Notifications { */ public function initialize(): void { add_action( 'wp_dashboard_setup', array( $this, 'register_widgets' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) ); + } + + /** + * Enqueue the dashboard styles. + * + * @return void + */ + public function enqueue_styles(): void { + $screen = get_current_screen(); + if ( $screen && 'dashboard' === $screen->id ) { + wp_enqueue_style( + self::PAGE_SLUG, + WPCOMSP_WAYBACK_LINK_FIXER_URL . 'assets/css/build/style-style.scss.css', + array(), + WPCOMSP_WAYBACK_LINK_FIXER_METADATA['Version'] + ); + } } /** @@ -51,70 +77,51 @@ public function register_widgets(): void { * @return void */ public function render_widget(): void { - $status = $this->get_status_update(); - $api_configured = Settings::is_archive_api_configured(); - - // If the api is not configured, show a message. - if ( ! $api_configured ) { - printf( - '

%s

', - esc_html__( 'You are using Link Fixer in unauthenticated mode, which restricts you to 4000 new snapshots per day. To unlock higher limits, please enter your API credentials to authenticate with Archive.org.', 'wpcomsp_wayback_link_fixer' ) - ); - - return; - } - - // if the status is pending, show a message. - if ( $status['pending'] ) { - printf( - '

%s

', - esc_html__( 'The status of the link fixer is currently pending, please check again shortly', 'wpcomsp_wayback_link_fixer' ) - ); - - return; - } - - print 'TODO'; - - printf( - '

%s: %s

', - esc_html__( 'Last Checked', 'wpcomsp_wayback_link_fixer' ), - $status['last_checked'] ? esc_html( $status['last_checked']->format( wpcomsp_wayback_link_fixer_get_date_format() ) ) : esc_html__( 'Never', 'wpcomsp_wayback_link_fixer' ) + wpcomsp_wayback_link_fixer_render_template( + 'admin/dashboard/widget.php', + array( + 'wlf_details' => $this->get_account_details(), + 'wlf_api_configured' => Settings::is_archive_api_configured(), + 'wlf_is_online' => wpcomsp_wayback_link_fixer_is_archive_api_online(), + 'wlf_link_to_settings' => Settings_Page::get_page_url(), + 'wlf_link_table' => Report_Page::get_page_url(), + 'wlf_total_links' => ( new Link_Repository() )->query_links( PHP_INT_MAX ), + 'wlf_auto_archiver_enabled' => Settings::add_own_links(), + 'wlf_scan_existing_enabled' => Settings::should_scan_existing_posts(), + 'wlf_link_processing_enabled' => Settings::is_link_processing_enabled(), + ) ); } /** - * Get the current status update. + * Get the sites account details from Archive.org. * - * @return array{ - * 'is_online' => bool, - * 'last_checked' => \DateTimeImmutable|null, - * 'pending' => bool, - * 'link_checker_online => bool, - * 'snapshot_online' => bool,} + * @return array{available:int, daily_captures:int, daily_captures_limit:int, processing:int}|null */ - public static function get_status_update(): array { - // Get the status. - $status = Settings::get_archive_api_status(); - - // if the status is null, return a default status. - if ( null === $status ) { - return array( - 'is_online' => false, - 'last_checked' => null, - 'pending' => true, - 'link_checker_online' => false, - 'snapshot_online' => false, - ); - } else { - $time = \DateTimeImmutable::createFromFormat( 'Y-m-d H:i:s', $status['last-checked'] ); - return array( - 'is_online' => 'online' === $status['status'], - 'last_checked' => $time ? $time : null, - 'pending' => false, - 'link_checker_online' => (bool) $status['link_checker'], - 'snapshot_online' => (bool) $status['snapshot'], + public static function get_account_details(): ?array { + $cached = get_transient( 'wayback_link_fixer_account_details' ); + if ( false !== $cached ) { + return $cached; + } + try { + $details = \wpcomsp_wayback_link_fixer_get_system_client()->get_user_stats( + Settings::get_archive_access_key(), + Settings::get_archive_secret_key() ); + + if ( is_array( $details ) ) { + set_transient( 'wayback_link_fixer_account_details', $details, HOUR_IN_SECONDS ); + return array( + 'available' => isset( $details['available'] ) ? (int) $details['available'] : 0, + 'daily_captures' => isset( $details['daily_captures'] ) ? (int) $details['daily_captures'] : 0, + 'daily_captures_limit' => isset( $details['daily_captures_limit'] ) ? (int) $details['daily_captures_limit'] : 0, + 'processing' => isset( $details['processing'] ) ? (int) $details['processing'] : 0, + ); + } + } catch ( \Exception $e ) { + return null; } + + return null; } } diff --git a/src/Dashboard/Setup_Wizard.php b/src/Dashboard/Setup_Wizard.php index b4463db4..abb5066a 100644 --- a/src/Dashboard/Setup_Wizard.php +++ b/src/Dashboard/Setup_Wizard.php @@ -230,33 +230,40 @@ private function handle_step_1(): void { return; } + // Mark the step as completed. + $mark_completed = function () { + $next = sanitize_text_field( wp_unslash( $_POST['wlf-next-step'] ) ); + update_option( self::OPTION_NAME, $next ); + }; + $access_key = sanitize_text_field( wp_unslash( $_POST['wlf_wizard_archive_access_key'] ) ); $secret_key = sanitize_text_field( wp_unslash( $_POST['wlf_wizard_archive_secret_key'] ) ); + // If both are empty. + if ( '' === $access_key && '' === $secret_key ) { + // Mark the account as not valid. + Settings::update_archive_api_credentials_validity( false ); + // If the user has not set any keys, we can mark the step as completed. + $mark_completed(); + return; + } + // Check the users api credentials. - if ( '' !== $access_key - && '' !== $secret_key - && ! wpcomsp_wayback_link_fixer_get_system_client()->is_valid_user( $access_key, $secret_key ) - ) { + if ( ! wpcomsp_wayback_link_fixer_get_system_client()->is_valid_user( $access_key, $secret_key ) ) { $this->add_notice( __( 'Invalid Archive.org API credentials. Please verify your Access Key and Secret Key, or leave both fields blank to proceed without authentication.', 'wpcomsp_wayback_link_fixer' ), 'error' ); $_POST['wlf_wizard_invalid_keys'] = true; // Set a flag to indicate invalid keys. // Hold the entered values in post. $_POST['wlf_wizard_archive_access_key_temp'] = $access_key; $_POST['wlf_wizard_archive_secret_key_temp'] = $secret_key; - - return; + } else { + // Save the keys. + update_option( Settings::ARCHIVE_ORG_ACCESS_KEY, $access_key ); + update_option( Settings::ARCHIVE_ORG_SECRET_KEY, $secret_key ); + // Mark the keys as valid. + Settings::update_archive_api_credentials_validity( true ); + $mark_completed(); } - // Save the keys. - update_option( Settings::ARCHIVE_ORG_ACCESS_KEY, $access_key ); - update_option( Settings::ARCHIVE_ORG_SECRET_KEY, $secret_key ); - - // Mark the keys as valid. - Settings::update_archive_api_credentials_validity( true ); - - // Update the step. - $next = sanitize_text_field( wp_unslash( $_POST['wlf-next-step'] ) ); - update_option( self::OPTION_NAME, $next ); // phpcs:enable WordPress.Security.NonceVerification.Missing } diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index e9df28a7..30f32316 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -370,7 +370,7 @@ public static function show_link_table_debug_data(): bool { * @return boolean */ public static function has_valid_archive_api_credentials(): bool { - return get_option( self::ARCHIVE_ORG_CREDS_VALID_KEY, false ) === true; + return (bool) get_option( self::ARCHIVE_ORG_CREDS_VALID_KEY, false ) === true; } /** diff --git a/src/Settings/Settings_Page.php b/src/Settings/Settings_Page.php index 85b8e34a..c069b6cd 100644 --- a/src/Settings/Settings_Page.php +++ b/src/Settings/Settings_Page.php @@ -47,6 +47,17 @@ public function initialize(): void { add_action( 'admin_init', array( $this, 'validate_archive_org_keys' ), 99 ); } + /** + * Get the settings page URL. + * + * @since 1.3.0 + * + * @return string + */ + public static function get_page_url(): string { + return admin_url( 'options-general.php?page=' . self::PAGE_SLUG ); + } + /** * Register the settings page. * diff --git a/templates/admin/dashboard/widget.php b/templates/admin/dashboard/widget.php new file mode 100644 index 00000000..2ea44989 --- /dev/null +++ b/templates/admin/dashboard/widget.php @@ -0,0 +1,121 @@ + + +
+ +
+ +
+ + + +
+ +
+ + +
+ + + + +
+ + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+ + +
+

+
+
+ + + +
+ +
+
+
+
+ + + +
+ +
+
+
+
+ + + +
+ +
+
+
+
+
+ + +
From ebd37db64555aa58cbf7cbea54564ec7ea4340f1 Mon Sep 17 00:00:00 2001 From: Glynn Quelch Date: Thu, 29 May 2025 15:17:52 +0100 Subject: [PATCH 2/2] Added extra column of data to say how often links are checked --- src/Dashboard/Dashboard_Notifications.php | 2 ++ templates/admin/dashboard/widget.php | 33 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Dashboard/Dashboard_Notifications.php b/src/Dashboard/Dashboard_Notifications.php index ed534a13..b806021b 100644 --- a/src/Dashboard/Dashboard_Notifications.php +++ b/src/Dashboard/Dashboard_Notifications.php @@ -89,6 +89,8 @@ public function render_widget(): void { 'wlf_auto_archiver_enabled' => Settings::add_own_links(), 'wlf_scan_existing_enabled' => Settings::should_scan_existing_posts(), 'wlf_link_processing_enabled' => Settings::is_link_processing_enabled(), + 'wlf_link_check_duration' => Settings::get_link_check_duration(), + 'wlf_failed_check_count' => Settings::get_failed_count(), ) ); } diff --git a/templates/admin/dashboard/widget.php b/templates/admin/dashboard/widget.php index 2ea44989..6a5ba117 100644 --- a/templates/admin/dashboard/widget.php +++ b/templates/admin/dashboard/widget.php @@ -13,6 +13,8 @@ * @param bool $wlf_auto_archiver_enabled Whether auto archiver is enabled. * @param bool $wlf_scan_existing_enabled Whether scanning existing posts is enabled. * @param bool $wlf_link_processing_enabled Whether link processing is enabled. + * @param int $wlf_link_check_duration Number of days between link checks. + * @param int $wlf_failed_check_count Number of failed checks before marking as broken. */ defined( 'ABSPATH' ) || exit; @@ -78,7 +80,7 @@
-
+
@@ -99,6 +101,35 @@
+
+ + + +
+ +
+ + + + ', + '' + ); + ?> + +
+
+