2016-06-29 12:54:05 +00:00
< ? php
/**
* Includes the core function of the Plugin - Search and Replace the Footnotes .
*
* @ filesource
* @ author Stefan Herndler
* @ since 1.5 . 0
2020-11-12 18:17:28 +00:00
*
2020-11-01 05:41:22 +00:00
* Edited for v2 . 0.0 and following .
2020-11-12 18:17:28 +00:00
*
2020-11-14 21:40:09 +00:00
* 2.0 . 5 : Autoload / infinite scroll support added thanks to code from
2020-11-05 02:34:35 +00:00
* @ docteurfitness < https :// wordpress . org / support / topic / auto - load - post - compatibility - update />
2020-11-12 18:17:28 +00:00
*
2020-11-14 21:40:09 +00:00
* 2.0 . 9 : DISABLED the_post HOOK 2020 - 11 - 08 T1839 + 0100
* 2.1 . 0 : promoted the 'Continue reading' button from localization to customization 2020 - 11 - 08 T2146 + 0100
* 2.1 . 1 : combining identical footnotes : fixed dead links 2020 - 11 - 14 T2233 + 0100
2020-11-16 20:57:15 +00:00
* 2.1 . 1 : options fixing ref container layout and referrer vertical alignment 2020 - 11 - 16 T2024 + 0100
2020-11-17 02:14:21 +00:00
* 2.1 . 1 : option fixing ref container relative position 2020 - 11 - 17 T0254 + 0100
2020-11-12 18:17:28 +00:00
*
2020-11-18 00:47:53 +00:00
* Last modified 2020 - 11 - 18 T0138 + 0100
2016-06-29 12:54:05 +00:00
*/
2020-11-01 05:41:22 +00:00
2020-10-27 11:56:49 +00:00
// If called directly, abort:
defined ( 'ABSPATH' ) or die ;
2016-06-29 12:54:05 +00:00
/**
* Looks for Footnotes short codes and replaces them . Also displays the Reference Container .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
*/
class MCI_Footnotes_Task {
2020-10-27 11:56:49 +00:00
/**
* Contains all footnotes found on current public page .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ var array
*/
public static $a_arr_Footnotes = array ();
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Flag if the display of 'LOVE FOOTNOTES' is allowed on the current public page .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ var bool
*/
public static $a_bool_AllowLoveMe = true ;
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Prefix for the Footnote html element ID .
*
* @ author Stefan Herndler
* @ since 1.5 . 8
* @ var string
*/
public static $a_str_Prefix = " " ;
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Register WordPress Hooks to replace Footnotes in the content of a public page .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
2020-11-12 18:17:28 +00:00
*
2020-11-19 20:34:45 +00:00
* Edited for v2 . 0.5 through v2 . 0.7 2020 - 11 - 02 T0330 + 0100. . 2020 - 11 - 06 T1344 + 0100
2020-11-12 18:17:28 +00:00
*
2020-11-19 20:34:45 +00:00
* Explicitly setting all priority to ( default ) " 10 " instead of lowest " PHP_INT_MAX " ,
* especially for the_content , makes the footnotes reference container display
* beneath the content and above other features added by other plugins .
2020-11-05 02:34:35 +00:00
* Requested by users : < https :// wordpress . org / support / topic / change - the - position - 5 />
* Documentation : < https :// codex . wordpress . org / Plugin_API / #Hook_in_your_Filter>
2020-11-19 20:34:45 +00:00
*
* But this change is suspected to cause issues and needs to be assessed !
* See < https :// wordpress . org / support / topic / change - the - position - 5 / #post-13612697>
2020-10-27 11:56:49 +00:00
*/
public function registerHooks () {
2020-11-18 00:47:53 +00:00
2020-11-19 20:34:45 +00:00
// first compute values from settings:
// for now only the_content is supported for customization:
$p_int_TheContentPriority = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_EXPERT_LOOKUP_THE_CONTENT_PRIORITY_LEVEL );
2020-11-18 00:47:53 +00:00
2020-11-19 20:34:45 +00:00
// PHP_INT_MAX can be set using the value -1:
if ( $p_int_TheContentPriority == - 1 ) {
$p_int_TheContentPriority = PHP_INT_MAX ;
}
2020-11-18 00:47:53 +00:00
2020-10-27 11:56:49 +00:00
// append custom css to the header
2020-11-06 14:20:33 +00:00
add_filter ( 'wp_head' , array ( $this , " wp_head " ), PHP_INT_MAX );
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
// append the love and share me slug to the footer
2020-11-06 14:20:33 +00:00
add_filter ( 'wp_footer' , array ( $this , " wp_footer " ), PHP_INT_MAX );
2016-06-29 12:54:05 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_EXPERT_LOOKUP_THE_TITLE ))) {
2020-11-19 20:34:45 +00:00
add_filter ( 'the_title' , array ( $this , " the_title " ), PHP_INT_MAX );
2020-11-17 02:14:21 +00:00
}
2020-11-19 20:34:45 +00:00
// SET PRIORITY LEVEL TO CUSTOM FOR PAGE LAYOUT; DEFAULT PHP_INT_MAX:
2016-06-29 12:54:05 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_EXPERT_LOOKUP_THE_CONTENT ))) {
2020-11-18 00:47:53 +00:00
add_filter ( 'the_content' , array ( $this , " the_content " ), $p_int_TheContentPriority );
2020-11-19 20:34:45 +00:00
}
2016-06-29 12:54:05 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_EXPERT_LOOKUP_THE_EXCERPT ))) {
2020-11-19 20:34:45 +00:00
add_filter ( 'the_excerpt' , array ( $this , " the_excerpt " ), PHP_INT_MAX );
2016-06-29 12:54:05 +00:00
}
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_EXPERT_LOOKUP_WIDGET_TITLE ))) {
2020-11-19 20:34:45 +00:00
add_filter ( 'widget_title' , array ( $this , " widget_title " ), PHP_INT_MAX );
2016-06-29 12:54:05 +00:00
}
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_EXPERT_LOOKUP_WIDGET_TEXT ))) {
2020-11-19 20:34:45 +00:00
add_filter ( 'widget_text' , array ( $this , " widget_text " ), PHP_INT_MAX );
}
// DISABLED the_post HOOK 2020-11-08T1839+0100
//
2020-11-08 17:54:50 +00:00
//
2016-06-29 12:54:05 +00:00
// reset stored footnotes when displaying the header
self :: $a_arr_Footnotes = array ();
self :: $a_bool_AllowLoveMe = true ;
2020-10-27 11:56:49 +00:00
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Outputs the custom css to the header of the public page .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
*/
public function wp_head () {
2016-06-29 12:54:05 +00:00
$l_str_Color = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_MOUSE_OVER_BOX_COLOR );
$l_str_Background = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_MOUSE_OVER_BOX_BACKGROUND );
$l_int_BorderWidth = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_BORDER_WIDTH );
$l_str_BorderColor = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_MOUSE_OVER_BOX_BORDER_COLOR );
$l_int_BorderRadius = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_BORDER_RADIUS );
$l_int_MaxWidth = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_MAX_WIDTH );
2020-10-27 11:56:49 +00:00
$l_str_BoxShadowColor = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_MOUSE_OVER_BOX_SHADOW_COLOR );
?>
< style type = " text/css " media = " screen " >
2016-06-29 12:54:05 +00:00
< ? php
echo MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_CUSTOM_CSS );
2020-11-16 20:57:15 +00:00
2020-11-17 02:14:21 +00:00
if ( ! MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_START_PAGE_ENABLE ))) {
2020-11-16 20:57:15 +00:00
echo " \r \n .home .footnotes_reference_container { display: none; } \r \n " ;
}
2020-11-11 20:49:44 +00:00
echo '.footnote_tooltip {' ;
2016-06-29 12:54:05 +00:00
if ( ! empty ( $l_str_Color )) {
printf ( " color: %s; " , $l_str_Color );
}
if ( ! empty ( $l_str_Background )) {
printf ( " background-color: %s; " , $l_str_Background );
}
if ( ! empty ( $l_int_BorderWidth ) && intval ( $l_int_BorderWidth ) > 0 ) {
printf ( " border-width: %dpx; border-style: solid; " , $l_int_BorderWidth );
}
if ( ! empty ( $l_str_BorderColor )) {
printf ( " border-color: %s; " , $l_str_BorderColor );
}
if ( ! empty ( $l_int_BorderRadius ) && intval ( $l_int_BorderRadius ) > 0 ) {
printf ( " border-radius: %dpx; " , $l_int_BorderRadius );
}
if ( ! empty ( $l_int_MaxWidth ) && intval ( $l_int_MaxWidth ) > 0 ) {
printf ( " max-width: %dpx; " , $l_int_MaxWidth );
}
if ( ! empty ( $l_str_BoxShadowColor )) {
printf ( " -webkit-box-shadow: 2px 2px 11px %s; " , $l_str_BoxShadowColor );
printf ( " -moz-box-shadow: 2px 2px 11px %s; " , $l_str_BoxShadowColor );
printf ( " box-shadow: 2px 2px 11px %s; " , $l_str_BoxShadowColor );
}
echo '}' ;
?>
2020-11-12 18:17:28 +00:00
</ style >
2020-11-11 20:49:44 +00:00
< ? php
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE ))) {
echo '<script content="text/javascript">' . " \r \n " ;
2020-11-12 18:17:28 +00:00
echo " \t function footnoteTooltipShow(footnoteTooltipId) { \r \n " ;
echo " \t \t document.getElementById(footnoteTooltipId).classList.remove('hidden'); \r \n " ;
echo " \t \t document.getElementById(footnoteTooltipId).classList.add('shown'); \r \n " ;
echo " \t } \r \n " ;
echo " \t function footnoteTooltipHide(footnoteTooltipId) { \r \n " ;
2020-11-13 16:54:31 +00:00
echo " \t \t document.getElementById(footnoteTooltipId).classList.remove('shown'); \r \n " ;
echo " \t \t document.getElementById(footnoteTooltipId).classList.add('hidden'); \r \n " ;
echo " \t } \r \n " ;
2020-11-11 20:49:44 +00:00
echo " </script> \r \n " ;
};
2020-10-27 11:56:49 +00:00
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Displays the 'LOVE FOOTNOTES' slug if enabled .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
*/
public function wp_footer () {
2016-06-29 12:54:05 +00:00
if ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_REFERENCE_CONTAINER_POSITION ) == " footer " ) {
echo $this -> ReferenceContainer ();
}
2020-10-27 11:56:49 +00:00
// get setting for love and share this plugin
$l_str_LoveMeIndex = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_LOVE );
// check if the admin allows to add a link to the footer
if ( empty ( $l_str_LoveMeIndex ) || strtolower ( $l_str_LoveMeIndex ) == " no " || ! self :: $a_bool_AllowLoveMe ) {
return ;
}
// set a hyperlink to the word "footnotes" in the Love slug
$l_str_LinkedName = sprintf ( '<a href="http://wordpress.org/plugins/footnotes/" target="_blank" style="text-decoration:none;">%s</a>' , MCI_Footnotes_Config :: C_STR_PLUGIN_PUBLIC_NAME );
// get random love me text
if ( strtolower ( $l_str_LoveMeIndex ) == " random " ) {
$l_str_LoveMeIndex = " text- " . rand ( 1 , 3 );
}
switch ( $l_str_LoveMeIndex ) {
case " text-1 " :
$l_str_LoveMeText = sprintf ( __ ( 'I %s %s' , MCI_Footnotes_Config :: C_STR_PLUGIN_NAME ), MCI_Footnotes_Config :: C_STR_LOVE_SYMBOL , $l_str_LinkedName );
break ;
case " text-2 " :
$l_str_LoveMeText = sprintf ( __ ( 'this site uses the awesome %s Plugin' , MCI_Footnotes_Config :: C_STR_PLUGIN_NAME ), $l_str_LinkedName );
break ;
case " text-3 " :
default :
$l_str_LoveMeText = sprintf ( __ ( 'extra smooth %s' , MCI_Footnotes_Config :: C_STR_PLUGIN_NAME ), $l_str_LinkedName );
break ;
}
echo sprintf ( '<div style="text-align:center; color:#acacac;">%s</div>' , $l_str_LoveMeText );
}
2016-06-29 12:54:05 +00:00
/**
* Replaces footnotes in the post / page title .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Widget content .
* @ return string Content with replaced footnotes .
*/
public function the_title ( $p_str_Content ) {
// appends the reference container if set to "post_end"
return $this -> exec ( $p_str_Content , false );
}
2020-10-27 11:56:49 +00:00
/**
* Replaces footnotes in the content of the current page / post .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Page / Post content .
* @ return string Content with replaced footnotes .
*/
public function the_content ( $p_str_Content ) {
// appends the reference container if set to "post_end"
return $this -> exec ( $p_str_Content , MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_REFERENCE_CONTAINER_POSITION ) == " post_end " ? true : false );
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Replaces footnotes in the excerpt of the current page / post .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Page / Post content .
* @ return string Content with replaced footnotes .
*/
public function the_excerpt ( $p_str_Content ) {
return $this -> exec ( $p_str_Content , false , ! MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_IN_EXCERPT )));
}
2016-06-29 12:54:05 +00:00
/**
* Replaces footnotes in the widget title .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Widget content .
* @ return string Content with replaced footnotes .
*/
public function widget_title ( $p_str_Content ) {
// appends the reference container if set to "post_end"
return $this -> exec ( $p_str_Content , false );
}
2020-10-27 11:56:49 +00:00
/**
* Replaces footnotes in the content of the current widget .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Widget content .
* @ return string Content with replaced footnotes .
*/
public function widget_text ( $p_str_Content ) {
// appends the reference container if set to "post_end"
return $this -> exec ( $p_str_Content , MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_REFERENCE_CONTAINER_POSITION ) == " post_end " ? true : false );
}
2016-06-29 12:54:05 +00:00
/**
* Replaces footnotes in each Content var of the current Post object .
*
* @ author Stefan Herndler
* @ since 1.5 . 4
* @ param array | WP_Post $p_mixed_Posts
*/
2020-11-09 19:09:54 +00:00
public function the_post ( & $p_mixed_Posts ) {
// single WP_Post object received
if ( ! is_array ( $p_mixed_Posts )) {
$p_mixed_Posts = $this -> replacePostObject ( $p_mixed_Posts );
return ;
}
// array of WP_Post objects received
for ( $l_int_Index = 0 ; $l_int_Index < count ( $p_mixed_Posts ); $l_int_Index ++ ) {
$p_mixed_Posts [ $l_int_Index ] = $this -> replacePostObject ( $p_mixed_Posts [ $l_int_Index ]);
}
}
2016-06-29 12:54:05 +00:00
/**
* Replace all Footnotes in a WP_Post object .
*
* @ author Stefan Herndler
* @ since 1.5 . 6
* @ param WP_Post $p_obj_Post
* @ return WP_Post
*/
private function replacePostObject ( $p_obj_Post ) {
//MCI_Footnotes_Convert::debug($p_obj_Post);
$p_obj_Post -> post_content = $this -> exec ( $p_obj_Post -> post_content );
$p_obj_Post -> post_content_filtered = $this -> exec ( $p_obj_Post -> post_content_filtered );
$p_obj_Post -> post_excerpt = $this -> exec ( $p_obj_Post -> post_excerpt );
return $p_obj_Post ;
}
2020-10-27 11:56:49 +00:00
/**
* Replaces all footnotes that occur in the given content .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Any string that may contain footnotes to be replaced .
* @ param bool $p_bool_OutputReferences Appends the Reference Container to the output if set to true , default true .
* @ param bool $p_bool_HideFootnotesText Hide footnotes found in the string .
* @ return string
*/
public function exec ( $p_str_Content , $p_bool_OutputReferences = false , $p_bool_HideFootnotesText = false ) {
// replace all footnotes in the content, settings are converted to html characters
$p_str_Content = $this -> search ( $p_str_Content , true , $p_bool_HideFootnotesText );
// replace all footnotes in the content, settings are NOT converted to html characters
$p_str_Content = $this -> search ( $p_str_Content , false , $p_bool_HideFootnotesText );
// append the reference container
if ( $p_bool_OutputReferences ) {
$p_str_Content = $p_str_Content . $this -> ReferenceContainer ();
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
// take a look if the LOVE ME slug should NOT be displayed on this page/post, remove the short code if found
if ( strpos ( $p_str_Content , MCI_Footnotes_Config :: C_STR_NO_LOVE_SLUG ) !== false ) {
self :: $a_bool_AllowLoveMe = false ;
$p_str_Content = str_replace ( MCI_Footnotes_Config :: C_STR_NO_LOVE_SLUG , " " , $p_str_Content );
}
// return the content with replaced footnotes and optional reference container append
return $p_str_Content ;
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Replaces all footnotes in the given content and appends them to the static property .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ param string $p_str_Content Content to be searched for footnotes .
* @ param bool $p_bool_ConvertHtmlChars html encode settings , default true .
* @ param bool $p_bool_HideFootnotesText Hide footnotes found in the string .
* @ return string
*/
public function search ( $p_str_Content , $p_bool_ConvertHtmlChars , $p_bool_HideFootnotesText ) {
2020-11-14 21:40:09 +00:00
2020-11-13 16:54:31 +00:00
// post ID to make everything unique wrt infinite scroll and archive view
2020-11-14 21:40:09 +00:00
global $l_int_PostId ;
$l_int_PostId = get_the_id ();
2020-10-27 11:56:49 +00:00
// contains the index for the next footnote on this page
2020-11-14 21:40:09 +00:00
$l_int_FootnoteIndex = count ( self :: $a_arr_Footnotes ) + 1 ;
2020-10-27 11:56:49 +00:00
// contains the starting position for the lookup of a footnote
2020-11-14 21:40:09 +00:00
$l_int_PosStart = 0 ;
2020-10-27 11:56:49 +00:00
// get start and end tag for the footnotes short code
$l_str_StartingTag = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_SHORT_CODE_START );
$l_str_EndingTag = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_SHORT_CODE_END );
if ( $l_str_StartingTag == " userdefined " || $l_str_EndingTag == " userdefined " ) {
$l_str_StartingTag = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_SHORT_CODE_START_USER_DEFINED );
$l_str_EndingTag = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_SHORT_CODE_END_USER_DEFINED );
}
// decode html special chars
if ( $p_bool_ConvertHtmlChars ) {
$l_str_StartingTag = htmlspecialchars ( $l_str_StartingTag );
$l_str_EndingTag = htmlspecialchars ( $l_str_EndingTag );
}
// if footnotes short code is empty, return the content without changes
if ( empty ( $l_str_StartingTag ) || empty ( $l_str_EndingTag )) {
return $p_str_Content ;
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
if ( ! $p_bool_HideFootnotesText ) {
// load template file
2020-11-11 20:49:44 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE ))) {
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " footnote-alternative " );
} else {
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " footnote " );
}
2020-10-27 11:56:49 +00:00
$l_obj_TemplateTooltip = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " tooltip " );
} else {
$l_obj_Template = null ;
$l_obj_TemplateTooltip = null ;
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
// search footnotes short codes in the content
do {
// get first occurrence of the footnote short code [start]
$i_int_len_Content = strlen ( $p_str_Content );
if ( $l_int_PosStart > $i_int_len_Content ) $l_int_PosStart = $i_int_len_Content ;
$l_int_PosStart = strpos ( $p_str_Content , $l_str_StartingTag , $l_int_PosStart );
// no short code found, stop here
if ( $l_int_PosStart === false ) {
break ;
}
// get first occurrence of a footnote short code [end]
$l_int_PosEnd = strpos ( $p_str_Content , $l_str_EndingTag , $l_int_PosStart );
// no short code found, stop here
if ( $l_int_PosEnd === false ) {
break ;
}
// calculate the length of the footnote
2020-11-14 21:40:09 +00:00
$l_int_Length = $l_int_PosEnd - $l_int_PosStart ;
2020-10-27 11:56:49 +00:00
// get footnote text
2020-11-14 21:40:09 +00:00
$l_str_FootnoteText = substr ( $p_str_Content , $l_int_PosStart + strlen ( $l_str_StartingTag ), $l_int_Length - strlen ( $l_str_StartingTag ));
2020-10-27 11:56:49 +00:00
// Text to be displayed instead of the footnote
2020-11-14 21:40:09 +00:00
$l_str_FootnoteReplaceText = " " ;
2020-11-16 20:57:15 +00:00
// display the footnote referrers and the tooltips:
2020-10-27 11:56:49 +00:00
if ( ! $p_bool_HideFootnotesText ) {
2020-11-14 21:40:09 +00:00
$l_int_Index = MCI_Footnotes_Convert :: Index ( $l_int_FootnoteIndex , MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_COUNTER_STYLE ));
2016-06-29 12:54:05 +00:00
// display only an excerpt of the footnotes text if enabled
2020-10-27 11:56:49 +00:00
$l_str_ExcerptText = $l_str_FootnoteText ;
2016-06-29 12:54:05 +00:00
$l_bool_EnableExcerpt = MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_EXCERPT_ENABLED ));
2020-11-14 21:40:09 +00:00
$l_int_MaxLength = intval ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_EXCERPT_LENGTH ));
2016-06-29 12:54:05 +00:00
if ( $l_bool_EnableExcerpt ) {
$l_str_DummyText = strip_tags ( $l_str_FootnoteText );
if ( is_int ( $l_int_MaxLength ) && strlen ( $l_str_DummyText ) > $l_int_MaxLength ) {
2020-11-16 20:57:15 +00:00
$l_str_ExcerptText = substr ( $l_str_DummyText , 0 , $l_int_MaxLength );
$l_str_ExcerptText = substr ( $l_str_ExcerptText , 0 , strrpos ( $l_str_ExcerptText , ' ' ));
$l_str_ExcerptText .= ' … ' ;
$l_str_ExcerptText .= '<span class="footnote_tooltip_continue" ' ;
$l_str_ExcerptText .= 'onclick="footnote_moveToAnchor_' . $l_int_PostId ;
$l_str_ExcerptText .= '(\'footnote_plugin_reference_' . $l_int_PostId ;
$l_str_ExcerptText .= '_' . $l_int_Index . '\');">' ;
$l_str_ExcerptText .= MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_TOOLTIP_READON_LABEL );
$l_str_ExcerptText .= '</span>' ;
2016-06-29 12:54:05 +00:00
}
}
2020-11-16 20:57:15 +00:00
// define the HTML element to use for the referrers:
2020-11-17 02:14:21 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_REFERRER_SUPERSCRIPT_TAGS ))) {
2020-11-16 20:57:15 +00:00
$l_str_Element = 'sup' ;
} else {
$l_str_Element = 'span' ;
}
2020-11-14 21:40:09 +00:00
// fill in 'templates/public/footnote.html':
2020-10-27 11:56:49 +00:00
$l_obj_Template -> replace (
array (
2020-11-14 21:40:09 +00:00
" post_id " => $l_int_PostId ,
" id " => $l_int_Index ,
2020-11-16 20:57:15 +00:00
" element " => $l_str_Element ,
2020-11-05 02:34:35 +00:00
" before " => MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_STYLING_BEFORE ),
2020-11-14 21:40:09 +00:00
" index " => $l_int_Index ,
2020-11-05 02:34:35 +00:00
" after " => MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_STYLING_AFTER ),
" text " => MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED )) ? $l_str_ExcerptText : " " ,
2020-10-27 11:56:49 +00:00
)
);
$l_str_FootnoteReplaceText = $l_obj_Template -> getContent ();
2020-11-12 18:17:28 +00:00
2020-10-27 11:56:49 +00:00
// reset the template
$l_obj_Template -> reload ();
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED ))) {
$l_int_OffsetY = intval ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_OFFSET_Y ));
$l_int_OffsetX = intval ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_INT_FOOTNOTES_MOUSE_OVER_BOX_OFFSET_X ));
2020-11-12 18:17:28 +00:00
2020-11-14 21:40:09 +00:00
// fill in 'templates/public/tooltip.html':
2020-10-27 11:56:49 +00:00
$l_obj_TemplateTooltip -> replace (
array (
2020-11-14 21:40:09 +00:00
" post_id " => $l_int_PostId ,
" id " => $l_int_Index ,
2020-10-27 11:56:49 +00:00
" position " => MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_MOUSE_OVER_BOX_POSITION ),
" offset-y " => ! empty ( $l_int_OffsetY ) ? $l_int_OffsetY : 0 ,
2020-11-12 18:17:28 +00:00
" offset-x " => ! empty ( $l_int_OffsetX ) ? $l_int_OffsetX : 0 ,
2020-10-27 11:56:49 +00:00
)
);
2020-11-12 18:17:28 +00:00
if ( ! MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE ))) {
$l_str_FootnoteReplaceText .= $l_obj_TemplateTooltip -> getContent ();
}
2020-10-27 11:56:49 +00:00
$l_obj_TemplateTooltip -> reload ();
}
}
// replace the footnote with the template
2020-11-14 21:40:09 +00:00
$p_str_Content = substr_replace ( $p_str_Content , $l_str_FootnoteReplaceText , $l_int_PosStart , $l_int_Length + strlen ( $l_str_EndingTag ));
2020-10-27 11:56:49 +00:00
// add footnote only if not empty
if ( ! empty ( $l_str_FootnoteText )) {
// set footnote to the output box at the end
self :: $a_arr_Footnotes [] = $l_str_FootnoteText ;
// increase footnote index
$l_int_FootnoteIndex ++ ;
}
// add offset to the new starting position
$l_int_PosStart += $l_int_Length + strlen ( $l_str_EndingTag );
$l_int_PosStart = $l_int_Length + strlen ( $l_str_FootnoteReplaceText );
} while ( true );
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
// return content
return $p_str_Content ;
}
2016-06-29 12:54:05 +00:00
2020-10-27 11:56:49 +00:00
/**
* Generates the reference container .
*
* @ author Stefan Herndler
* @ since 1.5 . 0
* @ return string
2020-11-14 21:40:09 +00:00
*
* Edited for 2.0 . 6 : fixed line breaking behavior in footnote # clusters
* Edited for 2.1 . 1 : fixed fragment IDs and backlinks with combine identical turned on 2020 - 11 - 14 T1808 + 0100
2020-10-27 11:56:49 +00:00
*/
public function ReferenceContainer () {
2020-11-14 21:40:09 +00:00
// post ID to make everything unique wrt infinite scroll and archive view:
global $l_int_PostId ;
$l_int_PostId = get_the_id ();
2020-10-27 11:56:49 +00:00
// no footnotes has been replaced on this page
if ( empty ( self :: $a_arr_Footnotes )) {
return " " ;
}
2020-11-14 21:40:09 +00:00
// FOOTNOTE INDEX BACKLINK SYMBOL
2020-11-18 00:47:53 +00:00
// check if arrow is enabled:
2020-11-17 02:14:21 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE ))) {
2020-11-16 20:57:15 +00:00
// get html arrow
$l_str_Arrow = MCI_Footnotes_Convert :: getArrow ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_HYPERLINK_ARROW ));
// set html arrow to the first one if invalid index defined
if ( is_array ( $l_str_Arrow )) {
$l_str_Arrow = MCI_Footnotes_Convert :: getArrow ( 0 );
}
// get user defined arrow
$l_str_ArrowUserDefined = MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_HYPERLINK_ARROW_USER_DEFINED );
if ( ! empty ( $l_str_ArrowUserDefined )) {
$l_str_Arrow = $l_str_ArrowUserDefined ;
}
// wrap the arrow in a @media print { display:hidden } span:
$l_str_FootnoteArrow = '<span class="footnote_index_arrow">' ;
$l_str_FootnoteArrow .= $l_str_Arrow . '</span>' ;
} else {
// if it is, set it to empty:
$l_str_Arrow = " " ;
$l_str_FootnoteArrow = " " ;
2020-10-27 11:56:49 +00:00
}
2016-06-29 12:54:05 +00:00
2020-11-14 21:40:09 +00:00
// REFERENCE CONTAINER TABLE ROW TEMPLATE LOAD
// line breaks for source readability:
$l_str_Body = " \r \n \r \n " ;
2020-11-16 20:57:15 +00:00
// when combine identical is turned on, another template is needed:
2020-11-14 21:40:09 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_COMBINE_IDENTICAL_FOOTNOTES ))) {
// In the combined template, identifiers only are clickable.
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " reference-container-body-combi " );
2020-11-16 20:57:15 +00:00
2020-11-14 21:40:09 +00:00
} else {
2020-11-16 20:57:15 +00:00
// when 3-column layout is turned on (only valid if combining is turned off):
2020-11-17 02:14:21 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_3COLUMN_LAYOUT_ENABLE ))) {
2020-11-16 20:57:15 +00:00
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " reference-container-body-3column " );
} else {
// when switch symbol and index is turned on (only valid if 3-column is disabled):
2020-11-17 02:14:21 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH ))) {
2020-11-16 20:57:15 +00:00
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " reference-container-body-switch " );
} else {
// default is the standard template:
$l_obj_Template = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " reference-container-body " );
}
}
2020-11-14 21:40:09 +00:00
}
// FILL IN THE TEMPLATE
2020-10-27 11:56:49 +00:00
// loop through all footnotes found in the page
2020-11-14 21:40:09 +00:00
for ( $l_int_Index = 0 ; $l_int_Index < count ( self :: $a_arr_Footnotes ); $l_int_Index ++ ) {
// TEXT COLUMN
2020-10-27 11:56:49 +00:00
// get footnote text
2020-11-14 21:40:09 +00:00
$l_str_FootnoteText = self :: $a_arr_Footnotes [ $l_int_Index ];
2020-10-27 11:56:49 +00:00
// if footnote is empty, get to the next one
2020-11-14 21:40:09 +00:00
// With combine identical turned on, identicals will be deleted and are skipped:
2020-10-27 11:56:49 +00:00
if ( empty ( $l_str_FootnoteText )) {
continue ;
}
2020-11-14 21:40:09 +00:00
// INDEX COLUMN WITH ONE BACKLINK PER TABLE ROW
// Standard behavior appropriate for combine identical TURNED OFF
2020-11-05 18:00:18 +00:00
// generate content of footnote index cell
2020-11-14 21:40:09 +00:00
$l_int_FirstFootnoteIndex = ( $l_int_Index + 1 );
// get the footnote index string and
2020-11-12 18:17:28 +00:00
// keep supporting legacy index placeholder:
2020-11-16 20:57:15 +00:00
$l_str_FootnoteIndex = MCI_Footnotes_Convert :: Index (( $l_int_Index + 1 ), MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_COUNTER_STYLE ));
2020-11-14 21:40:09 +00:00
// SUPPORT FOR COMBINE IDENTICAL: COMPOSING ENUMERATED BACKLINKS
2020-11-16 20:57:15 +00:00
$l_str_FootnoteBacklinks = " " ;
2020-11-14 21:40:09 +00:00
2020-11-16 20:57:15 +00:00
if ( MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_COMBINE_IDENTICAL_FOOTNOTES ))) {
2020-11-14 21:40:09 +00:00
2020-11-16 20:57:15 +00:00
$l_str_FootnoteId = $l_str_FootnoteIndex ;
2020-11-14 21:40:09 +00:00
2020-11-16 20:57:15 +00:00
// The dedicated template enumerating backlinks uses a new placeholder:
2020-11-14 21:40:09 +00:00
2020-11-16 20:57:15 +00:00
$l_str_FootnoteBacklinks = '<a id="footnote_plugin_reference_' ;
$l_str_FootnoteBacklinks .= $l_int_PostId ;
$l_str_FootnoteBacklinks .= " _ $l_str_FootnoteId " ;
$l_str_FootnoteBacklinks .= '" class="footnote_backlink" ' ;
$l_str_FootnoteBacklinks .= 'onclick="footnote_moveToAnchor_' . $l_int_PostId ;
$l_str_FootnoteBacklinks .= " ('footnote_plugin_tooltip_ $l_int_PostId " ;
$l_str_FootnoteBacklinks .= " _ $l_str_FootnoteId '); \" > " ;
$l_str_FootnoteBacklinks .= $l_str_FootnoteArrow ;
$l_str_FootnoteBacklinks .= $l_str_FootnoteId . '</a>' ;
2020-11-14 21:40:09 +00:00
2020-11-16 20:57:15 +00:00
// If that is the only footnote with this text, we’ re done.
}
2020-11-14 21:40:09 +00:00
// CHECK IF COMBINE IDENTICAL IS TURNED ON, and
// check if it isn't the last footnote in the array:
if ( $l_int_FirstFootnoteIndex < count ( self :: $a_arr_Footnotes ) && MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_COMBINE_IDENTICAL_FOOTNOTES ))) {
// get all footnotes that haven't passed yet:
for ( $l_int_CheckIndex = $l_int_FirstFootnoteIndex ; $l_int_CheckIndex < count ( self :: $a_arr_Footnotes ); $l_int_CheckIndex ++ ) {
// check if a further footnote is the same as the actual one:
if ( $l_str_FootnoteText == self :: $a_arr_Footnotes [ $l_int_CheckIndex ]) {
// if so, set the further footnote as empty so it won't be displayed later:
self :: $a_arr_Footnotes [ $l_int_CheckIndex ] = " " ;
// HERE GOES THE FRAGMENT IDENTIFIER AND THE BACKLINK TOO:
// add the footnote index to the actual index:
// update the footnote ID:
$l_str_FootnoteId = MCI_Footnotes_Convert :: Index (( $l_int_CheckIndex + 1 ), MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_COUNTER_STYLE ));
// keep on composing the backlinks enumeration:
$l_str_FootnoteBacklinks .= ', <a id="footnote_plugin_reference_' ;
$l_str_FootnoteBacklinks .= $l_int_PostId ;
$l_str_FootnoteBacklinks .= " _ $l_str_FootnoteId " ;
$l_str_FootnoteBacklinks .= '" class="footnote_backlink" ' ;
$l_str_FootnoteBacklinks .= 'onclick="footnote_moveToAnchor_' . $l_int_PostId ;
$l_str_FootnoteBacklinks .= " ('footnote_plugin_tooltip_ $l_int_PostId " ;
$l_str_FootnoteBacklinks .= " _ $l_str_FootnoteId '); \" > " ;
$l_str_FootnoteBacklinks .= $l_str_FootnoteArrow ;
$l_str_FootnoteBacklinks .= $l_str_FootnoteId . '</a>' ;
2020-11-16 20:57:15 +00:00
// this legacy is not used:
//$l_str_FootnoteIndex .= ', ' . MCI_Footnotes_Convert::Index(($l_int_CheckIndex + 1), MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE));
2020-11-14 21:40:09 +00:00
2020-10-27 11:56:49 +00:00
}
}
}
2020-11-12 18:17:28 +00:00
2020-11-14 21:40:09 +00:00
// replace all placeholders in 'templates/public/reference-container-body.html'
// or in 'templates/public/reference-container-body-combi.html'
2020-10-27 11:56:49 +00:00
$l_obj_Template -> replace (
array (
2020-11-14 21:40:09 +00:00
// placeholder used in all templates:
2020-11-12 18:17:28 +00:00
" text " => $l_str_FootnoteText ,
2020-11-14 21:40:09 +00:00
// used in standard layout W/O COMBINED FOOTNOTES:
" post_id " => $l_int_PostId ,
" id " => MCI_Footnotes_Convert :: Index ( $l_int_FirstFootnoteIndex , MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_FOOTNOTES_COUNTER_STYLE )),
// used in standard layout WITH COMBINED IDENTICALS TURNED ON:
" backlinks " => $l_str_FootnoteBacklinks ,
// Legacy placeholders for use in legacy layout templates:
2020-11-16 20:57:15 +00:00
" arrow " => $l_str_FootnoteArrow ,
2020-11-06 04:04:30 +00:00
" index " => $l_str_FootnoteIndex ,
2020-10-27 11:56:49 +00:00
)
);
2020-11-14 21:40:09 +00:00
$l_str_Body .= $l_obj_Template -> getContent ();
2020-11-16 20:57:15 +00:00
// extra line breaks for page source legibility:
2020-11-14 21:40:09 +00:00
$l_str_Body .= " \r \n \r \n " ;
2020-10-27 11:56:49 +00:00
$l_obj_Template -> reload ();
2020-11-14 21:40:09 +00:00
2020-10-27 11:56:49 +00:00
}
2016-06-29 12:54:05 +00:00
2020-11-14 21:40:09 +00:00
// load 'templates/public/reference-container.html':
2020-10-27 11:56:49 +00:00
$l_obj_TemplateContainer = new MCI_Footnotes_Template ( MCI_Footnotes_Template :: C_STR_PUBLIC , " reference-container " );
$l_obj_TemplateContainer -> replace (
array (
2020-11-14 21:40:09 +00:00
" post_id " => $l_int_PostId ,
2020-11-05 02:34:35 +00:00
" label " => MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_STR_REFERENCE_CONTAINER_NAME ),
2020-10-27 11:56:49 +00:00
" button-style " => ! MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_COLLAPSE )) ? 'display: none;' : '' ,
2020-11-05 02:34:35 +00:00
" style " => MCI_Footnotes_Convert :: toBool ( MCI_Footnotes_Settings :: instance () -> get ( MCI_Footnotes_Settings :: C_BOOL_REFERENCE_CONTAINER_COLLAPSE )) ? 'display: none;' : '' ,
2020-11-12 18:17:28 +00:00
" content " => $l_str_Body ,
2020-10-27 11:56:49 +00:00
)
);
// free all found footnotes if reference container will be displayed
self :: $a_arr_Footnotes = array ();
2020-11-12 18:17:28 +00:00
2020-10-27 11:56:49 +00:00
return $l_obj_TemplateContainer -> getContent ();
}
2016-06-29 12:54:05 +00:00
}