* @license GNU General Public License, version 2 * @link http://addthis.com AddThis website */ class AddThisFollowButtonsFeature extends AddThisFeature { //addthis_follow_settings,widget_addthis-follow-widget,addthis_settings protected $oldConfigVariableName = 'addthis_follow_settings'; protected $settingsVariableName = 'addthis_follow_buttons_settings'; protected $settingsPageId = 'addthis_follow_buttons'; protected $name = 'Follow Buttons'; protected $FollowButtonsHorizontalToolObject = null; protected $FollowButtonsVerticalToolObject = null; protected $FollowButtonsCustomToolObject = null; protected $FollowButtonsHeaderToolObject = null; protected $filterNamePrefix = 'addthis_follow_buttons_'; // a list of all settings fields used for this feature that aren't tool // specific protected $settingsFields = array( 'quick_tag', 'startUpgradeAt', ); protected $defaultConfigs = array( 'quick_tag' => 'disabled', ); // used for temporary compatability with the Sharing Buttons plugin public $globalLayersJsonField = 'addthis_layers_follow_json'; public $globalEnabledField = 'follow_buttons_feature_enabled'; // require the files with the tool and widget classes at the top of this // file for each tool // make a protected variable matching the name for each // tool + ToolObject protected $tools = array( 'FollowButtonsHorizontal', 'FollowButtonsVertical', 'FollowButtonsCustom', 'FollowButtonsHeader', ); protected $quickTagId = 'addthis_follow'; /** * Review https://codex.wordpress.org/Quicktags_API for access keys used * by WordPress */ protected $quickTagAccessKey = 'x'; /** * Checks to see if this upgrade is older than our upgrade tracking * method. This checks for the old widget settings variable name from * version 1.2. * * @return boolean true for upgrade from a really old version, false * otherwise. */ public function isReallyOldUpgrade() { $upgrade = false; $settings = get_option('widget_addthis-follow-widget'); if (!empty($settings)) { $upgrade = true; } return $upgrade; } /** * Upgrade to 2.0.0 * * @return null */ protected function upgradeIterative1() { $horizontalMerge = array(); $horizontalWidgetKeys = array(); $verticalMerge = array(); $verticalWidgetKeys = array(); $widgetIdMapping = array(); $oldWidgetName = 'addthis-follow-widget'; $oldWidgets = get_option('widget_' . $oldWidgetName); foreach ($oldWidgets as $key => $widget) { if ($key == '_multiwidget') { continue; } $newWidget = $this->upgradeIterative1ReformatWidgetData($widget); $oldWidgets[$key] = $newWidget; $toolName = $newWidget['tool']; if (isset($newWidget['title'])) { unset($newWidget['title']); } if (isset($newWidget['tool'])) { unset($newWidget['tool']); } if ($toolName == 'horizontal') { $horizontalMerge = array_merge_recursive($horizontalMerge, $newWidget); $horizontalWidgetKeys[] = $key; } else { $verticalMerge = array_merge_recursive($verticalMerge, $newWidget); $verticalWidgetKeys[] = $key; } } // horizontal widgets upgrade $newWidgetsName = 'addthis_horizontal_follow_toolbox_widget'; $toolCode = 'flwh'; $newWidgetIdMapping = $this->upgradeIterative1CreateNewWidgets( $oldWidgets, $horizontalWidgetKeys, $horizontalMerge, $oldWidgetName, $newWidgetsName, $toolCode ); $widgetIdMapping = array_merge($widgetIdMapping, $newWidgetIdMapping); // vertical widgets upgrade $newWidgetsName = 'addthis_vertical_follow_toolbox_widget'; $toolCode = 'flwv'; $newWidgetIdMapping = $this->upgradeIterative1CreateNewWidgets( $oldWidgets, $verticalWidgetKeys, $verticalMerge, $oldWidgetName, $newWidgetsName, $toolCode ); $widgetIdMapping = array_merge($widgetIdMapping, $newWidgetIdMapping); // Update sidebar pointers to use upgraded widgets $this->upgradeIterative1MigrateSidebarWidgetIds($widgetIdMapping); } /** * Takes in data about one type of widget, and saves as new widgits * * @param array $oldWidgets an array with old widget settings * @param array $relevantWidgetKeys an array with the keys (for the * array above) of widgets of the desired type * @param array $mergedWidgetConfig an array of new widget settings * @param string $oldWidgetName the name of the old widgets * @param string $newWidgetsName the name of the new widgets * @param string $toolCode the name of the tool in this plugin * (used to add settings to $this->config) * * @return array old widget id => new widget id */ protected function upgradeIterative1CreateNewWidgets( $oldWidgets, $relevantWidgetKeys, $mergedWidgetConfig, $oldWidgetName, $newWidgetsName, $toolCode ) { $results = $this->upgradeIterative1CleanUpWidgetMerge($mergedWidgetConfig); $conflict = $results['conflict']; $toolConfigs = $results['settings']; $newWidgetSettings = array(); $widgetIdMapping = array(); $newKey = 0; // simplify per widget settings because there are no conflicts foreach ($relevantWidgetKeys as $oldkey) { $newKey++; $widget = $this->upgradeIterative1UpgradeWidget($oldWidgets[$oldkey], $conflict); $newWidgetSettings[$newKey] = $widget; $oldWidgetId = $oldWidgetName . '-' . $oldkey; $newWidgetId = $newWidgetsName . '-' . $newKey; $widgetIdMapping[$oldWidgetId] = $newWidgetId; } $this->configs[$toolCode] = $toolConfigs; if ($conflict['size'] || $conflict['services']) { $this->configs[$toolCode]['conflict'] = true; } // save new widget info if (!empty($newWidgetSettings)) { $newWidgetSettings['_multiwidget'] = 1; update_option('widget_' . $newWidgetsName, $newWidgetSettings); } return $widgetIdMapping; } /** * Takes a mapping of old widget identifiers and new widgit identifiers, * and updates the widget area settings for them. * * @param array $widgetIdMapping old widget id => new widget id * * @return null */ protected function upgradeIterative1MigrateSidebarWidgetIds($widgetIdMapping) { $sideBarConfigs = get_option('sidebars_widgets'); foreach ($sideBarConfigs as $sideBarId => $sideBarInfo) { if (!is_array($sideBarInfo)) { continue; } foreach ($sideBarInfo as $key => $oldWidgetId) { if (isset($widgetIdMapping[$oldWidgetId])) { $newWidgetId = $widgetIdMapping[$oldWidgetId]; $sideBarConfigs[$sideBarId][$key] = $newWidgetId; } } } update_option('sidebars_widgets', $sideBarConfigs); } /** * Prepares the reformatted widget data from * upgradeIterative1ReformatWidgetData to be saved, based on what * conflicts were found during upgrade. * * @param array $sudoWidget the old widget settings * @param array $conflict and array with keys size and services, * telling us whether there were conflicts for those feilds * * @return array the new widget settings to be saved */ protected function upgradeIterative1UpgradeWidget( $sudoWidget, $conflict ) { $widgetFields = array('title'); foreach ($conflict as $field => $boolean) { if ($boolean) { $widgetFields[] = $field; } } foreach ($sudoWidget as $field => $value) { if (in_array($field, $widgetFields)) { $newWidget[$field] = $value; } } return $newWidget; } /** * Goes through merged data for all widgets of a type, and cleans them * up. Mostly dedupes arrays and turns them into a string when they only * have one element. This is part of determining the new settings for * this feature. * * @param array $mergedWidgets data from all the widgets, merged * * @return array An associative array that includes the new settings, as * well as information on whether there were conflicts in size or * service choices */ protected function upgradeIterative1CleanUpWidgetMerge($mergedWidgets) { $sizeConflict = false; $servicesConflict = false; // check for conflicts & clean up foreach ($mergedWidgets as $key => $value) { if (!is_array($value)) { continue; } if ($key != 'services') { $value = array_unique($value); if (count($value) == 1) { $value = array_pop($value); } else { $sizeConflict = true; } if (empty($value)) { unset($mergedWidgets[$key]); } else { $mergedWidgets[$key] = $value; } } else { foreach ($value as $service => $usernames) { if (!is_array($usernames)) { continue; } $usernames = array_unique($usernames); if (count($usernames) == 1) { $usernames = array_pop($usernames); } else { $servicesConflict = true; } $mergedWidgets[$key][$service] = $usernames; if (empty($usernames)) { unset($mergedWidgets[$key][$service]); } else { $mergedWidgets[$key][$service] = $usernames; } } } } $results = array( 'conflict' => array( 'size' => $sizeConflict, 'services' => $servicesConflict ), 'settings' => $mergedWidgets, ); return $results; } /** * Reformats the settings for old widgets to be closer in line with what * the 2.0 version of the plugin uses. * * @param array $input the old settings for the widget * * @return array */ public function upgradeIterative1ReformatWidgetData($input) { $output = array( 'enabled' => true, ); $sizeLarge = array('hl', 'vl'); $toolHorizontal = array('hl', 'hs'); foreach ($input as $key => $value) { if (empty($value) || $value == 'YOUR-USERNAME' || $value == 'YOUR-PROFILE' ) { continue; } switch ($key) { case 'twitter': case 'linkedin': case 'youtube': case 'flickr': case 'vimeo': case 'pinterest': case 'instagram': case 'foursquare': case 'tumblr': case 'rss': $output['services'][$key.'_user'] = $value; break; case 'facebook': $output['services']['facebook_user'] = $value; break; case 'linkedin-company': $output['services']['linkedin_company'] = $value; break; case 'youtube-channel': $output['services']['youtube_channel'] = $value; break; case 'google': $output['services']['google_follow_user'] = $value; break; case 'title': $output['title'] = $value; break; case 'style': // determine size here if (in_array($value, $sizeLarge)) { $output['size'] = 'large'; } else { $output['size'] = 'small'; } if (in_array($value, $toolHorizontal)) { $output['tool'] = 'horizontal'; } else { $output['tool'] = 'vertical'; } } } return $output; } /** * Builds the class used for horizontal follow buttons * * @param string $location Is this for a sharing button above or below * content/excerpts? * @param array $track Optional. Used by reference. If the * filter changes the value in any way the filter's name will be pushed * * @return string a class */ public function getClassForTypeAndLocation( $location = 'above', &$track = false ) { $toolClass = 'addthis_horizontal_follow_toolbox'; $toolClass = $this->applyToolClassFilters($toolClass, $location, $track); return $toolClass; } } }