PluginProbe
List Last Changes / 1.2.0
List Last Changes v1.2.0
trunk 0.3.0 0.3.1 0.3.2 0.4.0 0.4.1 0.5.0 0.6.0 0.6.5 0.6.6 0.7.0 0.8.0 0.8.1 0.8.5 0.8.6 0.8.7 0.9.0 0.9.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 All 31 releases
list-last-changes / list-last-changes.php

list-last-changes.php in List Last Changes 1.2.0, at list-last-changes.php

408 lines 16.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: List Last Changes
4 * Plugin URI: http://www.rolandbaer.ch/software/wordpress/plugin-last-changes/
5 * Description: Shows a list of the last changes of a WordPress site.
6 * Version: 1.2.0
7 * Author: Roland Bär
8 * Author URI: http://www.rolandbaer.ch/
9 * Text Domain: list-last-changes
10 * License: GPLv3
11 */
12
13 /* Copyright 2013-2024 Roland Bär (email : info@rolandbaer.ch)
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License, version 3, as
17 published by the Free Software Foundation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29 class ListLastChangesWidget extends WP_Widget {
30
31 function __construct() {
32 $widget_ops = array('classname' => 'widget_list_last_changes', 'description' => __('Shows a list of the last changes of a WordPress site.', 'list-last-changes') );
33
34 parent::__construct('list-last-changes-widget', __('List Last Changes', 'list-last-changes'), $widget_ops);
35 }
36
37 /**
38 * Front-end display of widget.
39 *
40 * @see WP_Widget::widget()
41 *
42 * @param array $args Widget arguments.
43 * @param array $instance Saved values from database.
44 */
45 function widget( $args, $instance ) {
46 extract($args);
47
48 // Get the title of the widget and the specified number of elements
49 $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title'], $instance, $this->id_base);
50 $number = empty($instance['number']) ? ' ' : $instance['number'];
51 $showpages = isset( $instance['showpages'] ) ? (bool) $instance['showpages'] : true;
52 $showposts = isset( $instance['showposts'] ) ? (bool) $instance['showposts'] : false;
53 $showauthor = isset( $instance['showauthor'] ) ? (bool) $instance['showauthor'] : false;
54 $usedatepublished = isset( $instance['usedatepublished'] ) ? (bool) $instance['usedatepublished'] : false;
55 $template = empty($instance['template']) ? list_last_changes_default_template($showauthor) : $instance['template'];
56
57 echo $args['before_widget'] . "\n";
58 if ( $title ) {
59 echo $args['before_title'] . $title . $args['after_title'] . "\n";
60 }
61 echo ListLastChangesWidget::generate_list($number, $showpages, $showposts, $usedatepublished, $template);
62 echo $args['after_widget'] . "\n";;
63 }
64
65 public static function generate_list($number, $showpages, $showposts, $usedatepublished, $template) {
66 $content = " <ul>\n";
67
68 $loop = new WP_Query(array('post_type' => 'page', 'meta_key' => 'list_last_changes_ignore', 'meta_value' => 'true', 'posts_per_page' => -1));
69 $excludePageIds = "";
70 while( $loop->have_posts() ) {
71 $loop->the_post();
72 $excludePageIds = $excludePageIds . get_the_ID() . ",";
73 }
74
75 $loop = new WP_Query(array('post_type' => 'post', 'meta_key' => 'list_last_changes_ignore', 'meta_value' => 'true', 'posts_per_page' => -1));
76 $excludePostIds = "";
77 while( $loop->have_posts() ) {
78 $loop->the_post();
79 $excludePostIds = $excludePostIds . get_the_ID() . ",";
80 }
81
82 $mypages = $showpages ? ListLastChangesWidget::wp_get_pages(array('sort_column' => $usedatepublished ? 'post_date' : 'post_modified', 'sort_order' => 'asc', 'show_date' => $usedatepublished ? 'published' : 'modified', 'hierarchical' => 0, 'exclude' => $excludePageIds)) : array();
83 usort($mypages, $usedatepublished ? 'sort_pages_by_date_published_desc' : 'sort_pages_by_date_modified_desc');
84 $myposts = $showposts ? get_posts(array('numberposts' => $number, 'orderby' => $usedatepublished ? 'date' : 'modified', 'exclude' => $excludePostIds)) : array();
85 usort($myposts, $usedatepublished ? 'sort_pages_by_date_published_desc' : 'sort_pages_by_date_modified_desc');
86 $count = min(count($mypages) + count($myposts), $number);
87 $pagePos = 0;
88 $postPos = 0;
89 for($i = 0; $i < $count; $i++) {
90 if($pagePos < count($mypages)) {
91 $pageDate = $usedatepublished ? $mypages[$pagePos]->post_date : $mypages[$pagePos]->post_modified;
92 } else {
93 $pageDate = date("YYYY-MM-DD HH:MM:SS", 0);
94 }
95 if($postPos < count($myposts)) {
96 $postDate = $usedatepublished ? $myposts[$postPos]->post_date : $myposts[$postPos]->post_modified;
97 } else {
98 $postDate = date("YYYY-MM-DD HH:MM:SS", 0);
99 }
100
101 if($pageDate > $postDate) {
102 $post = $mypages[$pagePos];
103 $pagePos++;
104 } else {
105 $post = $myposts[$postPos];
106 $postPos++;
107 }
108 setup_postdata($post);
109 $transitions = array(
110 "{title}" => '<a href="' . get_permalink( $post->ID ) .'">' . $post->post_title . "</a>",
111 "{change_date}" => '<span class="list_last_changes_date">' . date_i18n(get_option('date_format'), strtotime($post->post_modified)) . "</span>",
112 "{published_date}" => '<span class="list_last_changes_date">' . date_i18n(get_option('date_format'), strtotime($post->post_date)) . "</span>",
113 "{author}" => '<span class="list_last_changes_author">' . get_the_author_meta( 'display_name', $post->post_author ) . "</span>",
114 "{editor}" => '<span class="list_last_changes_author">' . ListLastChangesWidget::get_last_editor($post) . "</span>");
115 $entry = strtr($template, $transitions);
116 $entry = ListLastChangesWidget::replace_date_format("change_date", $entry, strtotime($post->post_modified));
117 $entry = ListLastChangesWidget::replace_date_format("published_date", $entry, strtotime($post->post_date));
118 $content = $content . ' <li class="list_last_changes_title">'. "\n" ;
119 $content = $content . $entry;
120 $content = $content . " </li>\n";
121 }
122
123 $content = $content . " </ul>\n";
124
125 wp_reset_postdata();
126
127 return $content;
128 }
129
130 public static function replace_date_format($date_name, $input, $date_time) {
131 $pattern = "/\{$date_name\[([^\]]*)\]\}/i";
132 if(preg_match($pattern, $input, $matches)) {
133 $input = preg_replace($pattern, date_i18n("$matches[1]", $date_time), $input);
134 }
135
136 return $input;
137 }
138
139 static function get_last_editor($post) {
140 $last_editor_id = null;
141
142 // get author of latest revision
143 $revisions = wp_get_post_revisions($post);
144 if(count($revisions) > 0) {
145 $rev = reset($revisions);
146 $last_editor_id = $rev->post_author;
147 }
148
149 if( !$last_editor_id) {
150 // fallback: use post_author
151 $last_editor_id = $post->post_author;
152 }
153
154 // finally get the display name of the user
155 if ( $last_editor_id ) {
156 $last_user = get_userdata( $last_editor_id );
157
158 return apply_filters( 'the_modified_author', $last_user ? $last_user->display_name : '' );
159 }
160
161 return '';
162 }
163
164 function update( $new_instance, $old_instance ) {
165 $instance = $old_instance;
166 $instance['title'] = strip_tags($new_instance['title']);
167 $instance['number'] = strip_tags($new_instance['number']);
168 $instance['showpages'] = isset( $new_instance['showpages'] ) ? (bool) $new_instance['showpages'] : false;
169 $instance['showposts'] = isset( $new_instance['showposts'] ) ? (bool) $new_instance['showposts'] : false;
170 $instance['usedatepublished'] = isset( $new_instance['usedatepublished'] ) ? (bool) $new_instance['usedatepublished'] : false;
171 $instance['template'] = strip_tags($new_instance['template']);
172 unset($instance['showauthor']);
173
174 return $instance;
175 }
176
177 function form( $instance ) {
178 // Assigns values
179 $instance = wp_parse_args( (array) $instance, array( 'title' => 'Last Changes', 'number' => '5', 'showpages' => true, 'showposts' => false, 'showauthor' => false, 'usedatepublished' => false ) );
180 $showauthor = strip_tags($instance['showauthor']);
181 $instance = wp_parse_args( (array) $instance, array( 'template' => list_last_changes_default_template($showauthor) ) );
182 $title = strip_tags($instance['title']);
183 $number = strip_tags($instance['number']);
184 $showpages = strip_tags($instance['showpages']);
185 $showposts = strip_tags($instance['showposts']);
186 $usedatepublished = strip_tags($instance['usedatepublished']);
187 $template = strip_tags($instance['template']);
188 ?>
189 <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php echo __('Title', 'list-last-changes'); ?>: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
190 <p><label for="<?php echo $this->get_field_id('number'); ?>"><?php echo __('Number of shown changes', 'list-last-changes'); ?>: <input class="widefat" id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo esc_attr($number); ?>" /></label></p>
191 <p><input class="checkbox" id="<?php echo $this->get_field_id('showpages'); ?>" name="<?php echo $this->get_field_name('showpages'); ?>" type="checkbox" <?php checked( $showpages ); ?> /><label for="<?php echo $this->get_field_id('showpages'); ?>"><?php echo __('Show changed Pages', 'list-last-changes'); ?></label></p>
192 <p><input class="checkbox" id="<?php echo $this->get_field_id('showposts'); ?>" name="<?php echo $this->get_field_name('showposts'); ?>" type="checkbox" <?php checked( $showposts ); ?> /><label for="<?php echo $this->get_field_id('showposts'); ?>"><?php echo __('Show changed Posts', 'list-last-changes'); ?></label></p>
193 <p><input class="checkbox" id="<?php echo $this->get_field_id('usedatepublished'); ?>" name="<?php echo $this->get_field_name('usedatepublished'); ?>" type="checkbox" <?php checked( $usedatepublished ); ?> /><label for="<?php echo $this->get_field_id('usedatepublished'); ?>"><?php echo __('Use published date', 'list-last-changes'); ?></label></p>
194 <p><label for="<?php echo $this->get_field_id('template'); ?>"><?php echo __('Template', 'list-last-changes'); ?>: <input class="widefat" id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>" type="text" value="<?php echo esc_attr($template); ?>" /></label></p>
195 <?php
196 return "show-form";
197 }
198
199 /**
200 * Get Pages
201 */
202 static function wp_get_pages($args = '') {
203 if ( is_array($args) ) {
204 $r = &$args;
205 } else {
206 parse_str($args, $r);
207 }
208
209 $defaults = array('depth' => 0, 'show_date' => '', 'date_format' => get_option('date_format'),
210 'child_of' => 0, 'exclude' => "", 'title_li' => 'Pages', 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order, post_title');
211 $r = array_merge($defaults, $r);
212
213 $output = '';
214 $current_page = 0;
215
216 // sanitize, mostly to keep spaces out
217 $r['exclude'] = preg_replace('[^0-9,]', '', $r['exclude']);
218
219 // Allow plugins to filter an array of excluded pages
220 $r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));
221
222 // Query pages.
223 $pages = get_pages($r);
224
225 return $pages;
226 }
227 }
228
229 function list_last_changes_register_widgets() {
230 register_widget( 'ListLastChangesWidget' );
231 }
232
233 add_action( 'widgets_init', 'list_last_changes_register_widgets' );
234 add_shortcode( 'list_last_changes', 'list_last_changes_shortcode_funct' );
235
236 /**
237 * Sort by modified date ascending
238 */
239 function sort_pages_by_date_modified($a, $b) {
240 if ($a->post_modified == $b->post_modified) {
241 return 0;
242 }
243 if ($a->post_modified < $b->post_modified) {
244 return -1;
245 }
246 return 1;
247 }
248
249 /**
250 * Sort by modified date descending
251 */
252 function sort_pages_by_date_modified_desc($a, $b) {
253 return sort_pages_by_date_modified($a, $b) * -1;
254 }
255
256 /**
257 * Sort by published date ascending
258 */
259 function sort_pages_by_date_published($a, $b) {
260 if ($a->post_date == $b->post_date) {
261 return 0;
262 }
263 if ($a->post_date < $b->post_date) {
264 return -1;
265 }
266 return 1;
267 }
268
269 /**
270 * Sort by published date descending
271 */
272 function sort_pages_by_date_published_desc($a, $b) {
273 return sort_pages_by_date_published($a, $b) * -1;
274 }
275
276 /**
277 * Register style sheet.
278 */
279 add_action( 'wp_enqueue_scripts', 'list_last_changes_register_plugin_styles' );
280
281 /**
282 * Register style sheet.
283 */
284 function list_last_changes_register_plugin_styles() {
285 wp_register_style( 'list-last-changes', plugins_url( 'list-last-changes/css/list-last-changes.css' ) );
286 wp_enqueue_style( 'list-last-changes' );
287 }
288
289 function list_last_changes_shortcode_funct($atts ) {
290 $a = shortcode_atts( array(
291 'number' => '5',
292 'showpages' => 'true',
293 'showposts' => 'false',
294 'showauthor' => 'false',
295 'usedatepublished' => 'false',
296 'template' => '',
297 ), $atts );
298
299 $number = empty($a['number']) ? ' ' : $a['number'];
300 $showpages = $a['showpages'] === 'true';
301 $showposts = $a['showposts'] === 'true';
302 $showauthor = $a['showauthor'] === 'true';
303 $usedatepublished = $a['usedatepublished'] === 'true';
304 $template = empty($a['template']) ? list_last_changes_default_template($showauthor) : $a['template'];
305 return ListLastChangesWidget::generate_list($number, $showpages, $showposts, $usedatepublished, $template);
306 }
307
308 function list_last_changes_default_template($showauthor) {
309 $template = " {title}\n {change_date}\n";
310 if($showauthor) {
311 $template = $template . " {author}\n";
312 }
313
314 return $template;
315 }
316
317 /**
318 * Renders the `plugins/list-last-changes` block on server.
319 *
320 * @param array $attributes The block attributes.
321 *
322 * @return string Returns the post content with the last changes added.
323 */
324 function render_block_plugins_list_last_changes( $attributes ) {
325 $args = array(
326 'number' => $attributes['number'],
327 'showpages' => $attributes['showpages'],
328 'showposts' => $attributes['showposts'],
329 'showauthor' => $attributes['showauthor'],
330 'usedatepublished' => $attributes['usedatepublished'],
331 'template' => $attributes['template'],
332 );
333
334 $number = empty($args['number']) ? ' ' : $args['number'];
335 $showpages = $args['showpages'];
336 $showposts = $args['showposts'];
337 $showauthor = $args['showauthor'];
338 $usedatepublished = $args['usedatepublished'];
339 $template = empty($args['template']) ? list_last_changes_default_template($showauthor) : $args['template'];
340
341 $recentChanges = ListLastChangesWidget::generate_list($number, $showpages, $showposts, $usedatepublished, $template);
342
343 return $recentChanges;
344 }
345
346 /**
347 * Registers all block assets so that they can be enqueued through Gutenberg in
348 * the corresponding context.
349 *
350 * Passes translations to JavaScript.
351 */
352 function list_last_changes_register_block() {
353 if ( ! function_exists( 'register_block_type' ) ) {
354 // Gutenberg is not active.
355 return;
356 }
357
358 wp_register_script(
359 'list-last-changes',
360 plugins_url( 'block.js', __FILE__ ),
361 array( 'wp-blocks', 'wp-block-editor', 'wp-i18n', 'wp-element'/*, 'wp-components'*/ ),
362 filemtime( plugin_dir_path( __FILE__ ) . 'block.js' )
363 );
364
365 register_block_type( 'plugins/list-last-changes', array(
366 'editor_script' => 'list-last-changes',
367 'attributes' => array(
368 'number' => array(
369 'type' => 'number',
370 'default' => 5,
371 ),
372 'showpages' => array(
373 'type' => 'boolean',
374 'default' => true,
375 ),
376 'showposts' => array(
377 'type' => 'boolean',
378 'default' => false,
379 ),
380 'showauthor' => array(
381 'type' => 'boolean',
382 'default' => false,
383 ),
384 'usedatepublished' => array(
385 'type' => 'boolean',
386 'default' => false,
387 ),
388 'template' => array(
389 'type' => 'string',
390 'default' => "{title} {change_date}"
391 ),
392 ),
393 'render_callback' => 'render_block_plugins_list_last_changes',
394 )
395 );
396
397 if ( function_exists( 'wp_set_script_translations' ) ) {
398 /**
399 * May be extended to wp_set_script_translations( 'my-handle', 'my-domain',
400 * plugin_dir_path( MY_PLUGIN ) . 'languages' ) ). For details see
401 * https://make.wordpress.org/core/2018/11/09/new-javascript-i18n-support-in-wordpress/
402 */
403 wp_set_script_translations( 'list-last-changes', 'list-last-changes' );
404 }
405 }
406
407 add_action('init', 'list_last_changes_register_block' );
408