Нет описания

class.about.php 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. <?php
  2. /**
  3. * About page class
  4. *
  5. * @package xshop
  6. * @subpackage Admin
  7. * @since 1.0.0
  8. */
  9. if ( ! class_exists( 'xshop_About' ) ) {
  10. /**
  11. * Singleton class used for generating the about page of the theme.
  12. */
  13. class xshop_About {
  14. /**
  15. * Define the version of the class.
  16. *
  17. * @var string $version The TI_About_Page class version.
  18. */
  19. private $version = '1.0.0';
  20. /**
  21. * Used for loading the texts and setup the actions inside the page.
  22. *
  23. * @var array $config The configuration array for the theme used.
  24. */
  25. private $config;
  26. /**
  27. * Get the theme name using wp_get_theme.
  28. *
  29. * @var string $theme_name The theme name.
  30. */
  31. private $theme_name;
  32. /**
  33. * Get the theme slug ( theme folder name ).
  34. *
  35. * @var string $theme_slug The theme slug.
  36. */
  37. private $theme_slug;
  38. /**
  39. * The current theme object.
  40. *
  41. * @var WP_Theme $theme The current theme.
  42. */
  43. private $theme;
  44. /**
  45. * Holds the theme version.
  46. *
  47. * @var string $theme_version The theme version.
  48. */
  49. private $theme_version;
  50. /**
  51. * Define the menu item name for the page.
  52. *
  53. * @var string $menu_name The name of the menu name under Appearance settings.
  54. */
  55. private $menu_name;
  56. /**
  57. * Define the page title name.
  58. *
  59. * @var string $page_name The title of the About page.
  60. */
  61. private $page_name;
  62. /**
  63. * Define the page tabs.
  64. *
  65. * @var array $tabs The page tabs.
  66. */
  67. private $tabs;
  68. /**
  69. * Define the html notification content displayed upon activation.
  70. *
  71. * @var string $notification The html notification content.
  72. */
  73. private $notification;
  74. /**
  75. * The single instance of TI_About_Page
  76. *
  77. * @var xshop_About $instance The TI_About_Page instance.
  78. */
  79. private static $instance;
  80. /**
  81. * The Main TI_About_Page instance.
  82. *
  83. * We make sure that only one instance of TI_About_Page exists in the memory at one time.
  84. *
  85. * @param array $config The configuration array.
  86. */
  87. public static function init( $config ) {
  88. if ( ! isset( self::$instance ) && ! ( self::$instance instanceof xshop_About ) ) {
  89. self::$instance = new xshop_About;
  90. if ( ! empty( $config ) && is_array( $config ) ) {
  91. self::$instance->config = $config;
  92. self::$instance->setup_config();
  93. self::$instance->setup_actions();
  94. }
  95. }
  96. }
  97. /**
  98. * Setup the class props based on the config array.
  99. */
  100. public function setup_config() {
  101. $theme = wp_get_theme();
  102. if ( is_child_theme() ) {
  103. $this->theme_name = $theme->parent()->get( 'Name' );
  104. $this->theme = $theme->parent();
  105. } else {
  106. $this->theme_name = $theme->get( 'Name' );
  107. $this->theme = $theme->parent();
  108. }
  109. $this->theme_name = $theme->get( 'Name' );
  110. $this->theme_version = $theme->get( 'Version' );
  111. $this->theme_slug = $theme->get_template();
  112. $this->menu_name = isset( $this->config['menu_name'] ) ? $this->config['menu_name'] : 'About ' . $this->theme_name;
  113. $this->page_name = isset( $this->config['page_name'] ) ? $this->config['page_name'] : 'About ' . $this->theme_name;
  114. $this->notification = isset( $this->config['notification'] ) ? $this->config['notification'] : ( '<p>' . sprintf( 'Welcome! Thank you for choosing %1$s! To fully take advantage of the best our theme can offer please make sure you visit our %2$swelcome page%3$s.', $this->theme_name, '<a href="' . esc_url( admin_url( 'themes.php?page=' . $this->theme_slug . '-welcome' ) ) . '">', '</a>' ) . '</p><p><a href="' . esc_url( admin_url( 'themes.php?page=' . $this->theme_slug . '-welcome' ) ) . '" class="button" style="text-decoration: none;">' . sprintf( 'Get started with %s', $this->theme_name ) . '</a></p>' );
  115. $this->tabs = isset( $this->config['tabs'] ) ? $this->config['tabs'] : array();
  116. }
  117. /**
  118. * Setup the actions used for this page.
  119. */
  120. public function setup_actions() {
  121. add_action( 'admin_menu', array( $this, 'register' ) );
  122. /* activation notice */
  123. add_action( 'load-themes.php', array( $this, 'activation_admin_notice' ) );
  124. /* enqueue script and style for about page */
  125. add_action( 'admin_enqueue_scripts', array( $this, 'style_and_scripts' ) );
  126. /* ajax callback for dismissable required actions */
  127. add_action( 'wp_ajax_ti_about_page_dismiss_required_action', array( $this, 'dismiss_required_action_callback' ) );
  128. add_action( 'wp_ajax_nopriv_ti_about_page_dismiss_required_action', array( $this, 'dismiss_required_action_callback') );
  129. }
  130. /**
  131. * Hide required tab if no actions present.
  132. *
  133. * @return bool Either hide the tab or not.
  134. */
  135. public function hide_required( $value, $tab ) {
  136. if ( $tab != 'recommended_actions' ) {
  137. return $value;
  138. }
  139. $required = $this->get_required_actions();
  140. if ( count( $required ) == 0 ) {
  141. return false;
  142. } else {
  143. return true;
  144. }
  145. }
  146. /**
  147. * Register the menu page under Appearance menu.
  148. */
  149. function register() {
  150. if ( ! empty( $this->menu_name ) && ! empty( $this->page_name ) ) {
  151. $count = 0;
  152. $actions_count = $this->get_required_actions();
  153. if ( ! empty( $actions_count ) ) {
  154. $count = count( $actions_count );
  155. }
  156. $title = $count > 0 ? $this->page_name . '<span class="badge-action-count">' . esc_html( $count ) . '</span>' : $this->page_name;
  157. add_theme_page(
  158. $this->menu_name, $title, 'activate_plugins', $this->theme_slug . '-welcome', array(
  159. $this,
  160. 'ti_about_page_render',
  161. )
  162. );
  163. }
  164. }
  165. /**
  166. * Adds an admin notice upon successful activation.
  167. */
  168. public function activation_admin_notice() {
  169. global $pagenow;
  170. if ( is_admin() && ( 'themes.php' == $pagenow ) && isset( $_GET['activated'] ) ) {
  171. add_action( 'admin_notices', array( $this, 'ti_about_page_welcome_admin_notice' ), 99 );
  172. }
  173. }
  174. /**
  175. * Display an admin notice linking to the about page
  176. */
  177. public function ti_about_page_welcome_admin_notice() {
  178. if ( ! empty( $this->notification ) ) {
  179. echo '<div class="updated notice is-dismissible">';
  180. echo wp_kses_post( $this->notification );
  181. echo '</div>';
  182. }
  183. }
  184. /**
  185. * Render the main content page.
  186. */
  187. public function ti_about_page_render() {
  188. if ( ! empty( $this->config['welcome_title'] ) ) {
  189. $welcome_title = $this->config['welcome_title'];
  190. }
  191. if ( ! empty( $this->config['welcome_content'] ) ) {
  192. $welcome_content = $this->config['welcome_content'];
  193. }
  194. if ( ! empty( $welcome_title ) || ! empty( $welcome_content ) || ! empty( $this->tabs ) ) {
  195. echo '<div class="wrap about-wrap xshop-about-wrap">';
  196. if ( ! empty( $welcome_title ) ) {
  197. echo '<h1>';
  198. echo esc_html( $welcome_title );
  199. if ( ! empty( $this->theme_version ) ) {
  200. echo esc_html( $this->theme_version ) . ' </sup>';
  201. }
  202. echo '</h1>';
  203. }
  204. if ( ! empty( $welcome_content ) ) {
  205. echo '<div class="about-text">' . wp_kses_post( $welcome_content ) . '</div>';
  206. }
  207. echo '<a href="'.esc_url('https://wpthemespace.com/product/xshop-pro/').'" target="_blank" class="wp-badge epsilon-welcome-logo"></a>';
  208. $this->render_quick_links();
  209. /* Display tabs */
  210. if ( ! empty( $this->tabs ) ) {
  211. $active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : 'getting_started';
  212. echo '<h2 class="nav-tab-wrapper wp-clearfix">';
  213. $actions_count = $this->get_required_actions();
  214. $count = 0;
  215. if ( ! empty( $actions_count ) ) {
  216. $count = count( $actions_count );
  217. }
  218. foreach ( $this->tabs as $tab_key => $tab_name ) {
  219. if ( ( $tab_key != 'changelog' ) || ( ( $tab_key == 'changelog' ) && isset( $_GET['show'] ) && ( $_GET['show'] == 'yes' ) ) ) {
  220. if ( ( $count == 0 ) && ( $tab_key == 'recommended_actions' ) ) {
  221. continue;
  222. }
  223. echo '<a href="' . esc_url( admin_url( 'themes.php?page=' . $this->theme_slug . '-welcome' ) ) . '&tab=' . esc_attr( $tab_key ) . '" class="nav-tab ' . ( $active_tab == $tab_key ? 'nav-tab-active' : '' ) . '" role="tab" data-toggle="tab">';
  224. echo esc_html( $tab_name );
  225. if ( $tab_key == 'recommended_actions' ) {
  226. $count = 0;
  227. $actions_count = $this->get_required_actions();
  228. if ( ! empty( $actions_count ) ) {
  229. $count = count( $actions_count );
  230. }
  231. if ( $count > 0 ) {
  232. echo '<span class="badge-action-count">' . esc_html( $count ) . '</span>';
  233. }
  234. }
  235. echo '</a>';
  236. }
  237. }
  238. echo '</h2>';
  239. /* Display content for current tab */
  240. if ( method_exists( $this, $active_tab ) ) {
  241. $this->$active_tab();
  242. }
  243. }
  244. echo '</div><!--/.wrap.about-wrap-->';
  245. }
  246. }
  247. /*
  248. * Call plugin api
  249. */
  250. public function call_plugin_api( $slug ) {
  251. include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); // phpcs:ignore
  252. if ( false === ( $call_api = get_transient( 'ti_about_page_plugin_information_transient_' . $slug ) ) ) {
  253. $call_api = plugins_api(
  254. 'plugin_information', array(
  255. 'slug' => $slug,
  256. 'fields' => array(
  257. 'downloaded' => false,
  258. 'rating' => false,
  259. 'description' => false,
  260. 'short_description' => true,
  261. 'donate_link' => false,
  262. 'tags' => false,
  263. 'sections' => true,
  264. 'homepage' => true,
  265. 'added' => false,
  266. 'last_updated' => false,
  267. 'compatibility' => false,
  268. 'tested' => false,
  269. 'requires' => false,
  270. 'downloadlink' => false,
  271. 'icons' => true
  272. )
  273. )
  274. );
  275. set_transient( 'ti_about_page_plugin_information_transient_' . $slug, $call_api, 30 * MINUTE_IN_SECONDS );
  276. }
  277. return $call_api;
  278. }
  279. public function check_if_plugin_active( $slug ) {
  280. if( ( $slug == 'intergeo-maps' ) || ( $slug == 'visualizer' ) ) {
  281. $plugin_root_file = 'index';
  282. } elseif ( $slug == 'adblock-notify-by-bweb' ) {
  283. $plugin_root_file = 'adblock-notify';
  284. } else {
  285. $plugin_root_file = $slug;
  286. }
  287. $path = WPMU_PLUGIN_DIR . '/' . $slug . '/' . $plugin_root_file . '.php';
  288. if ( ! file_exists( $path ) ) {
  289. $path = WP_PLUGIN_DIR . '/' . $slug . '/' . $plugin_root_file . '.php';
  290. if ( ! file_exists( $path ) ) {
  291. $path = false;
  292. }
  293. }
  294. if ( file_exists( $path ) ) {
  295. include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // phpcs:ignore
  296. $needs = is_plugin_active( $slug . '/' . $plugin_root_file . '.php' ) ? 'deactivate' : 'activate';
  297. return array( 'status' => is_plugin_active( $slug . '/' . $plugin_root_file . '.php' ), 'needs' => $needs );
  298. }
  299. return array( 'status' => false, 'needs' => 'install' );
  300. }
  301. /**
  302. * Get icon of wordpress.org plugin
  303. * @param $arr
  304. *
  305. * @return mixed
  306. */
  307. public function get_plugin_icon( $arr ) {
  308. if ( ! empty( $arr['svg'] ) ) {
  309. $plugin_icon_url = $arr['svg'];
  310. } elseif ( ! empty( $arr['2x'] ) ) {
  311. $plugin_icon_url = $arr['2x'];
  312. } elseif ( ! empty( $arr['1x'] ) ) {
  313. $plugin_icon_url = $arr['1x'];
  314. } else {
  315. $plugin_icon_url = get_template_directory_uri() . '/inc/about/images/logo.png';
  316. }
  317. return $plugin_icon_url;
  318. }
  319. public function create_action_link( $state, $slug ) {
  320. if( ( $slug == 'intergeo-maps' ) || ( $slug == 'visualizer' ) ) {
  321. $plugin_root_file = 'index';
  322. } elseif ( $slug == 'adblock-notify-by-bweb' ) {
  323. $plugin_root_file = 'adblock-notify';
  324. } else {
  325. $plugin_root_file = $slug;
  326. }
  327. switch ( $state ) {
  328. case 'install':
  329. return wp_nonce_url(
  330. add_query_arg(
  331. array(
  332. 'action' => 'install-plugin',
  333. 'plugin' => $slug
  334. ),
  335. network_admin_url( 'update.php' )
  336. ),
  337. 'install-plugin_' . $slug
  338. );
  339. break;
  340. case 'deactivate':
  341. return add_query_arg(
  342. array(
  343. 'action' => 'deactivate',
  344. 'plugin' => rawurlencode( $slug . '/' . $plugin_root_file . '.php' ),
  345. 'plugin_status' => 'all',
  346. 'paged' => '1',
  347. '_wpnonce' => wp_create_nonce( 'deactivate-plugin_' . $slug . '/' . $plugin_root_file . '.php' ),
  348. ), network_admin_url( 'plugins.php' )
  349. );
  350. break;
  351. case 'activate':
  352. return add_query_arg(
  353. array(
  354. 'action' => 'activate',
  355. 'plugin' => rawurlencode( $slug . '/' . $plugin_root_file . '.php' ),
  356. 'plugin_status' => 'all',
  357. 'paged' => '1',
  358. '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $slug . '/' . $plugin_root_file . '.php' ),
  359. ), network_admin_url( 'plugins.php' )
  360. );
  361. break;
  362. }
  363. }
  364. /**
  365. * Render quick links.
  366. *
  367. * @since 1.0.0
  368. */
  369. public function render_quick_links() {
  370. $quick_links = ( isset( $this->config['quick_links'] ) ) ? $this->config['quick_links'] : array();
  371. if ( ! empty( $quick_links ) ) {
  372. echo '<p class="quick-links">';
  373. foreach ( $quick_links as $link ) {
  374. $button_type = '';
  375. if ( isset( $link['button'] ) ) {
  376. $button_type = 'button-' . esc_attr( $link['button'] );
  377. }
  378. echo '<a href="' . esc_url( $link['url'] ) . '" class="button ' . esc_attr( $button_type ) . '" target="_blank">' . esc_html( $link['text'] ) . '</a>';
  379. }
  380. echo '</p>';
  381. }
  382. }
  383. /**
  384. * Render getting started.
  385. *
  386. * @since 1.0.0
  387. */
  388. public function getting_started() {
  389. $content = ( isset( $this->config['getting_started'] ) ) ? $this->config['getting_started'] : array();
  390. if ( empty( $content ) ) {
  391. return;
  392. }
  393. ?>
  394. <div class="feature-section xshop-section xshop-section-getting-started three-col">
  395. <?php foreach ( $content as $item ) : ?>
  396. <?php $this->render_grid_item( $item ); ?>
  397. <?php endforeach; ?>
  398. </div><!-- .feature-section .xshop-section -->
  399. <?php
  400. }
  401. /**
  402. * Render grid item.
  403. *
  404. * @since 1.0.0
  405. *
  406. * @param array $item Item details.
  407. */
  408. private function render_grid_item( $item ) {
  409. ?>
  410. <div class="col">
  411. <?php if ( isset( $item['title'] ) && ! empty( $item['title'] ) ) : ?>
  412. <h3>
  413. <?php if ( isset( $item['icon'] ) && ! empty( $item['icon'] ) ) : ?>
  414. <span class="<?php echo esc_attr( $item['icon'] ); ?>"></span>
  415. <?php endif; ?>
  416. <?php echo esc_html( $item['title'] ); ?>
  417. </h3>
  418. <?php endif; ?>
  419. <?php if ( isset( $item['description'] ) && ! empty( $item['description'] ) ) : ?>
  420. <p><?php echo wp_kses_post( $item['description'] ); ?></p>
  421. <?php endif; ?>
  422. <?php if ( isset( $item['button_text'] ) && ! empty( $item['button_text'] ) && isset( $item['button_url'] ) && ! empty( $item['button_url'] ) ) : ?>
  423. <?php
  424. $button_target = ( isset( $item['is_new_tab'] ) && true === $item['is_new_tab'] ) ? '_blank' : '_self';
  425. $button_class = '';
  426. if ( isset( $item['button_type'] ) && ! empty( $item['button_type'] ) ) {
  427. if ( 'primary' === $item['button_type'] ) {
  428. $button_class = 'button button-primary';
  429. } elseif ( 'secondary' === $item['button_type'] ) {
  430. $button_class = 'button button-secondary';
  431. }
  432. }
  433. ?>
  434. <a href="<?php echo esc_url( $item['button_url'] ); ?>" class="<?php echo esc_attr( $button_class ); ?>" target="<?php echo esc_attr( $button_target ); ?>"><?php echo esc_html( $item['button_text'] ); ?></a>
  435. <?php endif; ?>
  436. </div><!-- .col -->
  437. <?php
  438. }
  439. /**
  440. * Render support.
  441. *
  442. * @since 1.0.0
  443. */
  444. public function support() {
  445. $content = ( isset( $this->config['support'] ) ) ? $this->config['support'] : array();
  446. if ( empty( $content ) ) {
  447. return;
  448. }
  449. ?>
  450. <div class="feature-section xshop-section xshop-section-support three-col">
  451. <?php foreach ( $content as $item ) : ?>
  452. <?php $this->render_grid_item( $item ); ?>
  453. <?php endforeach; ?>
  454. </div><!-- .feature-section .xshop-section -->
  455. <?php
  456. }
  457. /**
  458. * Recommended Actions tab
  459. */
  460. public function recommended_actions() {
  461. $recommended_actions = isset( $this->config['recommended_actions'] ) ? $this->config['recommended_actions'] : array();
  462. if ( ! empty( $recommended_actions ) ) {
  463. echo '<div class="feature-section action-required demo-import-boxed" id="plugin-filter">';
  464. $actions = array();
  465. $req_actions = isset( $this->config['recommended_actions'] ) ? $this->config['recommended_actions'] : array();
  466. foreach ( $req_actions['content'] as $req_action ) {
  467. $actions[] = $req_action;
  468. }
  469. if ( ! empty( $actions ) && is_array( $actions ) ) {
  470. $ti_about_page_show_required_actions = get_option( $this->theme_slug . '_required_actions' );
  471. $hooray = true;
  472. foreach ( $actions as $action_key => $action_value ) {
  473. $hidden = false;
  474. echo '<div class="about-page-action-required-box">';
  475. if ( ! $hidden ) {
  476. echo '<span data-action="dismiss" class="dashicons dashicons-visibility about-page-required-action-button" id="' . esc_attr( $action_value['id'] ) . '"></span>';
  477. } else {
  478. echo '<span data-action="add" class="dashicons dashicons-hidden about-page-required-action-button" id="' . esc_attr( $action_value['id'] ) .'"></span>';
  479. }
  480. if ( ! empty( $action_value['title'] ) ) {
  481. echo '<h3>' . wp_kses_post( $action_value['title'] ) . '</h3>';
  482. }
  483. if ( ! empty( $action_value['description'] ) ) {
  484. echo '<p>' . wp_kses_post( $action_value['description'] ) . '</p>';
  485. }
  486. if ( ! empty( $action_value['plugin_slug'] ) ) {
  487. $active = $this->check_if_plugin_active( $action_value['plugin_slug'] );
  488. $url = $this->create_action_link( $active['needs'], $action_value['plugin_slug'] );
  489. $label = '';
  490. switch ( $active['needs'] ) {
  491. case 'install':
  492. $class = 'install-now button';
  493. if ( ! empty( $this->config['recommended_actions']['install_label'] ) ) {
  494. $label = $this->config['recommended_actions']['install_label'];
  495. }
  496. break;
  497. case 'activate':
  498. $class = 'activate-now button button-primary';
  499. if ( ! empty( $this->config['recommended_actions']['activate_label'] ) ) {
  500. $label = $this->config['recommended_actions']['activate_label'];
  501. }
  502. break;
  503. case 'deactivate':
  504. $class = 'deactivate-now button';
  505. if ( ! empty( $this->config['recommended_actions']['deactivate_label'] ) ) {
  506. $label = $this->config['recommended_actions']['deactivate_label'];
  507. }
  508. break;
  509. }
  510. ?>
  511. <p class="plugin-card-<?php echo esc_attr( $action_value['plugin_slug'] ) ?> action_button <?php echo ( $active['needs'] !== 'install' && $active['status'] ) ? 'active' : '' ?>">
  512. <a data-slug="<?php echo esc_attr( $action_value['plugin_slug'] ) ?>"
  513. class="<?php echo esc_attr( $class ); ?>"
  514. href="<?php echo esc_url( $url ) ?>"> <?php echo esc_html( $label ) ?> </a>
  515. </p>
  516. <?php
  517. }
  518. echo '</div>';
  519. }
  520. }
  521. echo '</div>';
  522. }
  523. }
  524. /**
  525. * Recommended plugins tab
  526. */
  527. public function useful_plugins() {
  528. $useful_plugins = $this->config['useful_plugins'];
  529. if ( ! empty( $useful_plugins ) ) {
  530. if ( ! empty( $useful_plugins['content'] ) && is_array( $useful_plugins['content'] ) ) {
  531. echo '<div class="feature-section recommended-plugins three-col demo-import-boxed" id="plugin-filter">';
  532. foreach ( $useful_plugins['content'] as $useful_plugins_item ) {
  533. if ( ! empty( $useful_plugins_item['slug'] ) ) {
  534. $info = $this->call_plugin_api( $useful_plugins_item['slug'] );
  535. if ( ! empty( $info->icons ) ) {
  536. $icon = $this->get_plugin_icon( $info->icons );
  537. }
  538. $active = $this->check_if_plugin_active( $useful_plugins_item['slug'] );
  539. if ( ! empty( $active['needs'] ) ) {
  540. $url = $this->create_action_link( $active['needs'], $useful_plugins_item['slug'] );
  541. }
  542. echo '<div class="col plugin_box">';
  543. if ( ! empty( $icon ) ) {
  544. echo '<img src="'.esc_url( $icon ).'" alt="plugin box image">';
  545. }
  546. if ( ! empty( $info->version ) ) {
  547. echo '<span class="version">'. ( ! empty( $this->config['useful_plugins']['version_label'] ) ? esc_html( $this->config['useful_plugins']['version_label'] ) : '' ) . esc_html( $info->version ).'</span>';
  548. }
  549. if ( ! empty( $info->name ) && ! empty( $active ) ) {
  550. echo '<div class="action_bar ' . ( ( $active['needs'] !== 'install' && $active['status'] ) ? 'active' : '' ) . '">';
  551. echo '<span class="plugin_name">' . ( ( $active['needs'] !== 'install' && $active['status'] ) ? 'Active: ' : '' ) . esc_html( $info->name ) . '</span>';
  552. echo '</div>';
  553. $label = '';
  554. switch ( $active['needs'] ) {
  555. case 'install':
  556. $class = 'install-now button';
  557. if ( ! empty( $this->config['useful_plugins']['install_label'] ) ) {
  558. $label = $this->config['useful_plugins']['install_label'];
  559. }
  560. break;
  561. case 'activate':
  562. $class = 'activate-now button button-primary';
  563. if ( ! empty( $this->config['useful_plugins']['activate_label'] ) ) {
  564. $label = $this->config['useful_plugins']['activate_label'];
  565. }
  566. break;
  567. case 'deactivate':
  568. $class = 'deactivate-now button';
  569. if ( ! empty( $this->config['useful_plugins']['deactivate_label'] ) ) {
  570. $label = $this->config['useful_plugins']['deactivate_label'];
  571. }
  572. break;
  573. }
  574. echo '<span class="plugin-card-' . esc_attr( $useful_plugins_item['slug'] ) . ' action_button ' . ( ( $active['needs'] !== 'install' && $active['status'] ) ? 'active' : '' ) . '">';
  575. echo '<a data-slug="' . esc_attr( $useful_plugins_item['slug'] ) . '" class="' . esc_attr( $class ) . '" href="' . esc_url( $url ) . '">' . esc_html( $label ) . '</a>';
  576. echo '</span>';
  577. }
  578. echo '</div><!-- .col.plugin_box -->';
  579. }
  580. }
  581. echo '</div><!-- .recommended-plugins -->';
  582. }
  583. }
  584. }
  585. /**
  586. * Changelog tab
  587. */
  588. public function changelog() {
  589. $changelog = $this->parse_changelog();
  590. if ( ! empty( $changelog ) ) {
  591. echo '<div class="featured-section changelog">';
  592. foreach ( $changelog as $release ) {
  593. if ( ! empty( $release['title'] ) ) {
  594. echo '<h2>' . wp_kses_post( $release['title'] ) . ' </h2 > ';
  595. }
  596. if ( ! empty( $release['changes'] ) ) {
  597. echo wp_kses_post( implode( '<br/>', $release['changes'] ) );
  598. }
  599. }
  600. echo '</div><!-- .featured-section.changelog -->';
  601. }
  602. }
  603. /**
  604. * Return the releases changes array.
  605. *
  606. * @return array The releases array.
  607. */
  608. private function parse_changelog() {
  609. WP_Filesystem();
  610. global $wp_filesystem;
  611. $changelog = $wp_filesystem->get_contents( get_template_directory() . '/CHANGELOG.md' );
  612. if ( is_wp_error( $changelog ) ) {
  613. $changelog = '';
  614. }
  615. $changelog = explode( PHP_EOL, $changelog );
  616. $releases = array();
  617. foreach ( $changelog as $changelog_line ) {
  618. if ( strpos( $changelog_line, '**Changes:**' ) !== false || empty( $changelog_line ) ) {
  619. continue;
  620. }
  621. if ( substr( $changelog_line, 0, 3 ) === '###' ) {
  622. if ( isset( $release ) ) {
  623. $releases[] = $release;
  624. }
  625. $release = array(
  626. 'title' => substr( $changelog_line, 3 ),
  627. 'changes' => array(),
  628. );
  629. } else {
  630. $release['changes'][] = $changelog_line;
  631. }
  632. }
  633. return $releases;
  634. }
  635. /**
  636. * Free vs PRO tab
  637. */
  638. public function free_pro() {
  639. $free_pro = isset( $this->config['free_pro'] ) ? $this->config['free_pro'] : array();
  640. if ( ! empty( $free_pro ) ) {
  641. if ( ! empty( $free_pro['free_theme_name'] ) && ! empty( $free_pro['pro_theme_name'] ) && ! empty( $free_pro['features'] ) && is_array( $free_pro['features'] ) ) {
  642. echo '<div class="feature-section">';
  643. echo '<div id="free_pro" class="about-page-tab-pane about-page-fre-pro">';
  644. echo '<table class="free-pro-table">';
  645. echo '<thead>';
  646. echo '<tr>';
  647. echo '<th></th>';
  648. echo '<th>' . esc_html( $free_pro['free_theme_name'] ) . '</th>';
  649. echo '<th>' . esc_html( $free_pro['pro_theme_name'] ) . '</th>';
  650. echo '</tr>';
  651. echo '</thead>';
  652. echo '<tbody>';
  653. foreach ( $free_pro['features'] as $feature ) {
  654. echo '<tr>';
  655. if ( ! empty( $feature['title'] ) || ! empty( $feature['description'] ) ) {
  656. echo '<td>';
  657. if ( ! empty( $feature['title'] ) ) {
  658. echo '<h3>' . wp_kses_post( $feature['title'] ) . '</h3>';
  659. }
  660. if ( ! empty( $feature['description'] ) ) {
  661. echo '<p>' . wp_kses_post( $feature['description'] ) . '</p>';
  662. }
  663. echo '</td>';
  664. }
  665. if ( ! empty( $feature['is_in_lite'] ) && ( $feature['is_in_lite'] == 'true' ) ) {
  666. echo '<td class="only-lite"><span class="dashicons-before dashicons-yes"></span></td>';
  667. } else {
  668. echo '<td class="only-pro"><span class="dashicons-before dashicons-no-alt"></span></td>';
  669. }
  670. if ( ! empty( $feature['is_in_pro'] ) && ( $feature['is_in_pro'] == 'true' ) ) {
  671. echo '<td class="only-lite"><span class="dashicons-before dashicons-yes"></span></td>';
  672. } else {
  673. echo '<td class="only-pro"><span class="dashicons-before dashicons-no-alt"></span></td>';
  674. }
  675. echo '</tr>';
  676. }
  677. echo '<tr><td style="border-top:0;"></td><td style="border-top:0;"></td><td style="border-top:0;" class="only-pro"><a href="'.esc_url('https://wpthemespace.com/product/xshop-pro/').'" target="_blank" >';
  678. echo esc_html ('X Shop Pro Live Preview', 'xshop');
  679. echo '</a></td></tr>';
  680. if ( ! empty( $free_pro['pro_theme_link'] ) && ! empty( $free_pro['get_pro_theme_label'] ) ) {
  681. echo '<tr class="about-page-text-center">';
  682. echo '<td></td>';
  683. echo '<td colspan="2"><a href="' . esc_url( $free_pro['pro_theme_link'] ) . '" target="_blank" class="button button-primary button-hero">' . wp_kses_post( $free_pro['get_pro_theme_label'] ) . '</a></td>';
  684. echo '</tr>';
  685. }
  686. echo '</tbody>';
  687. echo '</table>';
  688. echo '</div>';
  689. echo '</div>';
  690. }
  691. }
  692. }
  693. /**
  694. * Load css and scripts for the about page
  695. */
  696. public function style_and_scripts( $hook_suffix ) {
  697. // this is needed on all admin pages, not just the about page, for the badge action count in the WordPress main sidebar
  698. wp_enqueue_style( 'about-page-css', get_template_directory_uri() . '/inc/about/css/about.min.css', array(),'2.3.4','all' );
  699. wp_enqueue_script( 'eye-notice-js', get_template_directory_uri() . '/inc/about/js/notice.js', array('jquery'), '2.3.2', true );
  700. if ( 'appearance_page_' . $this->theme_slug . '-welcome' == $hook_suffix ) {
  701. wp_enqueue_script( 'about-page-js', get_template_directory_uri() . '/inc/about/js/about.min.js', array( 'jquery' ) );
  702. wp_enqueue_style( 'plugin-install' );
  703. wp_enqueue_script( 'plugin-install' );
  704. wp_enqueue_script( 'updates' );
  705. $recommended_actions = isset( $this->config['recommended_actions'] ) ? $this->config['recommended_actions'] : array();
  706. $required_actions = $this->get_required_actions();
  707. wp_localize_script(
  708. 'about-page-js', 'tiAboutPageObject', array(
  709. 'nr_actions_required' => count( $required_actions ),
  710. 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
  711. 'template_directory' => get_template_directory_uri(),
  712. 'activating_string' => __( 'Activating', 'xshop' )
  713. )
  714. );
  715. }
  716. }
  717. /**
  718. * Return the valid array of required actions.
  719. *
  720. * @return array The valid array of required actions.
  721. */
  722. private function get_required_actions() {
  723. $saved_actions = get_option( $this->theme_slug . '_required_actions' );
  724. if ( ! is_array( $saved_actions ) ) {
  725. $saved_actions = array();
  726. }
  727. $req_actions = isset( $this->config['recommended_actions'] ) ? $this->config['recommended_actions'] : array();
  728. $valid = array();
  729. foreach ( $req_actions['content'] as $req_action ) {
  730. if ( ( ! isset( $req_action['check'] ) || ( isset( $req_action['check'] ) && ( $req_action['check'] == false ) ) ) && ( ! isset( $saved_actions[ $req_action['id'] ] ) ) ) {
  731. $valid[] = $req_action;
  732. }
  733. }
  734. return $valid;
  735. }
  736. /**
  737. * Dismiss required actions
  738. */
  739. public function dismiss_required_action_callback() {
  740. $recommended_actions = array();
  741. $req_actions = isset( $this->config['recommended_actions'] ) ? $this->config['recommended_actions'] : array();
  742. foreach ( $req_actions['content'] as $req_action ) {
  743. $recommended_actions[] = $req_action;
  744. }
  745. $action_id = ( isset( $_GET['id'] ) ) ? sanitize_text_field( wp_unslash( $_GET['id'] ) ) : 0;
  746. echo esc_html( wp_unslash( $action_id ) ); /* this is needed and it's the id of the dismissable required action */
  747. if ( ! empty( $action_id ) ) {
  748. /* if the option exists, update the record for the specified id */
  749. if ( get_option( $this->theme_slug . '_required_actions' ) ) {
  750. $ti_about_page_show_required_actions = get_option( $this->theme_slug . '_required_actions' );
  751. $todo = ( isset( $_GET['todo'] ) ) ? sanitize_text_field( wp_unslash( $_GET['todo'] ) ) : '';
  752. switch ( $todo ) {
  753. case 'add';
  754. $ti_about_page_show_required_actions[ absint( $action_id ) ] = true;
  755. break;
  756. case 'dismiss';
  757. $ti_about_page_show_required_actions[ absint( $action_id ) ] = false;
  758. break;
  759. }
  760. update_option( $this->theme_slug . '_required_actions', $ti_about_page_show_required_actions );
  761. /* create the new option,with false for the specified id */
  762. } else {
  763. $ti_about_page_show_required_actions_new = array();
  764. if ( ! empty( $recommended_actions ) ) {
  765. foreach ( $recommended_actions as $ti_about_page_required_action ) {
  766. if ( $ti_about_page_required_action['id'] == $action_id ) {
  767. $ti_about_page_show_required_actions_new[ $ti_about_page_required_action['id'] ] = false;
  768. } else {
  769. $ti_about_page_show_required_actions_new[ $ti_about_page_required_action['id'] ] = true;
  770. }
  771. }
  772. update_option( $this->theme_slug . '_required_actions', $ti_about_page_show_required_actions_new );
  773. }
  774. }
  775. }
  776. }
  777. }
  778. }