Nenhuma Descrição

class-walker-comment.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. <?php
  2. /**
  3. * Comment API: Walker_Comment class
  4. *
  5. * @package WordPress
  6. * @subpackage Comments
  7. * @since 4.4.0
  8. */
  9. /**
  10. * Core walker class used to create an HTML list of comments.
  11. *
  12. * @since 2.7.0
  13. *
  14. * @see Walker
  15. */
  16. class Walker_Comment extends Walker {
  17. /**
  18. * What the class handles.
  19. *
  20. * @since 2.7.0
  21. * @var string
  22. *
  23. * @see Walker::$tree_type
  24. */
  25. public $tree_type = 'comment';
  26. /**
  27. * Database fields to use.
  28. *
  29. * @since 2.7.0
  30. * @var array
  31. *
  32. * @see Walker::$db_fields
  33. * @todo Decouple this
  34. */
  35. public $db_fields = array(
  36. 'parent' => 'comment_parent',
  37. 'id' => 'comment_ID',
  38. );
  39. /**
  40. * Starts the list before the elements are added.
  41. *
  42. * @since 2.7.0
  43. *
  44. * @see Walker::start_lvl()
  45. * @global int $comment_depth
  46. *
  47. * @param string $output Used to append additional content (passed by reference).
  48. * @param int $depth Optional. Depth of the current comment. Default 0.
  49. * @param array $args Optional. Uses 'style' argument for type of HTML list. Default empty array.
  50. */
  51. public function start_lvl( &$output, $depth = 0, $args = array() ) {
  52. $GLOBALS['comment_depth'] = $depth + 1;
  53. switch ( $args['style'] ) {
  54. case 'div':
  55. break;
  56. case 'ol':
  57. $output .= '<ol class="children">' . "\n";
  58. break;
  59. case 'ul':
  60. default:
  61. $output .= '<ul class="children">' . "\n";
  62. break;
  63. }
  64. }
  65. /**
  66. * Ends the list of items after the elements are added.
  67. *
  68. * @since 2.7.0
  69. *
  70. * @see Walker::end_lvl()
  71. * @global int $comment_depth
  72. *
  73. * @param string $output Used to append additional content (passed by reference).
  74. * @param int $depth Optional. Depth of the current comment. Default 0.
  75. * @param array $args Optional. Will only append content if style argument value is 'ol' or 'ul'.
  76. * Default empty array.
  77. */
  78. public function end_lvl( &$output, $depth = 0, $args = array() ) {
  79. $GLOBALS['comment_depth'] = $depth + 1;
  80. switch ( $args['style'] ) {
  81. case 'div':
  82. break;
  83. case 'ol':
  84. $output .= "</ol><!-- .children -->\n";
  85. break;
  86. case 'ul':
  87. default:
  88. $output .= "</ul><!-- .children -->\n";
  89. break;
  90. }
  91. }
  92. /**
  93. * Traverses elements to create list from elements.
  94. *
  95. * This function is designed to enhance Walker::display_element() to
  96. * display children of higher nesting levels than selected inline on
  97. * the highest depth level displayed. This prevents them being orphaned
  98. * at the end of the comment list.
  99. *
  100. * Example: max_depth = 2, with 5 levels of nested content.
  101. * 1
  102. * 1.1
  103. * 1.1.1
  104. * 1.1.1.1
  105. * 1.1.1.1.1
  106. * 1.1.2
  107. * 1.1.2.1
  108. * 2
  109. * 2.2
  110. *
  111. * @since 2.7.0
  112. *
  113. * @see Walker::display_element()
  114. * @see wp_list_comments()
  115. *
  116. * @param WP_Comment $element Comment data object.
  117. * @param array $children_elements List of elements to continue traversing. Passed by reference.
  118. * @param int $max_depth Max depth to traverse.
  119. * @param int $depth Depth of the current element.
  120. * @param array $args An array of arguments.
  121. * @param string $output Used to append additional content. Passed by reference.
  122. */
  123. public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
  124. if ( ! $element ) {
  125. return;
  126. }
  127. $id_field = $this->db_fields['id'];
  128. $id = $element->$id_field;
  129. parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
  130. /*
  131. * If at the max depth, and the current element still has children, loop over those
  132. * and display them at this level. This is to prevent them being orphaned to the end
  133. * of the list.
  134. */
  135. if ( $max_depth <= $depth + 1 && isset( $children_elements[ $id ] ) ) {
  136. foreach ( $children_elements[ $id ] as $child ) {
  137. $this->display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
  138. }
  139. unset( $children_elements[ $id ] );
  140. }
  141. }
  142. /**
  143. * Starts the element output.
  144. *
  145. * @since 2.7.0
  146. *
  147. * @see Walker::start_el()
  148. * @see wp_list_comments()
  149. * @global int $comment_depth
  150. * @global WP_Comment $comment Global comment object.
  151. *
  152. * @param string $output Used to append additional content. Passed by reference.
  153. * @param WP_Comment $comment Comment data object.
  154. * @param int $depth Optional. Depth of the current comment in reference to parents. Default 0.
  155. * @param array $args Optional. An array of arguments. Default empty array.
  156. * @param int $id Optional. ID of the current comment. Default 0 (unused).
  157. */
  158. public function start_el( &$output, $comment, $depth = 0, $args = array(), $id = 0 ) {
  159. $depth++;
  160. $GLOBALS['comment_depth'] = $depth;
  161. $GLOBALS['comment'] = $comment;
  162. if ( ! empty( $args['callback'] ) ) {
  163. ob_start();
  164. call_user_func( $args['callback'], $comment, $args, $depth );
  165. $output .= ob_get_clean();
  166. return;
  167. }
  168. if ( 'comment' === $comment->comment_type ) {
  169. add_filter( 'comment_text', array( $this, 'filter_comment_text' ), 40, 2 );
  170. }
  171. if ( ( 'pingback' === $comment->comment_type || 'trackback' === $comment->comment_type ) && $args['short_ping'] ) {
  172. ob_start();
  173. $this->ping( $comment, $depth, $args );
  174. $output .= ob_get_clean();
  175. } elseif ( 'html5' === $args['format'] ) {
  176. ob_start();
  177. $this->html5_comment( $comment, $depth, $args );
  178. $output .= ob_get_clean();
  179. } else {
  180. ob_start();
  181. $this->comment( $comment, $depth, $args );
  182. $output .= ob_get_clean();
  183. }
  184. if ( 'comment' === $comment->comment_type ) {
  185. remove_filter( 'comment_text', array( $this, 'filter_comment_text' ), 40 );
  186. }
  187. }
  188. /**
  189. * Ends the element output, if needed.
  190. *
  191. * @since 2.7.0
  192. *
  193. * @see Walker::end_el()
  194. * @see wp_list_comments()
  195. *
  196. * @param string $output Used to append additional content. Passed by reference.
  197. * @param WP_Comment $comment The current comment object. Default current comment.
  198. * @param int $depth Optional. Depth of the current comment. Default 0.
  199. * @param array $args Optional. An array of arguments. Default empty array.
  200. */
  201. public function end_el( &$output, $comment, $depth = 0, $args = array() ) {
  202. if ( ! empty( $args['end-callback'] ) ) {
  203. ob_start();
  204. call_user_func( $args['end-callback'], $comment, $args, $depth );
  205. $output .= ob_get_clean();
  206. return;
  207. }
  208. if ( 'div' === $args['style'] ) {
  209. $output .= "</div><!-- #comment-## -->\n";
  210. } else {
  211. $output .= "</li><!-- #comment-## -->\n";
  212. }
  213. }
  214. /**
  215. * Outputs a pingback comment.
  216. *
  217. * @since 3.6.0
  218. *
  219. * @see wp_list_comments()
  220. *
  221. * @param WP_Comment $comment The comment object.
  222. * @param int $depth Depth of the current comment.
  223. * @param array $args An array of arguments.
  224. */
  225. protected function ping( $comment, $depth, $args ) {
  226. $tag = ( 'div' === $args['style'] ) ? 'div' : 'li';
  227. ?>
  228. <<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( '', $comment ); ?>>
  229. <div class="comment-body">
  230. <?php _e( 'Pingback:' ); ?> <?php comment_author_link( $comment ); ?> <?php edit_comment_link( __( 'Edit' ), '<span class="edit-link">', '</span>' ); ?>
  231. </div>
  232. <?php
  233. }
  234. /**
  235. * Filters the comment text.
  236. *
  237. * Removes links from the pending comment's text if the commenter did not consent
  238. * to the comment cookies.
  239. *
  240. * @since 5.4.2
  241. *
  242. * @param string $comment_text Text of the current comment.
  243. * @param WP_Comment|null $comment The comment object. Null if not found.
  244. * @return string Filtered text of the current comment.
  245. */
  246. public function filter_comment_text( $comment_text, $comment ) {
  247. $commenter = wp_get_current_commenter();
  248. $show_pending_links = ! empty( $commenter['comment_author'] );
  249. if ( $comment && '0' == $comment->comment_approved && ! $show_pending_links ) {
  250. $comment_text = wp_kses( $comment_text, array() );
  251. }
  252. return $comment_text;
  253. }
  254. /**
  255. * Outputs a single comment.
  256. *
  257. * @since 3.6.0
  258. *
  259. * @see wp_list_comments()
  260. *
  261. * @param WP_Comment $comment Comment to display.
  262. * @param int $depth Depth of the current comment.
  263. * @param array $args An array of arguments.
  264. */
  265. protected function comment( $comment, $depth, $args ) {
  266. if ( 'div' === $args['style'] ) {
  267. $tag = 'div';
  268. $add_below = 'comment';
  269. } else {
  270. $tag = 'li';
  271. $add_below = 'div-comment';
  272. }
  273. $commenter = wp_get_current_commenter();
  274. $show_pending_links = isset( $commenter['comment_author'] ) && $commenter['comment_author'];
  275. if ( $commenter['comment_author_email'] ) {
  276. $moderation_note = __( 'Your comment is awaiting moderation.' );
  277. } else {
  278. $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' );
  279. }
  280. ?>
  281. <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?> id="comment-<?php comment_ID(); ?>">
  282. <?php if ( 'div' !== $args['style'] ) : ?>
  283. <div id="div-comment-<?php comment_ID(); ?>" class="comment-body">
  284. <?php endif; ?>
  285. <div class="comment-author vcard">
  286. <?php
  287. if ( 0 != $args['avatar_size'] ) {
  288. echo get_avatar( $comment, $args['avatar_size'] );
  289. }
  290. ?>
  291. <?php
  292. $comment_author = get_comment_author_link( $comment );
  293. if ( '0' == $comment->comment_approved && ! $show_pending_links ) {
  294. $comment_author = get_comment_author( $comment );
  295. }
  296. printf(
  297. /* translators: %s: Comment author link. */
  298. __( '%s <span class="says">says:</span>' ),
  299. sprintf( '<cite class="fn">%s</cite>', $comment_author )
  300. );
  301. ?>
  302. </div>
  303. <?php if ( '0' == $comment->comment_approved ) : ?>
  304. <em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em>
  305. <br />
  306. <?php endif; ?>
  307. <div class="comment-meta commentmetadata">
  308. <?php
  309. printf(
  310. '<a href="%s">%s</a>',
  311. esc_url( get_comment_link( $comment, $args ) ),
  312. sprintf(
  313. /* translators: 1: Comment date, 2: Comment time. */
  314. __( '%1$s at %2$s' ),
  315. get_comment_date( '', $comment ),
  316. get_comment_time()
  317. )
  318. );
  319. edit_comment_link( __( '(Edit)' ), ' &nbsp;&nbsp;', '' );
  320. ?>
  321. </div>
  322. <?php
  323. comment_text(
  324. $comment,
  325. array_merge(
  326. $args,
  327. array(
  328. 'add_below' => $add_below,
  329. 'depth' => $depth,
  330. 'max_depth' => $args['max_depth'],
  331. )
  332. )
  333. );
  334. ?>
  335. <?php
  336. comment_reply_link(
  337. array_merge(
  338. $args,
  339. array(
  340. 'add_below' => $add_below,
  341. 'depth' => $depth,
  342. 'max_depth' => $args['max_depth'],
  343. 'before' => '<div class="reply">',
  344. 'after' => '</div>',
  345. )
  346. )
  347. );
  348. ?>
  349. <?php if ( 'div' !== $args['style'] ) : ?>
  350. </div>
  351. <?php endif; ?>
  352. <?php
  353. }
  354. /**
  355. * Outputs a comment in the HTML5 format.
  356. *
  357. * @since 3.6.0
  358. *
  359. * @see wp_list_comments()
  360. *
  361. * @param WP_Comment $comment Comment to display.
  362. * @param int $depth Depth of the current comment.
  363. * @param array $args An array of arguments.
  364. */
  365. protected function html5_comment( $comment, $depth, $args ) {
  366. $tag = ( 'div' === $args['style'] ) ? 'div' : 'li';
  367. $commenter = wp_get_current_commenter();
  368. $show_pending_links = ! empty( $commenter['comment_author'] );
  369. if ( $commenter['comment_author_email'] ) {
  370. $moderation_note = __( 'Your comment is awaiting moderation.' );
  371. } else {
  372. $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' );
  373. }
  374. ?>
  375. <<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>>
  376. <article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
  377. <footer class="comment-meta">
  378. <div class="comment-author vcard">
  379. <?php
  380. if ( 0 != $args['avatar_size'] ) {
  381. echo get_avatar( $comment, $args['avatar_size'] );
  382. }
  383. ?>
  384. <?php
  385. $comment_author = get_comment_author_link( $comment );
  386. if ( '0' == $comment->comment_approved && ! $show_pending_links ) {
  387. $comment_author = get_comment_author( $comment );
  388. }
  389. printf(
  390. /* translators: %s: Comment author link. */
  391. __( '%s <span class="says">says:</span>' ),
  392. sprintf( '<b class="fn">%s</b>', $comment_author )
  393. );
  394. ?>
  395. </div><!-- .comment-author -->
  396. <div class="comment-metadata">
  397. <?php
  398. printf(
  399. '<a href="%s"><time datetime="%s">%s</time></a>',
  400. esc_url( get_comment_link( $comment, $args ) ),
  401. get_comment_time( 'c' ),
  402. sprintf(
  403. /* translators: 1: Comment date, 2: Comment time. */
  404. __( '%1$s at %2$s' ),
  405. get_comment_date( '', $comment ),
  406. get_comment_time()
  407. )
  408. );
  409. edit_comment_link( __( 'Edit' ), ' <span class="edit-link">', '</span>' );
  410. ?>
  411. </div><!-- .comment-metadata -->
  412. <?php if ( '0' == $comment->comment_approved ) : ?>
  413. <em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em>
  414. <?php endif; ?>
  415. </footer><!-- .comment-meta -->
  416. <div class="comment-content">
  417. <?php comment_text(); ?>
  418. </div><!-- .comment-content -->
  419. <?php
  420. if ( '1' == $comment->comment_approved || $show_pending_links ) {
  421. comment_reply_link(
  422. array_merge(
  423. $args,
  424. array(
  425. 'add_below' => 'div-comment',
  426. 'depth' => $depth,
  427. 'max_depth' => $args['max_depth'],
  428. 'before' => '<div class="reply">',
  429. 'after' => '</div>',
  430. )
  431. )
  432. );
  433. }
  434. ?>
  435. </article><!-- .comment-body -->
  436. <?php
  437. }
  438. }