Compare commits

...

83 Commits
2.0.2 ... 2

Author SHA1 Message Date
github-actions 2ee2bfbc8a Merge branch '2.4' into 2 2024-02-11 14:04:18 +00:00
Guy Sartorelli b12e6868bc
TLN Update translations (#120) 2024-02-07 16:05:28 +13:00
Steve Boyd e12e2aaece Merge branch '2.4' into 2 2023-11-13 17:24:09 +13:00
Sabina Talipova 8797f1f41e
ENH Restrict access to getJobStatus execution (#113) 2023-11-09 10:06:58 +13:00
github-actions a01c16b829 Merge branch '2.4' into 2 2023-08-27 14:03:52 +00:00
Guy Sartorelli 20c2231bff
ENH Update translations (#106) 2023-08-21 12:24:21 +12:00
Steve Boyd bea1716d94 Merge branch '2.4' into 2 2023-06-16 12:01:45 +12:00
Guy Sartorelli 062319682e
Merge pull request #102 from creative-commoners/pulls/2.4/tx-1686724684
ENH Update translations
2023-06-15 10:06:36 +12:00
Steve Boyd 2560888df0 ENH Update translations 2023-06-14 18:38:04 +12:00
Steve Boyd ae9dbddfb0 Merge branch '2.4' into 2 2023-03-29 09:58:29 +13:00
Guy Sartorelli 4f5309163b
MNT Revert erroneous dependency changes (#98) 2023-03-28 17:08:50 +13:00
Guy Sartorelli 44b575db9b
Merge pull request #96 from creative-commoners/pulls/2.4/fix-create-report-button
FIX Create button is disabled if server returns error
2023-03-27 11:42:20 +13:00
Sabina Talipova 4d67a327fe FIX Create button is disabled if server returns error 2023-03-24 12:59:39 +13:00
Maxime Rainville 418d69813f
Merge pull request #95 from creative-commoners/pulls/2/dispatch-ci
MNT Use gha-dispatch-ci
2023-03-23 14:10:53 +13:00
Steve Boyd 8b27314490 MNT Use gha-dispatch-ci 2023-03-21 12:25:06 +13:00
Guy Sartorelli 6ea69fabb2
MNT Update development dependencies 2023-03-10 16:34:29 +13:00
Guy Sartorelli 7698371ebf
MNT Update release dependencies 2023-03-10 16:34:25 +13:00
Guy Sartorelli cbd278685b
MNT Update development dependencies 2023-03-10 12:21:30 +13:00
Guy Sartorelli 2595fff257
Merge pull request #92 from creative-commoners/pulls/2/tx-1678079850
ENH Update translations
2023-03-08 10:25:03 +13:00
Steve Boyd a055868bfa ENH Update translations 2023-03-06 18:17:30 +13:00
Sabina Talipova bef19ec35c
Merge pull request #86 from creative-commoners/pulls/2/stop-using-depr
API Stop using deprecated API
2022-12-05 16:43:44 +13:00
Steve Boyd 1b66be22cd API Stop using deprecated API 2022-11-28 17:40:24 +13:00
Steve Boyd 9381f33959 Merge branch '2.3' into 2 2022-08-02 18:49:41 +12:00
Steve Boyd 93b0303ce0 Merge branch '2.2' into 2.3 2022-08-02 18:49:38 +12:00
Guy Sartorelli 0009a4bf13
Merge pull request #83 from creative-commoners/pulls/2.2/standardise-modules
MNT Standardise modules
2022-08-02 15:10:52 +12:00
Steve Boyd a70a9d1e82 MNT Standardise modules 2022-08-01 16:21:58 +12:00
Steve Boyd b47db91c2a Merge branch '2.3' into 2 2022-07-25 11:26:02 +12:00
Steve Boyd 2f72f9873a Merge branch '2.2' into 2.3 2022-07-25 11:25:44 +12:00
Guy Sartorelli 813cd2e4e7
Merge pull request #82 from creative-commoners/pulls/2.2/behat
FIX Move files to client directory
2022-07-20 09:41:32 +12:00
Steve Boyd d1cc3f80ab FIX Move files to client directory 2022-07-19 18:05:43 +12:00
Guy Sartorelli ec36ece776
Merge pull request #81 from creative-commoners/pulls/2.2/module-standards
MNT Use GitHub Actions CI
2022-07-15 16:58:23 +12:00
Steve Boyd d2c1aedf2e MNT Use GitHub Actions CI 2022-07-07 15:41:58 +12:00
Guy Sartorelli 11a4a6d6e1
Merge pull request #80 from ssmarco/patch-1
MNT - Composer.json - Fix wrong spelling of symbiote in suggestion
2022-05-13 11:40:39 +12:00
Marco Hermo ae9e7d0c96
MNT - Composer.json - Fix wrong spelling of symbiote in suggestion 2022-05-11 00:15:44 +12:00
Guy Sartorelli 4df31ad641 Merge branch '2.3' into 2 2022-05-06 09:56:59 +12:00
Guy Sartorelli e743b90607 Merge branch '2.2' into 2.3 2022-05-06 09:53:57 +12:00
Guy Sartorelli d4871e7d41
Merge pull request #78 from creative-commoners/pulls/2.2/fix-permission-cmsmain
FIX: CMSMain user able to see external broken links
2022-05-06 09:29:39 +12:00
Sabina Talipova 6d288c54f2 Add new permission group 2022-05-06 08:54:12 +12:00
Steve Boyd 3721dab425 Update translations 2022-05-04 13:29:41 +12:00
Guy Sartorelli 164032af76
Merge pull request #77 from creative-commoners/pulls/2/php81
ENH PHP 8.1 compatibility
2022-04-26 17:58:36 +12:00
Steve Boyd 1bfaf12909 ENH PHP 8.1 compatibility 2022-04-13 10:29:57 +12:00
Maxime Rainville 3fc084a1f0
Merge pull request #76 from creative-commoners/pulls/2/php74
DEP Set PHP 7.4 as the minimum version
2022-02-18 21:48:06 +13:00
Steve Boyd b1cd65d538 DEP Set PHP 7.4 as the minimum version 2022-02-10 16:18:31 +13:00
Steve Boyd 4176da66c7 Merge branch '2.2' into 2 2021-12-22 10:28:09 +13:00
Steve Boyd b4ccd03025 MNT Remove obsolete branch-alias 2021-11-30 13:55:20 +13:00
Steve Boyd c4e41d58ee Merge branch '2.1' into 2 2021-11-18 17:20:11 +13:00
Maxime Rainville aed847dc13
Merge pull request #74 from creative-commoners/pulls/2.1/behat
MNT Add behat tests
2021-11-10 16:51:36 +13:00
Maxime Rainville 75585f983a
Merge pull request #75 from creative-commoners/pulls/2/sapphire-test-nine
API phpunit 9 support
2021-11-01 21:26:14 +13:00
Steve Boyd fb9c340edb API phpunit 9 support 2021-10-27 18:06:53 +13:00
Steve Boyd 3da3567a7a MNT Add behat tests 2021-10-01 19:55:27 +13:00
Steve Boyd 40c96ce23f Merge branch '2.1' into 2 2021-02-04 09:47:18 +13:00
Garion Herman b4c210f211
FIX Exclude links attached to archived Pages from report (#72) 2021-02-04 09:45:39 +13:00
Steve Boyd 478d6613f8
Update build status badge 2021-01-21 16:34:25 +13:00
Steve Boyd 7b68fe0eaa Merge branch '2.0' into 2 2020-11-11 17:13:31 +13:00
Serge Latyntsev 75a4988f48
Merge pull request #70 from creative-commoners/pulls/2.0/shared-config
MNT Use shared travis config, use sminnee/phpunit
2020-11-10 17:00:31 +13:00
Steve Boyd 504f742aa7 MNT Use shared travis config, use sminnee/phpunit 2020-11-10 12:55:10 +13:00
Maxime Rainville 703ae9b2ca Merge branch '2.0' into 2 2020-10-22 22:07:03 +13:00
Alex Saelens 9282ed2e2d
FIX Allow to configure CurlLinkChecker request headers (#64)
* Allow to configure CurlLinkChecker request headers
* Make adding headers more explicit via array
* Remove extra character in comment
* Fix lint
* Align headers array with php docs
2020-07-07 10:25:25 +12:00
Robbie Averill 9cb88c96b2
Merge pull request #67 from creative-commoners/pulls/2.0/travis
Travis 2.0
2020-06-23 10:14:42 -07:00
Steve Boyd 80ddb80123 Travis 2.0 2020-06-23 12:58:22 +12:00
Maxime Rainville 05ded71c02 Merge branch '2.0' into 2 2020-06-12 14:04:09 +12:00
Guy Marriott 839cbb7185
Update translations 2019-08-20 16:37:59 +12:00
Robbie Averill 3746cb1368 Merge branch '2.0' 2019-08-15 10:00:55 +12:00
Dylan Wagstaff a166257690
Merge pull request #62 from creative-commoners/pulls/2.0/handle-http-errors-gracefully
FIX Add missing namespace import - unknown HTTP status codes are now handled
2019-07-29 10:17:31 +12:00
Robbie Averill b39a81b60b Use trusty in Travis builds 2019-07-26 11:22:53 +02:00
Robbie Averill 7a335726c4 Remove SilverStripe 4.0-4.2 from Travis builds 2019-07-26 11:22:37 +02:00
Robbie Averill 1ce8c3bbdf FIX Add missing namespace import - unknown HTTP status codes are now handled 2019-07-26 11:16:31 +02:00
Robbie Averill a180db21b9
Merge pull request #60 from lhalaa/pulls/add-legacy-file
Add legacy.yml for SS3 to SS4 upgrades
2019-05-15 16:51:48 +12:00
Sheila Bañez a1b7d3979e Add legacy.yml for SS3 to SS4 upgrades 2019-05-15 15:26:48 +12:00
Robbie Averill 5091bf91e5 Merge branch '2.0' 2019-03-11 15:39:46 +13:00
Robbie Averill e41ee18b7c
Merge pull request #59 from creative-commoners/pulls/2.0/fix-initial-button-state
FIX Reference alias for this inside javascript closure - report now works on initial load
2019-03-11 15:39:27 +13:00
Robbie Averill 4f0df463df FIX Reference alias for this inside javascript closure - report now works on initial load 2019-03-11 15:27:31 +13:00
Dylan Wagstaff 60893a87b1
Merge pull request #58 from creative-commoners/pulls/2.0/disable-button
FIX External links report generate button is now disabled while it is loading
2019-03-08 10:51:07 +13:00
Robbie Averill a3aed13ed0 FIX External links report generate button is now disabled while it is loading 2019-03-08 10:06:50 +13:00
Guy Marriott 1cfb249384
Merge pull request #56 from creative-commoners/pulls/2.0/remove-json-methods
FIX Replace Convert JSON methods with json_* methods, deprecated from SilverStripe 4.4
2018-10-29 11:30:10 +13:00
Robbie Averill 17604a5b42 FIX Replace Convert JSON methods with json_* methods, deprecated from SilverStripe 4.4 2018-10-28 21:36:50 +00:00
Robbie Averill 08fc708521 Merge branch '2.0' 2018-08-27 09:24:51 +12:00
Robbie Averill 4311de28fd
Merge pull request #55 from creative-commoners/pulls/2.0/fix-them-plurals
FIX Update plural name of BrokenExternalPageTrackStatus
2018-08-27 09:23:50 +12:00
Raissa North 61a63f36d9 FIX Update plural name of BrokenExternalPageTrackStatus 2018-08-24 17:13:31 +12:00
Robbie Averill 28ce2df1b7
Merge pull request #52 from creative-commoners/pulls/master/add-supported-module-badge
Add supported module badge to readme
2018-06-18 10:47:43 +12:00
Dylan Wagstaff 8002624da9 Add supported module badge to readme 2018-06-15 17:35:22 +12:00
Robbie Averill 4723e8742c Merge branch '2.0' 2018-05-08 15:38:30 +12:00
Robbie Averill e33f65ecc0 Merge branch '2.0' 2018-04-06 10:45:42 +12:00
41 changed files with 602 additions and 110 deletions

11
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,11 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1

16
.github/workflows/dispatch-ci.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Dispatch CI
on:
# At 2:00 PM UTC, only on Wednesday and Thursday
schedule:
- cron: '0 14 * * 3,4'
jobs:
dispatch-ci:
name: Dispatch CI
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Dispatch CI
uses: silverstripe/gha-dispatch-ci@v1

17
.github/workflows/keepalive.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Keepalive
on:
workflow_dispatch:
# The 4th of every month at 10:50am UTC
schedule:
- cron: '50 10 4 * *'
jobs:
keepalive:
name: Keepalive
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Keepalive
uses: silverstripe/gha-keepalive@v1

View File

@ -1,15 +0,0 @@
inherit: true
build:
nodes:
analysis:
tests:
override: [php-scrutinizer-run]
checks:
php:
code_rating: true
duplication: true
filter:
paths: [src/*, tests/*]

View File

@ -1,35 +0,0 @@
language: php
env:
global:
- COMPOSER_ROOT_VERSION=2.0.x-dev
matrix:
include:
- php: 5.6
env: DB=MYSQL RECIPE_VERSION=1.0.x-dev PHPCS_TEST=1 PHPUNIT_TEST=1
- php: 7.0
env: DB=MYSQL RECIPE_VERSION=1.1.x-dev PHPUNIT_TEST=1
- php: 7.1
env: DB=PGSQL RECIPE_VERSION=1.2.x-dev PHPUNIT_COVERAGE_TEST=1
- php: 7.2
env: DB=MYSQL RECIPE_VERSION=1.x-dev PHPUNIT_TEST=1
before_script:
# Init PHP
- phpenv rehash
- phpenv config-rm xdebug.ini
# Install composer dependencies
- composer validate
- composer require --no-update silverstripe/recipe-cms $RECIPE_VERSION
- if [[ $DB == PGSQL ]]; then composer require --no-update silverstripe/postgresql 2.0.x-dev; fi
- composer install --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
script:
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs src/ tests/; fi
after_success:
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi

View File

@ -1,8 +1,9 @@
[main]
host = https://www.transifex.com
[silverstripe-externallinks.master]
[o:silverstripe:p:silverstripe-externallinks:r:master]
file_filter = lang/<lang>.yml
source_file = lang/en.yml
source_lang = en
type = YML
type = YML

View File

@ -1,8 +1,7 @@
# External links
[![Build Status](http://img.shields.io/travis/silverstripe/silverstripe-externallinks.svg?style=flat)](https://travis-ci.org/silverstripe/silverstripe-externallinks)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-externallinks/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-externallinks/?branch=master)
[![codecov](https://codecov.io/gh/silverstripe/silverstripe-externallinks/branch/master/graph/badge.svg)](https://codecov.io/gh/silverstripe/silverstripe-externallinks)
[![CI](https://github.com/silverstripe/silverstripe-externallinks/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-externallinks/actions/workflows/ci.yml)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Introduction
@ -14,9 +13,9 @@ The external links module is a task and ModelAdmin to track and to report on bro
## Requirements
* SilverStripe ^4.0
* Silverstripe ^4.0
**Note:** For a SilverStripe 3.x compatible version, please use [the 1.x release line](https://github.com/silverstripe/silverstripe-externallinks/tree/1.0).
**Note:** For a Silverstripe 3.x compatible version, please use [the 1.x release line](https://github.com/silverstripe/silverstripe-externallinks/tree/1.0).
## Features
@ -80,7 +79,7 @@ SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask:
## Upgrading from 1.x to 2.x
When upgrading from 1.x to 2.x (SilverStripe 3.x to 4.x) you will need to be aware of the following API changes:
When upgrading from 1.x to 2.x (Silverstripe 3.x to 4.x) you will need to be aware of the following API changes:
* Configuration property `CheckExternalLinksTask.IgnoreCodes` renamed to `CheckExternalLinksTask.ignore_codes`
* Configuration property `CheckExternalLinksTask.FollowLocation` and `BypassCache` renamed to `follow_location` and `bypass_cache`
@ -109,3 +108,19 @@ following config in config.yml.
SilverStripe\ExternalLinks\Tasks\CurlLinkChecker::
bypass_cache: 1
```
## Headers
You may want to set headers to be sent with the CURL request (eg: user-agent) to avoid website rejecting the request thinking it is a bot.
You can set them with the following config in config.yml.
```yaml
# Headers
SilverStripe\ExternalLinks\Tasks\CurlLinkChecker:
headers:
- 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0'
- 'accept-encoding: gzip, deflate, br'
- 'referer: https://www.domain.com/'
- 'sec-fetch-mode: navigate'
...
```

5
_config/legacy.yml Normal file
View File

@ -0,0 +1,5 @@
SilverStripe\ORM\DatabaseAdmin:
classname_value_remapping:
BrokenExternalLink: SilverStripe\ExternalLinks\Model\BrokenExternalLink
BrokenExternalPageTrack: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack
BrokenExternalPageTrackStatus: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus

29
behat.yml Normal file
View File

@ -0,0 +1,29 @@
default:
suites:
externallinks:
paths:
- "%paths.modules.externallinks%/tests/behat/features"
contexts:
- SilverStripe\Admin\Tests\Behat\Context\AdminContext
- SilverStripe\BehatExtension\Context\BasicContext
- SilverStripe\BehatExtension\Context\EmailContext
- SilverStripe\BehatExtension\Context\LoginContext
- SilverStripe\Framework\Tests\Behaviour\CmsFormsContext
- SilverStripe\Framework\Tests\Behaviour\CmsUiContext
- SilverStripe\ExternalLinks\Tests\Behat\Context\FeatureContext
- SilverStripe\ExternalLinks\Tests\Behat\Context\FixtureContext
-
SilverStripe\ExternalLinks\Tests\Behat\Context\FixtureContext:
- "%paths.modules.externallinks%/tests/behat/files/"
extensions:
SilverStripe\BehatExtension\MinkExtension:
default_session: facebook_web_driver
javascript_session: facebook_web_driver
facebook_web_driver:
browser: chrome
wd_host: "http://127.0.0.1:9515"
SilverStripe\BehatExtension\Extension:
screenshot_path: "%paths.base%/artifacts/screenshots"
bootstrap_file: vendor/silverstripe/framework/tests/behat/serve-bootstrap.php

View File

@ -17,6 +17,7 @@
},
start: function() {
var self = this;
// initiate a new job
$('.external-links-report__report-progress')
.empty()
@ -25,10 +26,14 @@
$.ajax({
url: "admin/externallinks/start",
async: true,
timeout: 3000
timeout: 3000,
success: function() {
self.poll();
},
error: function() {
self.buttonReset();
}
});
this.poll();
},
/**
@ -53,6 +58,7 @@
// set button to "submitting" state
$button.addClass('btn--loading loading');
$button.attr('disabled', true);
if ($button.is('button')) {
$button.append($(
@ -75,6 +81,7 @@
var $button = this.getButton();
$button.removeClass('btn--loading loading');
$button.attr('disabled', false);
$button.find('.btn__loading-icon').remove();
$button.css('width', 'auto');
},
@ -89,7 +96,7 @@
success: function(data) {
// No report, so let user create one
if (!data) {
this.buttonReset();
self.buttonReset();
return;
}
@ -123,10 +130,8 @@
$('.external-links-report__create-report').poll();
}, 1000));
},
error: function(e) {
if (typeof console !== 'undefined') {
console.log(e);
}
error: function() {
self.buttonReset();
}
});
}

View File

@ -2,7 +2,12 @@
"name": "silverstripe/externallinks",
"description": "Adds tracking of broken external links to the SilverStripe CMS",
"type": "silverstripe-vendormodule",
"keywords": ["silverstripe", "broken", "links", "href"],
"keywords": [
"silverstripe",
"broken",
"links",
"href"
],
"license": "BSD-3-Clause",
"authors": [
{
@ -11,27 +16,30 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"silverstripe/cms": "^4.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.0"
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.0",
"symbiote/silverstripe-queuedjobs": "^4.9"
},
"suggest": {
"silverstripe/queuedjobs": "Provides a more efficient method of generating/updating the report"
"symbiote/silverstripe-queuedjobs": "Provides a more efficient method of generating/updating the report"
},
"autoload": {
"psr-4": {
"SilverStripe\\ExternalLinks\\": "src/",
"SilverStripe\\ExternalLinks\\Tests\\": "tests/"
"SilverStripe\\ExternalLinks\\Tests\\": "tests/",
"SilverStripe\\ExternalLinks\\Tests\\Behat\\Context\\": "tests/behat/src/"
}
},
"extra": {
"expose": [
"css",
"javascript"
"client/css",
"client/javascript"
]
},
"minimum-stability": "dev",
"prefer-stable": true
}
}

View File

@ -1,8 +1,14 @@
de:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Überprüfe defekte externe Links'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Server nicht verfügbar'
PLURALNAME: 'Defekte externe Links'
PLURALS:
one: 'Ein defekter externer Link'
other: '{count} defekte externe Links'
SINGULARNAME: 'Defekter externer Link'
UNKNOWNRESPONSE: 'Unbekannter Antwortcode'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Defekte externe Links Report'
RUNREPORT: 'Generiere neuen Bericht'

View File

@ -1,17 +1,38 @@
en:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Checking for external broken links'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Server Not Available'
PLURALNAME: 'Broken External Links'
PLURALS:
one: 'A Broken External Link'
other: '{count} Broken External Links'
SINGULARNAME: 'Broken External Link'
UNKNOWNRESPONSE: 'Unknown Response Code'
db_HTTPCode: 'HTTP code'
db_Link: Link
has_one_Status: Status
has_one_Track: Track
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Broken External Page Tracks'
PLURALS:
one: 'A Broken External Page Track'
other: '{count} Broken External Page Tracks'
SINGULARNAME: 'Broken External Page Track'
db_Processed: Processed
has_many_BrokenLinks: 'Broken links'
has_one_Page: Page
has_one_Status: Status
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Broken External Page Track Statuss'
PLURALNAME: 'Broken External Page Track Statuses'
PLURALS:
one: 'A Broken External Page Track Status'
other: '{count} Broken External Page Track Statuses'
SINGULARNAME: 'Broken External Page Track Status'
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Checking for external broken links'
db_JobInfo: 'Job info'
db_Status: Status
has_many_BrokenLinks: 'Broken links'
has_many_TrackedPages: 'Tracked pages'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'External broken links report'
RUNREPORT: 'Create new report'

View File

@ -1,17 +1,38 @@
eo:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Kontrolas por eksteraj rompitaj ligiloj'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Servilo estas neatingenbla'
PLURALNAME: 'Rompitaj eksteraj ligiloj'
PLURALS:
one: 'Unu rompita ekstera ligilo'
other: '{count} rompitaj eksteraj ligiloj'
SINGULARNAME: 'Rompita ekstera ligilo'
UNKNOWNRESPONSE: 'Nekonata respondokodo'
db_HTTPCode: HTTP-kodo
db_Link: Ligilo
has_one_Status: Stato
has_one_Track: Spuri
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Rompitaj eksteraj paĝaj trakoj'
PLURALS:
one: 'Unu rompita ekstera paĝa trako'
other: '{count} rompitaj eksteraj paĝaj trakoj'
SINGULARNAME: 'Rompita ekstera paĝa trako'
db_Processed: Traktita
has_many_BrokenLinks: 'Rompitaj ligiloj'
has_one_Page: Paĝo
has_one_Status: Stato
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Stato de rompitaj eksteraj paĝaj trakoj'
PLURALS:
one: 'Unu stato de rompita ekstera paĝa trako'
other: '{count} statoj de rompitaj eksteraj paĝaj trakoj'
SINGULARNAME: 'Stato de rompita ekstera paĝa trako'
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Kontrolas por eksteraj rompitaj ligiloj'
db_JobInfo: 'Taska informo'
db_Status: Stato
has_many_BrokenLinks: 'Rompitaj ligiloj'
has_many_TrackedPages: 'Spuritaj paĝoj'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Raporto pri eksteraj rompitaj ligiloj'
RUNREPORT: 'Krei novan raporton'

16
lang/fi.yml Normal file
View File

@ -0,0 +1,16 @@
fi:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Tarkastettaan rikkinäiset ulkoiset linkit'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Palvelin ei saatavilla'
PLURALNAME: 'Rikkinäiset ulkoiset linkit'
SINGULARNAME: 'Rikkinäinen ulkoinen linkki'
UNKNOWNRESPONSE: 'Tuntematon vastauskoodi'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Rikkinäiset ulkoisen sivun reitit'
SINGULARNAME: 'Rikkinäinen ulkoisen sivun reitti'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
SINGULARNAME: 'Rikkinäinen ulkoisen sivun reitin tila'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Raportti ulkoisista rikkinäisistä linkeistä'
RUNREPORT: 'Luo uusi raportti'

26
lang/fi_FI.yml Normal file
View File

@ -0,0 +1,26 @@
fi_FI:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Tarkastetaan ulkoiset rikkinäiset linkit'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Palvelin ei saatavilla'
PLURALNAME: 'Rikkinäiset ulkoiset linkit'
PLURALS:
one: 'Rikkinäinen ulkoinen linkki'
other: '{count} rikkinäistä ulkoista linkkiä'
SINGULARNAME: 'Rikkinäinen ulkoinen linkki'
UNKNOWNRESPONSE: 'Tuntematon vastauskoodi'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Rikkinäiset ulkoiset sivut'
PLURALS:
one: 'Rikkinäinen ulkoinen sivu'
other: '{count} rikkinäistä ulkoista sivua'
SINGULARNAME: 'Rikkinäinen ulkoinen sivu'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Rikkinäisten ulkoisten sivujen tila'
PLURALS:
one: 'Rikkinäisen ulkoisen sivun tila'
other: '{count} rikkinäistä ulkoisten sivujen tilaa'
SINGULARNAME: 'Rikkinäisen ulkoisen sivun tila'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Rikkinäisten ulkoisten linkkien raportti'
RUNREPORT: 'Luo uusi raportti'

29
lang/it.yml Normal file
View File

@ -0,0 +1,29 @@
it:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Ricerca link esterni orfani'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Server Non Disponibile'
PLURALNAME: 'Link Esterni Orfani'
PLURALS:
many: '{count} Link Esterni Orfani'
one: 'Un Link Esterno Orfano'
other: '{count} Link Esterni Orfani'
SINGULARNAME: 'Link Esterno Orfano'
UNKNOWNRESPONSE: 'Codice di Risposta Sconosciuto'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Tracce Pagine Esterne Orfane'
PLURALS:
many: '{count} Tracce Pagine Esterne Orfane'
one: 'Una Traccia Pagina Esterna Orfana'
other: '{count} Tracce Pagine Esterne Orfane'
SINGULARNAME: 'Traccia Pagina Esterna Orfana'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Stati Tracce Pagine Esterne Orfane'
PLURALS:
many: '{count} Stati Tracce Pagine Esterne Orfane'
one: 'Uno Stato Traccia Pagina Esterna Orfana'
other: '{count} Stati Tracce Pagine Esterne Orfane'
SINGULARNAME: 'Stato Traccia Pagina Esterna Orfana'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Report link esterni orfani'
RUNREPORT: 'Creare nuovo report'

26
lang/nl.yml Normal file
View File

@ -0,0 +1,26 @@
nl:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Niet-werkende externe links worden gecontroleerd'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Server niet beschikbaar'
PLURALNAME: 'Kapotte externe links'
PLURALS:
one: 'Kapotte externe link'
other: '{count} Kapotte externe links'
SINGULARNAME: 'Kapotte externe link'
UNKNOWNRESPONSE: 'Onbekende responsecode'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Kapotte externe Pagina Verwijzing'
PLURALS:
one: 'Kapotte externe Pagina Verwijzing'
other: '{count} Kapotte externe Pagina Verwijzing'
SINGULARNAME: 'Kapotte externe Pagina Verwijzing'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Kapotte externe Pagina Verwijzing Statusssen'
PLURALS:
one: 'Een kapotte externe Pagina Verwijzing Status'
other: '{count} Kapotte externe Pagina Verwijzing Statusssen'
SINGULARNAME: 'Kapotte externe Pagina Verwijzing Status'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Externe kapotte links overzicht'
RUNREPORT: 'Maak nieuw overzicht'

View File

@ -1,4 +1,6 @@
pl:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Wyszukiwanie uszkodzonych linków zewnętrznych'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Serwer niedostępny'
PLURALNAME: 'Uszkodzone linki zewnętrzne'
@ -10,8 +12,6 @@ pl:
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Statusy wykrywania wadliwych stron zewnętrznych'
SINGULARNAME: 'Status wykrywania wadliwych stron zewnętrznych'
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Wyszukiwanie uszkodzonych linków zewnętrznych'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Raport uszkodzonych linków zewnętrznych'
RUNREPORT: 'Stwórz nowy raport'

16
lang/ru.yml Normal file
View File

@ -0,0 +1,16 @@
ru:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Проверяю внешние ссылки'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Сервер не доступен'
PLURALNAME: 'Недоступные внешние ссылки'
SINGULARNAME: 'Недоступная внешняя ссылка'
UNKNOWNRESPONSE: 'Неизвестный ответ сервера'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Внешнее отслеживание страниц нарушено'
SINGULARNAME: 'Внешнее отслеживание страниц нарушено'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
SINGULARNAME: 'Внешнее отслеживание страниц нарушено'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Отчёт о неработающих внешних ссылках'
RUNREPORT: 'Создать новый отчёт'

44
lang/sk.yml Normal file
View File

@ -0,0 +1,44 @@
sk:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Kontrola externých nefunkčných odkazov'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Server nedostupný'
PLURALNAME: 'Nefunkčné externé odkazy'
PLURALS:
few: '{count} nefunkčné externé odkazy'
many: '{count} nefunkčných externých odkazov'
one: 'Nefunkčný externý odkaz'
other: '{count} nefunkčných externých odkazov'
SINGULARNAME: 'Nefunkčný externý odkaz'
UNKNOWNRESPONSE: 'Neznámy kód odpovede'
db_HTTPCode: 'HTTP kód'
db_Link: Odkaz
has_one_Status: Stav
has_one_Track: Stopa
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Nefunkčné externé stopy stránok'
PLURALS:
few: '{count} nefunkčné externé stopy stránky'
many: '{count} nefunkčných externých stôp stránky'
one: 'Nefunkčná externá stopa stránky'
other: '{count} nefunkčných externých stôp stránky'
SINGULARNAME: 'Nefunkčná externá stopa stránky'
db_Processed: Spracované
has_many_BrokenLinks: 'Nefunkčné odkazy'
has_one_Page: Stránka
has_one_Status: Stav
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Stavy nefunkčných externých stôp stránky'
PLURALS:
few: '{count} stavy nefunkčných externých stôp stránky'
many: '{count} stavov nefunkčných externých stôp stránky'
one: 'Stav nefunkčnej externej stopy stránky'
other: '{count} stavov nefunkčných externých stôp stránky'
SINGULARNAME: 'Stav nefunkčnej externej stopy stránky'
db_JobInfo: 'Informácie o úlohe'
db_Status: Stav
has_many_BrokenLinks: 'Nefunkčné odkazy'
has_many_TrackedPages: 'Sledované stránky'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Správa o externých nefunkčných odkazoch'
RUNREPORT: 'Vytvoriť novú správu'

32
lang/sl.yml Normal file
View File

@ -0,0 +1,32 @@
sl:
SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob:
TITLE: 'Preverjamo, ali so zunanje povezave dostopne'
SilverStripe\ExternalLinks\Model\BrokenExternalLink:
NOTAVAILABLE: 'Strežnik ni na voljo'
PLURALNAME: 'Nedostopne zunanje povezave'
PLURALS:
few: '{count} nedostopnih zunanjih povezav'
one: 'Nedostopna zunanja povezava'
other: '{count} nedostopnih zunanjih povezav'
two: '{count} nedostopni zunanji povezavi'
SINGULARNAME: 'Nedostopna zunanja povezava'
UNKNOWNRESPONSE: 'Neznana šifra odziva'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Preverjanja nedostopnih zunanjih povezav'
PLURALS:
few: '{count} preverjanj nedostopnih zunanjih povezav'
one: 'Preverjanje nedostopnih zunanjih povezav'
other: '{count} preverjanj nedostopnih zunanjih povezav'
two: '{count} preverjanji nedostopnih zunanjih povezav'
SINGULARNAME: 'Preverjanje nedostopnih zunanjih povezav'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Status preverjanj'
PLURALS:
few: '{count} statusov preverjanj'
one: 'Status preverjanja'
other: '{count} statusov preverjanj'
two: '{count} statusa preverjanj'
SINGULARNAME: 'Status preverjanja'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Poročilo o nedostopnih zunanjih povezavah'
RUNREPORT: 'Pripravi novo poročilo'

View File

@ -2,6 +2,9 @@
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<file>src</file>
<file>tests</file>
<rule ref="PSR2" >
<!-- Current exclusions -->
<exclude name="PSR1.Methods.CamelCapsMethodName" />

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/silverstripe/cms/tests/bootstrap.php" colors="true">
<testsuite name="Default">
<directory>tests/</directory>
</testsuite>
<testsuites>
<testsuite name="Default">
<directory>tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>

View File

@ -2,13 +2,13 @@
namespace SilverStripe\ExternalLinks\Controllers;
use SilverStripe\Control\HTTP;
use SilverStripe\Core\Convert;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus;
use SilverStripe\ExternalLinks\Jobs\CheckExternalLinksJob;
use SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask;
use SilverStripe\Control\Controller;
use Symbiote\QueuedJobs\Services\QueuedJobService;
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
use SilverStripe\Security\Permission;
class CMSExternalLinksController extends Controller
{
@ -25,9 +25,11 @@ class CMSExternalLinksController extends Controller
*/
public function getJobStatus()
{
if (!Permission::check('CMS_ACCESS_CMSMain')) {
return $this->httpError(403, 'You do not have permission to access this resource');
}
// Set headers
HTTP::set_cache_age(0);
HTTP::add_cache_headers($this->response);
HTTPCacheControlMiddleware::singleton()->setMaxAge(0);
$this->response
->addHeader('Content-Type', 'application/json')
->addHeader('Content-Encoding', 'UTF-8')
@ -36,7 +38,7 @@ class CMSExternalLinksController extends Controller
// Format status
$track = BrokenExternalPageTrackStatus::get_latest();
if ($track) {
return Convert::array2json([
return json_encode([
'TrackID' => $track->ID,
'Status' => $track->Status,
'Completed' => $track->getCompletedPages(),
@ -51,6 +53,9 @@ class CMSExternalLinksController extends Controller
*/
public function start()
{
if (!Permission::check('CMS_ACCESS_CMSMain')) {
return $this->httpError(403, 'You do not have permission to access this resource');
}
// return if the a job is already running
$status = BrokenExternalPageTrackStatus::get_latest();
if ($status && $status->Status == 'Running') {

View File

@ -2,9 +2,9 @@
namespace SilverStripe\ExternalLinks\Model;
use InvalidArgumentException;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
@ -12,6 +12,8 @@ use SilverStripe\Security\Security;
/**
* Represents a single link checked for a single run that is broken
*
* @property string Link
* @property int HTTPCode
* @method BrokenExternalPageTrack Track()
* @method BrokenExternalPageTrackStatus Status()
*/
@ -56,7 +58,7 @@ class BrokenExternalLink extends DataObject
public function canView($member = false)
{
$member = $member ? $member : Security::getCurrentUser();
$codes = array('content-authors', 'administrators');
$codes = ['CMS_ACCESS_CMSMain'];
return Permission::checkMember($member, $codes);
}

View File

@ -2,9 +2,8 @@
namespace SilverStripe\ExternalLinks\Model;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack;
use SilverStripe\ExternalLinks\Model\BrokenExternalLink;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\i18n\i18nEntityProvider;
use SilverStripe\Versioned\Versioned;
use SilverStripe\ORM\DataObject;
@ -16,7 +15,7 @@ use SilverStripe\ORM\DataObject;
* @property int $TotalPages Get total pages count
* @property int $CompletedPages Get completed pages count
*/
class BrokenExternalPageTrackStatus extends DataObject
class BrokenExternalPageTrackStatus extends DataObject implements i18nEntityProvider
{
private static $table_name = 'BrokenExternalPageTrackStatus';
@ -42,6 +41,23 @@ class BrokenExternalPageTrackStatus extends DataObject
->first();
}
/**
* Returns the list of provided translations for this object
*
* @return array
*/
public function provideI18nEntities()
{
return [
__CLASS__ . '.SINGULARNAME' => 'Broken External Page Track Status',
__CLASS__ . '.PLURALNAME' => 'Broken External Page Track Statuses',
__CLASS__ . '.PLURALS' => [
'one' => 'A Broken External Page Track Status',
'other' => '{count} Broken External Page Track Statuses',
],
];
}
/**
* Gets the list of Pages yet to be checked
*

View File

@ -71,15 +71,16 @@ class BrokenExternalLinksReport extends Report
{
$track = BrokenExternalPageTrackStatus::get_latest();
if ($track) {
return $track->BrokenLinks();
// Filter items that are attached to archived Pages
return $track->BrokenLinks()->exclude('Track.Page.ID', null);
}
return ArrayList::create();
}
public function getCMSFields()
{
Requirements::css('silverstripe/externallinks: css/BrokenExternalLinksReport.css');
Requirements::javascript('silverstripe/externallinks: javascript/BrokenExternalLinksReport.js');
Requirements::css('silverstripe/externallinks: client/css/BrokenExternalLinksReport.css');
Requirements::javascript('silverstripe/externallinks: client/javascript/BrokenExternalLinksReport.js');
$fields = parent::getCMSFields();

View File

@ -101,7 +101,7 @@ class CheckExternalLinksTask extends BuildTask
{
$class = $link->getAttribute('class');
$href = $link->getAttribute('href');
$markedBroken = preg_match('/\b(ss-broken)\b/', $class);
$markedBroken = preg_match('/\b(ss-broken)\b/', $class ?? '');
// Check link
$httpCode = $this->linkChecker->checkLink($href);
@ -127,9 +127,9 @@ class CheckExternalLinksTask extends BuildTask
if ($foundBroken) {
$class .= ' ss-broken';
} else {
$class = preg_replace('/\s*\b(ss-broken)\b\s*/', ' ', $class);
$class = preg_replace('/\s*\b(ss-broken)\b\s*/', ' ', $class ?? '');
}
$link->setAttribute('class', trim($class));
$link->setAttribute('class', trim($class ?? ''));
}
/**
@ -147,7 +147,7 @@ class CheckExternalLinksTask extends BuildTask
// do we have any whitelisted codes
$ignoreCodes = $this->config()->get('ignore_codes');
if (is_array($ignoreCodes) && in_array($httpCode, $ignoreCodes)) {
if (is_array($ignoreCodes) && in_array($httpCode, $ignoreCodes ?? [])) {
return false;
}

View File

@ -31,6 +31,14 @@ class CurlLinkChecker implements LinkChecker
*/
private static $bypass_cache = false;
/**
* Allow to pass custom header to be in CURL request
*
* @config
* @var array
*/
private static $headers = [];
/**
* Return cache
*
@ -50,11 +58,11 @@ class CurlLinkChecker implements LinkChecker
public function checkLink($href)
{
// Skip non-external links
if (!preg_match('/^https?[^:]*:\/\//', $href)) {
if (!preg_match('/^https?[^:]*:\/\//', $href ?? '')) {
return null;
}
$cacheKey = md5($href);
$cacheKey = md5($href ?? '');
if (!$this->config()->get('bypass_cache')) {
// Check if we have a cached result
$result = $this->getCache()->get($cacheKey, false);
@ -66,11 +74,19 @@ class CurlLinkChecker implements LinkChecker
// No cached result so just request
$handle = curl_init($href);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 10);
if ($this->config()->get('follow_location')) {
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);
}
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($handle, CURLOPT_TIMEOUT, 10);
// Add headers
$headers = (array) $this->config()->get('headers');
if (!empty($headers)) {
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
}
// Retrieve http code
curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
@ -79,6 +95,7 @@ class CurlLinkChecker implements LinkChecker
// Cache result
$this->getCache()->set($cacheKey, $httpCode);
}
return $httpCode;
}
}

View File

View File

@ -0,0 +1,34 @@
Feature: External links report
As a website user
I want to use the external links report
Background:
Given the "group" "EDITOR group" has permissions "CMS_ACCESS_LeftAndMain"
# Need to use single quotes rather than escaped double quotes when defining the fixture otherwise
# it'll end up saved as &quot; and the hyperlink will be wrong
# When the page is published it should be converted by tinymce to double quotes
Given a "page" "My page" has the "Content" "<p>My <a href='http://fsdjoifidsohfiohfsoifhiodshfhdosi.com'>link</a> content</p>"
Scenario: Operate the external links report
Given I am logged in with "ADMIN" permissions
# Publish page
When I go to "/admin/pages"
And I follow "My page"
And I press the "Publish" button
# Run report
When I go to "/admin/reports"
And I follow "External broken links"
And I press the "Create new report" button
# Run queuedjob, new job will be the first row
When I go to "/admin/queuedjobs"
When I click on the ".gridfield-button-jobexecute" element
And I wait for 15 seconds
# Assert report
When I go to "/admin/reports"
And I follow "External broken links"
Then I should see "http://fsdjoifidsohfiohfsoifhiodshfhdosi.com"
And I should see "My page"

View File

View File

@ -0,0 +1,9 @@
<?php
namespace SilverStripe\ExternalLinks\Tests\Behat\Context;
use SilverStripe\BehatExtension\Context\SilverStripeContext;
class FeatureContext extends SilverStripeContext
{
}

View File

@ -0,0 +1,9 @@
<?php
namespace SilverStripe\ExternalLinks\Tests\Behat\Context;
use SilverStripe\BehatExtension\Context\FixtureContext as BaseFixtureContext;
class FixtureContext extends BaseFixtureContext
{
}

View File

@ -3,7 +3,7 @@
namespace SilverStripe\ExternalLinks\Tests;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus;
use SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport;
use SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask;
@ -13,7 +13,7 @@ use SilverStripe\ExternalLinks\Tests\Stubs\PretendLinkChecker;
use SilverStripe\i18n\i18n;
use SilverStripe\Reports\Report;
class ExternalLinksTest extends SapphireTest
class ExternalLinksTest extends FunctionalTest
{
protected static $fixture_file = 'ExternalLinksTest.yml';
@ -22,7 +22,7 @@ class ExternalLinksTest extends SapphireTest
ExternalLinksTestPage::class
);
protected function setUp()
protected function setUp(): void
{
parent::setUp();
@ -68,7 +68,7 @@ class ExternalLinksTest extends SapphireTest
'http://www.broken.com/url/thing',
'http://www.nodomain.com'
),
array_values($links->map('ID', 'Link')->toArray())
array_values($links->map('ID', 'Link')->toArray() ?? [])
);
// Check response codes are correct
@ -107,4 +107,47 @@ class ExternalLinksTest extends SapphireTest
'BrokenExternalLinksReport is in reports list'
);
}
public function testArchivedPagesAreHiddenFromReport()
{
// Run link checker
$task = CheckExternalLinksTask::create();
$task->setSilent(true); // Be quiet during the test!
$task->runLinksCheck();
// Ensure report lists all broken links
$this->assertEquals(4, BrokenExternalLinksReport::create()->sourceRecords()->count());
// Archive a page
$page = $this->objFromFixture(ExternalLinksTestPage::class, 'page1');
$page->doArchive();
// Ensure report does not list the link associated with an archived page
$this->assertEquals(3, BrokenExternalLinksReport::create()->sourceRecords()->count());
}
public function provideGetJobStatus(): array
{
return [
'ADMIN - valid permission' => ['ADMIN', 200],
'CMS_ACCESS_CMSMain - valid permission' => ['CMS_ACCESS_CMSMain', 200],
'VIEW_SITE - not enough permission' => ['VIEW_SITE', 403],
];
}
/**
* @dataProvider provideGetJobStatus
*/
public function testGetJobStatus(
string $permission,
int $expectedResponseCode
): void {
$this->logInWithPermission($permission);
$response = $this->get('admin/externallinks/start', null, ['Accept' => 'application/json']);
$this->assertEquals($expectedResponseCode, $response->getStatusCode());
$response = $this->get('admin/externallinks/getJobStatus', null, ['Accept' => 'application/json']);
$this->assertEquals($expectedResponseCode, $response->getStatusCode());
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace SilverStripe\ExternalLinks\Tests\Model;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ExternalLinks\Model\BrokenExternalLink;
class BrokenExternalLinkTest extends SapphireTest
{
/**
* @dataProvider httpCodeProvider
*/
public function testGetHTTPCodeDescription(int $httpCode, string $expected)
{
$link = new BrokenExternalLink();
$link->HTTPCode = $httpCode;
$this->assertSame($expected, $link->getHTTPCodeDescription());
}
public function httpCodeProvider(): array
{
return [
[200, '200 (OK)'],
[302, '302 (Found)'],
[404, '404 (Not Found)'],
[500, '500 (Internal Server Error)'],
[789, '789 (Unknown Response Code)'],
];
}
public function permissionProvider(): array
{
return [
['admin', 'ADMIN'],
['content-author', 'CMS_ACCESS_CMSMain'],
['asset-admin', 'CMS_ACCESS_AssetAdmin'],
];
}
/**
* @dataProvider permissionProvider
*/
public function testCanViewReport(string $user, string $permission)
{
$this->logOut();
$this->logInWithPermission($permission);
$link = new BrokenExternalLink();
if ($user === 'asset-admin') {
$this->assertFalse($link->canView());
} else {
$this->assertTrue($link->canView());
}
}
}