Compare commits

..

10 Commits

10 changed files with 265 additions and 180 deletions

View File

@ -1,3 +1,16 @@
2023.06.17
- require dotclear 2.26
- fix php7.4 compatibility
2023.04.22
- require dotclear 2.26
- use latest helper namespace
- fix nullsafe warnings
2023.03.25
- require dotclear 2.26
- use namespace
2022.11.20 2022.11.20
- fix compatibility with Dotclear 2.24 (required) - fix compatibility with Dotclear 2.24 (required)

View File

@ -3,7 +3,7 @@
[![Release](https://img.shields.io/github/v/release/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/releases) [![Release](https://img.shields.io/github/v/release/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/releases)
[![Date](https://img.shields.io/github/release-date/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/releases) [![Date](https://img.shields.io/github/release-date/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/releases)
[![Issues](https://img.shields.io/github/issues/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/issues) [![Issues](https://img.shields.io/github/issues/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/issues)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.24-blue.svg)](https://fr.dotclear.org/download) [![Dotclear](https://img.shields.io/badge/dotclear-v2.26-blue.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-green.svg)](https://plugins.dotaddict.org/dc2/details/lastpostsExtend) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-green.svg)](https://plugins.dotaddict.org/dc2/details/lastpostsExtend)
[![License](https://img.shields.io/github/license/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/blob/master/LICENSE) [![License](https://img.shields.io/github/license/JcDenis/lastpostsExtend)](https://github.com/JcDenis/lastpostsExtend/blob/master/LICENSE)
@ -19,7 +19,7 @@ Like widget lastposts but with more options.
lastpostsExtend requires: lastpostsExtend requires:
* permissions to manage widgets * permissions to manage widgets
* Dotclear 2.24 * Dotclear 2.26
## USAGE ## USAGE

View File

@ -1,17 +0,0 @@
<?php
/**
* @brief lastpostsExtend, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
require __DIR__ . '/_widgets.php';

View File

@ -18,13 +18,15 @@ $this->registerModule(
'Last entries (Extended)', 'Last entries (Extended)',
'Extended list of entries', 'Extended list of entries',
'Jean-Christian Denis and contributors', 'Jean-Christian Denis and contributors',
'2022.11.20', '2023.06.17',
[ [
'requires' => [['core', '2.24']], 'requires' => [['core', '2.26']],
'permissions' => dcAuth::PERMISSION_ADMIN, 'permissions' => dcCore::app()->auth->makePermissions([
dcAuth::PERMISSION_ADMIN,
]),
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://github.com/JcDenis/lastpostsExtend', 'support' => 'https://github.com/JcDenis/' . basename(__DIR__),
'details' => 'http://plugins.dotaddict.org/dc2/details/lastpostsExtend', 'details' => 'http://plugins.dotaddict.org/dc2/details/' . basename(__DIR__),
'repository' => 'https://raw.githubusercontent.com/JcDenis/lastpostsExtend/master/repository.xml', 'repository' => 'https://raw.githubusercontent.com/JcDenis/' . basename(__DIR__) . '/master/repository.xml',
] ]
); );

View File

@ -1,17 +0,0 @@
<?php
/**
* @brief lastpostsExtend, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
if (!defined('DC_RC_PATH')) {
return null;
}
require __DIR__ . '/_widgets.php';

View File

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="lastpostsExtend"> <module id="lastpostsExtend">
<name>Last entries (Extended)</name> <name>Last entries (Extended)</name>
<version>2022.11.20</version> <version>2023.06.17</version>
<author>Jean-Christian Denis and contributors</author> <author>Jean-Christian Denis and contributors</author>
<desc>Extended list of entries</desc> <desc>Extended list of entries</desc>
<file>https://github.com/JcDenis/lastpostsExtend/releases/download/v2022.11.20/plugin-lastpostsExtend.zip</file> <file>https://github.com/JcDenis/lastpostsExtend/releases/download/v2023.06.17/plugin-lastpostsExtend.zip</file>
<da:dcmin>2.24</da:dcmin> <da:dcmin>2.26</da:dcmin>
<da:details>http://plugins.dotaddict.org/dc2/details/lastpostsExtend</da:details> <da:details>http://plugins.dotaddict.org/dc2/details/lastpostsExtend</da:details>
<da:support>https://github.com/JcDenis/lastpostsExtend</da:support> <da:support>https://github.com/JcDenis/lastpostsExtend</da:support>
</module> </module>

View File

@ -0,0 +1,28 @@
<?php
/**
* @package Dotclear
*
* @copyright Olivier Meunier & Association Dotclear
* @copyright GPL-2.0-only
*/
#
# DOT NOT MODIFY THIS FILE !
#
use Dotclear\Helper\L10n;
L10n::$locales['Last entries (Extended)'] = 'Derniers billets (étendu)';
L10n::$locales['Extended list of entries'] = 'Liste étendue de billets';
L10n::$locales['Post'] = 'Billet';
L10n::$locales['Gallery'] = 'Galerie';
L10n::$locales['Protection:'] = 'Protection :';
L10n::$locales['only without password'] = 'seulement sans mot de passe';
L10n::$locales['only with password'] = 'seulement avec mot de passe';
L10n::$locales['Selected entries only'] = 'Billets sélectionnés seulement';
L10n::$locales['Updated entries only'] = 'Billets mis à jour seulement';
L10n::$locales['Limit to tags:'] = 'Limiter aux mots-clés :';
L10n::$locales['Limit to words:'] = 'Limiter aux mots :';
L10n::$locales['Show entries first image:'] = 'Afficher la première image du billet :';
L10n::$locales['Show entries excerpt'] = 'Afficher l\'extrait';
L10n::$locales['Excerpt length:'] = 'Taille de l\'extrait :';
L10n::$locales['Show comments count'] = 'Afficher le nombre de commentaires';

41
src/Backend.php 100644
View File

@ -0,0 +1,41 @@
<?php
/**
* @brief lastpostsExtend, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\lastpostsExtend;
use dcCore;
use dcNsProcess;
class Backend extends dcNsProcess
{
public static function init(): bool
{
static::$init = defined('DC_CONTEXT_ADMIN');
return static::$init;
}
public static function process(): bool
{
if (!static::$init) {
return false;
}
dcCore::app()->addBehaviors([
'initWidgets' => [Widgets::class, 'initWidgets'],
]);
return true;
}
}

41
src/Frontend.php 100644
View File

@ -0,0 +1,41 @@
<?php
/**
* @brief lastpostsExtend, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\lastpostsExtend;
use dcCore;
use dcNsProcess;
class Frontend extends dcNsProcess
{
public static function init(): bool
{
static::$init = true;
return static::$init;
}
public static function process(): bool
{
if (!static::$init) {
return false;
}
dcCore::app()->addBehaviors([
'initWidgets' => [Widgets::class, 'initWidgets'],
]);
return true;
}
}

View File

@ -10,43 +10,49 @@
* @copyright Jean-Christian Denis * @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
if (!defined('DC_RC_PATH')) { declare(strict_types=1);
return null;
}
dcCore::app()->addBehavior( namespace Dotclear\Plugin\lastpostsExtend;
'initWidgets',
['lastpostsextendWidget', 'initWidget']
);
class lastpostsextendWidget use dcBlog;
use dcCore;
use dcMeta;
use Dotclear\Helper\Date;
use Dotclear\Helper\Text;
use Dotclear\Helper\File\Path;
use Dotclear\Helper\Html\Html;
use Dotclear\Plugin\widgets\WidgetsStack;
use Dotclear\Plugin\widgets\WidgetsElement;
class Widgets
{ {
public static function initWidget($w) public static function initWidgets(WidgetsStack $w): void
{ {
# Create widget // nullsafe
if (is_null(dcCore::app()->blog)) {
return;
}
// Create widget
$w->create( $w->create(
'lastpostsextend', 'lastpostsextend',
__('Last entries (Extended)'), __('Last entries (Extended)'),
['lastpostsextendWidget', 'parseWidget'], [self::class, 'parseWidget'],
null, null,
__('Extended list of entries') __('Extended list of entries')
); );
# Title // Title
$w->lastpostsextend->setting( $w->lastpostsextend->addTitle(__('Last entries'));
'title',
__('Title:'), // post type
__('Last entries'),
'text'
);
# type
$posttypes = [ $posttypes = [
__('Post') => 'post', __('Post') => 'post',
__('Page') => 'page', __('Page') => 'page',
__('Gallery') => 'galitem', __('Gallery') => 'galitem',
]; ];
# plugin muppet types // plugin muppet types
if (dcCore::app()->plugins->moduleExists('muppet')) { if (dcCore::app()->plugins->moduleExists('muppet') && class_exists('\muppet')) {
$muppet_types = muppet::getPostTypes(); $muppet_types = \muppet::getPostTypes();
if (is_array($muppet_types) && !empty($muppet_types)) { if (is_array($muppet_types) && !empty($muppet_types)) {
foreach ($muppet_types as $k => $v) { foreach ($muppet_types as $k => $v) {
$posttypes[$v['name']] = $k; $posttypes[$v['name']] = $k;
@ -60,7 +66,8 @@ class lastpostsextendWidget
'combo', 'combo',
$posttypes $posttypes
); );
# Category (post and page have same category)
// Category (post and page have same category)
$rs = dcCore::app()->blog->getCategories([ $rs = dcCore::app()->blog->getCategories([
'post_type' => 'post', 'post_type' => 'post',
]); ]);
@ -71,8 +78,8 @@ class lastpostsextendWidget
while ($rs->fetch()) { while ($rs->fetch()) {
$categories[str_repeat( $categories[str_repeat(
'&nbsp;&nbsp;', '&nbsp;&nbsp;',
$rs->level - 1 (int) $rs->f('level') - 1
) . '&bull; ' . html::escapeHTML($rs->cat_title)] = $rs->cat_id; ) . '&bull; ' . Html::escapeHTML($rs->f('cat_title'))] = $rs->f('cat_id');
} }
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'category', 'category',
@ -82,7 +89,8 @@ class lastpostsextendWidget
$categories $categories
); );
unset($rs, $categories); unset($rs, $categories);
# Pasworded
// Passworded
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'passworded', 'passworded',
__('Protection:'), __('Protection:'),
@ -94,7 +102,8 @@ class lastpostsextendWidget
__('only with password') => 'yes', __('only with password') => 'yes',
] ]
); );
# Status
// Status
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'status', 'status',
__('Status:'), __('Status:'),
@ -108,21 +117,24 @@ class lastpostsextendWidget
__('published') => '1', __('published') => '1',
] ]
); );
# Selected entries only
// Selected entries only
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'selectedonly', 'selectedonly',
__('Selected entries only'), __('Selected entries only'),
0, 0,
'check' 'check'
); );
# Updated entries only
// Updated entries only
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'updatedonly', 'updatedonly',
__('Updated entries only'), __('Updated entries only'),
0, 0,
'check' 'check'
); );
# Tag
// Tag
if (dcCore::app()->plugins->moduleExists('tags')) { if (dcCore::app()->plugins->moduleExists('tags')) {
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'tag', 'tag',
@ -131,21 +143,24 @@ class lastpostsextendWidget
'text' 'text'
); );
} }
# Search
// Search
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'search', 'search',
__('Limit to words:'), __('Limit to words:'),
'', '',
'text' 'text'
); );
# Entries limit
// Entries limit
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'limit', 'limit',
__('Entries limit:'), __('Entries limit:'),
10, 10,
'text' 'text'
); );
# Sort type
// Sort
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'sortby', 'sortby',
__('Order by:'), __('Order by:'),
@ -157,7 +172,6 @@ class lastpostsextendWidget
__('Comments') => 'nb_comment', __('Comments') => 'nb_comment',
] ]
); );
# Sort order
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'sort', 'sort',
__('Sort:'), __('Sort:'),
@ -168,7 +182,8 @@ class lastpostsextendWidget
__('Descending') => 'desc', __('Descending') => 'desc',
] ]
); );
# First image
// First image
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'firstimage', 'firstimage',
__('Show entries first image:'), __('Show entries first image:'),
@ -183,103 +198,76 @@ class lastpostsextendWidget
__('original') => 'o', __('original') => 'o',
] ]
); );
# With excerpt
// With excerpt
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'excerpt', 'excerpt',
__('Show entries excerpt'), __('Show entries excerpt'),
0, 0,
'check' 'check'
); );
# Excerpt length
// Excerpt cut length
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'excerptlen', 'excerptlen',
__('Excerpt length:'), __('Excerpt length:'),
100, 100,
'text' 'text'
); );
# Comment count
// Comment count
$w->lastpostsextend->setting( $w->lastpostsextend->setting(
'commentscount', 'commentscount',
__('Show comments count'), __('Show comments count'),
0, 0,
'check' 'check'
); );
# Home only
$w->lastpostsextend->setting( // commons
'homeonly', $w->lastpostsextend
__('Display on:'), ->addHomeOnly()
0, ->addContentOnly()
'combo', ->addClass()
[ ->addOffline();
__('All pages') => 0,
__('Home page only') => 1,
__('Except on home page') => 2,
]
);
# widget option - content only
$w->lastpostsextend->setting(
'content_only',
__('Content only'),
0,
'check'
);
# widget option - additionnal CSS
$w->lastpostsextend->setting(
'class',
__('CSS class:'),
''
);
# widget option - put offline
$w->lastpostsextend->setting(
'offline',
__('Offline'),
0,
'check'
);
} }
public static function parseWidget($w) public static function parseWidget(WidgetsElement $w): string
{ {
// Widget is offline & Home page only
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || $w->offline || !$w->checkHomeOnly(dcCore::app()->url->type)) {
return '';
}
// Need posts excerpt
if ($w->excerpt) {
$params['columns'][] = 'post_excerpt';
}
// prepare request params
$params = [ $params = [
'sql' => '', 'sql' => '',
'columns' => [], 'columns' => [],
'from' => '', 'from' => '',
]; ];
# Widget is offline // Passworded
if ($w->offline) {
return;
}
# Home page only
if ($w->homeonly == 1 && dcCore::app()->url->type != 'default'
|| $w->homeonly == 2 && dcCore::app()->url->type == 'default') {
return null;
}
# Need posts excerpt
if ($w->excerpt) {
$params['columns'][] = 'post_excerpt';
}
# Passworded
if ($w->passworded == 'yes') { if ($w->passworded == 'yes') {
$params['sql'] .= 'AND post_password IS NOT NULL '; $params['sql'] .= 'AND post_password IS NOT NULL ';
} elseif ($w->passworded == 'no') { } elseif ($w->passworded == 'no') {
$params['sql'] .= 'AND post_password IS NULL '; $params['sql'] .= 'AND post_password IS NULL ';
} }
# Status // Status
if ($w->status != 'all') { if ($w->status != 'all') {
$params['post_status'] = $w->status; $params['post_status'] = $w->status;
} }
# Search words // Search words
if ('' != $w->search) { if ('' != $w->search) {
$params['search'] = $w->search; $params['search'] = $w->search;
} }
# Updated posts only // Updated posts only
if ($w->updatedonly) { if ($w->updatedonly) {
$params['sql'] .= 'AND post_creadt < post_upddt ' . $params['sql'] .= 'AND post_creadt < post_upddt ' .
'AND post_dt < post_upddt '; 'AND post_dt < post_upddt ';
@ -298,15 +286,15 @@ class lastpostsextendWidget
$params['limit'] = abs((int) $w->limit); $params['limit'] = abs((int) $w->limit);
$params['no_content'] = true; $params['no_content'] = true;
# Selected posts only // Selected posts only
if ($w->selectedonly) { if ($w->selectedonly) {
$params['post_selected'] = 1; $params['post_selected'] = 1;
} }
# Type // Post type
$params['post_type'] = $w->posttype; $params['post_type'] = $w->posttype;
# Category // Category
if ($w->category) { if ($w->category) {
if ($w->category == 'null') { if ($w->category == 'null') {
$params['sql'] .= ' AND P.cat_id IS NULL '; $params['sql'] .= ' AND P.cat_id IS NULL ';
@ -317,13 +305,13 @@ class lastpostsextendWidget
} }
} }
# Tags // Tags
if (dcCore::app()->plugins->moduleExists('tags') && $w->tag) { if (dcCore::app()->plugins->moduleExists('tags') && $w->tag) {
$tags = explode(',', $w->tag); $tags = explode(',', $w->tag);
foreach ($tags as $i => $tag) { foreach ($tags as $i => $tag) {
$tags[$i] = trim($tag); $tags[$i] = trim($tag);
} }
$params['from'] .= ', ' . dcCore::app()->prefix . 'meta META '; $params['from'] .= ', ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' META ';
$params['sql'] .= 'AND META.post_id = P.post_id '; $params['sql'] .= 'AND META.post_id = P.post_id ';
$params['sql'] .= 'AND META.meta_id ' . dcCore::app()->con->in($tags) . ' '; $params['sql'] .= 'AND META.meta_id ' . dcCore::app()->con->in($tags) . ' ';
$params['sql'] .= "AND META.meta_type = 'tag' "; $params['sql'] .= "AND META.meta_type = 'tag' ";
@ -335,53 +323,58 @@ class lastpostsextendWidget
false false
); );
# No result // No result
if ($rs->isEmpty()) { if ($rs->isEmpty()) {
return null; return '';
} }
# Return // Parse result
$res = $w->title ? $w->renderTitle(html::escapeHTML($w->title)) : ''; $res = $w->title ? $w->renderTitle(Html::escapeHTML($w->title)) : '';
while ($rs->fetch()) { while ($rs->fetch()) {
$res .= '<li>' . if (is_null(dcCore::app()->blog)) { // phpstan ignores previous check !?
'<' . ($rs->post_status == 1 ? 'a href="' . $rs->getURL() . '"' : 'span') . break;
' title="' . }
dt::dt2str( $published = ((int) $rs->f('post_status')) == dcBlog::POST_PUBLISHED;
dcCore::app()->blog->settings->system->date_format,
$rs->post_upddt
) . ', ' .
dt::dt2str(
dcCore::app()->blog->settings->system->time_format,
$rs->post_upddt
) . '">' .
html::escapeHTML($rs->post_title) .
'</' . ($rs->post_status == 1 ? 'a' : 'span') . '>';
# Nb comments $res .= '<li>' .
if ($w->commentscount && $rs->post_status == 1) { '<' . ($published ? 'a href="' . $rs->getURL() . '"' : 'span') .
' title="' .
Date::dt2str(
dcCore::app()->blog->settings->get('system')->get('date_format'),
$rs->f('post_upddt')
) . ', ' .
Date::dt2str(
dcCore::app()->blog->settings->get('system')->get('time_format'),
$rs->f('post_upddt')
) . '">' .
Html::escapeHTML($rs->f('post_title')) .
'</' . ($published ? 'a' : 'span') . '>';
// Nb comments
if ($w->commentscount && $published) {
$res .= ' (' . $rs->nb_comment . ')'; $res .= ' (' . $rs->nb_comment . ')';
} }
# First image // First image
if ($w->firstimage != '') { if ($w->firstimage != '') {
$res .= self::entryFirstImage( $res .= self::entryFirstImage(
$rs->post_type, $rs->f('post_type'),
$rs->post_id, $rs->f('post_id'),
$w->firstimage $w->firstimage
); );
} }
# Excerpt // Excerpt
if ($w->excerpt) { if ($w->excerpt) {
$excerpt = $rs->post_excerpt; $excerpt = $rs->f('post_excerpt');
if ($rs->post_format == 'wiki') { if ($rs->f('post_format') == 'wiki') {
dcCore::app()->initWikiComment(); dcCore::app()->initWikiComment();
$excerpt = dcCore::app()->wikiTransform($excerpt); $excerpt = dcCore::app()->wikiTransform($excerpt);
$excerpt = dcCore::app()->HTMLfilter($excerpt); $excerpt = dcCore::app()->HTMLfilter($excerpt);
} }
if (strlen($excerpt) > 0) { if (strlen($excerpt) > 0) {
$cut = text::cutString( $cut = Text::cutString(
$excerpt, $excerpt,
abs((int) $w->excerptlen) abs((int) $w->excerptlen)
); );
@ -394,16 +387,16 @@ class lastpostsextendWidget
} }
return $w->renderDiv( return $w->renderDiv(
$w->content_only, (bool) $w->content_only,
'lastpostsextend ' . $w->class, 'lastpostsextend ' . $w->class,
'', '',
'<ul>' . $res . '</ul>' '<ul>' . $res . '</ul>'
); );
} }
private static function entryFirstImage($type, $id, $size = 's') private static function entryFirstImage(string $type, $id, string $size = 's'): string
{ {
if (!in_array($type, ['post', 'page', 'galitem'])) { if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || !in_array($type, ['post', 'page', 'galitem'])) {
return ''; return '';
} }
@ -421,8 +414,8 @@ class lastpostsextendWidget
$size = 's'; $size = 's';
} }
$p_url = dcCore::app()->blog->settings->system->public_url; $p_url = (string) dcCore::app()->blog->settings->get('system')->get('public_url');
$p_site = preg_replace( $p_site = (string) preg_replace(
'#^(.+?//.+?)/(.*)$#', '#^(.+?//.+?)/(.*)$#',
'$1', '$1',
dcCore::app()->blog->url dcCore::app()->blog->url
@ -435,10 +428,10 @@ class lastpostsextendWidget
$src = ''; $src = '';
$alt = ''; $alt = '';
$subject = $rs->post_excerpt_xhtml . $rs->post_content_xhtml . $rs->cat_desc; $subject = $rs->f('post_excerpt_xhtml') . $rs->f('post_content_xhtml') . $rs->f('cat_desc');
if (preg_match_all($pattern, $subject, $m) > 0) { if (preg_match_all($pattern, $subject, $m) > 0) {
foreach ($m[1] as $i => $img) { foreach ($m[1] as $i => $img) {
if (($src = self::ContentFirstImageLookup($p_root, $img, $size)) !== false) { if (($src = self::ContentFirstImageLookup($p_root, $img, $size)) != '') {
$src = $p_url . (dirname($img) != '/' ? dirname($img) : '') . '/' . $src; $src = $p_url . (dirname($img) != '/' ? dirname($img) : '') . '/' . $src;
if (preg_match('/alt="([^"]+)"/', $m[0][$i], $malt)) { if (preg_match('/alt="([^"]+)"/', $m[0][$i], $malt)) {
$alt = $malt[1]; $alt = $malt[1];
@ -456,23 +449,24 @@ class lastpostsextendWidget
return return
'<div class="img-box">' . '<div class="img-box">' .
'<div class="img-thumbnail">' . '<div class="img-thumbnail">' .
'<a title="' . html::escapeHTML($rs->post_title) . '" href="' . $rs->getURL() . '">' . '<a title="' . Html::escapeHTML($rs->f('post_title')) . '" href="' . $rs->getURL() . '">' .
'<img alt="' . $alt . '" src="' . stripslashes($src) . '" />' . '<img alt="' . $alt . '" src="' . stripslashes($src) . '" />' .
'</a></div>' . '</a></div>' .
"</div>\n"; "</div>\n";
} }
private static function ContentFirstImageLookup($root, $img, $size) private static function ContentFirstImageLookup(string $root, string $img, string $size): string
{ {
$res = '';
# Get base name and extension # Get base name and extension
$info = path::info($img); $info = Path::info($img);
$base = $info['base']; $base = $info['base'];
if (preg_match('/^\.(.+)_(sq|t|s|m)$/', $base, $m)) { if (preg_match('/^\.(.+)_(sq|t|s|m)$/', $base, $m)) {
$base = $m[1]; $base = $m[1];
} }
$res = false;
if ($size != 'o' && file_exists($root . '/' . $info['dirname'] . '/.' . $base . '_' . $size . '.jpg')) { if ($size != 'o' && file_exists($root . '/' . $info['dirname'] . '/.' . $base . '_' . $size . '.jpg')) {
$res = '.' . $base . '_' . $size . '.jpg'; $res = '.' . $base . '_' . $size . '.jpg';
} else { } else {
@ -488,6 +482,6 @@ class lastpostsextendWidget
} }
} }
return $res ? $res : false; return $res;
} }
} }