PluginProbe
Easy Footnotes / 1.0.16
Easy Footnotes v1.0.16
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
← All changes | easy-footnotes.php +85 -229 1.1.101.0.16 View file →
@@ -2,109 +2,62 @@
2 2 /**
3 3 * Plugin Name: Easy Footnotes
4 4 * Plugin URI: https://jasonyingling.me/easy-footnotes-wordpress/
5 5 * Description: Easily add footnotes to your posts with a simple shortcode.
6 - * Text Domain: easy-footnotes
7 - * Version: 1.1.10
6 + * Version: 1.0.16
8 7 * Author: Jason Yingling
9 8 * Author URI: https://jasonyingling.me
10 9 * License: GPL2
11 - *
12 - * @package easy-footnotes
13 10 */
14 11
15 -/*
16 - Copyright 2018 Jason Yingling (email : yingling017@gmail.com)
12 + /* Copyright 2018 Jason Yingling (email : yingling017@gmail.com)
17 13
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.
14 + This program is free software; you can redistribute it and/or modify
15 + it under the terms of the GNU General Public License, version 2, as
16 + published by the Free Software Foundation.
21 17
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.
18 + This program is distributed in the hope that it will be useful,
19 + but WITHOUT ANY WARRANTY; without even the implied warranty of
20 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 + GNU General Public License for more details.
26 22
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
23 + You should have received a copy of the GNU General Public License
24 + along with this program; if not, write to the Free Software
25 + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 26 */
31 -/**
32 - * The Easy Footnotes class. In camel case. Because I didn't follow WPCS way back when.
33 - */
27 +
34 28 class easyFootnotes {
35 29
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();
30 + // Add label option using add_option if it does not already exist
31 + public $footnotes = array();
42 32 public $footnoteCount = 0;
43 33 public $prevPost;
44 - public $footnoteOptions;
45 - public $footnoteLookup = array();
46 - public $usedFootnoteNumbers = array();
47 34
48 - private $footnoteSettings;
49 -
50 - private $version = '1.1.10';
51 -
52 - /**
53 - * Constructing the initial plugin options, shortcodes, and hooks.
54 - */
55 35 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,
36 + $footnoteSettings = array(
37 + 'footnoteLabel' => 'Footnotes',
38 + 'useLabel' => false,
39 + 'hide_easy_footnote_after_posts' => false
62 40 );
63 41
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' );
42 + add_option('easy_footnotes_options', $footnoteSettings);
43 + add_shortcode( 'note', array($this, 'easy_footnote_shortcode') );
44 + add_filter('the_content', array($this, 'easy_footnote_after_content'), 20);
45 + add_filter('the_content', array($this, 'easy_footnote_reset'), 999);
46 + add_action('wp_enqueue_scripts', array($this, 'register_qtip_scripts'));
47 + add_action('admin_menu', array($this, 'easy_footnotes_admin_actions'));
48 + add_action( 'admin_enqueue_scripts', array($this, 'easy_footnotes_admin_scripts') );
81 49 }
82 50
83 - /**
84 - * Registering the scripts and styles used by jQuery qTip.
85 - */
86 51 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 );
52 + wp_register_script( 'imagesloaded', plugins_url( '/assets/qtip/imagesloaded.pkgd.min.js' , __FILE__ ), null, false, true );
53 + wp_register_script( 'qtip', plugins_url( '/assets/qtip/jquery.qtip.min.js' , __FILE__ ), array('jquery', 'imagesloaded'), false, true );
54 + wp_register_script( 'qtipcall', plugins_url( '/assets/qtip/jquery.qtipcall.js' , __FILE__ ), array('jquery', 'qtip'), false, true );
55 + wp_register_style( 'qtipstyles', plugins_url( '/assets/qtip/jquery.qtip.min.css' , __FILE__ ), null, false, false );
56 + wp_register_style( 'easyfootnotescss', plugins_url( '/assets/easy-footnotes.css' , __FILE__ ), null, false, false );
92 57 }
93 58
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 -
59 + public function easy_footnote_shortcode($atts, $content = null) {
107 60 wp_enqueue_style( 'qtipstyles' );
108 61 wp_enqueue_style( 'easyfootnotescss' );
109 62 wp_enqueue_script( 'imagesloaded' );
110 63 wp_enqueue_script( 'qtip' );
@@ -110,162 +63,95 @@
110 63 wp_enqueue_script( 'qtip' );
111 64 wp_enqueue_script( 'qtipcall' );
112 65 wp_enqueue_style( 'dashicons' );
113 66
114 - // Accept optional custom number attribute
115 - $atts = shortcode_atts(
116 - array(
117 - 'num' => null
118 - ),
119 - $atts
120 - );
67 + extract (shortcode_atts(array(
68 + ), $atts));
121 69
122 70 $post_id = get_the_ID();
123 71
124 - $content = do_shortcode( $content );
72 + $content = do_shortcode($content);
73 +
74 + $count = $this->footnoteCount;
125 75
126 - $content_id = md5( preg_replace("/[^A-Za-z0-9 ]/", '', wp_strip_all_tags( html_entity_decode( $content ) ) ) );
76 + // Increment the counter
77 + $count++;
127 78
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 - }
79 + // Set the footnoteCount (This whole process needs reworked)
80 + $this->footnoteCount = $count;
138 81
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];
82 + //$this->easy_footnote_count($this->footnoteCount, get_the_ID());
83 + $this->easy_footnote_content($content);
84 +
85 + if (is_singular() && is_main_query()) {
86 + $footnoteLink = '#easy-footnote-bottom-'.$this->footnoteCount.'-'.$post_id;;
148 87 } 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;
88 + $footnoteLink = get_permalink(get_the_ID()).'#easy-footnote-bottom-'.$this->footnoteCount.'-'.$post_id;
158 89 }
159 90
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 -
91 + $footnoteContent = "<span id='easy-footnote-".esc_attr($this->footnoteCount).'-'.$post_id."' class='easy-footnote-margin-adjust'></span><span class='easy-footnote'><a href='".esc_url($footnoteLink)."' title='".htmlspecialchars($content, ENT_QUOTES)."'><sup>".esc_html($this->footnoteCount)."</sup></a></span>";
92 +
171 93 return $footnoteContent;
172 94 }
173 95
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;
96 + public function easy_footnote_content($content) {
97 + $this->footnotes[$this->footnoteCount] = $content;
181 98
182 99 return $this->footnotes;
183 100 }
184 101
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;
102 + public function easy_footnote_count($count, $currentPost) {
103 + if ($this->prevPost != $currentPost) {
104 + $count = 0;
193 105 }
194 106
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;
107 + $this->prevPost = $currentPost;
108 +
109 + $count++;
110 +
111 + $this->footnoteCount = $count;
112 +
113 + return $this->footnoteCount;
114 + }
115 +
116 + public function easy_footnote_after_content($content) {
117 +
118 + $footnoteOptions = get_option('easy_footnotes_options');
119 +
120 + if ( isset($footnoteOptions['hide_easy_footnote_after_posts']) && $footnoteOptions['hide_easy_footnote_after_posts'] ) {
121 + return $content;
199 122 }
200 123
201 - if ( ( is_singular() || $efn_show_on_front ) && is_main_query() ) {
124 + if (is_singular() && is_main_query()) {
202 125 $footnotesInsert = $this->footnotes;
203 126
204 127 $footnoteCopy = '';
205 - $efn_output = '';
206 128
207 - $useLabel = isset( $this->footnoteOptions['useLabel'] ) ? $this->footnoteOptions['useLabel'] : false;
208 - $efLabel = isset($this->footnoteOptions['footnoteLabel'] ) ? $this->footnoteOptions['footnoteLabel'] : __( 'Footnotes', 'easy-footnotes' );
129 + $useLabel = $footnoteOptions['useLabel'];
130 + $efLabel = $footnoteOptions['footnoteLabel'];
209 131
210 132 $post_id = get_the_ID();
211 133
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];
134 + foreach ($footnotesInsert as $count => $footnote) {
135 + $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>';
136 + }
137 + if (!empty($footnotesInsert)) {
138 + if ($useLabel === true) {
139 + $content .= '<div class="easy-footnote-title"><h4>'.esc_html($efLabel).'</h4></div><ol class="easy-footnotes-wrapper">'.$footnoteCopy.'</ol>';
222 140 } else {
223 - // Skip custom numbers that were already used
224 - while ( in_array( $footnote_number, $this->usedFootnoteNumbers ) ) {
225 - $footnote_number++;
226 - }
141 + $content .= '<ol class="easy-footnotes-wrapper">'.$footnoteCopy.'</ol>';
227 142 }
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 143 }
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 144
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 145 }
258 -
146 +
259 147 return $content;
260 148 }
261 149
262 150 /**
263 151 * 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 152 */
267 - public function easy_footnote_reset( $content ) {
153 + public function easy_footnote_reset($content) {
268 154 $this->footnoteCount = 0;
269 155
270 156 $this->footnotes = array();
271 157
@@ -271,50 +157,20 @@
271 157
272 158 return $content;
273 159 }
274 160
275 - /**
276 - * Include the easy-footnotes-admin.php file.
277 - */
161 + // Functions to create Reading Time admin pages
278 162 public function easy_footnotes_admin() {
279 - include 'easy-footnotes-admin.php';
163 + include('easy-footnotes-admin.php');
280 164 }
281 165
282 - /**
283 - * Function to add options page for Easy Footnote Settings.
284 - */
285 166 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 - );
167 + add_options_page("Easy Footnotes Settings", "Easy Footnotes", "manage_options", "easy-footnotes-settings", array($this, "easy_footnotes_admin"));
293 168 }
294 169
295 - /**
296 - * Function for enqueuring EAsy Footnotes admin scripts.
297 - */
298 170 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 );
171 + wp_enqueue_style( 'easy-footnotes-admin-styles', plugins_url( '/assets/easy-footnotes-admin.css' , __FILE__ ), '', '1.0.13' );
301 172 }
302 173
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 174 }
319 175
320 176 $easyFootnotes = new easyFootnotes();