rt( string $url ): string { $url = trailingslashit( $this->normalize_url( $url ) ); if ( mb_strlen( $url ) > 256 ) { throw new ApprovedDirectoriesException( __( 'Approved directory URLs cannot be longer than 256 characters.', 'woocommerce' ), ApprovedDirectoriesException::INVALID_URL ); } return $url; } /** * Normalizes the provided URL, by trimming whitespace per normal PHP conventions * and removing any trailing slashes. If it lacks a scheme, the file scheme is * assumed and prepended. * * @throws URLException If the URL is badly formed. * * @param string $url The URL to be normalized. * * @return string */ private function normalize_url( string $url ): string { $url = untrailingslashit( trim( $url ) ); return ( new URL( $url ) )->get_url(); } /** * Lists currently approved directories. * * Returned array will have the following structure: * * [ * 'total_urls' => 12345, * 'total_pages' => 123, * 'urls' => [], # StoredUrl[] * ] * * @param array $args { * Controls pagination and ordering. * * @type null|bool $enabled Controls if only enabled (true), disabled (false) or all rules (null) should be listed. * @type string $order Ordering ('ASC' for ascending, 'DESC' for descending). * @type string $order_by Field to order by (one of 'url_id' or 'url'). * @type int $page The page of results to retrieve. * @type int $per_page The number of results to retrieve per page. * @type string $search Term to search for. * } * * @return array */ public function list( array $args ): array { global $wpdb; $args = array_merge( array( 'enabled' => null, 'order' => 'ASC', 'order_by' => 'url', 'page' => 1, 'per_page' => 20, 'search' => '', ), $args ); $table = $this->get_table(); $paths = array(); $order = in_array( $args['order'], array( 'ASC', 'DESC' ), true ) ? $args['order'] : 'ASC'; $order_by = in_array( $args['order_by'], array( 'url_id', 'url' ), true ) ? $args['order_by'] : 'url'; $page = absint( $args['page'] ); $per_page = absint( $args['per_page'] ); $enabled = is_bool( $args['enabled'] ) ? $args['enabled'] : null; $search = '%' . $wpdb->esc_like( sanitize_text_field( $args['search'] ) ) . '%'; if ( $page < 1 ) { $page = 1; } if ( $per_page < 1 ) { $per_page = 1; } $where = array(); $where_sql = ''; if ( ! empty( $search ) ) { $where[] = $wpdb->prepare( 'url LIKE %s', $search ); } if ( is_bool( $enabled ) ) { $where[] = 'enabled = ' . (int) $enabled; } if ( ! empty( $where ) ) { $where_sql = 'WHERE ' . join( ' AND ', $where ); } // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $results = $wpdb->get_results( $wpdb->prepare( " SELECT url_id, url, enabled FROM {$table} {$where_sql} ORDER BY {$order_by} {$order} LIMIT %d, %d ", ( $page - 1 ) * $per_page, $per_page ) ); $total_rows = (int) $wpdb->get_var( "SELECT COUNT( * ) FROM {$table} {$where_sql}" ); // phpcs:enable foreach ( $results as $single_result ) { $paths[] = new StoredUrl( $single_result->url_id, $single_result->url, $single_result->enabled ); } return array( 'total_urls' => $total_rows, 'total_pages' => (int) ceil( $total_rows / $per_page ), 'approved_directories' => $paths, ); } /** * Delete the approved directory identitied by the supplied ID. * * @param int $id The ID of the rule to be deleted. * * @return bool */ public function delete_by_id( int $id ): bool { global $wpdb; $table = $this->get_table(); return (bool) $wpdb->delete( $table, array( 'url_id' => $id ) ); } /** * Delete the entirev approved directory list. * * @return bool */ public function delete_all(): bool { global $wpdb; $table = $this->get_table(); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared return (bool) $wpdb->query( "DELETE FROM $table" ); } /** * Enable the approved directory identitied by the supplied ID. * * @param int $id The ID of the rule to be deleted. * * @return bool */ public function enable_by_id( int $id ): bool { global $wpdb; $table = $this->get_table(); return (bool) $wpdb->update( $table, array( 'enabled' => 1 ), array( 'url_id' => $id ) ); } /** * Disable the approved directory identitied by the supplied ID. * * @param int $id The ID of the rule to be deleted. * * @return bool */ public function disable_by_id( int $id ): bool { global $wpdb; $table = $this->get_table(); return (bool) $wpdb->update( $table, array( 'enabled' => 0 ), array( 'url_id' => $id ) ); } /** * Enables all Approved Download Directory rules in a single operation. * * @return bool */ public function enable_all(): bool { global $wpdb; $table = $this->get_table(); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared return (bool) $wpdb->query( "UPDATE {$table} SET enabled = 1" ); } /** * Disables all Approved Download Directory rules in a single operation. * * @return bool */ public function disable_all(): bool { global $wpdb; $table = $this->get_table(); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared return (bool) $wpdb->query( "UPDATE {$table} SET enabled = 0" ); } /** * Indicates the number of approved directories that are enabled (or disabled, if optional * param $enabled is set to false). * * @param bool $enabled Controls whether enabled or disabled directory rules are counted. * * @return int */ public function count( bool $enabled = true ): int { global $wpdb; $table = $this->get_table(); return (int) $wpdb->get_var( $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared "SELECT COUNT(*) FROM {$table} WHERE enabled = %d", $enabled ? 1 : 0 ) ); } }