class-wc-admin-pointers.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. /**
  3. * Adds and controls pointers for contextual help/tutorials
  4. *
  5. * @author WooThemes
  6. * @category Admin
  7. * @package WooCommerce/Admin
  8. * @version 2.4.0
  9. */
  10. if ( ! defined( 'ABSPATH' ) ) {
  11. exit;
  12. }
  13. /**
  14. * WC_Admin_Pointers Class.
  15. */
  16. class WC_Admin_Pointers {
  17. /**
  18. * Constructor.
  19. */
  20. public function __construct() {
  21. add_action( 'admin_enqueue_scripts', array( $this, 'setup_pointers_for_screen' ) );
  22. }
  23. /**
  24. * Setup pointers for screen.
  25. */
  26. public function setup_pointers_for_screen() {
  27. if ( ! $screen = get_current_screen() ) {
  28. return;
  29. }
  30. switch ( $screen->id ) {
  31. case 'product':
  32. $this->create_product_tutorial();
  33. break;
  34. }
  35. }
  36. /**
  37. * Pointers for creating a product.
  38. */
  39. public function create_product_tutorial() {
  40. if ( ! isset( $_GET['tutorial'] ) || ! current_user_can( 'manage_options' ) ) {
  41. return;
  42. }
  43. // These pointers will chain - they will not be shown at once.
  44. $pointers = array(
  45. 'pointers' => array(
  46. 'title' => array(
  47. 'target' => '#title',
  48. 'next' => 'content',
  49. 'next_trigger' => array(
  50. 'target' => '#title',
  51. 'event' => 'input',
  52. ),
  53. 'options' => array(
  54. 'content' => '<h3>' . esc_html__( 'Product name', 'woocommerce' ) . '</h3>' .
  55. '<p>' . esc_html__( 'Give your new product a name here. This is a required field and will be what your customers will see in your store.', 'woocommerce' ) . '</p>',
  56. 'position' => array(
  57. 'edge' => 'top',
  58. 'align' => 'left',
  59. ),
  60. ),
  61. ),
  62. 'content' => array(
  63. 'target' => '#wp-content-editor-container',
  64. 'next' => 'product-type',
  65. 'next_trigger' => array(),
  66. 'options' => array(
  67. 'content' => '<h3>' . esc_html__( 'Product description', 'woocommerce' ) . '</h3>' .
  68. '<p>' . esc_html__( 'This is your products main body of content. Here you should describe your product in detail.', 'woocommerce' ) . '</p>',
  69. 'position' => array(
  70. 'edge' => 'bottom',
  71. 'align' => 'middle',
  72. ),
  73. ),
  74. ),
  75. 'product-type' => array(
  76. 'target' => '#product-type',
  77. 'next' => 'virtual',
  78. 'next_trigger' => array(
  79. 'target' => '#product-type',
  80. 'event' => 'change blur click',
  81. ),
  82. 'options' => array(
  83. 'content' => '<h3>' . esc_html__( 'Choose product type', 'woocommerce' ) . '</h3>' .
  84. '<p>' . esc_html__( 'Choose a type for this product. Simple is suitable for most physical goods and services (we recommend setting up a simple product for now).', 'woocommerce' ) . '</p>' .
  85. '<p>' . esc_html__( 'Variable is for more complex products such as t-shirts with multiple sizes.', 'woocommerce' ) . '</p>' .
  86. '<p>' . esc_html__( 'Grouped products are for grouping several simple products into one.', 'woocommerce' ) . '</p>' .
  87. '<p>' . esc_html__( 'Finally, external products are for linking off-site.', 'woocommerce' ) . '</p>',
  88. 'position' => array(
  89. 'edge' => 'bottom',
  90. 'align' => 'middle',
  91. ),
  92. ),
  93. ),
  94. 'virtual' => array(
  95. 'target' => '#_virtual',
  96. 'next' => 'downloadable',
  97. 'next_trigger' => array(
  98. 'target' => '#_virtual',
  99. 'event' => 'change',
  100. ),
  101. 'options' => array(
  102. 'content' => '<h3>' . esc_html__( 'Virtual products', 'woocommerce' ) . '</h3>' .
  103. '<p>' . esc_html__( 'Check the "Virtual" box if this is a non-physical item, for example a service, which does not need shipping.', 'woocommerce' ) . '</p>',
  104. 'position' => array(
  105. 'edge' => 'bottom',
  106. 'align' => 'middle',
  107. ),
  108. ),
  109. ),
  110. 'downloadable' => array(
  111. 'target' => '#_downloadable',
  112. 'next' => 'regular_price',
  113. 'next_trigger' => array(
  114. 'target' => '#_downloadable',
  115. 'event' => 'change',
  116. ),
  117. 'options' => array(
  118. 'content' => '<h3>' . esc_html__( 'Downloadable products', 'woocommerce' ) . '</h3>' .
  119. '<p>' . esc_html__( 'If purchasing this product gives a customer access to a downloadable file, e.g. software, check this box.', 'woocommerce' ) . '</p>',
  120. 'position' => array(
  121. 'edge' => 'bottom',
  122. 'align' => 'middle',
  123. ),
  124. ),
  125. ),
  126. 'regular_price' => array(
  127. 'target' => '#_regular_price',
  128. 'next' => 'postexcerpt',
  129. 'next_trigger' => array(
  130. 'target' => '#_regular_price',
  131. 'event' => 'input',
  132. ),
  133. 'options' => array(
  134. 'content' => '<h3>' . esc_html__( 'Prices', 'woocommerce' ) . '</h3>' .
  135. '<p>' . esc_html__( 'Next you need to give your product a price.', 'woocommerce' ) . '</p>',
  136. 'position' => array(
  137. 'edge' => 'bottom',
  138. 'align' => 'middle',
  139. ),
  140. ),
  141. ),
  142. 'postexcerpt' => array(
  143. 'target' => '#postexcerpt',
  144. 'next' => 'postimagediv',
  145. 'next_trigger' => array(
  146. 'target' => '#postexcerpt',
  147. 'event' => 'input',
  148. ),
  149. 'options' => array(
  150. 'content' => '<h3>' . esc_html__( 'Product short description', 'woocommerce' ) . '</h3>' .
  151. '<p>' . esc_html__( 'Add a quick summary for your product here. This will appear on the product page under the product name.', 'woocommerce' ) . '</p>',
  152. 'position' => array(
  153. 'edge' => 'bottom',
  154. 'align' => 'middle',
  155. ),
  156. ),
  157. ),
  158. 'postimagediv' => array(
  159. 'target' => '#postimagediv',
  160. 'next' => 'product_tag',
  161. 'options' => array(
  162. 'content' => '<h3>' . esc_html__( 'Product images', 'woocommerce' ) . '</h3>' .
  163. '<p>' . esc_html__( "Upload or assign an image to your product here. This image will be shown in your store's catalog.", 'woocommerce' ) . '</p>',
  164. 'position' => array(
  165. 'edge' => 'right',
  166. 'align' => 'middle',
  167. ),
  168. ),
  169. ),
  170. 'product_tag' => array(
  171. 'target' => '#tagsdiv-product_tag',
  172. 'next' => 'product_catdiv',
  173. 'options' => array(
  174. 'content' => '<h3>' . esc_html__( 'Product tags', 'woocommerce' ) . '</h3>' .
  175. '<p>' . esc_html__( 'You can optionally "tag" your products here. Tags are a method of labeling your products to make them easier for customers to find.', 'woocommerce' ) . '</p>',
  176. 'position' => array(
  177. 'edge' => 'right',
  178. 'align' => 'middle',
  179. ),
  180. ),
  181. ),
  182. 'product_catdiv' => array(
  183. 'target' => '#product_catdiv',
  184. 'next' => 'submitdiv',
  185. 'options' => array(
  186. 'content' => '<h3>' . esc_html__( 'Product categories', 'woocommerce' ) . '</h3>' .
  187. '<p>' . esc_html__( 'Optionally assign categories to your products to make them easier to browse through and find in your store.', 'woocommerce' ) . '</p>',
  188. 'position' => array(
  189. 'edge' => 'right',
  190. 'align' => 'middle',
  191. ),
  192. ),
  193. ),
  194. 'submitdiv' => array(
  195. 'target' => '#submitdiv',
  196. 'next' => '',
  197. 'options' => array(
  198. 'content' => '<h3>' . esc_html__( 'Publish your product!', 'woocommerce' ) . '</h3>' .
  199. '<p>' . esc_html__( 'When you are finished editing your product, hit the "Publish" button to publish your product to your store.', 'woocommerce' ) . '</p>',
  200. 'position' => array(
  201. 'edge' => 'right',
  202. 'align' => 'middle',
  203. ),
  204. ),
  205. ),
  206. ),
  207. );
  208. $this->enqueue_pointers( $pointers );
  209. }
  210. /**
  211. * Enqueue pointers and add script to page.
  212. *
  213. * @param array $pointers
  214. */
  215. public function enqueue_pointers( $pointers ) {
  216. $pointers = wp_json_encode( $pointers );
  217. wp_enqueue_style( 'wp-pointer' );
  218. wp_enqueue_script( 'wp-pointer' );
  219. wc_enqueue_js(
  220. "jQuery( function( $ ) {
  221. var wc_pointers = {$pointers};
  222. setTimeout( init_wc_pointers, 800 );
  223. function init_wc_pointers() {
  224. $.each( wc_pointers.pointers, function( i ) {
  225. show_wc_pointer( i );
  226. return false;
  227. });
  228. }
  229. function show_wc_pointer( id ) {
  230. var pointer = wc_pointers.pointers[ id ];
  231. var options = $.extend( pointer.options, {
  232. pointerClass: 'wp-pointer wc-pointer',
  233. close: function() {
  234. if ( pointer.next ) {
  235. show_wc_pointer( pointer.next );
  236. }
  237. },
  238. buttons: function( event, t ) {
  239. var close = '" . esc_js( __( 'Dismiss', 'woocommerce' ) ) . "',
  240. next = '" . esc_js( __( 'Next', 'woocommerce' ) ) . "',
  241. button = $( '<a class=\"close\" href=\"#\">' + close + '</a>' ),
  242. button2 = $( '<a class=\"button button-primary\" href=\"#\">' + next + '</a>' ),
  243. wrapper = $( '<div class=\"wc-pointer-buttons\" />' );
  244. button.bind( 'click.pointer', function(e) {
  245. e.preventDefault();
  246. t.element.pointer('destroy');
  247. });
  248. button2.bind( 'click.pointer', function(e) {
  249. e.preventDefault();
  250. t.element.pointer('close');
  251. });
  252. wrapper.append( button );
  253. wrapper.append( button2 );
  254. return wrapper;
  255. },
  256. } );
  257. var this_pointer = $( pointer.target ).pointer( options );
  258. this_pointer.pointer( 'open' );
  259. if ( pointer.next_trigger ) {
  260. $( pointer.next_trigger.target ).on( pointer.next_trigger.event, function() {
  261. setTimeout( function() { this_pointer.pointer( 'close' ); }, 400 );
  262. });
  263. }
  264. }
  265. });"
  266. );
  267. }
  268. }
  269. new WC_Admin_Pointers();