WPInv_Notes::get_invoice_notes()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 18
rs 9.9666
cc 2
nc 2
nop 2
1
<?php
2
/**
3
 * Notes class.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Handles invoice notes.
11
 *
12
 */
13
class WPInv_Notes {
14
15
	/**
16
	 * Class constructor.
17
	 */
18
	public function __construct() {
19
20
		// Filter inovice notes.
21
		add_action( 'pre_get_comments', array( $this, 'set_invoice_note_type' ), 11, 1 );
22
		add_action( 'comment_feed_where', array( $this, 'wpinv_comment_feed_where' ), 10, 1 );
23
24
		// Delete comments count cache whenever there is a new comment or a comment status changes.
25
		add_action( 'wp_insert_comment', array( $this, 'delete_comments_count_cache' ) );
26
		add_action( 'wp_set_comment_status', array( $this, 'delete_comments_count_cache' ) );
27
28
		// Count comments.
29
		add_filter( 'wp_count_comments', array( $this, 'wp_count_comments' ), 100, 2 );
30
31
		// Fires after notes are loaded.
32
		do_action( 'wpinv_notes_init', $this );
33
	}
34
35
	/**
36
	 * Filters invoice notes query to only include our notes.
37
	 *
38
	 * @param WP_Comment_Query $query
39
	 */
40
	public function set_invoice_note_type( $query ) {
41
		$post_id = ! empty( $query->query_vars['post_ID'] ) ? $query->query_vars['post_ID'] : $query->query_vars['post_id'];
42
43
		if ( $post_id && getpaid_is_invoice_post_type( get_post_type( $post_id ) ) ) {
44
			$query->query_vars['type'] = 'wpinv_note';
45
		} else {
46
47
			if ( empty( $query->query_vars['type__not_in'] ) ) {
48
				$query->query_vars['type__not_in'] = array();
49
			}
50
51
			$query->query_vars['type__not_in'] = wpinv_parse_list( $query->query_vars['type__not_in'] );
52
			$query->query_vars['type__not_in'] = array_merge( array( 'wpinv_note' ), $query->query_vars['type__not_in'] );
53
		}
54
55
		return $query;
56
	}
57
58
	/**
59
	 * Exclude notes from the comments feed.
60
	 */
61
	function wpinv_comment_feed_where( $where ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
62
		return $where . ( $where ? ' AND ' : '' ) . " comment_type != 'wpinv_note' ";
63
	}
64
65
	/**
66
	 * Delete comments count cache whenever there is
67
	 * new comment or the status of a comment changes. Cache
68
	 * will be regenerated next time WPInv_Notes::wp_count_comments()
69
	 * is called.
70
	 */
71
	public function delete_comments_count_cache() {
72
		delete_transient( 'getpaid_count_comments' );
73
	}
74
75
	/**
76
	 * Remove invoice notes from wp_count_comments().
77
	 *
78
	 * @since  2.2
79
	 * @param  object $stats   Comment stats.
80
	 * @param  int    $post_id Post ID.
81
	 * @return object
82
	 */
83
	public function wp_count_comments( $stats, $post_id ) {
84
		global $wpdb;
85
86
		if ( empty( $post_id ) ) {
87
			$stats = get_transient( 'getpaid_count_comments' );
88
89
			if ( ! $stats ) {
90
				$stats = array(
91
					'total_comments' => 0,
92
					'all'            => 0,
93
				);
94
95
				$count = $wpdb->get_results(
96
					"
97
					SELECT comment_approved, COUNT(*) AS num_comments
98
					FROM {$wpdb->comments}
99
					WHERE comment_type NOT IN ('action_log', 'order_note', 'webhook_delivery', 'wpinv_note')
100
					GROUP BY comment_approved
101
					",
102
					ARRAY_A
103
				);
104
105
				$approved = array(
106
					'0'            => 'moderated',
107
					'1'            => 'approved',
108
					'spam'         => 'spam',
109
					'trash'        => 'trash',
110
					'post-trashed' => 'post-trashed',
111
				);
112
113
				foreach ( (array) $count as $row ) {
114
					// Don't count post-trashed toward totals.
115
					if ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash', 'spam' ), true ) ) {
116
						$stats['all']            += $row['num_comments'];
117
						$stats['total_comments'] += $row['num_comments'];
118
					} elseif ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash' ), true ) ) {
119
						$stats['total_comments'] += $row['num_comments'];
120
					}
121
					if ( isset( $approved[ $row['comment_approved'] ] ) ) {
122
						$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
123
					}
124
				}
125
126
				foreach ( $approved as $key ) {
127
					if ( empty( $stats[ $key ] ) ) {
128
						$stats[ $key ] = 0;
129
					}
130
				}
131
132
				$stats = (object) $stats;
133
				set_transient( 'getpaid_count_comments', $stats );
134
			}
135
}
136
137
		return $stats;
138
	}
139
140
	/**
141
	 * Returns an array of invoice notes.
142
	 *
143
	 * @param int $invoice_id The invoice ID whose notes to retrieve.
144
	 * @param string $type Optional. Pass in customer to only return customer notes.
145
	 * @return WP_Comment[]
146
	 */
147
	public function get_invoice_notes( $invoice_id = 0, $type = 'all' ) {
148
149
		// Default comment args.
150
		$args = array(
151
			'post_id' => $invoice_id,
152
			'orderby' => 'comment_ID',
153
			'order'   => 'ASC',
154
		);
155
156
		// Maybe only show customer comments.
157
		if ( $type == 'customer' ) {
158
			$args['meta_key']   = '_wpi_customer_note';
159
			$args['meta_value'] = 1;
160
		}
161
162
		$args = apply_filters( 'wpinv_invoice_notes_args', $args, $this, $invoice_id, $type );
163
164
		return get_comments( $args );
0 ignored issues
show
Bug Best Practice introduced by
The expression return get_comments($args) returns the type integer which is incompatible with the documented return type WP_Comment[].
Loading history...
165
	}
166
167
	/**
168
	 * Saves an invoice comment.
169
	 *
170
	 * @param WPInv_Invoice $invoice The invoice to add the comment to.
171
	 * @param string $note The note content.
172
	 * @param string $note_author The name of the author of the note.
173
	 * @param bool $for_customer Whether or not this comment is meant to be sent to the customer.
174
	 * @return int|false The new note's ID on success, false on failure.
175
	 */
176
	function add_invoice_note( $invoice, $note, $note_author, $author_email, $for_customer = false ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
177
178
		do_action( 'wpinv_pre_insert_invoice_note', $invoice->get_id(), $note, $for_customer );
179
180
		/**
181
		 * Insert the comment.
182
		 */
183
		$note_id = wp_insert_comment(
184
			wp_filter_comment(
185
				array(
186
					'comment_post_ID'      => $invoice->get_id(),
187
					'comment_content'      => $note,
188
					'comment_agent'        => 'Invoicing',
189
					'user_id'              => get_current_user_id(),
190
					'comment_author'       => $note_author,
191
					'comment_author_IP'    => wpinv_get_ip(),
192
					'comment_author_email' => $author_email,
193
					'comment_author_url'   => $invoice->get_view_url(),
194
					'comment_type'         => 'wpinv_note',
195
				)
196
			)
197
		);
198
199
		do_action( 'wpinv_insert_payment_note', $note_id, $invoice->get_id(), $note, $for_customer );
200
201
		// Are we notifying the customer?
202
		if ( empty( $note_id ) || empty( $for_customer ) ) {
203
			return $note_id;
204
		}
205
206
		add_comment_meta( $note_id, '_wpi_customer_note', 1 );
207
		do_action(
208
            'wpinv_new_customer_note',
209
            array(
210
				'invoice_id' => $invoice->get_id(),
211
				'user_note'  => $note,
212
            )
213
        );
214
		do_action( 'getpaid_new_customer_note', $invoice, $note );
215
		return $note_id;
216
	}
217
218
}
219