Plugin Directory

Changeset 1240463


Ignore:
Timestamp:
09/08/2015 09:31:08 AM (11 years ago)
Author:
samface
Message:

Some bugfixes and much longed for documentation

Location:
angry-creative-logger/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • angry-creative-logger/trunk/plugin.php

    r1235366 r1240463  
    44Plugin URI: http://angrycreative.se
    55Description: Inspects and logs possible issues with your Wordpress installation.
    6 Version: 0.8.3
     6Version: 0.8.4
    77Author: Robin Björklund, Sammy Nordström, Angry Creative AB
    88*/
    99
    10 define( 'ACI_PLUGIN_VERSION', '0.8.3' );
     10define( 'ACI_PLUGIN_VERSION', '0.8.4' );
    1111
    1212define( 'ACI_PLUGIN_DIR', dirname( __FILE__ ) );
  • angry-creative-logger/trunk/readme.txt

    r1235366 r1240463  
    44Requires at least: 4.0
    55Tested up to: 4.2.4
    6 Stable tag: 0.8.3
     6Stable tag: 0.8.4
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
    99
    10 Inspects, logs and with the aid of WP-CLI it may even repair possible issues with your Wordpress installation.
     10Inspects, logs and with the aid of WP-CLI, it may even repair possible issues with your WordPress installation.
    1111
    1212== Description ==
    1313
    14 Inspects, logs and with the aid of WP-CLI it may even repair possible issues with your Wordpress installation.
    15 
    16 TO-DO: Documentation :)
     14The *Angry Creative Inspector*, or Angry Inspector for short, will weigh, measure and find possible issues with your WordPress installation. This plugin is especially recommended to maintainers of WordPress installations that needs to continously monitor the health of their sites. Got WP-CLI? Then you may even be able to repair what's wrong with your WordPress. Read on to learn more.
     15
     16The inspector has two basic types of inspection routines; regularly repeating inspections run once every 24 hours and inspections triggered by a WordPress hook or user action. Currently, the following regularly running inspection routines are supported out of the box:
     17
     18* File permissions check - You didn't do a chmod 777 on all files, right?
     19* Git modifications check - Is your WordPress revisioned by Git? Then we log uncomitted file changes.
     20* Database collation check - Does your tables have the proper character set and collations?
     21* Site visibility check - Is your website blocking search engines?
     22
     23Then there's the following WordPress hook or otherwise user action triggered routines:
     24
     25* Plugin enabling/disabling - Who disabled or enabled that plugin?
     26* User registrations - Logs all user registrations. No more, no less.
     27* User profile updates - Logs all user profile updates, even password changes.
     28* User capabilitiy changes - Who promoted or demoted that user?
     29* Site registrations - Who created that site in your site network?
     30* Site enabling/disabling - Who disabled or enabled that site in your site network?
     31* Javascript error logging - Keep track of javascript errors, even the ones that appears in your visitor's browsers.
     32
     33A little configuration is needed to take full advantage of the file permissions and site visibility routines, see installation instructions.
     34
     35= Doing inspections and viewing inspection logs =
     36
     37Login to your WordPress site with an administrator account and navigate to the Angry Inspector page under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite). In here you should see the inspection log and may trigger the scheduled inspection routines manually by clicking the "Inspect now" button. Also take note of the "Inspection routines" and "Action routines" tabs where you among other things may change the log level for each routine. Set log level to 'ignore' to completely disable a routine.
     38
     39= Inspect and repair using WP-CLI =
     40
     41First make sure you have WP-CLI installed, see http://wp-cli.org for instructions. Then navigate your commandline shell to your WordPress install directory and issue the following command:
     42
     43    wp angry-inspector inspect
     44
     45You may also call a specific inspection routine like this (use all lowercase name of class or function without "ACI_Routine_"-prefix and replace underscores with dashes):
     46
     47    wp angry-inspector inspect file-permissions
     48
     49Any inspection remarks while inspecting with WP-CLI will cause the inspector to look for a possible repair method and prompt you with the question wether you would like to make an attempt at repairing if one is found. Want to skip inspection and go directly for repairing? Here's how:
     50
     51    wp angry-inspector repair
     52
     53To call a repair method for a specific inspection routine:
     54
     55    wp angry-inspector repair site-visibility
     56
     57Please note that for utilizing a repair method like the one for file permissions, you need to run the command as super-user (root) and add --allow-root to your WP-CLI commands, like this:
     58
     59    sudo wp angry-inspector repair file-permissions --allow-root
     60
     61That's all there is to it, really. Note that the given log_level option is just a default and may be overridden in the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite) like all the other registered inspection routines.
     62
     63= Creating your own inspection routines =
     64
     65Are you skilled in the arts of WordPress development and have a need for a check not covered by the above? Then you should extend the inspector with your own inspection routine! It's really simple. Here's an example you can put in your theme's functions.php or in a plugin (after plugins loaded):
     66
     67    if ( function_exists( 'aci_register_routine' ) ) {
     68
     69        $options = array( 'description' => 'My awesome inspection routine!',
     70                          'log_level' => 'warning' ); // Possible values: notice, warning, fatal, ignore
     71
     72        $action = 'ac_inspection'; // Default inspection action run once every 24 hrs
     73
     74        aci_register_routine( 'my_inspection_routine', $options, $action );
     75
     76        function my_inspection_routine() {
     77
     78            $inspection_passed = false;
     79
     80            // Put your inspection code here,
     81            // then log your results like so:
     82
     83            if ( !$inspection_passed ) {
     84                AC_Inspector::log( 'Your WordPress-install did not pass your inspection routine.', __FUNCTION__ );
     85            }
     86
     87            // No need to return anything...
     88            return;
     89
     90        }
     91
     92    }
     93
     94For a bit more advanced developers, you may also register a class as an inspection routine. The syntax and function used is the same, it's just a matter of passing the class name instead of a function name. The inspector will by default look for a class function called 'inspect' to register as inspection method, otherwise you may add 'inspection_method' => 'your_inspection_function' to the options array to use any class function you like as your inspection method.
     95
     96The reason why you would want to register a class instead of just a function is that it gives you the ability to extend the settings for your routine beyond just the log level and maybe even add a repair method to call if the inspection fails (WP-CLI only).
     97
     98First off, here's how you extend the settings for your routine (inside your inspection routine class):
     99
     100    public static function settings_field( $options, $args = array() ) {
     101
     102        $routine = $args["routine"];
     103
     104        /**
     105        *
     106        *   Input field name convention: aci_options[<?php echo $routine; ?>][field_name]
     107        *   Input field id convention: aci_options_<?php echo $routine; ?>_field_name
     108        *
     109        **/
     110
     111        ?>
     112
     113        <tr valign="top">
     114            <td scope="row" valign="top" style="vertical-align: top;">Example setting field</td>
     115            <td>
     116                <p class="description">Here be extra settings field :)</p>
     117            </td>
     118        </tr>
     119
     120        <?php
     121
     122    }
     123
     124    public static function settings( $options ) {
     125
     126        // Here be code that parses and validates submitted values
     127
     128        return $options;
     129
     130    }
     131
     132Then when you register your routine:
     133
     134    $default_options = array( 'log_level' => 'warning',
     135                              'description' => 'My awesome inspection routine!' );
     136
     137    aci_register_routine( 'my_inspection_routine_class', $default_options );
     138
     139    // Optional extra settings fields
     140    add_action( 'my_inspection_routine_class_settings_field', array( 'my_inspection_routine_class', 'settings_field' ), 10, 2 );
     141    add_filter( 'my_inspection_routine_class_settings',  array( 'my_inspection_routine_class', 'settings' ), 10, 1 );
     142
     143Your extra settings fields should now be visible in either the Inspection or the Action routines tab under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite).
     144
     145For a complete example routine class, checkout the routines/wp_mail.php file in the plugin directory.
     146
     147As for registering a repair function, it works the same as when registering a class with an inspection method. The inspector looks for a class function called 'repair' by default. Override with any class function you like by defining 'repair_method' => 'your_repair_function' in the options array. However, a repair method will never be called automatically. You need WP-CLI ( http://wp-cli.org/ ) installed and issue the appropriate commands, see "Inspect and repair using WP-CLI" above.
     148
     149Happy... no wait, angry inspecting! :)
    17150
    18151== Installation ==
     
    201531. Download, unzip and upload the plugin folder to the `/wp-content/plugins/` directory
    211542. Activate the plugin through the 'Plugins' menu in WordPress (activate for network if multisite)
    22 3. Make sure the right log file path is set under the 'Settings/AC Inspector' menu in Wordpress
     1553. Make sure the right log file path is set under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite)
     156
     157To get the file permissions and site visibility routines working properly, edit wp-config.php and add the following (before "That's all, stop editing!"):
     158
     159    //define("FS_METHOD", "direct"); // Recommended: Enable this for dev/stage-environments
     160    define("DISALLOW_FILE_MODS", true); // Recommended: Enable this for production-evironments
     161
     162    define("HTTPD_USER", "www-data"); // The user of your HTTP-daemon (Apache/Nginx/Lighttpd/etc)
     163    define("FS_USER", "my-user"); // The username/accountname you login and maintain your WordPress install with
     164    define("SITE_RELEASE_TIER", "production"); // Possible values: 'local', 'development', 'integration', 'test', 'stage', 'production'
     165
     166Setting FS_METHOD to 'direct' will ensure write permissions in your entire WordPress-directory for FS_USER as well as HTTPD_USER, while enabling DISALLOW_FILE_MODS will restrict the HTTPD_USER to only having write permissions as configured under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite). Default allowed dirs:
     167
     168    wp-content/uploads/*
     169    wp-content/blogs.dir/*
     170    wp-content/cache/*
     171    wp-content/avatars/*
     172    wp-content/*/LC_MESSAGES/*
     173
     174Setting SITE_RELEASE_TIER helps the inspector determine wether the site should allow search engine indexing or not. Forgetting to block search engines in a development or staging site can have terrible results on your search engine ranking.
    23175
    24176== Changelog ==
     
    33185* Added repair method to site visibility routine using SITE_RELEASE_TIER for making the site public or private
    34186* Added the abiltity to define HIDDEN_SITES to prevent specific sites from being made public by the site visibility repair method
     187* Finally added a bit of useful documentation and user instructions to this readme, please start asking questions if you want an FAQ :)
    35188
    36189= 0.7.x =
  • angry-creative-logger/trunk/routines/file_permissions.php

    r1235366 r1240463  
    171171
    172172        return true;
     173
     174    }
     175
     176    private static function file_user_may( $file_op, $file, $user = '' ) {
     177
     178        if ( empty( $file_op ) ) {
     179            return false;
     180        }
     181
     182        if ( empty( $file ) ) {
     183            return false;
     184        }
     185
     186        if ( empty( $user ) ) {
     187            if ( defined( 'FS_USER' ) ) {
     188                $user = FS_USER;
     189            } else if ( defined( 'FTP_USER' ) ) {
     190                $user = FTP_USER;
     191            } else {
     192                $process_user_info = posix_getpwuid(posix_geteuid());
     193                $user = $process_user_info['name'];
     194            }
     195        }
     196
     197        $file_ops = array( 'r' => 'read', 'w' => 'write', 'x' => 'execute' );
     198
     199        if ( in_array( $file_op, $file_ops ) ) {
     200            $req_perm_bit = array_search( $file_op, $file_ops );
     201        } else if ( in_array( $file_op, array_keys( $file_ops ) ) ) {
     202            $req_perm_bit = $file_op;
     203        } else {
     204            return false;
     205        }
     206
     207        clearstatcache();
     208
     209        $file_owner_info = posix_getpwuid( fileowner( $file ) );
     210        $file_group_info = posix_getgrgid( filegroup( $file ) );
     211        $file_perms = fileperms( $file );
     212
     213        $file_perm_bits = '';
     214
     215        if ( $user == $file_owner_info['name'] ) {
     216
     217            $file_perm_bits .= (($file_perms & 0x0100) ? 'r' : '-');
     218            $file_perm_bits .= (($file_perms & 0x0080) ? 'w' : '-');
     219            $file_perm_bits .= (($file_perms & 0x0040) ? 'x' : '-');
     220
     221        } else if ( in_array( $user, $file_group_info['members'] ) ) {
     222
     223            $file_perm_bits .= (($file_perms & 0x0020) ? 'r' : '-');
     224            $file_perm_bits .= (($file_perms & 0x0010) ? 'w' : '-');
     225            $file_perm_bits .= (($file_perms & 0x0008) ? 'x' : '-');
     226
     227        } else {
     228
     229            $file_perm_bits .= (($file_perms & 0x0004) ? 'r' : '-');
     230            $file_perm_bits .= (($file_perms & 0x0002) ? 'w' : '-');
     231            $file_perm_bits .= (($file_perms & 0x0001) ? 'x' : '-');
     232
     233        }
     234
     235        if ( false !== strpos( $file_perm_bits, $req_perm_bit ) ) {
     236            return true;
     237        }
     238
     239        return false;
    173240
    174241    }
     
    283350                $file = str_replace('//', '/', $file);
    284351
    285                 if ( !$allowed_dir && @touch($file, date('U', filemtime($file)), time() ) ) {
     352                if ( !$allowed_dir && self::file_user_may( 'w', $file ) ) {
    286353                    $bad_file_perm = true;
    287354                    AC_Inspector::log( "Writable file `$file` is in a file directory that should not be writeable. Check your file permissions.", __CLASS__ );
    288                 } else if ( $allowed_dir && !@touch($file, date('U', filemtime($file)), time() ) ) {
     355                } else if ( $allowed_dir && !self::file_user_may( 'w', $file ) ) {
    289356                    $bad_file_perm = true;
    290357                    AC_Inspector::log( "Unwritable file `$file` is in a file directory that should be writeable. Check your file permissions.", __CLASS__ );
     
    362429
    363430        if ( is_dir( $path ) ) {
     431
     432            if ( !empty( $group ) ) {
     433                try {
     434                    $chowned = @chgrp( $path, $group );
     435                    if ( !$chowned ) {
     436                        throw new Exception( "Failed changing group ownership of directory '$path' to '$group'" );
     437                    } else if ( $verbose ) {
     438                        AC_Inspector::log( "Changed group ownership of directory '$path' to '$group'", __CLASS__, array( 'success' => true ) );
     439                    }
     440                } catch ( Exception $e ) {
     441                    AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
     442                    $group = '';
     443                }
     444            }
    364445
    365446            if ( !empty( $owner ) ) {
     
    374455                    AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
    375456                    $owner = '';
    376                 }
    377             }
    378 
    379             if ( !empty( $group ) ) {
    380                 try {
    381                     $chowned = @chgrp( $path, $group );
    382                     if ( !$chowned ) {
    383                         throw new Exception( "Failed changing group ownership of directory '$path' to '$group'" );
    384                     } else if ( $verbose ) {
    385                         AC_Inspector::log( "Changed group ownership of directory '$path' to '$group'", __CLASS__, array( 'success' => true ) );
    386                     }
    387                 } catch ( Exception $e ) {
    388                     AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
    389                     $group = '';
    390457                }
    391458            }
     
    431498        } else {
    432499
     500            if ( !empty( $group ) ) {
     501                try {
     502                    $chowned = @chown( $path, $group );
     503                    if ( !$chowned ) {
     504                        throw new Exception( "Failed changing group ownership of file '$path' to '$group'" );
     505                    }
     506                } catch ( Exception $e ) {
     507                    AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
     508                    $group = '';
     509                }
     510            }
     511
    433512            if ( !empty( $owner ) ) {
    434513                try {
     
    440519                    AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
    441520                    $owner = '';
    442                 }
    443             }
    444 
    445             if ( !empty( $group ) ) {
    446                 try {
    447                     $chowned = @chown( $path, $group );
    448                     if ( !$chowned ) {
    449                         throw new Exception( "Failed changing group ownership of file '$path' to '$group'" );
    450                     }
    451                 } catch ( Exception $e ) {
    452                     AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );
    453                     $group = '';
    454521                }
    455522            }
Note: See TracChangeset for help on using the changeset viewer.