Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Plugins often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Plugins, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 24 | class Plugins { |
||
| 25 | |||
| 26 | /** |
||
| 27 | * @var string[] Active plugin IDs with IDs as the array keys. Missing keys imply inactive plugins. |
||
| 28 | */ |
||
| 29 | protected $active_ids = array(); |
||
| 30 | |||
| 31 | /** |
||
| 32 | * @var bool Has $active_ids been populated? |
||
| 33 | */ |
||
| 34 | protected $active_ids_known = false; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * @var \Elgg\Cache\MemoryPool |
||
| 38 | */ |
||
| 39 | protected $plugins_by_id; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Constructor |
||
| 43 | * |
||
| 44 | * @param \Elgg\EventsService $events Events service |
||
| 45 | * @param \Elgg\Cache\MemoryPool $pool Cache for referencing plugins by ID |
||
| 46 | */ |
||
| 47 | 1 | public function __construct(\Elgg\EventsService $events, \Elgg\Cache\MemoryPool $pool) { |
|
| 50 | |||
| 51 | /** |
||
| 52 | * Returns a list of plugin directory names from a base directory. |
||
| 53 | * |
||
| 54 | * @param string $dir A dir to scan for plugins. Defaults to config's plugins_path. |
||
| 55 | * Must have a trailing slash. |
||
| 56 | * |
||
| 57 | * @return array Array of directory names (not full paths) |
||
| 58 | * @access private |
||
| 59 | */ |
||
| 60 | function getDirsInDir($dir = null) { |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Discovers plugins in the plugins_path setting and creates \ElggPlugin |
||
| 84 | * entities for them if they don't exist. If there are plugins with entities |
||
| 85 | * but not actual files, will disable the \ElggPlugin entities and mark as inactive. |
||
| 86 | * The \ElggPlugin object holds config data, so don't delete. |
||
| 87 | * |
||
| 88 | * @return bool |
||
| 89 | * @access private |
||
| 90 | */ |
||
| 91 | function generateEntities() { |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Cache a reference to this plugin by its ID |
||
| 184 | * |
||
| 185 | * @param \ElggPlugin $plugin |
||
| 186 | * |
||
| 187 | * @access private |
||
| 188 | */ |
||
| 189 | function cache(\ElggPlugin $plugin) { |
||
| 192 | |||
| 193 | /** |
||
| 194 | * Returns an \ElggPlugin object with the path $path. |
||
| 195 | * |
||
| 196 | * @param string $plugin_id The id (dir name) of the plugin. NOT the guid. |
||
| 197 | * @return \ElggPlugin|null |
||
| 198 | */ |
||
| 199 | function get($plugin_id) { |
||
| 223 | |||
| 224 | /** |
||
| 225 | * Returns if a plugin exists in the system. |
||
| 226 | * |
||
| 227 | * @warning This checks only plugins that are registered in the system! |
||
| 228 | * If the plugin cache is outdated, be sure to regenerate it with |
||
| 229 | * {@link _elgg_generate_plugin_objects()} first. |
||
| 230 | * |
||
| 231 | * @param string $id The plugin ID. |
||
| 232 | * @return bool |
||
| 233 | */ |
||
| 234 | function exists($id) { |
||
| 239 | |||
| 240 | /** |
||
| 241 | * Returns the highest priority of the plugins |
||
| 242 | * |
||
| 243 | * @return int |
||
| 244 | * @access private |
||
| 245 | */ |
||
| 246 | function getMaxPriority() { |
||
| 267 | |||
| 268 | /** |
||
| 269 | * Returns if a plugin is active for a current site. |
||
| 270 | * |
||
| 271 | * @param string $plugin_id The plugin ID |
||
| 272 | * @param int $site_guid The site guid |
||
| 273 | * @return bool |
||
| 274 | */ |
||
| 275 | function isActive($plugin_id, $site_guid = null) { |
||
| 301 | |||
| 302 | /** |
||
| 303 | * Loads all active plugins in the order specified in the tool admin panel. |
||
| 304 | * |
||
| 305 | * @note This is called on every page load. If a plugin is active and problematic, it |
||
| 306 | * will be disabled and a visible error emitted. This does not check the deps system because |
||
| 307 | * that was too slow. |
||
| 308 | * |
||
| 309 | * @return bool |
||
| 310 | * @access private |
||
| 311 | */ |
||
| 312 | function load() { |
||
| 362 | |||
| 363 | /** |
||
| 364 | * Returns an ordered list of plugins |
||
| 365 | * |
||
| 366 | * @param string $status The status of the plugins. active, inactive, or all. |
||
| 367 | * @param mixed $site_guid Optional site guid |
||
| 368 | * @return \ElggPlugin[] |
||
| 369 | */ |
||
| 370 | function find($status = 'active', $site_guid = null) { |
||
| 420 | |||
| 421 | /** |
||
| 422 | * Reorder plugins to an order specified by the array. |
||
| 423 | * Plugins not included in this array will be appended to the end. |
||
| 424 | * |
||
| 425 | * @note This doesn't use the \ElggPlugin->setPriority() method because |
||
| 426 | * all plugins are being changed and we don't want it to automatically |
||
| 427 | * reorder plugins. |
||
| 428 | * |
||
| 429 | * @param array $order An array of plugin ids in the order to set them |
||
| 430 | * @return bool |
||
| 431 | * @access private |
||
| 432 | */ |
||
| 433 | function setPriorities(array $order) { |
||
| 482 | |||
| 483 | /** |
||
| 484 | * Reindexes all plugin priorities starting at 1. |
||
| 485 | * |
||
| 486 | * @todo Can this be done in a single sql command? |
||
| 487 | * @return bool |
||
| 488 | * @access private |
||
| 489 | */ |
||
| 490 | function reindexPriorities() { |
||
| 493 | |||
| 494 | /** |
||
| 495 | * Namespaces a string to be used as a private setting name for a plugin. |
||
| 496 | * |
||
| 497 | * For user_settings, two namespaces are added: a user setting namespace and the |
||
| 498 | * plugin id. |
||
| 499 | * |
||
| 500 | * For internal (plugin priority), there is a single internal namespace added. |
||
| 501 | * |
||
| 502 | * @param string $type The type of setting: user_setting or internal. |
||
| 503 | * @param string $name The name to namespace. |
||
| 504 | * @param string $id The plugin's ID to namespace with. Required for user_setting. |
||
| 505 | * @return string |
||
| 506 | * @access private |
||
| 507 | */ |
||
| 508 | function namespacePrivateSetting($type, $name, $id = null) { |
||
| 530 | |||
| 531 | |||
| 532 | /** |
||
| 533 | * Returns an array of all provides from all active plugins. |
||
| 534 | * |
||
| 535 | * Array in the form array( |
||
| 536 | * 'provide_type' => array( |
||
| 537 | * 'provided_name' => array( |
||
| 538 | * 'version' => '1.8', |
||
| 539 | * 'provided_by' => 'provider_plugin_id' |
||
| 540 | * ) |
||
| 541 | * ) |
||
| 542 | * ) |
||
| 543 | * |
||
| 544 | * @param string $type The type of provides to return |
||
| 545 | * @param string $name A specific provided name to return. Requires $provide_type. |
||
| 546 | * |
||
| 547 | * @return array |
||
| 548 | * @access private |
||
| 549 | */ |
||
| 550 | function getProvides($type = null, $name = null) { |
||
| 592 | |||
| 593 | /** |
||
| 594 | * Deletes all cached data on plugins being provided. |
||
| 595 | * |
||
| 596 | * @return boolean |
||
| 597 | * @access private |
||
| 598 | */ |
||
| 599 | function invalidateProvidesCache() { |
||
| 604 | |||
| 605 | /** |
||
| 606 | * Delete the cache holding whether plugins are active or not |
||
| 607 | * |
||
| 608 | * @return void |
||
| 609 | * @access private |
||
| 610 | */ |
||
| 611 | public function invalidateIsActiveCache() { |
||
| 615 | |||
| 616 | /** |
||
| 617 | * Checks if a plugin is currently providing $type and $name, and optionally |
||
| 618 | * checking a version. |
||
| 619 | * |
||
| 620 | * @param string $type The type of the provide |
||
| 621 | * @param string $name The name of the provide |
||
| 622 | * @param string $version A version to check against |
||
| 623 | * @param string $comparison The comparison operator to use in version_compare() |
||
| 624 | * |
||
| 625 | * @return array An array in the form array( |
||
| 626 | * 'status' => bool Does the provide exist?, |
||
| 627 | * 'value' => string The version provided |
||
| 628 | * ) |
||
| 629 | * @access private |
||
| 630 | */ |
||
| 631 | function checkProvides($type, $name, $version = null, $comparison = 'ge') { |
||
| 651 | |||
| 652 | /** |
||
| 653 | * Returns an array of parsed strings for a dependency in the |
||
| 654 | * format: array( |
||
| 655 | * 'type' => requires, conflicts, or provides. |
||
| 656 | * 'name' => The name of the requirement / conflict |
||
| 657 | * 'value' => A string representing the expected value: <1, >=3, !=enabled |
||
| 658 | * 'local_value' => The current value, ("Not installed") |
||
| 659 | * 'comment' => Free form text to help resovle the problem ("Enable / Search for plugin <link>") |
||
| 660 | * ) |
||
| 661 | * |
||
| 662 | * @param array $dep An \ElggPluginPackage dependency array |
||
| 663 | * @return array |
||
| 664 | * @access private |
||
| 665 | */ |
||
| 666 | function getDependencyStrings($dep) { |
||
| 779 | |||
| 780 | /** |
||
| 781 | * Returns an array of all plugin user settings for a user. |
||
| 782 | * |
||
| 783 | * @param int $user_guid The user GUID or 0 for the currently logged in user. |
||
| 784 | * @param string $plugin_id The plugin ID (Required) |
||
| 785 | * @param bool $return_obj Return settings as an object? This can be used to in reusable |
||
| 786 | * views where the settings are passed as $vars['entity']. |
||
| 787 | * @return array |
||
| 788 | * @see \ElggPlugin::getAllUserSettings() |
||
| 789 | */ |
||
| 790 | function getAllUserSettings($user_guid = 0, $plugin_id = null, $return_obj = false) { |
||
| 816 | |||
| 817 | /** |
||
| 818 | * Set a user specific setting for a plugin. |
||
| 819 | * |
||
| 820 | * @param string $name The name. Note: cannot be "title". |
||
| 821 | * @param mixed $value The value. |
||
| 822 | * @param int $user_guid The user GUID or 0 for the currently logged in user. |
||
| 823 | * @param string $plugin_id The plugin ID (Required) |
||
| 824 | * |
||
| 825 | * @return bool |
||
| 826 | * @see \ElggPlugin::setUserSetting() |
||
| 827 | */ |
||
| 828 | View Code Duplication | function setUserSetting($name, $value, $user_guid = 0, $plugin_id = null) { |
|
| 842 | |||
| 843 | /** |
||
| 844 | * Unsets a user-specific plugin setting |
||
| 845 | * |
||
| 846 | * @param string $name Name of the setting |
||
| 847 | * @param int $user_guid The user GUID or 0 for the currently logged in user. |
||
| 848 | * @param string $plugin_id The plugin ID (Required) |
||
| 849 | * |
||
| 850 | * @return bool |
||
| 851 | * @see \ElggPlugin::unsetUserSetting() |
||
| 852 | */ |
||
| 853 | View Code Duplication | function unsetUserSetting($name, $user_guid = 0, $plugin_id = null) { |
|
| 867 | |||
| 868 | /** |
||
| 869 | * Get a user specific setting for a plugin. |
||
| 870 | * |
||
| 871 | * @param string $name The name of the setting. |
||
| 872 | * @param int $user_guid The user GUID or 0 for the currently logged in user. |
||
| 873 | * @param string $plugin_id The plugin ID (Required) |
||
| 874 | * @param mixed $default The default value to return if none is set |
||
| 875 | * |
||
| 876 | * @return mixed |
||
| 877 | * @see \ElggPlugin::getUserSetting() |
||
| 878 | */ |
||
| 879 | View Code Duplication | function getUserSetting($name, $user_guid = 0, $plugin_id = null, $default = null) { |
|
| 893 | |||
| 894 | /** |
||
| 895 | * Set a setting for a plugin. |
||
| 896 | * |
||
| 897 | * @param string $name The name of the setting - note, can't be "title". |
||
| 898 | * @param mixed $value The value. |
||
| 899 | * @param string $plugin_id The plugin ID (Required) |
||
| 900 | * |
||
| 901 | * @return bool |
||
| 902 | * @see \ElggPlugin::setSetting() |
||
| 903 | */ |
||
| 904 | function setSetting($name, $value, $plugin_id = null) { |
||
| 918 | |||
| 919 | /** |
||
| 920 | * Get setting for a plugin. |
||
| 921 | * |
||
| 922 | * @param string $name The name of the setting. |
||
| 923 | * @param string $plugin_id The plugin ID (Required) |
||
| 924 | * @param mixed $default The default value to return if none is set |
||
| 925 | * |
||
| 926 | * @return mixed |
||
| 927 | * @see \ElggPlugin::getSetting() |
||
| 928 | */ |
||
| 929 | View Code Duplication | function getSetting($name, $plugin_id = null, $default = null) { |
|
| 943 | |||
| 944 | /** |
||
| 945 | * Unsets a plugin setting. |
||
| 946 | * |
||
| 947 | * @param string $name The name of the setting. |
||
| 948 | * @param string $plugin_id The plugin ID (Required) |
||
| 949 | * |
||
| 950 | * @return bool |
||
| 951 | * @see \ElggPlugin::unsetSetting() |
||
| 952 | */ |
||
| 953 | function unsetSetting($name, $plugin_id = null) { |
||
| 967 | |||
| 968 | /** |
||
| 969 | * Unsets all plugin settings for a plugin. |
||
| 970 | * |
||
| 971 | * @param string $plugin_id The plugin ID (Required) |
||
| 972 | * |
||
| 973 | * @return bool |
||
| 974 | * @see \ElggPlugin::unsetAllSettings() |
||
| 975 | */ |
||
| 976 | function unsetAllSettings($plugin_id = null) { |
||
| 990 | |||
| 991 | /** |
||
| 992 | * Returns entities based upon plugin user settings. |
||
| 993 | * Takes all the options for {@link elgg_get_entities_from_private_settings()} |
||
| 994 | * in addition to the ones below. |
||
| 995 | * |
||
| 996 | * @param array $options Array in the format: |
||
| 997 | * |
||
| 998 | * plugin_id => STR The plugin id. Required. |
||
| 999 | * |
||
| 1000 | * plugin_user_setting_names => null|ARR private setting names |
||
| 1001 | * |
||
| 1002 | * plugin_user_setting_values => null|ARR metadata values |
||
| 1003 | * |
||
| 1004 | * plugin_user_setting_name_value_pairs => null|ARR ( |
||
| 1005 | * name => 'name', |
||
| 1006 | * value => 'value', |
||
| 1007 | * 'operand' => '=', |
||
| 1008 | * ) |
||
| 1009 | * Currently if multiple values are sent via |
||
| 1010 | * an array (value => array('value1', 'value2') |
||
| 1011 | * the pair's operand will be forced to "IN". |
||
| 1012 | * |
||
| 1013 | * plugin_user_setting_name_value_pairs_operator => null|STR The operator to use for combining |
||
| 1014 | * (name = value) OPERATOR (name = value); default AND |
||
| 1015 | * |
||
| 1016 | * @return mixed int If count, int. If not count, array. false on errors. |
||
| 1017 | */ |
||
| 1018 | function getEntitiesFromUserSettings(array $options = array()) { |
||
| 1058 | } |
||
| 1059 |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: