Skip to content

Commit fa496f8

Browse files
committed
WIP refactored backend
This splits up all the code in classes and cleans everything up. A very few tests have been added. HTML has been simplified. Next up: frontend refactoring
1 parent bbfb182 commit fa496f8

16 files changed

+1041
-610
lines changed

.github/workflows/phpTestLinux.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: PHP Tests on Linux
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
testLinux:
7+
name: PHP ${{ matrix.php-versions }} DokuWiki ${{ matrix.dokuwiki-branch }}
8+
runs-on: ubuntu-latest
9+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
10+
11+
strategy:
12+
matrix:
13+
php-versions: ['7.2', '7.3', '7.4', '8.0']
14+
dokuwiki-branch: [ 'master', 'stable']
15+
exclude:
16+
- dokuwiki-branch: 'stable'
17+
php-versions: '8.0'
18+
fail-fast: false
19+
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v2
23+
24+
- name: Setup PHP
25+
uses: shivammathur/setup-php@v2
26+
with:
27+
php-version: ${{ matrix.php-versions }}
28+
extensions: mbstring, intl, PDO, pdo_sqlite, bz2
29+
30+
- name: Setup problem matchers
31+
run: |
32+
echo ::add-matcher::${{ runner.tool_cache }}/php.json
33+
echo ::add-matcher::${{ runner.tool_cache }}/phpunit.json
34+
35+
- name: Download DokuWiki Test-setup
36+
run: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh
37+
38+
- name: Run DokuWiki Test-setup
39+
env:
40+
CI_SERVER: 1
41+
DOKUWIKI: ${{ matrix.dokuwiki-branch }}
42+
run: sh travis.sh
43+
44+
- name: Setup PHPUnit
45+
run: |
46+
php _test/fetchphpunit.php
47+
cd _test
48+
49+
- name: Run PHPUnit
50+
run: |
51+
cd _test
52+
php phpunit.phar --verbose --stderr --group plugin_gallery

_test/FeedGalleryTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\gallery\test;
4+
5+
use dokuwiki\plugin\gallery\classes\FeedGallery;
6+
use dokuwiki\plugin\gallery\classes\Options;
7+
use DokuWikiTest;
8+
9+
/**
10+
* Media Feed tests for the gallery plugin
11+
*
12+
* @group plugin_gallery
13+
* @group plugins
14+
* @group internet
15+
*/
16+
class FeedGalleryTest extends DokuWikiTest
17+
{
18+
protected $pluginsEnabled = ['gallery'];
19+
20+
public function testGetImages()
21+
{
22+
$url = 'https://www.flickr.com/services/feeds/photoset.gne?nsid=22019303@N00&set=72177720310667219&lang=en-us&format=atom';
23+
$gallery = new FeedGallery($url, new Options());
24+
$images = $gallery->getImages();
25+
$this->assertIsArray($images);
26+
$this->assertCount(3, $images);
27+
}
28+
}

_test/GeneralTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\gallery\test;
4+
5+
use DokuWikiTest;
6+
7+
/**
8+
* General tests for the gallery plugin
9+
*
10+
* @group plugin_gallery
11+
* @group plugins
12+
*/
13+
class GeneralTest extends DokuWikiTest
14+
{
15+
16+
/**
17+
* Simple test to make sure the plugin.info.txt is in correct format
18+
*/
19+
public function testPluginInfo(): void
20+
{
21+
$file = __DIR__ . '/../plugin.info.txt';
22+
$this->assertFileExists($file);
23+
24+
$info = confToHash($file);
25+
26+
$this->assertArrayHasKey('base', $info);
27+
$this->assertArrayHasKey('author', $info);
28+
$this->assertArrayHasKey('email', $info);
29+
$this->assertArrayHasKey('date', $info);
30+
$this->assertArrayHasKey('name', $info);
31+
$this->assertArrayHasKey('desc', $info);
32+
$this->assertArrayHasKey('url', $info);
33+
34+
$this->assertEquals('gallery', $info['base']);
35+
$this->assertRegExp('/^https?:\/\//', $info['url']);
36+
$this->assertTrue(mail_isvalid($info['email']));
37+
$this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
38+
$this->assertTrue(false !== strtotime($info['date']));
39+
}
40+
41+
/**
42+
* Test to ensure that every conf['...'] entry in conf/default.php has a corresponding meta['...'] entry in
43+
* conf/metadata.php.
44+
*/
45+
public function testPluginConf(): void
46+
{
47+
$conf_file = __DIR__ . '/../conf/default.php';
48+
$meta_file = __DIR__ . '/../conf/metadata.php';
49+
50+
if (!file_exists($conf_file) && !file_exists($meta_file)) {
51+
self::markTestSkipped('No config files exist -> skipping test');
52+
}
53+
54+
if (file_exists($conf_file)) {
55+
include($conf_file);
56+
}
57+
if (file_exists($meta_file)) {
58+
include($meta_file);
59+
}
60+
61+
$this->assertEquals(
62+
gettype($conf),
63+
gettype($meta),
64+
'Both ' . DOKU_PLUGIN . 'gallery/conf/default.php and ' . DOKU_PLUGIN . 'gallery/conf/metadata.php have to exist and contain the same keys.'
65+
);
66+
67+
if ($conf !== null && $meta !== null) {
68+
foreach ($conf as $key => $value) {
69+
$this->assertArrayHasKey(
70+
$key,
71+
$meta,
72+
'Key $meta[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'gallery/conf/metadata.php'
73+
);
74+
}
75+
76+
foreach ($meta as $key => $value) {
77+
$this->assertArrayHasKey(
78+
$key,
79+
$conf,
80+
'Key $conf[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'gallery/conf/default.php'
81+
);
82+
}
83+
}
84+
85+
}
86+
}

_test/NamespaceGalleryTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\gallery\test;
4+
5+
use dokuwiki\plugin\gallery\classes\NamespaceGallery;
6+
use dokuwiki\plugin\gallery\classes\Options;
7+
use DokuWikiTest;
8+
9+
/**
10+
* Namespace Gallery tests for the gallery plugin
11+
*
12+
* @group plugin_gallery
13+
* @group plugins
14+
*/
15+
class NamespaceGalleryTest extends DokuWikiTest
16+
{
17+
protected $pluginsEnabled = ['gallery'];
18+
19+
/**
20+
* Copy demo images to the media directory
21+
*
22+
* @inheritdoc
23+
*/
24+
public static function setUpBeforeClass(): void
25+
{
26+
parent::setUpBeforeClass();
27+
global $conf;
28+
\TestUtils::rcopy($conf['mediadir'], __DIR__ . '/data/media/gallery');
29+
}
30+
31+
32+
/**
33+
* Check that the images are returned correctly
34+
*/
35+
public function testGetImages()
36+
{
37+
$gallery = new NamespaceGallery('gallery', new Options());
38+
39+
$images = $gallery->getImages();
40+
$this->assertIsArray($images);
41+
$this->assertCount(3, $images);
42+
}
43+
}

_test/data/media/gallery/img_0153.jpg

2.73 MB
Loading

_test/data/media/gallery/img_0373.jpg

2.19 MB
Loading

_test/data/media/gallery/img_1378.jpg

2.87 MB
Loading

classes/AbstractGallery.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\gallery\classes;
4+
5+
abstract class AbstractGallery
6+
{
7+
8+
9+
/** @var Image[] */
10+
protected $images = [];
11+
/** @var Options */
12+
protected Options $options;
13+
14+
/**
15+
* Initialize the Gallery
16+
*
17+
* @param string $src The source from where to get the images
18+
* @param Options $options Gallery configuration
19+
*/
20+
public function __construct($src, Options $options)
21+
{
22+
$this->options = $options;
23+
}
24+
25+
/**
26+
* Simple heuristic if something is an image
27+
*
28+
* @param string $src
29+
* @return bool
30+
*/
31+
public function hasImageExtension($src)
32+
{
33+
return (bool)preg_match(Image::IMG_REGEX, $src);
34+
}
35+
36+
/**
37+
* Get the images of this gallery
38+
*
39+
* The result will be sorted, reversed and limited according to the options
40+
*
41+
* @return Image[]
42+
*/
43+
public function getImages()
44+
{
45+
$images = $this->images; // create a copy of the array
46+
47+
switch ($this->options->sort) {
48+
case Options::SORT_FILE:
49+
usort($images, function ($a, $b) {
50+
return strcmp($a->getFilename(), $b->getFilename());
51+
});
52+
break;
53+
case Options::SORT_CTIME:
54+
usort($images, function ($a, $b) {
55+
return $a->getCreated() - $b->getCreated();
56+
});
57+
break;
58+
case Options::SORT_MTIME:
59+
usort($images, function ($a, $b) {
60+
return $a->getModified() - $b->getModified();
61+
});
62+
break;
63+
case Options::SORT_TITLE:
64+
usort($images, function ($a, $b) {
65+
return strcmp($a->getTitle(), $b->getTitle());
66+
});
67+
break;
68+
case Options::SORT_RANDOM:
69+
shuffle($images);
70+
break;
71+
}
72+
if ($this->options->reverse) {
73+
$images = array_reverse($images);
74+
}
75+
if ($this->options->offset) {
76+
$images = array_slice($images, $this->options->offset);
77+
}
78+
if ($this->options->limit) {
79+
$images = array_slice($images, 0, $this->options->limit);
80+
}
81+
82+
return $images;
83+
}
84+
}

classes/FeedGallery.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\gallery\classes;
4+
5+
use FeedParser;
6+
7+
class FeedGallery extends AbstractGallery
8+
{
9+
protected $feedHost;
10+
protected $feedPath;
11+
12+
/** @inheritdoc */
13+
public function __construct($url, Options $options)
14+
{
15+
parent::__construct($url, $options);
16+
$this->initBaseUrl($url);
17+
$this->parseFeed($url);
18+
}
19+
20+
/**
21+
* Parses the given feed and adds all images to the gallery
22+
*
23+
* @param string $url
24+
* @return void
25+
* @throws \Exception
26+
*/
27+
protected function parseFeed($url) {
28+
$feed = new FeedParser();
29+
$feed->set_feed_url($url);
30+
$ok = $feed->init();
31+
if (!$ok) throw new \Exception($feed->error());
32+
33+
foreach ($feed->get_items() as $item) {
34+
$enclosure = $item->get_enclosure();
35+
if (!$enclosure) continue;
36+
37+
// skip non-image enclosures
38+
if ($enclosure->get_type() && substr($enclosure->get_type(), 0, 5) != 'image') {
39+
continue;
40+
} elseif (!$this->hasImageExtension($enclosure->get_link())) {
41+
continue;
42+
}
43+
44+
$enclosureLink = $this->makeAbsoluteUrl($enclosure->get_link());
45+
$detailLink = $this->makeAbsoluteUrl($item->get_link());
46+
47+
$image = new Image($enclosureLink);
48+
$image->setDetaillink($detailLink);
49+
$image->setTitle(htmlspecialchars_decode($enclosure->get_title() ?? '', ENT_COMPAT));
50+
$image->setDescription(strip_tags(htmlspecialchars_decode($enclosure->get_description() ?? '', ENT_COMPAT)));
51+
$image->setCreated($item->get_date('U'));
52+
$image->setModified($item->get_date('U'));
53+
$image->setWidth($enclosure->get_width());
54+
$image->setHeight($enclosure->get_height());
55+
56+
$this->images[] = $image;
57+
}
58+
}
59+
60+
/**
61+
* Make the given URL absolute using feed's URL as base
62+
*
63+
* @param string $url
64+
* @return string
65+
*/
66+
protected function makeAbsoluteUrl($url)
67+
{
68+
69+
if (!preg_match('/^https?:\/\//i', $url)) {
70+
if ($url[0] == '/') {
71+
$url = $this->feedHost . $url;
72+
} else {
73+
$url = $this->feedHost . $this->feedPath . $url;
74+
}
75+
}
76+
return $url;
77+
}
78+
79+
/**
80+
* Initialize base url to use for broken feeds with non-absolute links
81+
* @param string $url The feed URL
82+
* @return void
83+
*/
84+
protected function initBaseUrl($url)
85+
{
86+
$main = parse_url($url);
87+
$this->feedHost = $main['scheme'] . '://' . $main['host'] . (!empty($main['port']) ? ':' . $main['port'] : '');
88+
$this->feedPath = dirname($main['path']) . '/';
89+
}
90+
}

0 commit comments

Comments
 (0)