WordPress.org

Make WordPress Core

Ticket #10810: wpd.candeletes.php

File wpd.candeletes.php, 3.6 KB (added by 5ubliminal, 6 years ago)

This is my fix but I'd rather you include these filters in the core.

Line 
1<?php
2/*
3Plugin Name: WPD.Can_Delete_*
4Plugin URI: http://blog.5ubliminal.com/topics/wordpress/plugins/
5Description: Add <code>can_delete_*</code> before the <code>delete_* action</code> to allow gracefull failure induced by other plugins.
6Version: 5.U.B
7Author: 5ubliminal
8Author URI: http://blog.5ubliminal.com/
9Support URI: http://blog.5ubliminal.com/support/
10*/
11// ---------------------------------------------------------- //
12if(true): // TRUE installation, set FALSE to rollback changes
13        /**
14        * This injects the can_delete_* filters
15        */
16        function WPD_CanDelete_Injector(){
17                $files = array(); // Let's save files to alter here
18                $recursiveIterator = new RecursiveDirectoryIterator($path = realpath(ABSPATH));
19                foreach(new RecursiveIteratorIterator($recursiveIterator) as $file) {
20                        // Files must be .php
21                        if(!preg_match('~\.php$~i', ($fpath = realpath($file->getPathname())))) continue;
22                        // Load file's PHP code for further processing
23                        $php = file_get_contents($fpath, FILE_BINARY);
24                        // Try and locate delete_.* actions or continue to next file
25                        if(!preg_match_all('~^(.+?)do_action\(\'delete_.+?\',.+?\)\s*;~mi', $php, $matches)) continue;
26                        // Backup file contents [just once ... the original] ... who knows
27                        if(!file_exists($fpath.'.backup')) copy($fpath, $fpath.'.backup');
28                        // Save changes for final display
29                        $files[substr($fpath, strlen($path))] = array_map('trim', ($matches = array_unique($matches[0])));
30                        // Take each change at a time and fix it
31                        foreach($matches as $match){
32                                // Break it into slices: index, name, arguments
33                                if(!preg_match('~^(\s+)do_action\(\'delete_(.+?)\',(.+?)\)\s*;$~i', $match, $slices)) continue;
34                                array_shift($slices); // Drop first match which is the entire thing
35                                $indent = array_shift($slices); // The index ... spaces before
36                                list($name, $args) = array_map('trim', $slices); // Extract variables
37                                // Prepare new line which gets added to the file
38                                $new_line = "{$indent}if(!apply_filters('can_delete_{$name}', true, {$args})) return false; /* 5ub.HACK */";
39                                // Try to loate new line ... if it exists ... fail gracefully
40                                if(strpos($php, $new_line) !== false) continue;
41                                // Replace old line with newline.[crlf].oldline
42                                $php = str_replace($match, PHP_EOL.$new_line.PHP_EOL.$match.PHP_EOL, $php);
43                        }
44                        // Fix enters ... the notepad compatible way ;)
45                        $php = preg_replace('~\r?\n~', PHP_EOL, $php);
46                        // Overwrite file contents [you still have the backup in case shit happens]
47                        file_put_contents($fpath, $php, FILE_BINARY);
48                }
49                // Self deactivate
50                deactivate_plugins(__FILE__, true);
51        }
52        register_activation_hook(__FILE__, 'WPD_CanDelete_Injector');
53else:
54        /**
55        * This rollsback can_delete_* additions to WP .php files
56        */
57        function WPD_CanDelete_Ejector(){
58                $files = array(); // Let's save files to alter here
59                $recursiveIterator = new RecursiveDirectoryIterator($path = realpath(ABSPATH));
60                foreach(new RecursiveIteratorIterator($recursiveIterator) as $file) {
61                        // Files must be .php
62                        if(!preg_match('~\.php$~i', ($fpath = realpath($file->getPathname())))) continue;
63                        // Load file's PHP code for further processing
64                        $php = file_get_contents($fpath, FILE_BINARY);
65                        // Check if code still exists
66                        if(!preg_match('~apply_filters\(\'can_delete_.+?\',~i', $php)) continue;
67                        // Replace hack instances
68                        $php = preg_replace('~^if\(!apply_filters\(\'can_delete_.+?\', true, .+?\)\) return false; /* 5ub.HACK */[\r\n]+~i', null, $php);
69                        // Overwrite file contents [you still have the backup in case shit happens]
70                        file_put_contents($fpath, $php, FILE_BINARY);
71                }
72        }
73        register_activation_hook(__FILE__, 'WPD_CanDelete_Ejector');
74endif
75// ---------------------------------------------------------- //
76?>