PluginProbe
Easy Footnotes / 1.1.10
Easy Footnotes v1.1.10
trunk 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.2 All 32 releases
easy-footnotes / easy-footnotes.php

easy-footnotes.php in Easy Footnotes 1.1.10, at easy-footnotes.php

321 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Easy Footnotes
4 * Plugin URI: https://jasonyingling.me/easy-footnotes-wordpress/
5 * Description: Easily add footnotes to your posts with a simple shortcode.
6 * Text Domain: easy-footnotes
7 * Version: 1.1.10
8 * Author: Jason Yingling
9 * Author URI: https://jasonyingling.me
10 * License: GPL2
11 *
12 * @package easy-footnotes
13 */
14
15 /*
16 Copyright 2018 Jason Yingling (email : yingling017@gmail.com)
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License, version 2, as
20 published by the Free Software Foundation.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31 /**
32 * The Easy Footnotes class. In camel case. Because I didn't follow WPCS way back when.
33 */
34 class easyFootnotes {
35
36 /**
37 * Add label option using add_option if it does not already exist.
38 *
39 * @var array $footnotes An array for the footnotes to be stored.
40 */
41 public $footnotes = array();
42 public $footnoteCount = 0;
43 public $prevPost;
44 public $footnoteOptions;
45 public $footnoteLookup = array();
46 public $usedFootnoteNumbers = array();
47
48 private $footnoteSettings;
49
50 private $version = '1.1.10';
51
52 /**
53 * Constructing the initial plugin options, shortcodes, and hooks.
54 */
55 public function __construct() {
56 $this->footnoteSettings = array(
57 'footnoteLabel' => __( 'Footnotes', 'easy-footnotes' ),
58 'useLabel' => false,
59 'hide_easy_footnote_after_posts' => false,
60 'show_easy_footnote_on_front' => false,
61 'reset_footnotes' => false,
62 );
63
64 add_option( 'easy_footnotes_options', $this->footnoteSettings );
65 add_shortcode( 'note', array( $this, 'easy_footnote_shortcode' ) );
66 add_shortcode( 'efn_note', array( $this, 'easy_footnote_shortcode' ) );
67 add_shortcode( 'efn_reset', array( $this, 'short_code_reset' ) );
68 add_filter( 'the_content', array( $this, 'easy_footnote_after_content' ), 20 );
69
70 $this->footnoteOptions = get_option( 'easy_footnotes_options' );
71 if ( isset( $this->footnoteOptions['reset_footnotes'] ) && $this->footnoteOptions['reset_footnotes'] ) {
72 add_filter( 'the_content', array( $this, 'easy_footnote_reset' ), 999 );
73 }
74
75 add_action( 'wp_enqueue_scripts', array( $this, 'register_qtip_scripts' ) );
76 add_action( 'admin_menu', array( $this, 'easy_footnotes_admin_actions' ) );
77 add_action( 'admin_enqueue_scripts', array( $this, 'easy_footnotes_admin_scripts' ) );
78 add_action( 'init', array($this, 'efn_load_textdomain') );
79
80 $this->footnoteOptions = get_option( 'easy_footnotes_options' );
81 }
82
83 /**
84 * Registering the scripts and styles used by jQuery qTip.
85 */
86 public function register_qtip_scripts() {
87 wp_register_script( 'imagesloaded', plugins_url( '/assets/qtip/imagesloaded.pkgd.min.js', __FILE__ ), array(), $this->version, true );
88 wp_register_script( 'qtip', plugins_url( '/assets/qtip/jquery.qtip.min.js', __FILE__ ), array( 'jquery', 'imagesloaded' ), $this->version, true );
89 wp_register_script( 'qtipcall', plugins_url( '/assets/qtip/jquery.qtipcall.js', __FILE__ ), array( 'jquery', 'qtip' ), $this->version, true );
90 wp_register_style( 'qtipstyles', plugins_url( '/assets/qtip/jquery.qtip.min.css', __FILE__ ), array(), $this->version, false );
91 wp_register_style( 'easyfootnotescss', plugins_url( '/assets/easy-footnotes.css', __FILE__ ), array(), $this->version, false );
92 }
93
94 /**
95 * Create the Easy Footnotes shortcode.
96 *
97 * @param array $atts Shortcode attributes.
98 * @param string $content Content within the shortcode.
99 */
100 public function easy_footnote_shortcode( $atts, $content = null ) {
101 if ( isset( $this->footnoteOptions['show_easy_footnote_on_front'] ) && $this->footnoteOptions['show_easy_footnote_on_front'] ) {
102 $efn_show_on_front = is_front_page();
103 } else {
104 $efn_show_on_front = false;
105 }
106
107 wp_enqueue_style( 'qtipstyles' );
108 wp_enqueue_style( 'easyfootnotescss' );
109 wp_enqueue_script( 'imagesloaded' );
110 wp_enqueue_script( 'qtip' );
111 wp_enqueue_script( 'qtipcall' );
112 wp_enqueue_style( 'dashicons' );
113
114 // Accept optional custom number attribute
115 $atts = shortcode_atts(
116 array(
117 'num' => null
118 ),
119 $atts
120 );
121
122 $post_id = get_the_ID();
123
124 $content = do_shortcode( $content );
125
126 $content_id = md5( preg_replace("/[^A-Za-z0-9 ]/", '', wp_strip_all_tags( html_entity_decode( $content ) ) ) );
127
128 /**
129 * Search for existing footnote for removing duplicate
130 * Also add the same numbers to duplicate footnotes
131 */
132 if (!isset($this->usedFootnoteNumbers)) {
133 $this->usedFootnoteNumbers = array();
134 }
135 if (!isset($this->footnoteLookup)) {
136 $this->footnoteLookup = array();
137 }
138
139 // If a custom number is provided, use that number and mark it as used
140 if ( ! empty( $atts['num'] ) ) {
141 $footnote_number = intval( $atts['num'] );
142 $this->usedFootnoteNumbers[] = $footnote_number; // Track custom number
143 $this->footnoteLookup[$content_id] = $footnote_number;
144 $this->footnotes[$footnote_number] = $content;
145 } elseif ( isset( $this->footnoteLookup[$content_id] ) ) {
146 // Use existing footnote number for duplicate content
147 $footnote_number = $this->footnoteLookup[$content_id];
148 } else {
149 // Auto-increment for new footnotes, skipping used numbers
150 do {
151 $this->footnoteCount++;
152 } while ( in_array( $this->footnoteCount, $this->usedFootnoteNumbers ) );
153
154 $footnote_number = $this->footnoteCount;
155 $this->footnoteLookup[$content_id] = $footnote_number;
156 $this->usedFootnoteNumbers[] = $footnote_number; // Mark as used
157 $this->footnotes[$footnote_number] = $content;
158 }
159
160 // Generate the correct footnote link with the correct number
161 $footnoteLink = (is_singular() || $efn_show_on_front) && is_main_query()
162 ? '#easy-footnote-bottom-' . $footnote_number . '-' . $post_id
163 : get_permalink($post_id) . '#easy-footnote-bottom-' . $footnote_number . '-' . $post_id;
164
165 // Now generate the footnote markup with the correct number and link
166 $footnoteContent = "<span id='easy-footnote-" . esc_attr($footnote_number) . '-' . $post_id
167 . "' class='easy-footnote-margin-adjust'></span><span class='easy-footnote'>"
168 . "<a href='" . esc_url($footnoteLink) . "' title='" . htmlspecialchars($content, ENT_QUOTES)
169 . "'><sup>" . esc_html($footnote_number) . "</sup></a></span>";
170
171 return $footnoteContent;
172 }
173
174 /**
175 * The content of a particular footnote.
176 *
177 * @param string $content The content from a particular call of the shortcode.
178 */
179 public function easy_footnote_content( $content ) {
180 $this->footnotes[ $this->footnoteCount ] = $content;
181
182 return $this->footnotes;
183 }
184
185 /**
186 * Display the list of footnotes after the post content.
187 *
188 * @param string $content The content of the current post.
189 */
190 public function easy_footnote_after_content( $content ) {
191 if ( isset( $this->footnoteOptions['hide_easy_footnote_after_posts'] ) && $this->footnoteOptions['hide_easy_footnote_after_posts'] ) {
192 return $content;
193 }
194
195 if ( isset( $this->footnoteOptions['show_easy_footnote_on_front'] ) && $this->footnoteOptions['show_easy_footnote_on_front'] ) {
196 $efn_show_on_front = is_front_page() || is_home();
197 } else {
198 $efn_show_on_front = false;
199 }
200
201 if ( ( is_singular() || $efn_show_on_front ) && is_main_query() ) {
202 $footnotesInsert = $this->footnotes;
203
204 $footnoteCopy = '';
205 $efn_output = '';
206
207 $useLabel = isset( $this->footnoteOptions['useLabel'] ) ? $this->footnoteOptions['useLabel'] : false;
208 $efLabel = isset($this->footnoteOptions['footnoteLabel'] ) ? $this->footnoteOptions['footnoteLabel'] : __( 'Footnotes', 'easy-footnotes' );
209
210 $post_id = get_the_ID();
211
212 // Create a new array to track used footnotes and their numbers
213 $footnote_number = 1;
214
215 // sort footnotes according to numbers
216 ksort($footnotesInsert);
217
218 foreach ( $footnotesInsert as $count => $footnote ) {
219 // If the footnote is already in the lookup, use its number
220 if ( isset( $this->footnoteLookup[$footnote] ) ) {
221 $count = $this->footnoteLookup[$footnote];
222 } else {
223 // Skip custom numbers that were already used
224 while ( in_array( $footnote_number, $this->usedFootnoteNumbers ) ) {
225 $footnote_number++;
226 }
227 }
228
229 // Generate back-to-top link and the footnote item
230 $footnoteCopy .= '<li class="easy-footnote-single"><span id="easy-footnote-bottom-' . esc_attr( $count ) . '-' . $post_id . '" class="easy-footnote-margin-adjust"></span>' . wp_kses_post( $footnote ) . '<a class="easy-footnote-to-top" href="' . esc_url( '#easy-footnote-' . $count . '-' . $post_id ) . '"></a></li>';
231 }
232 if ( ! empty( $footnotesInsert ) ) {
233 if ( true === $useLabel ) {
234 $footnote_label = '<div class="easy-footnote-title"><h4>' . esc_html( $efLabel ) . '</h4></div>';
235 // Filter for editing footnote label markup and output.
236 $footnote_label = apply_filters( 'efn_footnote_label', $footnote_label, $efLabel );
237
238 $efn_output .= $footnote_label;
239 }
240
241 $footnote_content = '';
242
243 // Add filter before footnote list.
244 $footnote_content = apply_filters( 'before_footnote', $footnote_content );
245 $footnote_content .= '<ol class="easy-footnotes-wrapper">' . $footnoteCopy . '</ol>';
246
247 // Add filter after footnote list.
248 $footnote_content = apply_filters( 'after_footnote', $footnote_content );
249
250 $efn_output .= $footnote_content;
251
252 // Add filters for the entire footnote list output.
253 $efn_output = apply_filters( 'efn_footnote_list_output', $efn_output );
254
255 $content .= do_shortcode( $efn_output );
256 }
257 }
258
259 return $content;
260 }
261
262 /**
263 * Reset the footnote count and footnote array each time the_content has been run.
264 *
265 * @param string $content The content of the post from the_content filter.
266 */
267 public function easy_footnote_reset( $content ) {
268 $this->footnoteCount = 0;
269
270 $this->footnotes = array();
271
272 return $content;
273 }
274
275 /**
276 * Include the easy-footnotes-admin.php file.
277 */
278 public function easy_footnotes_admin() {
279 include 'easy-footnotes-admin.php';
280 }
281
282 /**
283 * Function to add options page for Easy Footnote Settings.
284 */
285 public function easy_footnotes_admin_actions() {
286 add_options_page(
287 __( 'Easy Footnotes Settings', 'easy-footnotes' ),
288 __( 'Easy Footnotes', 'easy-footnotes' ),
289 'manage_options',
290 'easy-footnotes-settings',
291 array( $this, 'easy_footnotes_admin' )
292 );
293 }
294
295 /**
296 * Function for enqueuring EAsy Footnotes admin scripts.
297 */
298 public function easy_footnotes_admin_scripts() {
299 wp_enqueue_style( 'easy-footnotes-admin-styles', plugins_url( '/assets/easy-footnotes-admin.css', __FILE__ ), '', $this->version );
300 wp_enqueue_script( 'easy-footnotes-admin-scripts', plugins_url( '/assets/js/easy-footnotes-admin.js', __FILE__ ), array( 'jquery' ), $this->version, true );
301 }
302
303 /**
304 * Load plugin textdomain easy-footnotes
305 */
306 public function efn_load_textdomain() {
307 load_plugin_textdomain( 'easy-footnotes', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
308 }
309
310 /**
311 * Manually reset footnotes and counter
312 */
313 public function short_code_reset() {
314 $this->footnoteCount = 0;
315 $this->footnotes = array();
316 return "";
317 }
318 }
319
320 $easyFootnotes = new easyFootnotes();
321