prefix . 'orderchirp_log'; } /** * Add a row. * * @param array $row channel, direction, recipient, event, chat_id, body, order_id, status, detail. * @return int Row id (0 on failure). */ public static function add( array $row ) { global $wpdb; $data = array( 'created_at' => gmdate( 'Y-m-d H:i:s' ), 'order_id' => isset( $row['order_id'] ) ? (int) $row['order_id'] : 0, 'channel' => isset( $row['channel'] ) ? substr( (string) $row['channel'], 0, 20 ) : 'telegram', 'direction' => isset( $row['direction'] ) && 'in' === $row['direction'] ? 'in' : 'out', 'recipient' => isset( $row['recipient'] ) ? substr( (string) $row['recipient'], 0, 10 ) : 'customer', 'event' => isset( $row['event'] ) ? substr( (string) $row['event'], 0, 40 ) : '', 'chat_id' => isset( $row['chat_id'] ) ? substr( (string) $row['chat_id'], 0, 32 ) : '', 'body' => isset( $row['body'] ) ? (string) $row['body'] : '', 'status' => isset( $row['status'] ) ? substr( (string) $row['status'], 0, 12 ) : 'queued', 'detail' => isset( $row['detail'] ) ? substr( (string) $row['detail'], 0, 255 ) : '', 'attempts' => 0, ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- own table. $ok = $wpdb->insert( self::table(), $data ); return $ok ? (int) $wpdb->insert_id : 0; } /** * One row. * * @param int $id Id. * @return array|null */ public static function get( $id ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table, must be fresh. $row = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE id = %d', self::table(), (int) $id ), ARRAY_A ); return is_array( $row ) ? $row : null; } /** * Record the outcome of an attempt. * * @param int $id Id. * @param string $status queued|sent|failed|skipped. * @param string $detail Detail. * @param bool $count_attempt Whether this was a send attempt. */ public static function update( $id, $status, $detail = '', $count_attempt = true ) { global $wpdb; $row = self::get( $id ); if ( ! $row ) { return; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table. $wpdb->update( self::table(), array( 'status' => substr( (string) $status, 0, 12 ), 'detail' => substr( (string) $detail, 0, 255 ), 'attempts' => (int) $row['attempts'] + ( $count_attempt ? 1 : 0 ), ), array( 'id' => (int) $id ) ); } /** * Newest rows for the Activity tab. * * @param int $limit Limit. * @return array> */ public static function recent( $limit = 100 ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table, admin screen. $rows = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC LIMIT %d', self::table(), max( 1, (int) $limit ) ), ARRAY_A ); return is_array( $rows ) ? $rows : array(); } /** * Rows of some orders (privacy export). * * @param int[] $order_ids Orders. * @return array> */ public static function for_orders( array $order_ids ) { global $wpdb; $order_ids = array_values( array_filter( array_map( 'intval', $order_ids ) ) ); if ( ! $order_ids ) { return array(); } $placeholders = implode( ',', array_fill( 0, count( $order_ids ), '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- own table; placeholders built from a count. $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE order_id IN ($placeholders) ORDER BY id", array_merge( array( self::table() ), $order_ids ) ), ARRAY_A ); return is_array( $rows ) ? $rows : array(); } /** * Remove the rows of some orders, or of one chat (privacy erasure, /stop). * * @param int[] $order_ids Orders. * @param string $chat_id Chat id ('' = none). * @return int Rows removed. */ public static function erase( array $order_ids, $chat_id = '' ) { global $wpdb; $removed = 0; foreach ( array_filter( array_map( 'intval', $order_ids ) ) as $order_id ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table. $removed += (int) $wpdb->delete( self::table(), array( 'order_id' => $order_id ) ); } if ( '' !== (string) $chat_id ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table. $removed += (int) $wpdb->delete( self::table(), array( 'chat_id' => (string) $chat_id ) ); } return $removed; } /** * Daily clean-up. */ public static function purge() { global $wpdb; $cutoff = gmdate( 'Y-m-d H:i:s', time() - self::KEEP_DAYS * DAY_IN_SECONDS ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- own table. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE created_at < %s', self::table(), $cutoff ) ); } }