1
0
mirror of https://github.com/e107inc/e107.git synced 2025-07-16 04:26:20 +02:00

Closes #5365 Image alt attribute management via Media Manager. Test added.

This commit is contained in:
camer0n
2024-12-19 13:17:32 -08:00
parent 176f8eb325
commit b25e60888b
7 changed files with 132 additions and 38 deletions

View File

@ -873,39 +873,47 @@ class media_admin_ui extends e_admin_ui
public $deleteConfirmScreen = true;
public $deleteConfirmMessage = IMALAN_129;
protected $grid = array('id'=>'media_id', 'title'=>'media_name', 'image'=>'media_preview', 'body'=>'', 'class'=>'col-sm-6 col-md-4 col-lg-2', 'perPage'=>24, 'carousel'=>false);
protected $grid = array('id'=>'media_id', 'title'=>'media_name', 'image'=>'media_preview', 'dimensions'=>'media_dimensions', 'body'=>'', 'class'=>'col-sm-6 col-md-4 col-lg-2', 'perPage'=>24, 'carousel'=>false);
protected $preftabs = array(IMALAN_78,IMALAN_89, 'Youtube');
protected $fields = array(
'checkboxes' => array('title'=> '', 'type' => null, 'data'=> null, 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'),
'media_id' => array('title'=> LAN_ID, 'type' => 'number', 'data'=> 'int', 'width' =>'5%', 'forced'=> TRUE, 'nolist'=>TRUE),
'media_preview' => array('title'=> LAN_PREVIEW, 'type' => 'method', 'data'=>false, 'forced'=>true, 'width' => '110px', 'thclass' => 'center', 'class'=>'center'),
'media_url' => array('title'=> IMALAN_110, 'type' => 'text', 'data'=> 'str', 'inline'=>false, 'thclass' => 'left', 'class'=>'left', 'width' => 'auto', 'writeParms'=>'size=xxlarge'),
'media_category' => array('title'=> LAN_CATEGORY, 'type' => 'comma', 'inline'=>false, 'data'=> 'str', 'width' => '10%', 'filter' => true, 'batch' => true, 'class'=>'left'),
// Upload should be managed completely separately via upload-handler.
// 'media_upload' => array('title'=> "Upload File", 'type' => 'upload', 'data'=> false, 'readParms' => 'hidden', 'writeParms' => 'disable_button=1', 'width' => '10%', 'nolist' => true),
'media_name' => array('title'=> LAN_TITLE, 'type' => 'text', 'data'=> 'str', 'inline'=>true, 'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge')),
'media_caption' => array('title'=> LAN_CAPTION, 'type' => 'text', 'data'=> 'str', 'inline'=>true, 'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge')),
// media_description is type = textarea until bbarea can be reduced to not include youtube etc
'media_sef' => array('title'=> LAN_URL, 'readonly'=>1, 'type'=>'method', 'data'=>false),
protected $tabs = ['general'=>LAN_GENERAL, 'advanced'=>LAN_ADVANCED];
'media_description' => array('title'=> LAN_DESCRIPTION, 'type' => 'textarea', 'data'=> 'str', 'width' => 'auto', 'thclass' => 'left first', 'readParms' => 'truncate=100', 'writeParms' => 'size=xxlarge&counter=0'),
'media_type' => array('title'=> IMALAN_118, 'type' => 'dropdown', 'data'=> 'str', 'filter'=>true, 'width' => 'auto', 'noedit'=>TRUE),
'media_author' => array('title'=> LAN_USER, 'type' => 'user', 'data'=> 'int', 'width' => 'auto', 'thclass' => 'center', 'class'=>'center','readParms' => 'link=1', 'filter' => true, 'batch' => true, 'noedit'=>TRUE ),
'media_datestamp' => array('title'=> LAN_DATESTAMP, 'type' => 'datestamp', 'data'=> 'int', 'width' => '10%', 'noedit'=>TRUE), // User date
'media_size' => array('title'=> LAN_SIZE, 'type' => 'number', 'data'=> 'int', 'width' => 'auto', 'readonly'=>2),
'media_dimensions' => array('title'=> IMALAN_120, 'type' => 'text', 'data'=> 'str', 'width' => '5%', 'readonly'=>TRUE, 'class'=>'nowrap','noedit'=>TRUE),
'media_userclass' => array('title'=> LAN_USERCLASS, 'type' => 'userclass', 'data'=> 'str', 'inline'=>true, 'width' => '10%', 'thclass' => 'center','filter'=>TRUE,'batch'=>TRUE ),
'media_tags' => array('title'=> IMALAN_132, 'type' => 'tags', 'inline'=>true, 'data'=> 'str', 'width' => '10%', 'filter'=>TRUE,'batch'=>TRUE ),
'media_usedby' => array('title'=> IMALAN_21, 'type' => 'hidden', 'data'=> 'text', 'width' => 'auto', 'thclass' => 'center', 'class'=>'center', 'nolist'=>true, 'readonly'=>TRUE ),
protected $fields = [
'checkboxes' => array('title'=> '', 'type' => null, 'data'=> null, 'tab'=>'general', 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'),
'media_id' => array('title'=> LAN_ID, 'type' => 'number', 'data'=> 'int', 'tab'=>'general', 'width' =>'5%', 'forced'=> TRUE, 'nolist'=>TRUE),
'media_preview' => array('title'=> LAN_PREVIEW, 'type' => 'method', 'data'=>false, 'tab'=>'general', 'forced'=>true, 'width' => '110px', 'thclass' => 'center', 'class'=>'center'),
'media_url' => array('title'=> IMALAN_110, 'type' => 'text', 'data'=> 'str', 'tab'=>'general', 'inline'=>false, 'thclass' => 'left', 'class'=>'left', 'width' => 'auto', 'writeParms'=>'size=xxlarge'),
'media_category' => array('title'=> LAN_CATEGORY, 'type' => 'comma', 'inline'=>false, 'data'=> 'str', 'tab'=>'advanced', 'width' => '10%', 'filter' => true, 'batch' => true, 'class'=>'left'),
// Upload should be managed completely separately via upload-handler.
// 'media_upload' => array('title'=> "Upload File", 'type' => 'upload', 'data'=> false, 'tab'=>'general', 'readParms' => 'hidden', 'writeParms' => 'disable_button=1', 'width' => '10%', 'nolist' => true),
'media_name' => array('title'=> LAN_TITLE, 'type' => 'text', 'data'=> 'str', 'tab'=>'general', 'inline'=>true, 'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge')),
'media_caption' => array('title'=> LAN_CAPTION, 'type' => 'text', 'data'=> 'str', 'tab'=>'general', 'inline'=>true, 'width' => 'auto', 'writeParms'=>array('size'=>'xxlarge')),
// media_description is type = textarea until bbarea can be reduced to not include youtube etc
'media_alt' => array('title' => IMALAN_191, 'type' => 'text', 'data' => 'str', 'tab'=>'general', 'width' => '20%', 'inline' => true, 'writeParms' => array('size' => 'xxlarge'), 'thclass' => 'left', 'class' => 'left', 'filter' => true),
'options' => array('title'=> LAN_OPTIONS, 'type' => 'method', 'data'=> null, 'forced'=>TRUE, 'width' => '10%', 'thclass' => 'center last', 'class' => 'center', 'batch'=>true, 'noedit'=>true)
);
'media_sef' => array('title'=> LAN_URL, 'readonly'=>1, 'type'=>'method', 'data'=>false, 'tab'=>'general'),
'media_description' => array('title'=> LAN_DESCRIPTION, 'type' => 'textarea', 'data'=> 'str', 'tab'=>'general', 'width' => 'auto', 'thclass' => 'left first', 'readParms' => 'truncate=100', 'writeParms' => 'size=xxlarge&counter=0'),
'media_type' => array('title'=> IMALAN_118, 'type' => 'dropdown', 'data'=> 'str', 'tab'=>'general', 'filter'=>true, 'width' => 'auto', 'noedit'=>TRUE),
'media_author' => array('title'=> LAN_USER, 'type' => 'user', 'data'=> 'int', 'tab'=>'general', 'width' => 'auto', 'thclass' => 'center', 'class'=>'center','readParms' => 'link=1', 'filter' => true, 'batch' => true, 'noedit'=>TRUE),
'media_datestamp' => array('title'=> LAN_DATESTAMP, 'type' => 'datestamp', 'data'=> 'int', 'tab'=>'general', 'width' => '10%', 'noedit'=>TRUE), // User date
'media_size' => array('title'=> LAN_SIZE, 'type' => 'number', 'data'=> 'int', 'tab'=>'general', 'width' => 'auto', 'readonly'=>2, 'readParms'=>['format'=>'bytes']),
'media_dimensions' => array('title'=> IMALAN_120, 'type' => 'text', 'data'=> 'str', 'tab'=>'general', 'width' => '5%', 'readonly'=>TRUE, 'class'=>'nowrap','noedit'=>TRUE),
'media_userclass' => array('title'=> LAN_USERCLASS, 'type' => 'userclass', 'data'=> 'str', 'tab'=>'advanced', 'inline'=>true, 'width' => '10%', 'thclass' => 'center','filter'=>TRUE,'batch'=>TRUE ),
'media_tags' => array('title'=> IMALAN_132, 'type' => 'tags', 'inline'=>true, 'data'=> 'str', 'tab'=>'advanced', 'width' => '10%', 'filter'=>TRUE,'batch'=>TRUE ),
'media_credits' => array('title' => IMALAN_192, 'type' => 'text', 'data' => 'str', 'tab'=>'advanced', 'width' => '20%', 'inline' => true, 'writeParms' => array('size' => 'xxlarge'), 'thclass' => 'left', 'class' => 'left', 'filter' => false),
'media_expires' => array('title' => IMALAN_193, 'type' => 'datestamp', 'data' => 'int', 'tab'=>'advanced', 'width' => '15%', 'inline' => true, 'writeParms' => '', 'thclass' => 'center', 'class' => 'center', 'filter' => true, 'batch' => true),
'media_usedby' => array('title'=> IMALAN_21, 'type' => 'hidden', 'data'=> 'text', 'tab'=>'advanced', 'width' => 'auto', 'thclass' => 'center', 'class'=>'center', 'nolist'=>true, 'readonly'=>TRUE ),
protected $mimePaths = array(
'options' => array('title'=> LAN_OPTIONS, 'type' => 'method', 'data'=> null, 'forced'=>TRUE, 'width' => '10%', 'thclass' => 'center last', 'class' => 'center', 'batch'=>true, 'noedit'=>true)
];
// protected $filterSort = ['media_author']; // Display these fields first
// protected $batchSort = ['media_author']; // Display these fields first
protected $mimePaths = [
'text' => e_MEDIA_FILE,
'multipart' => e_MEDIA_FILE,
'application' => e_MEDIA_FILE,
@ -913,15 +921,12 @@ class media_admin_ui extends e_admin_ui
'image' => e_MEDIA_IMAGE,
'video' => e_MEDIA_VIDEO,
'other' => e_MEDIA_FILE
);
];
protected $fieldpref = array( 'media_id', 'media_name', 'media_caption', 'media_category', 'media_datestamp','media_userclass', 'options');
protected $fieldpref = ['media_id', 'media_name', 'media_caption', 'media_category', 'media_datestamp','media_alt', 'options'];
protected $prefs = array(
protected $prefs = array(
'image_post' => array('title'=> IMALAN_1, 'tab'=>0, 'type'=>'boolean', 'data'=>'int', 'writeParms'=>'help=IMALAN_2'),
'image_post_class' => array('title'=> IMALAN_10, 'type' => 'userclass', 'data'=>'int', 'writeParms'=>'help=IMALAN_11&classlist=public,guest,nobody,member,admin,main,classes' ),
'image_post_disabled_method' => array('title'=> IMALAN_12, 'type' => 'boolean','writeParms'=>'enabled=IMALAN_15&disabled=IMALAN_14'),
@ -1353,6 +1358,7 @@ class media_admin_ui extends e_admin_ui
$this->grid['template'] = '<div class="panel panel-default">
<div class="e-overlay" >{IMAGE}
<div class="e-overlay-content">
<span class="label label-default" style="font-size:1.2rem;position:absolute;top:0;right:0;padding:5px">{DIMENSIONS}</span>
<p>{TITLE}</p>
<p>{OPTIONS}</p>
<p>{CHECKBOX} <label for="multiselect-{ID}-{ID}">'.LAN_SELECT.'</label></p>
@ -3127,6 +3133,18 @@ class media_admin_ui extends e_admin_ui
// return $this->observeUploaded($new_data);
}
public function afterUpdate($new_data, $old_data, $id)
{
file_put_contents(__DIR__.'/test.txt', print_r($new_data, true));
if(isset($new_data['media_alt']) && !empty($new_data['media_url']))
{
e107::getParser()->setImageAltCacheFile($new_data['media_url'], $new_data['media_alt']);
}
}
public function mediaData($sc_path)
{
if(!$sc_path)

View File

@ -493,7 +493,7 @@ class news_shortcodes extends e_shortcode
}
$style = !empty($this->param['thumbnail']) ? $this->param['thumbnail'] : '';
$alt = !empty($parm['alt']) ? $parm['alt'] : basename($srcPath);
$alt = !empty($parm['alt']) ? $parm['alt'] : '';
$imgParms = array(
'class' => $class,

View File

@ -136,6 +136,9 @@ CREATE TABLE core_media (
media_userclass varchar(255) NOT NULL default '',
media_usedby text NOT NULL,
media_tags text NOT NULL,
media_alt varchar(255) NOT NULL default '',
media_credits varchar(255) NOT NULL default '',
media_expires int(10) unsigned NOT NULL default '0',
PRIMARY KEY (media_id),
UNIQUE KEY media_url (media_url)
) ENGINE=InnoDB;

View File

@ -2288,6 +2288,50 @@ class e_parse
}
/**
* Sets a cache file for storing alternate text data for an image.
*
* @param string $path The file path of the image whose alternate text is being cached.
* @param string $value The alternate text value to cache.
* @return string or false on failure
*/
public function setImageAltCacheFile($path, $value)
{
$cache_str = sha1($path);
$pre = 'alt_';
$post = '.cache.txt';
$file = e_CACHE_IMAGE .'alt_' . sha1($path) . '.cache.txt';
if (file_put_contents($file, $value) !== false)
{
return $file;
}
return false;
}
/**
* Retrieves the content of the alternative cache file for the specified path if it exists.
*
* @param string $path The file path to generate the cache filename for.
* @return string|null The content of the cache file if it exists, or null if the file does not exist.
*/
public function getImageAltCacheFile($path)
{
$file = e_CACHE_IMAGE .'alt_' . sha1($path) . '.cache.txt';
if (file_exists($file))
{
return file_get_contents($file);
}
return null;
}
/**
* Generated a Thumb Cache File Name from path and options.
*
@ -4545,6 +4589,11 @@ class e_parse
$tp = $this;
if(($alt = $this->getImageAltCacheFile($file)) && empty($parm['alt']))
{
$parm['alt'] = $alt;
}
// e107::getDebug()->log($file);
// e107::getDebug()->log($parm);
@ -4621,6 +4670,8 @@ class e_parse
$path = $tp->thumbUrl($file, $parm);
}
$id = (!empty($parm['id'])) ? 'id="' . $parm['id'] . '" ' : '';
$class = (!empty($parm['class'])) ? $parm['class'] : 'img-responsive img-fluid';
$alt = (!empty($parm['alt'])) ? $tp->toAttribute($parm['alt']) : basename($file);

View File

@ -5467,7 +5467,11 @@ var_dump($select_options);*/
if($parms)
{
if(isset($parms['sep']))
if (!empty($parms['format']) && $parms['format'] === 'bytes')
{
$value = eHelper::parseMemorySize($value, varset($parms['decimals'], 2)); // Use 'decimals' from parms or default to 2
}
elseif(isset($parms['sep']))
{
$value = number_format($value, varset($parms['decimals'],0), vartrue($parms['point'], '.'), vartrue($parms['sep'], ' '));
}
@ -5486,7 +5490,6 @@ var_dump($select_options);*/
$value = $this->renderLink($value,$parms,$id);
}
$value = vartrue($parms['pre']).$value.vartrue($parms['post']);
// else same
break;

View File

@ -216,3 +216,7 @@ define("IMALAN_187", "Convert to webp during import");
define("IMALAN_188", "Convert to webp during render");
define("IMALAN_189", "JPEG, PNG and GIF files will be automatically converted to webp format. (icons excluded)");
define("IMALAN_190", "Importing of this file-type is not allowed.");
define("IMALAN_191", "Image Alt Text");
define("IMALAN_192", "Credits");
define("IMALAN_193", "Expiry Date");

View File

@ -60,10 +60,25 @@ class e_parseTest extends \Codeception\Test\Unit
);
$result = $this->tp->toRoute($posted);
$this->assertSame($expected, $result);
self::assertSame($expected, $result);
}
public function testSetGetImageAltCacheFile()
{
$path = '{e_THEME}basic/screenshot.png';
$value = 'Test Alt Text';
// Call setImageAltCacheFile to generate the cache file
$this->tp->setImageAltCacheFile($path, $value);
$retrievedValue = $this->tp->getImageAltCacheFile($path);
self::assertSame($value, $retrievedValue, "Retrieved value does not match the expected value");
}
public function testStripBlockTags()
{