Current Path : /var/www/html/wp-content/plugins/duplicator-pro/src/Views/ |
Current File : /var/www/html/wp-content/plugins/duplicator-pro/src/Views/AdminNotices.php |
<?php namespace Duplicator\Views; use Closure; use DUP_PRO_CTRL_Tools; use Duplicator\Core\CapMng; use Duplicator\Core\Controllers\ControllersManager; use Duplicator\Core\Views\TplMng; use Duplicator\Libs\Snap\SnapURL; use Duplicator\Models\RecommendedFix; use Duplicator\Models\SystemGlobalEntity; use Duplicator\Utils\Autoloader; use Exception; /** * Admin notices class, Used to display notices in the WordPress Admin area */ class AdminNotices { const OPTION_KEY_INSTALLER_HASH_NOTICE = 'duplicator_pro_inst_hash_notice'; const OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL = 'duplicator_pro_activate_plugins_after_installation'; const OPTION_KEY_MIGRATION_SUCCESS_NOTICE = 'duplicator_pro_migration_success'; const OPTION_KEY_S3_CONTENTS_FETCH_FAIL_NOTICE = 'duplicator_pro_s3_contents_fetch_fail'; const QUICK_FIX_NOTICE = 'duplicator_pro_quick_fix_notice'; const FAILED_SCHEDULE_NOTICE = 'duplicator_pro_failed_schedule_notice'; const GEN_INFO_NOTICE = 0; const GEN_SUCCESS_NOTICE = 1; const GEN_WARNING_NOTICE = 2; const GEN_ERROR_NOTICE = 3; /** * init notice actions * * @return void */ public static function init() { add_action('admin_init', array(__CLASS__, 'adminInit')); add_action('admin_enqueue_scripts', array(__CLASS__, 'unhookThirdPartyNotices'), 99999, 1); } /** * HOOK admin_init * * @return void */ public static function adminInit() { $notices = array(); $notices[] = array( __CLASS__, 'migrationSuccessNotice', ); // BEFORE MIGRATION SUCCESS NOTICE $notices[] = array( __CLASS__, 's3ContentsFetchFailNotice', ); $notices[] = array( __CLASS__, 'addonInitFailNotice', ); $notices[] = array( __CLASS__, 'activatePluginsAfterInstall', ); $system_global = SystemGlobalEntity::getInstance(); foreach ($system_global->recommended_fixes as $fix) { if ($fix->recommended_fix_type === RecommendedFix::TYPE_TEXT || $fix->recommended_fix_type === RecommendedFix::TYPE_FIX) { $notices[] = array( __CLASS__, 'showQuickFixNotice', ); } } if ($system_global->schedule_failed) { $notices[] = array( __CLASS__, 'showFailedSchedule', ); } $action = is_multisite() ? 'network_admin_notices' : 'admin_notices'; foreach ($notices as $notice) { add_action($action, $notice); } } /** * Addon init fail notice * * @return void */ public static function addonInitFailNotice() { if (\Duplicator\Core\Addons\AddonsManager::getInstance()->isAddonsReady()) { return; } if (!CapMng::can(CapMng::CAP_BASIC, false)) { return; } ob_start(); ?> <strong>Duplicator Pro</strong> <hr> <p> <?php _e( 'The plugin cannot be activated due to problems during initialization. Please reinstall the plugin deleting the current installation', 'duplicator-pro' ); ?> </p> <?php $content = ob_get_clean(); self::displayGeneralAdminNotice($content, self::GEN_ERROR_NOTICE, false); } /** * Remove all notices coming from other plugins * * @param string $hook Hook string * * @return void */ public static function unhookThirdPartyNotices($hook) { if (!ControllersManager::getInstance()->isDuplicatorPage()) { return; } global $wp_filter; $filterHooks = [ 'user_admin_notices', 'admin_notices', 'all_admin_notices', 'network_admin_notices', ]; foreach ($filterHooks as $filterHook) { if (empty($wp_filter[$filterHook]->callbacks) || !is_array($wp_filter[$filterHook]->callbacks)) { continue; } foreach ($wp_filter[$filterHook]->callbacks as $priority => $hooks) { foreach ($hooks as $name => $arr) { if (is_object($arr['function']) && $arr['function'] instanceof Closure) { unset($wp_filter[$filterHook]->callbacks[$priority][$name]); continue; } if ( !empty($arr['function'][0]) && is_object($arr['function'][0]) && strpos(get_class($arr['function'][0]), Autoloader::ROOT_NAMESPACE) === 0 ) { continue; } if (!empty($name) && strpos($name, Autoloader::ROOT_NAMESPACE) !== 0) { unset($wp_filter[$filterHook]->callbacks[$priority][$name]); } } } } } /** * Shows notice in case we were enable to fetch contents of S3 bucket * * @throws Exception * @return void */ public static function s3ContentsFetchFailNotice() { if ( get_option(self::OPTION_KEY_S3_CONTENTS_FETCH_FAIL_NOTICE, false) != true || !ControllersManager::isCurrentPage(ControllersManager::PACKAGES_SUBMENU_SLUG) ) { return; } if (!CapMng::can(CapMng::CAP_CREATE, false)) { return; } $errorMessage = __( '<strong>Duplicator Pro</strong> was unable to fetch the contents of the S3 bucket to remove old packages.', 'duplicator-pro' ) . "<hr><br>" . sprintf( __( '<strong>RECOMMENDATION:</strong> Please make sure your S3 bucket settings are aligned with our %1$sStep-by-Step guide%2$s and %3$sUser Bucket Policy%4$s.', 'duplicator-pro' ), '<a target="_blank" href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-step-by-step">', '</a>', '<a target="_blank" href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-step-by-step">', '</a>' ); self::displayGeneralAdminNotice( $errorMessage, self::GEN_ERROR_NOTICE, true, array('dup-pro-quick-fix-notice'), array( 'data-to-dismiss' => self::OPTION_KEY_S3_CONTENTS_FETCH_FAIL_NOTICE, ) ); } /** * Shows a display message in the wp-admin if any reserved files are found * * @return void */ public static function migrationSuccessNotice() { if (get_option(self::OPTION_KEY_MIGRATION_SUCCESS_NOTICE) != true) { return; } if (!CapMng::can(CapMng::CAP_BASIC, false)) { return; } if (!DUP_PRO_CTRL_Tools::isDiagnosticPage()) { TplMng::getInstance()->render('parts/migration/almost-complete'); } } /** * Shows the scheduled failed alert * * @return void */ public static function showFailedSchedule() { if (!CapMng::can(CapMng::CAP_SCHEDULE, false)) { return; } $schedulesUrl = ControllersManager::getMenuLink(ControllersManager::SCHEDULES_SUBMENU_SLUG); $img_url = plugins_url('duplicator-pro/assets/img/warning.png'); $clear_url = SnapURL::getCurrentUrl(); $clear_url = SnapURL::appendQueryValue($clear_url, 'dup_pro_clear_schedule_failure', 1); $html = "<img src='" . esc_url($img_url) . "' style='float:left; padding:0 10px 0 5px' />" . sprintf(esc_html__('%1$sWarning! A Duplicator Pro scheduled backup has failed.%2$s', 'duplicator-pro'), '<b>', '</b> <br/>') . sprintf( esc_html__( 'This message will continue to be displayed until a %1$sscheduled build%2$s successfully runs. ', 'duplicator-pro' ), "<a href='" . esc_url($schedulesUrl) . "'>", '</a> ' ) . sprintf( esc_html__('To ignore and clear this message %1$sclick here%2$s', 'duplicator-pro'), "<a href='" . esc_url($clear_url) . "'>", '</a>.<br/>' ); self::displayGeneralAdminNotice( $html, self::GEN_ERROR_NOTICE, true, array('dup-pro-quick-fix-notice'), array( 'data-to-dismiss' => self::FAILED_SCHEDULE_NOTICE, ) ); } /** * Shows the quick fix notice * * @return void */ public static function showQuickFixNotice() { if (!ControllersManager::isCurrentPage(ControllersManager::PACKAGES_SUBMENU_SLUG)) { return; } if (!CapMng::can(CapMng::CAP_BASIC, false)) { return; } $system_global = SystemGlobalEntity::getInstance(); $html = '<b class="title"><i class="fa fa-exclamation-circle fa-3 color-alert" ></i> ' . __('Duplicator Pro Errors Detected', 'duplicator-pro') . '</b></br>'; $html .= '<p>' . __('Package build error(s) were encountered. Click the button(s) in the', 'duplicator-pro') . ' <i>' . __('Necessary Actions', 'duplicator-pro') . '</i> ' . __('section to reconfigure Duplicator Pro.', 'duplicator-pro') . "</p>"; $html .= '<p>'; $html .= '<b>' . __('Error(s):', 'duplicator-pro') . ' </b>'; $html .= '<ul style="list-style: disc; padding-left: 40px">'; foreach ($system_global->recommended_fixes as $fix) { $html .= '<li>' . $fix->error_text . '</li>'; } $html .= '</ul>'; $html .= '</p>'; $html .= '<b>' . __('Necessary Action(s):', 'duplicator-pro') . ' </b>' . '<br/>'; foreach ($system_global->recommended_fixes as $fix) { if ($fix->recommended_fix_type == RecommendedFix::TYPE_FIX) { $html .= '<p id ="quick-fix-' . $fix->id . '">' . '<button id="quick-fix-' . $fix->id . '-button" class="dup-pro-quick-fix button" ' . 'type="button" class="button button-primary" ' . 'data-param="' . esc_attr(json_encode($fix->parameter2)) . '" data-id="' . $fix->id . '" data-toggle="#quick-fix-' . $fix->id . '">' . "<i class='fa fa-wrench' aria-hidden='true'></i> " . __('Resolve This', 'duplicator-pro') . '</button>' . $fix->parameter1 . '</p>'; } elseif ($fix->recommended_fix_type == RecommendedFix::TYPE_TEXT) { $html .= "<p><i class='fa fa-question-circle color-alert' data-tooltip='" . esc_attr($fix->error_text) . "'></i> " . $fix->parameter1 . "</br></p>"; } } self::displayGeneralAdminNotice( $html, self::GEN_ERROR_NOTICE, true, array('dup-pro-quick-fix-notice'), array( 'data-to-dismiss' => self::QUICK_FIX_NOTICE, ) ); } /** * display genral admin notice by printing it * * @param string $htmlMsg html code to be printed * @param integer $noticeType constant value of SELF::GEN_ * @param boolean $isDismissible whether the notice is dismissable or not. Default is true * @param string|string[] $extraClasses add more classes to the notice div * @param array<string,mixed> $extraAtts assosiate array in which key as attr and value as value of the attr * @param bool $blockContent if false wraps htmlMsg in <p> otherwise allows to use block tags e.g. <div> * * @return void */ public static function displayGeneralAdminNotice( $htmlMsg, $noticeType, $isDismissible = true, $extraClasses = array(), $extraAtts = array(), $blockContent = false ) { if (empty($extraClasses)) { $classes = array(); } elseif (is_array($extraClasses)) { $classes = $extraClasses; } else { $classes = array($extraClasses); } $classes[] = 'notice'; switch ($noticeType) { case self::GEN_INFO_NOTICE: $classes[] = 'notice-info'; break; case self::GEN_SUCCESS_NOTICE: $classes[] = 'notice-success'; break; case self::GEN_WARNING_NOTICE: $classes[] = 'notice-warning'; break; case self::GEN_ERROR_NOTICE: $classes[] = 'notice-error'; break; default: throw new Exception('Invalid Admin notice type!'); } $classes[] = 'dpro-admin-notice'; if ($isDismissible) { $classes[] = 'is-dismissible'; } $classesStr = implode(' ', $classes); $attsStr = ''; if (!empty($extraAtts)) { $attsStrArr = array(); foreach ($extraAtts as $att => $attVal) { $attsStrArr[] = $att . '="' . $attVal . '"'; } $attsStr = implode(' ', $attsStrArr); } // $htmlMsg = self::GEN_ERROR_NOTICE == $noticeType ? "<i class='fa fa-exclamation-triangle'></i> " . $htmlMsg : $htmlMsg; $htmlMsg = !$blockContent ? "<p>" . $htmlMsg . "</p>" : $htmlMsg; ?> <div class="<?php echo esc_attr($classesStr); ?>" <?php echo $attsStr; ?>> <?php echo $htmlMsg; ?> </div> <?php } /** * Displays notice for plugins deactivated during install, * and removes already activated from DB * * @return void */ public static function activatePluginsAfterInstall() { if (!CapMng::can(CapMng::CAP_BASIC, false)) { return; } $pluginsToActive = get_option(AdminNotices::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, false); if (!is_array($pluginsToActive) || empty($pluginsToActive)) { return; } $shouldBeActivated = array(); $allPlugins = get_plugins(); foreach ($pluginsToActive as $index => $pluginSlug) { if (!isset($allPlugins[$pluginSlug])) { unset($pluginsToActive[$index]); continue; } if (is_multisite()) { $isActive = is_plugin_active_for_network($pluginSlug); } else { $isActive = is_plugin_active($pluginSlug); } if (!$isActive) { $shouldBeActivated[$pluginSlug] = $allPlugins[$pluginSlug]['Name']; } else { unset($pluginsToActive[$index]); } } if (empty($shouldBeActivated)) { delete_option(AdminNotices::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL); return; } else { update_option(AdminNotices::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, $pluginsToActive); } $html = "<img src='" . esc_url(plugins_url('duplicator-pro/assets/img/warning.png')) . "' style='float:left; padding:0 10px 0 5px' />" . "<div style='margin-left: 70px;'><p><b>" . __('Warning!', 'duplicator-pro') . "</b> " . __('Migration Almost Complete!', 'duplicator-pro') . "<br/>" . __('Plugin(s) listed here must be activated, Please activate them:', 'duplicator-pro') . "</p><ul>"; foreach ($shouldBeActivated as $slug => $title) { if (is_multisite()) { $activateURL = network_admin_url('plugins.php?action=activate&plugin=' . $slug); } else { $activateURL = admin_url('plugins.php?action=activate&plugin=' . $slug); } $activateURL = wp_nonce_url($activateURL, 'activate-plugin_' . $slug); $anchorTitle = sprintf(__('Activate %s', 'duplicator-pro'), $title); $html .= '<li><a href="' . esc_attr($activateURL) . '" title="' . esc_attr($anchorTitle) . '">' . esc_attr($title) . '</a></li>'; } $html .= "</ul></div>"; AdminNotices::displayGeneralAdminNotice( $html, AdminNotices::GEN_WARNING_NOTICE, true, array('dpro-yellow-border'), array( 'data-to-dismiss' => AdminNotices::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, ), true ); } }