Merge branch 'develop'

This commit is contained in:
Stefan Kalscheuer 2020-04-10 17:25:54 +02:00
commit cf65d6d7c3
26 changed files with 640 additions and 365 deletions

View File

@ -1,15 +1,8 @@
kind: pipeline kind: pipeline
name: default name: default
type: docker
clone:
disable: true
steps: steps:
- name: clone
image: plugins/git
settings:
depth: 10
skip_verify: true
- name: pre-build - name: pre-build
image: composer image: composer
commands: commands:
@ -17,8 +10,8 @@ steps:
- name: test - name: test
image: composer image: composer
commands: commands:
- ./vendor/bin/robo test - composer test
- name: test-style - name: lint
image: composer image: composer
commands: commands:
- ./vendor/bin/robo test:cs - composer lint-php

View File

@ -1,3 +1,25 @@
{ {
"extends": "./vendor/npm-asset/eslint-config-wordpress/index.js" "env": {
"es6": false,
"browser": true
},
"globals": {
"sclivetickerAjax": "readonly",
"wp": "readonly"
},
"extends": [
"plugin:@wordpress/eslint-plugin/recommended",
"plugin:@wordpress/eslint-plugin/es5"
],
"overrides": [
{
"files": [
"*"
],
"rules": {
"no-var": "off",
"object-shorthand": "off"
}
}
]
} }

2
.gitignore vendored
View File

@ -1,7 +1,9 @@
composer.lock composer.lock
package-lock.json
/vendor/ /vendor/
/node_modules/ /node_modules/
/dist/ /dist/
.idea .idea
.phpunit.result.cache
**/*.min.css **/*.min.css
**/*.min.js **/*.min.js

View File

@ -1,16 +1,14 @@
language: php language: php
dist: trusty
php: php:
- '5.5'
- '5.6'
- '7.0'
- '7.1'
- '7.2' - '7.2'
- '7.3' - '7.3'
- '7.4'
before_script: before_script:
- composer install - composer install
- npm install
script: script:
- composer test-all - composer test
- composer lint-all
notifications: notifications:
slack: slack:
secure: "R40BhRCETuDule7lz4oGN+qyLvd7dBmuEu6hVELNhWg3DgCgYOXyrWR2dgxsWsAZ3sldpWGfTJKzSShdDanGCpygpYzuvXxjt23YYJ2ihrohYJwiGIhkR9c24LF2yvWBQDBNZaeLBQ3o6FSnbkTBsmRy5ShgKehfKCOQTKmI1yWHi3fvkMElTorrJc710O41yy/bRKBnoIYd4ZfpLMSSVGCPzR5lZPZy3EiGWXPgYdY7jGMI7ADsy+T5VWHyFqgSSJz/U2bcryKzF08FAry8pyu9lN3r61kXHfVCCJX+kcsFxW9yCfuPLnLu14O776y3U6zrX9is+8mEfkMuTXFaL5o8+iq32AmFjTIDQn6o9BKHsknfmppjwZiLgFTp1T7Z/XR6I4nyK9Z5HXDU2HS0eCUknbgXlMLhxWpKhkyx4rQELuvVlgD+u7yRYraawc3v1ycqaPj0S0G5QBFljSuxsZgNnX1hs8VmgafIvOq5qm4ZVVBhhbz+LgvW1m9COr8DDPVhWWdpcWzF8jtkqC3m4Q/1Ssc6T/MbJMgcXRq/C4DlfEs4aYGYfSl7gLtF2PwlEQCppKJwx0fEPkcbZZ1PjpzF+JMwwRmWS88R0oRyThOyCwlG50c+ktB94pJC+sP1aQZrLAd4WDKUPD9vJTas86V3XBjTUJPs8HQaBDFqFdg=" secure: "R40BhRCETuDule7lz4oGN+qyLvd7dBmuEu6hVELNhWg3DgCgYOXyrWR2dgxsWsAZ3sldpWGfTJKzSShdDanGCpygpYzuvXxjt23YYJ2ihrohYJwiGIhkR9c24LF2yvWBQDBNZaeLBQ3o6FSnbkTBsmRy5ShgKehfKCOQTKmI1yWHi3fvkMElTorrJc710O41yy/bRKBnoIYd4ZfpLMSSVGCPzR5lZPZy3EiGWXPgYdY7jGMI7ADsy+T5VWHyFqgSSJz/U2bcryKzF08FAry8pyu9lN3r61kXHfVCCJX+kcsFxW9yCfuPLnLu14O776y3U6zrX9is+8mEfkMuTXFaL5o8+iq32AmFjTIDQn6o9BKHsknfmppjwZiLgFTp1T7Z/XR6I4nyK9Z5HXDU2HS0eCUknbgXlMLhxWpKhkyx4rQELuvVlgD+u7yRYraawc3v1ycqaPj0S0G5QBFljSuxsZgNnX1hs8VmgafIvOq5qm4ZVVBhhbz+LgvW1m9COr8DDPVhWWdpcWzF8jtkqC3m4Q/1Ssc6T/MbJMgcXRq/C4DlfEs4aYGYfSl7gLtF2PwlEQCppKJwx0fEPkcbZZ1PjpzF+JMwwRmWS88R0oRyThOyCwlG50c+ktB94pJC+sP1aQZrLAd4WDKUPD9vJTas86V3XBjTUJPs8HQaBDFqFdg="

View File

@ -1,5 +1,6 @@
[![Build Status](https://travis-ci.org/stklcode/wp-liveticker.svg?branch=master)](https://travis-ci.org/stklcode/wp-liveticker) [![Build Status](https://travis-ci.org/stklcode/wp-liveticker.svg?branch=master)](https://travis-ci.org/stklcode/wp-liveticker)
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=de.stklcode.web.wordpress.plugins%3Awp-liveticker&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.stklcode.web.wordpress.plugins%3Awp-liveticker) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=de.stklcode.web.wordpress.plugins%3Awp-liveticker&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.stklcode.web.wordpress.plugins%3Awp-liveticker)
[![WP Plugin Version](https://img.shields.io/wordpress/plugin/v/stklcode-liveticker.svg)](https://wordpress.org/plugins/stklcode-liveticker/)
[![Packagist Version](https://img.shields.io/packagist/v/stklcode/stklcode-liveticker.svg)](https://packagist.org/packages/stklcode/stklcode-liveticker) [![Packagist Version](https://img.shields.io/packagist/v/stklcode/stklcode-liveticker.svg)](https://packagist.org/packages/stklcode/stklcode-liveticker)
[![License](https://img.shields.io/badge/license-GPL%20v2-blue.svg)](https://github.com/stklcode/wp-liveticker/blob/master/LICENSE.md) [![License](https://img.shields.io/badge/license-GPL%20v2-blue.svg)](https://github.com/stklcode/wp-liveticker/blob/master/LICENSE.md)
@ -8,8 +9,8 @@
* Contributors: Stefan Kalscheuer * Contributors: Stefan Kalscheuer
* Tags: liveticker, feed, rss * Tags: liveticker, feed, rss
* Requires at least: 4.0 * Requires at least: 4.0
* Tested up to: 5.3 * Tested up to: 5.4
* Requires PHP: 5.2 * Requires PHP: 5.6
* Stable tag: 1.0.0 * Stable tag: 1.0.0
* License: GPLv2 or later * License: GPLv2 or later
* License URI: http://www.gnu.org/licenses/gpl-2.0.html * License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -26,9 +27,9 @@ Easily add multiple livetickers, add them to posts with shortcode or use them as
* Handle multiple Tickers * Handle multiple Tickers
* Automatic update via AJAX * Automatic update via AJAX
* RSS feed capability * RSS feed capability
* Shortcode to display liveticker * Gutenberg block and shortcode to display liveticker
* Add ticker to sidebar widgets * Add ticker to sidebar widgets
* Ability to customise through CSS * Ability to customize through CSS
* Localization support * Localization support
@ -47,7 +48,9 @@ Easily add multiple livetickers, add them to posts with shortcode or use them as
### How do I display a liveticker on my post/page? ### How do I display a liveticker on my post/page?
Use the shortcode `[liveticker ticker="my-ticker"]`. On WordPress 5 sites there is a Gutenberg Block available to embed a liveticker in your post.
You can also use the shortcode `[liveticker ticker="my-ticker"]` on WordPress 4 or classic-mode sites.
If you want to define a custom tick limit, you might also add a limit with `[liveticker ticker="my-ticker" limit="10"]`. If you want to define a custom tick limit, you might also add a limit with `[liveticker ticker="my-ticker" limit="10"]`.
### Can I use my own styles? ### Can I use my own styles?
@ -57,9 +60,11 @@ You can deactivate the default stylesheet on the settings page and include your
### Does the liveticker work with caching? ### Does the liveticker work with caching?
It strongly depends on the use case. If you activate AJAX updates (enabled by default), the JavaScript will automatically update the content, even when the
If you update your ticker every 5 minutes, a caching time of 12 hours obviously makes no sense. page is loaded from cached.
However the AJAX update will fetch the latest ticks and update cached tickers depending on the configured interval.
If AJAX is disabled, it depends on your update and caching intervals. If you update your ticker every 5 minutes, a
caching time of 12 hours obviously makes no sense.
## Screenshots ## Screenshots
@ -68,11 +73,18 @@ However the AJAX update will fetch the latest ticks and update cached tickers d
2. Tick management 2. Tick management
3. Ticker configuration. 3. Ticker configuration.
4. Settings page 4. Settings page
5. Example shortcode 5. Gutenberg block
6. Example widget 6. Example shortcode
7. Example widget
## Changelog ## Changelog
### 1.1.0 - unreleased
* Requires PHP 5.6 or above
* Use GMT for automatic updates
* Gutenberg Block available
### 1.0.0 - 2018-11-02 ### 1.0.0 - 2018-11-02
* Initial release * Initial release

View File

@ -26,6 +26,7 @@ class RoboFile extends Tasks {
const OPT_SKIPTEST = 'skipTests'; const OPT_SKIPTEST = 'skipTests';
const OPT_SKIPSTYLE = 'skipStyle'; const OPT_SKIPSTYLE = 'skipStyle';
const OPT_MINIFY = 'minify'; const OPT_MINIFY = 'minify';
const OPT_NODE = 'node';
/** /**
* Version tag (read from composer.json). * Version tag (read from composer.json).
@ -94,11 +95,31 @@ class RoboFile extends Tasks {
/** /**
* Run code style tests * Run code style tests
* *
* @param array $opts Options.
*
* @return void * @return void
*/ */
public function testCS() { public function testCS(
$this->say( 'Executing PHPCS tests...' ); $opts = array(
self::OPT_TARGET => 'dist',
self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true,
self::OPT_NODE => false,
)
) {
$this->say( 'Executing PHPCS...' );
$this->_exec( __DIR__ . '/vendor/bin/phpcs --standard=phpcs.xml -s' ); $this->_exec( __DIR__ . '/vendor/bin/phpcs --standard=phpcs.xml -s' );
if ( $opts[ self::OPT_NODE ] ) {
$this->say( 'Executing ESLint...' );
$this->_exec( __DIR__ . '/node_modules/eslint/bin/eslint.js ' . __DIR__ . '/scripts/block.js' );
$this->_exec( __DIR__ . '/node_modules/eslint/bin/eslint.js ' . __DIR__ . '/scripts/liveticker.js' );
$this->say( 'Executing StyleLint...' );
$this->_exec( __DIR__ . '/node_modules/stylelint/bin/stylelint.js ' . __DIR__ . '/styles/block.css' );
$this->_exec( __DIR__ . '/node_modules/stylelint/bin/stylelint.js ' . __DIR__ . '/styles/liveticker.css' );
}
} }
/** /**
@ -114,6 +135,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
$this->clean( $opts ); $this->clean( $opts );
@ -125,7 +147,7 @@ class RoboFile extends Tasks {
if ( isset( $opts[ self::OPT_SKIPSTYLE ] ) && true === $opts[ self::OPT_SKIPSTYLE ] ) { if ( isset( $opts[ self::OPT_SKIPSTYLE ] ) && true === $opts[ self::OPT_SKIPSTYLE ] ) {
$this->say( 'Style checks skipped' ); $this->say( 'Style checks skipped' );
} else { } else {
$this->testCS(); $this->testCS( $opts );
} }
$this->bundle(); $this->bundle();
} }
@ -137,12 +159,14 @@ class RoboFile extends Tasks {
*/ */
private function bundle() { private function bundle() {
$this->say( 'Bundling resources...' ); $this->say( 'Bundling resources...' );
$this->taskCopyDir( array( $this->taskCopyDir(
array(
'includes' => $this->target_dir . '/' . $this->final_name . '/includes', 'includes' => $this->target_dir . '/' . $this->final_name . '/includes',
'scripts' => $this->target_dir . '/' . $this->final_name . '/scripts', 'scripts' => $this->target_dir . '/' . $this->final_name . '/scripts',
'styles' => $this->target_dir . '/' . $this->final_name . '/styles', 'styles' => $this->target_dir . '/' . $this->final_name . '/styles',
'views' => $this->target_dir . '/' . $this->final_name . '/views', 'views' => $this->target_dir . '/' . $this->final_name . '/views',
) )->run(); )
)->run();
$this->_copy( 'stklcode-liveticker.php', $this->target_dir . '/' . $this->final_name . '/stklcode-liveticker.php' ); $this->_copy( 'stklcode-liveticker.php', $this->target_dir . '/' . $this->final_name . '/stklcode-liveticker.php' );
$this->_copy( 'README.md', $this->target_dir . '/' . $this->final_name . '/README.md' ); $this->_copy( 'README.md', $this->target_dir . '/' . $this->final_name . '/README.md' );
$this->_copy( 'LICENSE.md', $this->target_dir . '/' . $this->final_name . '/LICENSE.md' ); $this->_copy( 'LICENSE.md', $this->target_dir . '/' . $this->final_name . '/LICENSE.md' );
@ -190,6 +214,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
if ( ! isset( $opts[ self::OPT_MINIFY ] ) ) { if ( ! isset( $opts[ self::OPT_MINIFY ] ) ) {
@ -224,6 +249,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
if ( ! isset( $opts[ self::OPT_MINIFY ] ) ) { if ( ! isset( $opts[ self::OPT_MINIFY ] ) ) {
@ -259,6 +285,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
$this->build( $opts ); $this->build( $opts );
@ -282,6 +309,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
// First execute build job. // First execute build job.
@ -315,6 +343,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
// First execute build job. // First execute build job.
@ -348,6 +377,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
// First execute build job. // First execute build job.
@ -380,6 +410,7 @@ class RoboFile extends Tasks {
self::OPT_SKIPTEST => false, self::OPT_SKIPTEST => false,
self::OPT_SKIPSTYLE => false, self::OPT_SKIPSTYLE => false,
self::OPT_MINIFY => true, self::OPT_MINIFY => true,
self::OPT_NODE => false,
) )
) { ) {
// First execute build job. // First execute build job.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/screenshot-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,6 +1,6 @@
{ {
"name": "stklcode/stklcode-liveticker", "name": "stklcode/stklcode-liveticker",
"version": "1.0.0", "version": "1.1.0-alpha",
"description": "A simple Liveticker for Wordpress.", "description": "A simple Liveticker for Wordpress.",
"keywords": [ "keywords": [
"wordpress", "wordpress",
@ -17,23 +17,22 @@
], ],
"type": "wordpress-plugin", "type": "wordpress-plugin",
"require": { "require": {
"php": ">=5.2", "php": ">=5.6",
"composer/installers": "~1.7" "composer/installers": "~1.7"
}, },
"require-dev": { "require-dev": {
"php": ">=5.2", "php": ">=7",
"consolidation/robo": "^1.4", "consolidation/robo": "^2",
"phpunit/phpunit": "*", "phpunit/phpunit": "^8",
"phpunit/php-code-coverage": "*", "phpunit/php-code-coverage": "^7",
"dealerdirect/phpcodesniffer-composer-installer": "^0.5", "dealerdirect/phpcodesniffer-composer-installer": "^0.6",
"slowprog/composer-copy-file": "~0.3", "slowprog/composer-copy-file": "~0.3",
"squizlabs/php_codesniffer": "^3.4", "squizlabs/php_codesniffer": "^3.5",
"phpcompatibility/php-compatibility": "^9.2", "phpcompatibility/php-compatibility": "^9.3",
"wp-coding-standards/wpcs": "^2.1", "wp-coding-standards/wpcs": "^2.2",
"patchwork/jsqueeze": "^2.0", "patchwork/jsqueeze": "^2.0",
"natxet/cssmin": "^3.0", "natxet/cssmin": "^3.0",
"matthiasmullie/minify": "^1.3", "matthiasmullie/minify": "^1.3"
"npm-asset/eslint-config-wordpress": "^2.0"
}, },
"scripts": { "scripts": {
"post-install-cmd": [ "post-install-cmd": [
@ -54,28 +53,30 @@
"@minify", "@minify",
"robo deploy:all" "robo deploy:all"
], ],
"test-all": [
"@test",
"@test-cs"
],
"test": [ "test": [
"phpunit" "phpunit"
], ],
"test-cs": [ "lint-all": [
"@lint-php",
"@lint-css",
"@lint-js"
],
"lint-php": [
"phpcs --standard=phpcs.xml -s" "phpcs --standard=phpcs.xml -s"
], ],
"fix-cs": [ "lint-css": [
"phpcbf --standard=phpcs.xml" "./node_modules/stylelint/bin/stylelint.js styles/block.css",
"./node_modules/stylelint/bin/stylelint.js styles/liveticker.css"
],
"lint-js": [
"./node_modules/eslint/bin/eslint.js scripts/block.js",
"./node_modules/eslint/bin/eslint.js scripts/liveticker.js"
], ],
"minify": [ "minify": [
"minifycss styles/block.css > styles/block.min.css",
"minifycss styles/liveticker.css > styles/liveticker.min.css", "minifycss styles/liveticker.css > styles/liveticker.min.css",
"minifyjs scripts/block.js > scripts/block.min.js",
"minifyjs scripts/liveticker.js > scripts/liveticker.min.js" "minifyjs scripts/liveticker.js > scripts/liveticker.min.js"
] ]
},
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
} }
]
} }

View File

@ -4,9 +4,11 @@
* *
* This file contains the derived class for the plugin's administration features. * This file contains the derived class for the plugin's administration features.
* *
* @package Liveticker * @package SCLiveticker
*/ */
namespace SCLiveticker;
// Exit if accessed directly. // Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
@ -15,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
/** /**
* Liveticker admin configuration. * Liveticker admin configuration.
*/ */
class SCLiveticker_Admin extends SCLiveticker { class Admin extends SCLiveticker {
/** /**
* Add to Right Now Widget * Add to Right Now Widget
* *
@ -202,4 +204,35 @@ class SCLiveticker_Admin extends SCLiveticker {
return $result; return $result;
} }
/**
* Register custom Gutenberg block type.
*
* @return void
* @since 1.1
*/
public static function register_block() {
wp_register_script(
'scliveticker-editor',
SCLIVETICKER_BASE . 'scripts/block.min.js',
array( 'wp-blocks', 'wp-element' ),
self::VERSION,
true
);
wp_register_style(
'scliveticker-editor',
SCLIVETICKER_BASE . 'styles/block.min.css',
array(),
self::VERSION
);
register_block_type(
'scliveticker-block/liveticker',
array(
'editor_script' => 'scliveticker-editor',
'editor_style' => 'scliveticker-editor',
)
);
}
} }

View File

@ -4,14 +4,19 @@
* *
* This file contains the plugin's base class. * This file contains the plugin's base class.
* *
* @package Liveticker * @package SCLiveticker
*/ */
namespace SCLiveticker;
use WP_Query;
// Exit if accessed directly. // Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
/** /**
* Liveticker. * Liveticker.
*/ */
@ -21,7 +26,7 @@ class SCLiveticker {
* *
* @var string OPTIONS * @var string OPTIONS
*/ */
const VERSION = '1.0.0'; const VERSION = '1.1.0-alpha';
/** /**
* Options tag. * Options tag.
@ -80,11 +85,8 @@ class SCLiveticker {
// Add shortcode. // Add shortcode.
add_shortcode( 'liveticker', array( __CLASS__, 'shortcode_ticker_show' ) ); add_shortcode( 'liveticker', array( __CLASS__, 'shortcode_ticker_show' ) );
// Enqueue styles. // Enqueue styles and JavaScript.
add_action( 'wp_footer', array( __CLASS__, 'enqueue_styles' ) ); add_action( 'wp_footer', array( __CLASS__, 'enqueue_resources' ) );
// Enqueue JavaScript.
add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts' ) );
// Add AJAX hook if configured. // Add AJAX hook if configured.
if ( 1 === self::$options['enable_ajax'] ) { if ( 1 === self::$options['enable_ajax'] ) {
@ -95,11 +97,11 @@ class SCLiveticker {
// Admin only actions. // Admin only actions.
if ( is_admin() ) { if ( is_admin() ) {
// Add dashboard "right now" functionality. // Add dashboard "right now" functionality.
add_action( 'right_now_content_table_end', array( 'SCLiveticker_Admin', 'dashboard_right_now' ) ); add_action( 'right_now_content_table_end', array( 'SCLiveticker\\Admin', 'dashboard_right_now' ) );
// Settings. // Settings.
add_action( 'admin_init', array( 'SCLiveticker_Admin', 'register_settings' ) ); add_action( 'admin_init', array( 'SCLiveticker\\Admin', 'register_settings' ) );
add_action( 'admin_menu', array( 'SCLiveticker_Admin', 'register_settings_page' ) ); add_action( 'admin_menu', array( 'SCLiveticker\\Admin', 'register_settings_page' ) );
} }
} }
@ -133,6 +135,7 @@ class SCLiveticker {
'show_ui' => true, 'show_ui' => true,
'show_admin_column' => true, 'show_admin_column' => true,
'query_var' => true, 'query_var' => true,
'show_in_rest' => true,
) )
); );
@ -198,14 +201,14 @@ class SCLiveticker {
$show_feed = 1 === self::$options['show_feed']; $show_feed = 1 === self::$options['show_feed'];
} }
$output = '<ul class="sclt-ticker'; $output = '<div class="wp-block-scliveticker-ticker';
if ( 1 === self::$options['enable_ajax'] ) { if ( 1 === self::$options['enable_ajax'] ) {
$output .= ' sclt-ticker-ajax" ' $output .= ' sclt-ajax" '
. 'data-sclt-ticker="' . $ticker . '" ' . 'data-sclt-ticker="' . $ticker . '" '
. 'data-sclt-limit="' . $limit . '" ' . 'data-sclt-limit="' . $limit . '" '
. 'data-sclt-last="' . current_time( 'timestamp' ); . 'data-sclt-last="' . current_datetime()->getTimestamp();
} }
$output .= '">'; $output .= '"><ul>';
$args = array( $args = array(
'post_type' => 'scliveticker_tick', 'post_type' => 'scliveticker_tick',
@ -226,7 +229,7 @@ class SCLiveticker {
$output .= self::tick_html( get_the_time( 'd.m.Y H.i' ), get_the_title(), get_the_content() ); $output .= self::tick_html( get_the_time( 'd.m.Y H.i' ), get_the_title(), get_the_content() );
} }
$output .= '</ul>'; $output .= '</ul></div>';
// Show RSS feed link, if configured. // Show RSS feed link, if configured.
if ( $show_feed ) { if ( $show_feed ) {
@ -243,32 +246,15 @@ class SCLiveticker {
return $output; return $output;
} }
/**
* Register frontend CSS.
*
* @return void
*/
public static function enqueue_styles() {
// Only add if shortcode is present.
if ( self::$shortcode_present || self::$widget_present ) {
wp_enqueue_style(
'wplt-css',
SCLIVETICKER_BASE . 'styles/liveticker.min.css',
'',
self::VERSION,
'all'
);
}
}
/** /**
* Register frontend JS. * Register frontend JS.
* *
* @return void * @return void
* @since 1.1 Combined former methods "enqueue_styles" and "enqueue_scripts".
*/ */
public static function enqueue_scripts() { public static function enqueue_resources() {
// Only add if shortcode is present. // Only add if shortcode is present.
if ( self::$shortcode_present || self::$widget_present ) { if ( self::$shortcode_present || self::$widget_present || self::block_present() ) {
wp_enqueue_script( wp_enqueue_script(
'scliveticker-js', 'scliveticker-js',
SCLIVETICKER_BASE . 'scripts/liveticker.min.js', SCLIVETICKER_BASE . 'scripts/liveticker.min.js',
@ -287,6 +273,17 @@ class SCLiveticker {
'poll_interval' => self::$options['poll_interval'] * 1000, 'poll_interval' => self::$options['poll_interval'] * 1000,
) )
); );
// Enqueue CSS if enabled.
if ( 1 === self::$options['enable_css'] ) {
wp_enqueue_style(
'sclt-css',
SCLIVETICKER_BASE . 'styles/liveticker.min.css',
'',
self::VERSION,
'all'
);
}
} }
} }
@ -317,7 +314,13 @@ class SCLiveticker {
} }
$limit = ( isset( $update_req['l'] ) ) ? intval( $update_req['l'] ) : - 1; $limit = ( isset( $update_req['l'] ) ) ? intval( $update_req['l'] ) : - 1;
$last_poll = ( isset( $update_req['t'] ) ) ? intval( $update_req['t'] ) : 0; $last_poll = explode(
',',
gmdate(
'Y,m,d,H,i,s',
( isset( $update_req['t'] ) ) ? intval( $update_req['t'] ) : 0
)
);
// Query new ticks from DB. // Query new ticks from DB.
$query_args = array( $query_args = array(
@ -331,7 +334,15 @@ class SCLiveticker {
), ),
), ),
'date_query' => array( 'date_query' => array(
'after' => date( 'c', $last_poll ), 'column' => 'post_date_gmt',
'after' => array(
'year' => intval( $last_poll[0] ),
'month' => intval( $last_poll[1] ),
'day' => intval( $last_poll[2] ),
'hour' => intval( $last_poll[3] ),
'minute' => intval( $last_poll[4] ),
'second' => intval( $last_poll[5] ),
),
), ),
); );
@ -351,13 +362,13 @@ class SCLiveticker {
$res[] = array( $res[] = array(
'w' => $slug, 'w' => $slug,
'h' => $out, 'h' => $out,
't' => current_time( 'timestamp' ), 't' => current_datetime()->getTimestamp(),
); );
} else { } else {
$res[] = array( $res[] = array(
's' => $slug, 's' => $slug,
'h' => $out, 'h' => $out,
't' => current_time( 'timestamp' ), 't' => current_datetime()->getTimestamp(),
); );
} }
} }
@ -443,4 +454,15 @@ class SCLiveticker {
. '<span class="sclt-widget-title">' . $title . '</span>' . '<span class="sclt-widget-title">' . $title . '</span>'
. '</li>'; . '</li>';
} }
/**
* Check if the Gutenberg block is present in current post.
*
* @return boolean True, if Gutenberg block is present.
* @since 1.1
*/
private static function block_present() {
return function_exists( 'has_block' ) && // We are in WP 5.x environment.
has_block( 'scliveticker/ticker' ); // Specific block is present.
}
} }

View File

@ -4,9 +4,13 @@
* *
* This file contains the derived class for the plugin's system operations. * This file contains the derived class for the plugin's system operations.
* *
* @package Liveticker * @package SCLiveticker
*/ */
namespace SCLiveticker;
use WP_Query;
// Exit if accessed directly. // Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
@ -15,7 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) {
/** /**
* Liveticker system configuration. * Liveticker system configuration.
*/ */
class SCLiveticker_System extends SCLiveticker { class System extends SCLiveticker {
/** /**
* Activation hook. * Activation hook.

View File

@ -4,17 +4,22 @@
* *
* This file contains the liveticker widget. * This file contains the liveticker widget.
* *
* @package Liveticker * @package SCLiveticker
*/ */
namespace SCLiveticker;
use WP_Query;
use WP_Widget;
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
/** /**
* Class SCLiveticker_Widget. * Class Widget.
*/ */
class SCLiveticker_Widget extends WP_Widget { class Widget extends WP_Widget {
/** /**
* SCLiveticker_Widget constructor. * SCLiveticker_Widget constructor.
@ -68,12 +73,12 @@ class SCLiveticker_Widget extends WP_Widget {
echo $before_title . esc_html( $title ) . $after_title; echo $before_title . esc_html( $title ) . $after_title;
} }
echo '<ul class="sclt-widget'; echo '<div class="wp-widget-scliveticker-ticker';
if ( '1' === $ajax ) { if ( '1' === $ajax ) {
echo ' sclt-widget-ajax" ' echo ' sclt-ajax" '
. 'data-sclt-ticker="' . esc_attr( $category ) . '" ' . 'data-sclt-ticker="' . esc_attr( $category ) . '" '
. 'data-sclt-limit="' . esc_attr( $count ) . '" ' . 'data-sclt-limit="' . esc_attr( $count ) . '" '
. 'data-sclt-last="' . esc_attr( current_time( 'timestamp' ) ); . 'data-sclt-last="' . esc_attr( current_datetime()->getTimestamp() );
} }
echo '">'; echo '">';

88
package-lock.json generated
View File

@ -1,88 +0,0 @@
{
"name": "wp-liveticker2",
"version": "1.0.0-beta",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"cssesc": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-1.0.1.tgz",
"integrity": "sha512-S2hzrpWvE6G/rW7i7IxJfWBYn27QWfOIncUW++8Rbo1VB5zsJDSVPcnI+Q8z7rhxT6/yZeLOCja4cZnghJrNGA=="
},
"indexes-of": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
"integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc="
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"postcss-media-query-parser": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
"integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ="
},
"postcss-resolve-nested-selector": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
"integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4="
},
"postcss-selector-parser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-4.0.0.tgz",
"integrity": "sha512-5h+MvEjnzu1qy6MabjuoPatsGAjjDV9B24e7Cktjl+ClNtjVjmvAXjOFQr1u7RlWULKNGYaYVE4s+DIIQ4bOGA==",
"requires": {
"cssesc": "^1.0.1",
"indexes-of": "^1.0.1",
"uniq": "^1.0.1"
}
},
"postcss-value-parser": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
},
"stylelint-config-recommended": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.1.0.tgz",
"integrity": "sha512-ajMbivOD7JxdsnlS5945KYhvt7L/HwN6YeYF2BH6kE4UCLJR0YvXMf+2j7nQpJyYLZx9uZzU5G1ZOSBiWAc6yA=="
},
"stylelint-config-recommended-scss": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-3.2.0.tgz",
"integrity": "sha512-M8BFHMRf8KNz5EQPKJd8nMCGmBd2o5coDEObfHVbEkyLDgjIf1V+U5dHjaGgvhm0zToUxshxN+Gc5wpbOOew4g==",
"requires": {
"stylelint-config-recommended": "^2.0.0"
}
},
"stylelint-config-wordpress": {
"version": "13.1.0",
"resolved": "https://registry.npmjs.org/stylelint-config-wordpress/-/stylelint-config-wordpress-13.1.0.tgz",
"integrity": "sha512-dpKj2/d3/XjDVoOvQzd54GoM8Rj5zldluOZKkVhBCc4JYMc6r1VYL5hpcgIjqy/i2Hyqg4Rh7zTafE/2AWq//w==",
"requires": {
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-scss": "^3.3.0"
}
},
"stylelint-scss": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.3.2.tgz",
"integrity": "sha512-0x+nD1heoMJYOfi3FfGcz3Hrwhcm+Qyq+BuvoBv5v9xrZZ1aziRXQauuhjwb87gWAa9MBzxhfUqBnvTUrHlLjA==",
"requires": {
"lodash": "^4.17.10",
"postcss-media-query-parser": "^0.2.3",
"postcss-resolve-nested-selector": "^0.1.1",
"postcss-selector-parser": "^4.0.0",
"postcss-value-parser": "^3.3.0"
}
},
"uniq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
}
}
}

View File

@ -1,10 +1,13 @@
{ {
"name": "stklcode-liveticker", "name": "stklcode-liveticker",
"version": "1.0.0", "version": "1.1.0-alpha",
"description": "A simple Liveticker for Wordpress.", "description": "A simple Liveticker for Wordpress.",
"author": "Stefan Kalscheuer", "author": "Stefan Kalscheuer",
"license": "GPL-2.0+", "license": "GPL-2.0+",
"dependencies": { "devDependencies": {
"stylelint-config-wordpress": "^13.1.0" "@wordpress/eslint-plugin": "^3.4.1",
"eslint": "^6",
"stylelint": "^13",
"stylelint-config-wordpress": "^16"
} }
} }

View File

@ -18,6 +18,6 @@
</rule> </rule>
<!-- PHP compatibility level --> <!-- PHP compatibility level -->
<config name="testVersion" value="5.2-"/> <config name="testVersion" value="5.6-"/>
<rule ref="PHPCompatibility"/> <rule ref="PHPCompatibility"/>
</ruleset> </ruleset>

190
scripts/block.js Normal file
View File

@ -0,0 +1,190 @@
/**
* stklcode-liveticker Gutenberg Block
*
* Gutenberg Block to integrate the liveticker widget without shortcode.
*/
( function() {
var __ = wp.i18n.__;
var registerBlockType = wp.blocks.registerBlockType;
var registerStore = wp.data.registerStore;
var withSelect = wp.data.withSelect;
var el = wp.element.createElement;
/**
* Datastore actions.
*/
var actions = {
setTickers: function( tickers ) {
return {
type: 'SET_TICKERS',
tickers: tickers,
};
},
getTickers: function( path ) {
return {
type: 'RECEIVE_TICKERS',
path: path,
};
},
};
registerStore( 'scliveticker/ticker', {
reducer: function( state, action ) {
if ( undefined === state ) {
state = { tickers: null };
}
switch ( action.type ) {
case 'SET_TICKERS':
state.tickers = action.tickers;
return state;
case 'RECEIVE_TICKERS':
return action.tickers;
}
return state;
},
actions: actions,
selectors: {
receiveTickers: function( state ) {
return state.tickers;
},
},
resolvers: {
receiveTickers: function() {
return wp.apiFetch( { path: '/wp/v2/scliveticker_ticker' } ).then( function( tickers ) {
return actions.setTickers( tickers.map( function( t ) {
return {
name: t.name,
slug: t.slug,
};
} ) );
} );
},
},
} );
registerBlockType( 'scliveticker/ticker', {
title: __( 'Liveticker', 'stklcode-liveticker' ),
icon: 'rss',
category: 'widgets',
keywords: [
__( 'Liveticker', 'stklcode-liveticker' ),
],
attributes: {
ticker: {
type: 'string',
default: '',
},
limit: {
type: 'number',
default: 5,
},
unlimited: {
type: 'boolean',
default: false,
},
},
edit: withSelect( function( select ) {
return {
tickers: select( 'scliveticker/ticker' ).receiveTickers(),
};
} )( function( props ) {
var label = [
el(
wp.components.Dashicon,
{ icon: 'rss' }
),
__( 'Liveticker', 'stklcode-liveticker' ),
];
var content;
if ( null === props.tickers ) {
// Tickers not yet loaded.
content = [
el(
'span',
{ className: 'components-base-control label' },
label
),
el( wp.components.Spinner ),
];
} else if ( 0 === props.tickers.length ) {
// No tickers available.
content = [
el(
'span',
{ className: 'components-base-control label' },
label
),
el( 'span', null, __( 'No tickers available', 'stklcode-liveticker' ) ),
];
} else {
// Tickers loaded and available.
if ( 0 === props.attributes.ticker.length && props.tickers.length > 0 ) {
props.attributes.ticker = props.tickers[ 0 ].slug;
}
content = [
el(
wp.components.SelectControl,
{
label: label,
value: props.attributes.ticker,
options: props.tickers.map( function( t ) {
return {
value: t.slug,
label: t.name,
};
} ),
onChange: function( val ) {
props.setAttributes( { ticker: val } );
},
}
),
el(
wp.components.TextControl,
{
label: __( 'Number of Ticks', 'stklcode-liveticker' ),
type: 'number',
min: 1,
step: 1,
disabled: props.attributes.unlimited,
value: props.attributes.limit,
onChange: function( val ) {
props.setAttributes( { limit: val } );
},
}
),
el(
wp.components.CheckboxControl,
{
label: __( 'unlimited', 'stklcode-liveticker' ),
checked: props.attributes.unlimited,
onChange: function( val ) {
props.setAttributes( { unlimited: val } );
},
}
),
];
}
return el(
'div',
{ className: props.className + ' components-placeholder' },
content
);
} ),
save: function( props ) {
return el(
'div',
{
className: 'sclt-ajax',
'data-sclt-ticker': props.attributes.ticker,
'data-sclt-limit': props.attributes.unlimited ? 0 : props.attributes.limit,
'data-sclt-last': 0,
}
);
},
} );
}() );

View File

@ -1,17 +1,22 @@
/** /**
* Contructor of the scLiveticker object. * Contructor of the scLiveticker object.
* *
* @constructor * @class
*/ */
function scLiveticker() { ( function() {
} var ajaxURL = sclivetickerAjax.ajax_url;
var nonce = sclivetickerAjax.nonce;
var pollInterval = sclivetickerAjax.poll_interval;
var ticker;
var widgets;
/** /**
* Initialize iveticker JS component. * Initialize iveticker JS component.
* *
* @return {void} * @return {void}
*/ */
scLiveticker.init = function() { var init = function() {
var updateNow = false;
// Opt out if AJAX pobject not present. // Opt out if AJAX pobject not present.
if ( 'undefined' === typeof sclivetickerAjax ) { if ( 'undefined' === typeof sclivetickerAjax ) {
@ -19,39 +24,67 @@ scLiveticker.init = function() {
} }
// Extract AJAX settings. // Extract AJAX settings.
scLiveticker.ajaxURL = sclivetickerAjax.ajax_url; ajaxURL = sclivetickerAjax.ajax_url;
scLiveticker.nonce = sclivetickerAjax.nonce; nonce = sclivetickerAjax.nonce;
scLiveticker.pollInterval = sclivetickerAjax.poll_interval; pollInterval = sclivetickerAjax.poll_interval;
// Get ticker elements. // Get ticker elements.
scLiveticker.ticker = [].map.call( ticker = [].map.call(
document.querySelectorAll( 'ul.sclt-ticker-ajax' ), document.querySelectorAll( 'div.wp-block-scliveticker-ticker.sclt-ajax' ),
function( elem ) { function( elem ) {
var list = elem.querySelector( 'ul' );
var last = Number( elem.getAttribute( 'data-sclt-last' ) );
if ( ! list ) {
list = document.createElement( 'ul' );
elem.appendChild( list );
}
if ( 0 === last ) {
updateNow = true;
}
return { return {
s: elem.getAttribute( 'data-sclt-ticker' ), s: elem.getAttribute( 'data-sclt-ticker' ),
l: elem.getAttribute( 'data-sclt-limit' ), l: elem.getAttribute( 'data-sclt-limit' ),
t: elem.getAttribute( 'data-sclt-last' ), t: last,
e: elem e: list,
}; };
} }
); );
// Get widget elements. // Get widget elements.
scLiveticker.widgets = [].map.call( widgets = [].map.call(
document.querySelectorAll( 'ul.sclt-widget-ajax' ), document.querySelectorAll( 'div.wp-widget-scliveticker-ticker.sclt-ajax' ),
function( elem ) { function( elem ) {
var list = elem.querySelector( 'ul' );
var last = Number( elem.getAttribute( 'data-sclt-last' ) );
if ( ! list ) {
list = document.createElement( 'ul' );
elem.appendChild( list );
}
if ( 0 === last ) {
updateNow = true;
}
return { return {
w: elem.getAttribute( 'data-sclt-ticker' ), w: elem.getAttribute( 'data-sclt-ticker' ),
l: elem.getAttribute( 'data-sclt-limit' ), l: elem.getAttribute( 'data-sclt-limit' ),
t: elem.getAttribute( 'data-sclt-last' ), t: last,
e: elem e: list,
}; };
} }
); );
// Trigger update, if necessary. // Trigger update, if necessary.
if ( ( 0 < scLiveticker.ticker.length || scLiveticker.widgets.length ) && 0 < scLiveticker.pollInterval ) { if ( ( 0 < ticker.length || widgets.length ) && 0 < pollInterval ) {
setTimeout( scLiveticker.update, scLiveticker.pollInterval ); if ( updateNow ) {
update();
} else {
setTimeout( update, pollInterval );
}
} }
}; };
@ -60,58 +93,58 @@ scLiveticker.init = function() {
* *
* @return {void} * @return {void}
*/ */
scLiveticker.update = function() { var update = function() {
// Extract ticker-slug, limit and timestamp of last poll. // Extract ticker-slug, limit and timestamp of last poll.
var updateReq = 'action=sclt_update-ticks&_ajax_nonce=' + scLiveticker.nonce; var updateReq = 'action=sclt_update-ticks&_ajax_nonce=' + nonce;
var i, j; var i, j;
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
for ( i = 0; i < scLiveticker.ticker.length; i++ ) { for ( i = 0; i < ticker.length; i++ ) {
updateReq = updateReq + updateReq = updateReq +
'&update[' + i + '][s]=' + scLiveticker.ticker[ i ].s + '&update[' + i + '][s]=' + ticker[ i ].s +
'&update[' + i + '][l]=' + scLiveticker.ticker[ i ].l + '&update[' + i + '][l]=' + ticker[ i ].l +
'&update[' + i + '][t]=' + scLiveticker.ticker[ i ].t; '&update[' + i + '][t]=' + ticker[ i ].t;
} }
for ( j = 0; j < scLiveticker.widgets.length; j++ ) { for ( j = 0; j < widgets.length; j++ ) {
updateReq = updateReq + updateReq = updateReq +
'&update[' + ( i + j ) + '][w]=' + scLiveticker.widgets[ j ].w + '&update[' + ( i + j ) + '][w]=' + widgets[ j ].w +
'&update[' + ( i + j ) + '][l]=' + scLiveticker.widgets[ j ].l + '&update[' + ( i + j ) + '][l]=' + widgets[ j ].l +
'&update[' + ( i + j ) + '][t]=' + scLiveticker.widgets[ j ].t; '&update[' + ( i + j ) + '][t]=' + widgets[ j ].t;
} }
// Issue AJAX request. // Issue AJAX request.
xhr.open( 'POST', scLiveticker.ajaxURL, true ); xhr.open( 'POST', ajaxURL, true );
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' ); xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' );
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
var update; var updateResp;
if ( XMLHttpRequest.DONE === this.readyState && 200 === this.status ) { if ( XMLHttpRequest.DONE === this.readyState && 200 === this.status ) {
try { try {
update = JSON.parse( this.responseText ); updateResp = JSON.parse( this.responseText );
if ( update ) { if ( updateResp ) {
update.forEach( updateResp.forEach(
function( u ) { function( u ) {
scLiveticker.ticker.forEach( ticker.forEach(
function( t ) { function( t ) {
if ( t.s === u.s ) { if ( t.s === u.s ) {
t.t = u.t; // Update last poll timestamp. t.t = u.t; // Update last poll timestamp.
scLiveticker.updateHTML( t, u ); // Update HTML markup. updateHTML( t, u ); // Update HTML markup.
} }
} }
); );
scLiveticker.widgets.forEach( widgets.forEach(
function( t ) { function( t ) {
if ( t.w === u.w ) { if ( t.w === u.w ) {
t.t = u.t; t.t = u.t;
scLiveticker.updateHTML( t, u ); updateHTML( t, u );
} }
} }
); );
} }
); );
} }
setTimeout( scLiveticker.update, scLiveticker.pollInterval ); // Re-trigger update. setTimeout( update, pollInterval ); // Re-trigger update.
} catch ( e ) { } catch ( e ) {
// eslint-disable-next-line no-console
console.warn( 'Liveticker AJAX update failed, stopping automatic updates.' ); console.warn( 'Liveticker AJAX update failed, stopping automatic updates.' );
} }
} }
@ -130,11 +163,10 @@ scLiveticker.update = function() {
* @param {number} u.t Timetsamp of last update. * @param {number} u.t Timetsamp of last update.
* @return {void} * @return {void}
*/ */
scLiveticker.updateHTML = function( t, u ) { var updateHTML = function( t, u ) {
// Prepend HTML of new ticks. // Prepend HTML of new ticks.
t.e.innerHTML = u.h + t.e.innerHTML; t.e.innerHTML = u.h + t.e.innerHTML;
t.e.setAttribute( 'data-sclt-last', u.t ); t.e.parentNode.setAttribute( 'data-sclt-last', u.t );
// Remove tail, if limit is set. // Remove tail, if limit is set.
if ( 0 < t.l ) { if ( 0 < t.l ) {
@ -149,6 +181,7 @@ scLiveticker.updateHTML = function( t, u ) {
document.addEventListener( document.addEventListener(
'DOMContentLoaded', 'DOMContentLoaded',
function() { function() {
scLiveticker.init(); // Trigger periodic update of livetickers. init(); // Trigger periodic update of livetickers.
} }
); );
}() );

View File

@ -41,19 +41,22 @@ define( 'SCLIVETICKER_BASE', plugin_dir_url( __FILE__ ) );
define( 'SCLIVETICKER_BASENAME', plugin_basename( __FILE__ ) ); define( 'SCLIVETICKER_BASENAME', plugin_basename( __FILE__ ) );
// System Hooks. // System Hooks.
add_action( 'init', array( 'SCLiveticker', 'register_types' ) ); add_action( 'init', array( 'SCLiveticker\\SCLiveticker', 'register_types' ) );
add_action( 'plugins_loaded', array( 'SCLiveticker', 'init' ) ); add_action( 'plugins_loaded', array( 'SCLiveticker\\SCLiveticker', 'init' ) );
register_activation_hook( SCLIVETICKER_FILE, array( 'SCLiveticker_System', 'activate' ) ); register_activation_hook( SCLIVETICKER_FILE, array( 'SCLiveticker\\System', 'activate' ) );
register_uninstall_hook( SCLIVETICKER_FILE, array( 'SCLiveticker_System', 'uninstall' ) ); register_uninstall_hook( SCLIVETICKER_FILE, array( 'SCLiveticker\\System', 'uninstall' ) );
// Allow shortcodes in widgets. // Allow shortcodes in widgets.
add_filter( 'widget_text', 'do_shortcode' ); add_filter( 'widget_text', 'do_shortcode' );
// Add shortcode. // Add shortcode.
add_shortcode( 'liveticker', array( 'SCLiveticker', 'shortcode_ticker_show' ) ); add_shortcode( 'liveticker', array( 'SCLiveticker\\SCLiveticker', 'shortcode_ticker_show' ) );
// Add Widget. // Add Widget.
add_action( 'widgets_init', array( 'SCLiveticker_Widget', 'register' ) ); add_action( 'widgets_init', array( 'SCLiveticker\\Widget', 'register' ) );
// Add Gutenberg block.
add_action( 'enqueue_block_editor_assets', array( 'SCLiveticker\\Admin', 'register_block' ) );
// Autoload. // Autoload.
spl_autoload_register( 'scliveticker_autoload' ); spl_autoload_register( 'scliveticker_autoload' );
@ -67,16 +70,16 @@ spl_autoload_register( 'scliveticker_autoload' );
*/ */
function scliveticker_autoload( $class ) { function scliveticker_autoload( $class ) {
$plugin_classes = array( $plugin_classes = array(
'SCLiveticker', 'SCLiveticker\\SCLiveticker',
'SCLiveticker_Admin', 'SCLiveticker\\Admin',
'SCLiveticker_System', 'SCLiveticker\\System',
'SCLiveticker_Widget', 'SCLiveticker\\Widget',
); );
if ( in_array( $class, $plugin_classes, true ) ) { if ( in_array( $class, $plugin_classes, true ) ) {
require_once sprintf( require_once sprintf(
'%s/includes/class-%s.php', '%s/includes/class-%s.php',
SCLIVETICKER_DIR, SCLIVETICKER_DIR,
strtolower( str_replace( '_', '-', $class ) ) strtolower( str_replace( '_', '-', substr( $class, 13 ) ) )
); );
} }
} }

9
styles/block.css Normal file
View File

@ -0,0 +1,9 @@
div.wp-block-scliveticker-ticker div.components-base-control:first-child label,
div.wp-block-scliveticker-ticker .label {
font-weight: 600;
}
div.wp-block-scliveticker-ticker .label > .dashicon,
div.wp-block-scliveticker-ticker div.components-base-control:first-child label > .dashicon {
margin-right: 8px;
}

View File

@ -1,8 +1,10 @@
ul.sclt-ticker { div.wp-block-scliveticker-ticker ul,
div.wp-block-scliveticker-ajax-ticker ul {
list-style-type: none; list-style-type: none;
} }
ul.sclt-ticker > li.sclt-tick { div.wp-block-scliveticker-ticker ul > li.sclt-tick,
div.wp-block-scliveticker-ajax-ticker ul > li.sclt-tick {
background-color: #f5f5f5; background-color: #f5f5f5;
list-style-type: none; list-style-type: none;
margin: 0.1em; margin: 0.1em;

View File

@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr> </tr>
<tr> <tr>
<td> <td>
<label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_html_e( 'Number of Ticks:', 'stklcode-liveticker' ); ?></label> <label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_html_e( 'Number of Ticks', 'stklcode-liveticker' ); ?>:</label>
</td> </td>
<td> <td>
<select id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>"> <select id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>">