← All changes
|
includes/admin/tickets/class-wpsc-individual-ticket.php
+64
-36
3.4.8
→
3.5.4
View file →
| @@ -253,9 +253,9 @@ | ||
| 253 | 253 | $auth_code = isset( $_REQUEST['auth-code'] ) ? sanitize_text_field( $_REQUEST['auth-code'] ) : ''; // phpcs:ignore |
| 254 | 254 | if ( ! $auth_code ) { |
| 255 | 255 | $auth_code = isset( $_REQUEST['auth_code'] ) ? sanitize_text_field( $_REQUEST['auth_code'] ) : ''; // phpcs:ignore |
| 256 | 256 | } |
| 257 | - if ( $auth_code && $ticket->auth_code == $auth_code ) { | |
| 257 | + if ( $auth_code && $ticket->auth_code && hash_equals( (string) $ticket->auth_code, $auth_code ) ) { | |
| 258 | 258 | self::$url_auth = true; |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | 261 | // Set view profile as 'customer' if the user is either a valid logged-in customer or a guest with a valid auth code. |
| @@ -1188,29 +1188,10 @@ | ||
| 1188 | 1188 | </div> |
| 1189 | 1189 | |
| 1190 | 1190 | <script> |
| 1191 | 1191 | |
| 1192 | - jQuery(document).find('.thread-text').each(function(){ | |
| 1193 | - var height = parseInt(jQuery(this).height()); | |
| 1194 | - <?php | |
| 1195 | - $advanced = get_option( 'wpsc-ms-advanced-settings', array() ); | |
| 1196 | - if ( $advanced['view-more'] ) { | |
| 1197 | - ?> | |
| 1198 | - if( height > 100){ | |
| 1199 | - jQuery(this).height(100); | |
| 1200 | - jQuery(this).parent().find('.wpsc-ticket-thread-expander').text(supportcandy.translations.view_more); | |
| 1201 | - jQuery(this).parent().find('.wpsc-ticket-thread-expander').show(); | |
| 1202 | - } | |
| 1203 | - <?php | |
| 1204 | - } else { | |
| 1205 | - ?> | |
| 1206 | - jQuery(this).parent().find('.thread-text').height('auto'); | |
| 1207 | - <?php | |
| 1208 | - } | |
| 1209 | - ?> | |
| 1192 | + wpsc_init_thread_expanders(jQuery(document).find('.thread-text')); | |
| 1210 | 1193 | |
| 1211 | - }); | |
| 1212 | - | |
| 1213 | 1194 | supportcandy.threads = {last_thread: <?php echo esc_attr( $last_id ); ?>} |
| 1214 | 1195 | </script> |
| 1215 | 1196 | <?php |
| 1216 | 1197 | |
| @@ -1331,9 +1312,9 @@ | ||
| 1331 | 1312 | ?> |
| 1332 | 1313 | |
| 1333 | 1314 | </div> |
| 1334 | 1315 | |
| 1335 | - <div class="thread-text"> | |
| 1316 | + <div class="thread-text<?php echo $advanced['view-more'] ? ' wpsc-collapsed' : ''; ?>"> | |
| 1336 | 1317 | <?php |
| 1337 | 1318 | if ( $thread->is_active ) { |
| 1338 | 1319 | echo wp_kses_post( $thread->body ); |
| 1339 | 1320 | } else { |
| @@ -1697,10 +1678,10 @@ | ||
| 1697 | 1678 | $validated_attachments = array(); |
| 1698 | 1679 | foreach ( $attachments as $id ) { |
| 1699 | 1680 | |
| 1700 | 1681 | $attachment = new WPSC_Attachment( $id ); |
| 1701 | - if ( ! $attachment->id || | |
| 1702 | - ( $attachment->ticket_id && $attachment->is_active ) ) { | |
| 1682 | + // Only the uploader may bind their own, not-yet-bound attachment. | |
| 1683 | + if ( ! WPSC_Attachment::can_claim( $attachment ) ) { | |
| 1703 | 1684 | continue; |
| 1704 | 1685 | } |
| 1705 | 1686 | |
| 1706 | 1687 | $validated_attachments[] = $id; |
| @@ -1732,11 +1713,18 @@ | ||
| 1732 | 1713 | $attachment->save(); |
| 1733 | 1714 | endforeach; |
| 1734 | 1715 | |
| 1735 | 1716 | // activate description editor img attachments. |
| 1736 | - if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(&auth_code=[^&\s]*)?/', $description, $matches ) ) { | |
| 1737 | - foreach ( $matches[1] as $id ) { | |
| 1738 | - $attachment = new WPSC_Attachment( $id ); | |
| 1717 | + if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(?:&auth_code=[^&\s"\']*)?(?:&(?:amp;)?wpsc_nonce=([a-f0-9]*))?/', $description, $matches ) ) { | |
| 1718 | + foreach ( $matches[1] as $key => $id ) { | |
| 1719 | + $attachment = new WPSC_Attachment( $id ); | |
| 1720 | + // Only the uploader may bind their own, not-yet-bound | |
| 1721 | + // attachment, proven by the recorded uploader identity or | |
| 1722 | + // by the per-attachment nonce carried in the image url. | |
| 1723 | + $nonce = isset( $matches[2][ $key ] ) ? $matches[2][ $key ] : ''; | |
| 1724 | + if ( ! WPSC_Attachment::can_claim( $attachment, $nonce ) ) { | |
| 1725 | + continue; | |
| 1726 | + } | |
| 1739 | 1727 | $attachment->is_active = 1; |
| 1740 | 1728 | $attachment->source_id = $thread->id; |
| 1741 | 1729 | $attachment->ticket_id = self::$ticket->id; |
| 1742 | 1730 | $attachment->source = 'img_editor'; |
| @@ -1814,10 +1802,10 @@ | ||
| 1814 | 1802 | $validated_attachments = array(); |
| 1815 | 1803 | foreach ( $attachments as $id ) { |
| 1816 | 1804 | |
| 1817 | 1805 | $attachment = new WPSC_Attachment( $id ); |
| 1818 | - if ( ! $attachment->id || | |
| 1819 | - ( $attachment->ticket_id && $attachment->is_active ) ) { | |
| 1806 | + // Only the uploader may bind their own, not-yet-bound attachment. | |
| 1807 | + if ( ! WPSC_Attachment::can_claim( $attachment ) ) { | |
| 1820 | 1808 | continue; |
| 1821 | 1809 | } |
| 1822 | 1810 | |
| 1823 | 1811 | $validated_attachments[] = $id; |
| @@ -1849,11 +1837,18 @@ | ||
| 1849 | 1837 | $attachment->save(); |
| 1850 | 1838 | endforeach; |
| 1851 | 1839 | |
| 1852 | 1840 | // activate description editor img attachments. |
| 1853 | - if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(&auth_code=[^&\s]*)?/', $description, $matches ) ) { | |
| 1854 | - foreach ( $matches[1] as $id ) { | |
| 1855 | - $attachment = new WPSC_Attachment( $id ); | |
| 1841 | + if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(?:&auth_code=[^&\s"\']*)?(?:&(?:amp;)?wpsc_nonce=([a-f0-9]*))?/', $description, $matches ) ) { | |
| 1842 | + foreach ( $matches[1] as $key => $id ) { | |
| 1843 | + $attachment = new WPSC_Attachment( $id ); | |
| 1844 | + // Only the uploader may bind their own, not-yet-bound | |
| 1845 | + // attachment, proven by the recorded uploader identity or | |
| 1846 | + // by the per-attachment nonce carried in the image url. | |
| 1847 | + $nonce = isset( $matches[2][ $key ] ) ? $matches[2][ $key ] : ''; | |
| 1848 | + if ( ! WPSC_Attachment::can_claim( $attachment, $nonce ) ) { | |
| 1849 | + continue; | |
| 1850 | + } | |
| 1856 | 1851 | $attachment->is_active = 1; |
| 1857 | 1852 | $attachment->source_id = $thread->id; |
| 1858 | 1853 | $attachment->ticket_id = self::$ticket->id; |
| 1859 | 1854 | $attachment->source = 'img_editor'; |
| @@ -1974,9 +1969,21 @@ | ||
| 1974 | 1969 | } |
| 1975 | 1970 | |
| 1976 | 1971 | // description attachments. |
| 1977 | 1972 | $attachments = isset( $_POST['description_attachments'] ) ? array_filter( array_map( 'intval', $_POST['description_attachments'] ) ) : array(); |
| 1973 | + $validated_attachments = array(); | |
| 1974 | + foreach ( $attachments as $id ) { | |
| 1978 | 1975 | |
| 1976 | + $attachment = new WPSC_Attachment( $id ); | |
| 1977 | + // Only the uploader may bind their own, not-yet-bound attachment. | |
| 1978 | + if ( ! WPSC_Attachment::can_claim( $attachment ) ) { | |
| 1979 | + continue; | |
| 1980 | + } | |
| 1981 | + | |
| 1982 | + $validated_attachments[] = $id; | |
| 1983 | + } | |
| 1984 | + $attachments = $validated_attachments; | |
| 1985 | + | |
| 1979 | 1986 | // submit reply. |
| 1980 | 1987 | $thread = WPSC_Thread::insert( |
| 1981 | 1988 | array( |
| 1982 | 1989 | 'ticket' => self::$ticket->id, |
| @@ -2001,11 +2008,18 @@ | ||
| 2001 | 2008 | $attachment->save(); |
| 2002 | 2009 | endforeach; |
| 2003 | 2010 | |
| 2004 | 2011 | // activate description editor img attachments. |
| 2005 | - if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(&auth_code=[^&\s]*)?/', $description, $matches ) ) { | |
| 2006 | - foreach ( $matches[1] as $id ) { | |
| 2007 | - $attachment = new WPSC_Attachment( $id ); | |
| 2012 | + if ( preg_match_all( '/' . preg_quote( home_url( '/' ), '/' ) . '\?wpsc_attachment=(\d*)(?:&auth_code=[^&\s"\']*)?(?:&(?:amp;)?wpsc_nonce=([a-f0-9]*))?/', $description, $matches ) ) { | |
| 2013 | + foreach ( $matches[1] as $key => $id ) { | |
| 2014 | + $attachment = new WPSC_Attachment( $id ); | |
| 2015 | + // Only the uploader may bind their own, not-yet-bound | |
| 2016 | + // attachment, proven by the recorded uploader identity or | |
| 2017 | + // by the per-attachment nonce carried in the image url. | |
| 2018 | + $nonce = isset( $matches[2][ $key ] ) ? $matches[2][ $key ] : ''; | |
| 2019 | + if ( ! WPSC_Attachment::can_claim( $attachment, $nonce ) ) { | |
| 2020 | + continue; | |
| 2021 | + } | |
| 2008 | 2022 | $attachment->is_active = 1; |
| 2009 | 2023 | $attachment->source_id = $thread->id; |
| 2010 | 2024 | $attachment->ticket_id = self::$ticket->id; |
| 2011 | 2025 | $attachment->source = 'img_editor'; |
| @@ -3032,8 +3046,14 @@ | ||
| 3032 | 3046 | ) { |
| 3033 | 3047 | continue; |
| 3034 | 3048 | } |
| 3035 | 3049 | |
| 3050 | + // Already part of this ticket, otherwise only the uploader may | |
| 3051 | + // bind a not-yet-bound attachment to it. | |
| 3052 | + if ( ! $attachment->ticket_id && ! WPSC_Attachment::can_claim( $attachment ) ) { | |
| 3053 | + continue; | |
| 3054 | + } | |
| 3055 | + | |
| 3036 | 3056 | $validated_attachments[] = $id; |
| 3037 | 3057 | } |
| 3038 | 3058 | $thread_attachments = $validated_attachments; |
| 3039 | 3059 | |
| @@ -3061,9 +3081,15 @@ | ||
| 3061 | 3081 | |
| 3062 | 3082 | foreach ( $matches[1] as $id ) { |
| 3063 | 3083 | |
| 3064 | 3084 | $attachment = new WPSC_Attachment( $id ); |
| 3065 | - if ( $attachment->is_active ) { | |
| 3085 | + // is_active is not an ownership test: a deleted thread | |
| 3086 | + // clears it while leaving ticket_id in place. Bind only | |
| 3087 | + // what already belongs to this ticket, or what the | |
| 3088 | + // requester uploaded and nothing owns yet. | |
| 3089 | + if ( ! $attachment->id || | |
| 3090 | + ( $attachment->ticket_id && $attachment->ticket_id != self::$ticket->id ) || | |
| 3091 | + ( ! $attachment->ticket_id && ! WPSC_Attachment::can_claim( $attachment ) ) ) { | |
| 3066 | 3092 | continue; |
| 3067 | 3093 | } |
| 3068 | 3094 | |
| 3069 | 3095 | $attachment->is_active = 1; |
| @@ -3586,8 +3612,10 @@ | ||
| 3586 | 3612 | $thread_types['val'][] = 'log'; |
| 3587 | 3613 | } |
| 3588 | 3614 | |
| 3589 | 3615 | $filters['meta_query'][] = $thread_types; |
| 3616 | + | |
| 3617 | + $filters = apply_filters( 'wpsc_it_load_older_threads_filters', $filters ); | |
| 3590 | 3618 | |
| 3591 | 3619 | $response = WPSC_Thread::find( $filters ); |
| 3592 | 3620 | $last_id = $response['results'][ count( $response['results'] ) - 1 ]->id; |
| 3593 | 3621 | |