Compare commits

..

No commits in common. "2" and "2.1.1" have entirely different histories.
2 ... 2.1.1

36 changed files with 105 additions and 407 deletions

View File

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

View File

@ -1,16 +0,0 @@
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

View File

@ -1,17 +0,0 @@
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

15
.scrutinizer.yml Normal file
View File

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

4
.travis.yml Normal file
View File

@ -0,0 +1,4 @@
version: ~> 1.0
import:
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml

View File

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

View File

@ -1,7 +1,9 @@
# External links # External links
[![CI](https://github.com/silverstripe/silverstripe-externallinks/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-externallinks/actions/workflows/ci.yml) [![Build Status](http://img.shields.io/travis/silverstripe/silverstripe-externallinks.svg?style=flat)](https://travis-ci.org/silverstripe/silverstripe-externallinks)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/) [![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)
[![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Introduction ## Introduction
@ -13,9 +15,9 @@ The external links module is a task and ModelAdmin to track and to report on bro
## Requirements ## 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 ## Features
@ -79,7 +81,7 @@ SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask:
## Upgrading from 1.x to 2.x ## 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.IgnoreCodes` renamed to `CheckExternalLinksTask.ignore_codes`
* Configuration property `CheckExternalLinksTask.FollowLocation` and `BypassCache` renamed to `follow_location` and `bypass_cache` * Configuration property `CheckExternalLinksTask.FollowLocation` and `BypassCache` renamed to `follow_location` and `bypass_cache`

View File

@ -1,29 +0,0 @@
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

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

View File

@ -17,7 +17,6 @@
}, },
start: function() { start: function() {
var self = this;
// initiate a new job // initiate a new job
$('.external-links-report__report-progress') $('.external-links-report__report-progress')
.empty() .empty()
@ -26,14 +25,10 @@
$.ajax({ $.ajax({
url: "admin/externallinks/start", url: "admin/externallinks/start",
async: true, async: true,
timeout: 3000, timeout: 3000
success: function() {
self.poll();
},
error: function() {
self.buttonReset();
}
}); });
this.poll();
}, },
/** /**
@ -130,8 +125,10 @@
$('.external-links-report__create-report').poll(); $('.external-links-report__create-report').poll();
}, 1000)); }, 1000));
}, },
error: function() { error: function(e) {
self.buttonReset(); if (typeof console !== 'undefined') {
console.log(e);
}
} }
}); });
} }

View File

@ -9,30 +9,18 @@ en:
other: '{count} Broken External Links' other: '{count} Broken External Links'
SINGULARNAME: 'Broken External Link' SINGULARNAME: 'Broken External Link'
UNKNOWNRESPONSE: 'Unknown Response Code' UNKNOWNRESPONSE: 'Unknown Response Code'
db_HTTPCode: 'HTTP code'
db_Link: Link
has_one_Status: Status
has_one_Track: Track
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Broken External Page Tracks' PLURALNAME: 'Broken External Page Tracks'
PLURALS: PLURALS:
one: 'A Broken External Page Track' one: 'A Broken External Page Track'
other: '{count} Broken External Page Tracks' other: '{count} Broken External Page Tracks'
SINGULARNAME: 'Broken External Page Track' 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: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Broken External Page Track Statuses' PLURALNAME: 'Broken External Page Track Statuses'
PLURALS: PLURALS:
one: 'A Broken External Page Track Status' one: 'A Broken External Page Track Status'
other: '{count} Broken External Page Track Statuses' other: '{count} Broken External Page Track Statuses'
SINGULARNAME: 'Broken External Page Track Status' SINGULARNAME: 'Broken External Page Track Status'
db_JobInfo: 'Job info'
db_Status: Status
has_many_BrokenLinks: 'Broken links'
has_many_TrackedPages: 'Tracked pages'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport: SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'External broken links report' EXTERNALBROKENLINKS: 'External broken links report'
RUNREPORT: 'Create new report' RUNREPORT: 'Create new report'

View File

@ -9,30 +9,18 @@ eo:
other: '{count} rompitaj eksteraj ligiloj' other: '{count} rompitaj eksteraj ligiloj'
SINGULARNAME: 'Rompita ekstera ligilo' SINGULARNAME: 'Rompita ekstera ligilo'
UNKNOWNRESPONSE: 'Nekonata respondokodo' UNKNOWNRESPONSE: 'Nekonata respondokodo'
db_HTTPCode: HTTP-kodo
db_Link: Ligilo
has_one_Status: Stato
has_one_Track: Spuri
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Rompitaj eksteraj paĝaj trakoj' PLURALNAME: 'Rompitaj eksteraj paĝaj trakoj'
PLURALS: PLURALS:
one: 'Unu rompita ekstera paĝa trako' one: 'Unu rompita ekstera paĝa trako'
other: '{count} rompitaj eksteraj paĝaj trakoj' other: '{count} rompitaj eksteraj paĝaj trakoj'
SINGULARNAME: 'Rompita ekstera paĝa trako' 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: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Stato de rompitaj eksteraj paĝaj trakoj' PLURALNAME: 'Stato de rompitaj eksteraj paĝaj trakoj'
PLURALS: PLURALS:
one: 'Unu stato de rompita ekstera paĝa trako' one: 'Unu stato de rompita ekstera paĝa trako'
other: '{count} statoj de rompitaj eksteraj paĝaj trakoj' other: '{count} statoj de rompitaj eksteraj paĝaj trakoj'
SINGULARNAME: 'Stato de rompita ekstera paĝa trako' SINGULARNAME: 'Stato de rompita ekstera paĝa trako'
db_JobInfo: 'Taska informo'
db_Status: Stato
has_many_BrokenLinks: 'Rompitaj ligiloj'
has_many_TrackedPages: 'Spuritaj paĝoj'
SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport: SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport:
EXTERNALBROKENLINKS: 'Raporto pri eksteraj rompitaj ligiloj' EXTERNALBROKENLINKS: 'Raporto pri eksteraj rompitaj ligiloj'
RUNREPORT: 'Krei novan raporton' RUNREPORT: 'Krei novan raporton'

View File

@ -1,16 +0,0 @@
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'

View File

@ -5,7 +5,6 @@ it:
NOTAVAILABLE: 'Server Non Disponibile' NOTAVAILABLE: 'Server Non Disponibile'
PLURALNAME: 'Link Esterni Orfani' PLURALNAME: 'Link Esterni Orfani'
PLURALS: PLURALS:
many: '{count} Link Esterni Orfani'
one: 'Un Link Esterno Orfano' one: 'Un Link Esterno Orfano'
other: '{count} Link Esterni Orfani' other: '{count} Link Esterni Orfani'
SINGULARNAME: 'Link Esterno Orfano' SINGULARNAME: 'Link Esterno Orfano'
@ -13,14 +12,12 @@ it:
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrack:
PLURALNAME: 'Tracce Pagine Esterne Orfane' PLURALNAME: 'Tracce Pagine Esterne Orfane'
PLURALS: PLURALS:
many: '{count} Tracce Pagine Esterne Orfane'
one: 'Una Traccia Pagina Esterna Orfana' one: 'Una Traccia Pagina Esterna Orfana'
other: '{count} Tracce Pagine Esterne Orfane' other: '{count} Tracce Pagine Esterne Orfane'
SINGULARNAME: 'Traccia Pagina Esterna Orfana' SINGULARNAME: 'Traccia Pagina Esterna Orfana'
SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus: SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus:
PLURALNAME: 'Stati Tracce Pagine Esterne Orfane' PLURALNAME: 'Stati Tracce Pagine Esterne Orfane'
PLURALS: PLURALS:
many: '{count} Stati Tracce Pagine Esterne Orfane'
one: 'Uno Stato Traccia Pagina Esterna Orfana' one: 'Uno Stato Traccia Pagina Esterna Orfana'
other: '{count} Stati Tracce Pagine Esterne Orfane' other: '{count} Stati Tracce Pagine Esterne Orfane'
SINGULARNAME: 'Stato Traccia Pagina Esterna Orfana' SINGULARNAME: 'Stato Traccia Pagina Esterna Orfana'

View File

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

View File

@ -1,16 +0,0 @@
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: 'Создать новый отчёт'

View File

@ -1,44 +0,0 @@
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'

View File

@ -1,32 +0,0 @@
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

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

View File

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

View File

@ -58,7 +58,7 @@ class BrokenExternalLink extends DataObject
public function canView($member = false) public function canView($member = false)
{ {
$member = $member ? $member : Security::getCurrentUser(); $member = $member ? $member : Security::getCurrentUser();
$codes = ['CMS_ACCESS_CMSMain']; $codes = array('content-authors', 'administrators');
return Permission::checkMember($member, $codes); return Permission::checkMember($member, $codes);
} }

View File

@ -79,8 +79,8 @@ class BrokenExternalLinksReport extends Report
public function getCMSFields() public function getCMSFields()
{ {
Requirements::css('silverstripe/externallinks: client/css/BrokenExternalLinksReport.css'); Requirements::css('silverstripe/externallinks: css/BrokenExternalLinksReport.css');
Requirements::javascript('silverstripe/externallinks: client/javascript/BrokenExternalLinksReport.js'); Requirements::javascript('silverstripe/externallinks: javascript/BrokenExternalLinksReport.js');
$fields = parent::getCMSFields(); $fields = parent::getCMSFields();

View File

@ -101,7 +101,7 @@ class CheckExternalLinksTask extends BuildTask
{ {
$class = $link->getAttribute('class'); $class = $link->getAttribute('class');
$href = $link->getAttribute('href'); $href = $link->getAttribute('href');
$markedBroken = preg_match('/\b(ss-broken)\b/', $class ?? ''); $markedBroken = preg_match('/\b(ss-broken)\b/', $class);
// Check link // Check link
$httpCode = $this->linkChecker->checkLink($href); $httpCode = $this->linkChecker->checkLink($href);
@ -127,9 +127,9 @@ class CheckExternalLinksTask extends BuildTask
if ($foundBroken) { if ($foundBroken) {
$class .= ' ss-broken'; $class .= ' ss-broken';
} else { } 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 // do we have any whitelisted codes
$ignoreCodes = $this->config()->get('ignore_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; return false;
} }

View File

@ -58,11 +58,11 @@ class CurlLinkChecker implements LinkChecker
public function checkLink($href) public function checkLink($href)
{ {
// Skip non-external links // Skip non-external links
if (!preg_match('/^https?[^:]*:\/\//', $href ?? '')) { if (!preg_match('/^https?[^:]*:\/\//', $href)) {
return null; return null;
} }
$cacheKey = md5($href ?? ''); $cacheKey = md5($href);
if (!$this->config()->get('bypass_cache')) { if (!$this->config()->get('bypass_cache')) {
// Check if we have a cached result // Check if we have a cached result
$result = $this->getCache()->get($cacheKey, false); $result = $this->getCache()->get($cacheKey, false);

View File

@ -3,7 +3,7 @@
namespace SilverStripe\ExternalLinks\Tests; namespace SilverStripe\ExternalLinks\Tests;
use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\SapphireTest;
use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus; use SilverStripe\ExternalLinks\Model\BrokenExternalPageTrackStatus;
use SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport; use SilverStripe\ExternalLinks\Reports\BrokenExternalLinksReport;
use SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask; use SilverStripe\ExternalLinks\Tasks\CheckExternalLinksTask;
@ -13,7 +13,7 @@ use SilverStripe\ExternalLinks\Tests\Stubs\PretendLinkChecker;
use SilverStripe\i18n\i18n; use SilverStripe\i18n\i18n;
use SilverStripe\Reports\Report; use SilverStripe\Reports\Report;
class ExternalLinksTest extends FunctionalTest class ExternalLinksTest extends SapphireTest
{ {
protected static $fixture_file = 'ExternalLinksTest.yml'; protected static $fixture_file = 'ExternalLinksTest.yml';
@ -22,7 +22,7 @@ class ExternalLinksTest extends FunctionalTest
ExternalLinksTestPage::class ExternalLinksTestPage::class
); );
protected function setUp(): void protected function setUp()
{ {
parent::setUp(); parent::setUp();
@ -68,7 +68,7 @@ class ExternalLinksTest extends FunctionalTest
'http://www.broken.com/url/thing', 'http://www.broken.com/url/thing',
'http://www.nodomain.com' 'http://www.nodomain.com'
), ),
array_values($links->map('ID', 'Link')->toArray() ?? []) array_values($links->map('ID', 'Link')->toArray())
); );
// Check response codes are correct // Check response codes are correct
@ -125,29 +125,4 @@ class ExternalLinksTest extends FunctionalTest
// Ensure report does not list the link associated with an archived page // Ensure report does not list the link associated with an archived page
$this->assertEquals(3, BrokenExternalLinksReport::create()->sourceRecords()->count()); $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,35 @@
<?php
namespace SilverStripe\ExternalLinks\Tests\Model;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ExternalLinks\Model\BrokenExternalLink;
class BrokenExternalLinkTest extends SapphireTest
{
/**
* @param int $httpCode
* @param string $expected
* @dataProvider httpCodeProvider
*/
public function testGetHTTPCodeDescription($httpCode, $expected)
{
$link = new BrokenExternalLink();
$link->HTTPCode = $httpCode;
$this->assertSame($expected, $link->getHTTPCodeDescription());
}
/**
* @return array[]
*/
public function httpCodeProvider()
{
return [
[200, '200 (OK)'],
[302, '302 (Found)'],
[404, '404 (Not Found)'],
[500, '500 (Internal Server Error)'],
[789, '789 (Unknown Response Code)'],
];
}
}

View File

@ -1,34 +0,0 @@
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

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

View File

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

View File

@ -1,56 +0,0 @@
<?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());
}
}
}