prefix . 'convohub_leads'; } /** * Creates or upgrades the table when the stored schema version is behind. */ public static function maybe_install() { if ( get_option( self::DB_VERSION_OPTION ) === self::DB_VERSION ) { return; } global $wpdb; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $table = self::table(); $charset = $wpdb->get_charset_collate(); dbDelta( "CREATE TABLE {$table} ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, payload longtext NOT NULL, status varchar(10) NOT NULL DEFAULT 'queued', attempts smallint(5) unsigned NOT NULL DEFAULT 0, last_error text NULL, created_at datetime NOT NULL, updated_at datetime NOT NULL, PRIMARY KEY (id), KEY status (status) ) {$charset};" ); update_option( self::DB_VERSION_OPTION, self::DB_VERSION ); } /** * Drops the table. */ public static function uninstall() { global $wpdb; $table = self::table(); $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) ); delete_option( self::DB_VERSION_OPTION ); } /** * Stores a lead. * * @param array $lead Sanitized lead. * @param string $status Status. * @param int $attempts Delivery attempts so far. * @param string $error Last error message. * @return int New row ID. */ public static function insert( array $lead, $status, $attempts, $error ) { global $wpdb; $now = current_time( 'mysql', true ); $wpdb->insert( self::table(), array( 'payload' => wp_json_encode( $lead ), 'status' => $status, 'attempts' => $attempts, 'last_error' => $error, 'created_at' => $now, 'updated_at' => $now, ), array( '%s', '%s', '%d', '%s', '%s', '%s' ) ); return (int) $wpdb->insert_id; } /** * Fetches one row, with the payload decoded. * * @param int $id Row ID. * @return array|null */ public static function get( $id ) { global $wpdb; $table = self::table(); $row = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE id = %d', $table, $id ), ARRAY_A ); return $row ? self::decode( $row ) : null; } /** * Most recent rows, newest first. * * @param int $limit Maximum rows. * @return array */ public static function recent( $limit = 100 ) { global $wpdb; $table = self::table(); $rows = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id DESC LIMIT %d', $table, $limit ), ARRAY_A ); return array_map( array( __CLASS__, 'decode' ), (array) $rows ); } /** * Updates status, attempts and the last error of a row. * * @param int $id Row ID. * @param string $status Status. * @param int $attempts Attempts. * @param string $error Last error message. */ public static function update( $id, $status, $attempts, $error ) { global $wpdb; $wpdb->update( self::table(), array( 'status' => $status, 'attempts' => $attempts, 'last_error' => $error, 'updated_at' => current_time( 'mysql', true ), ), array( 'id' => $id ), array( '%s', '%d', '%s', '%s' ), array( '%d' ) ); } /** * Deletes a row. * * @param int $id Row ID. */ public static function delete( $id ) { global $wpdb; $wpdb->delete( self::table(), array( 'id' => $id ), array( '%d' ) ); } /** * Deletes rows not updated for a number of days. * * @param int $days Age in days. */ public static function purge_older_than( $days ) { global $wpdb; $table = self::table(); $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE updated_at < %s', $table, gmdate( 'Y-m-d H:i:s', time() - $days * DAY_IN_SECONDS ) ) ); } /** * Decodes the payload column. * * @param array $row Raw row. * @return array */ private static function decode( array $row ) { $row['id'] = (int) $row['id']; $row['attempts'] = (int) $row['attempts']; $row['lead'] = (array) json_decode( $row['payload'], true ); unset( $row['payload'] ); return $row; } }