PluginProbe
Code Snippets / 3.6.3
Code Snippets v3.6.3
3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 3.0.1 All 64 releases
code-snippets / php / class-db.php

class-db.php in Code Snippets 3.6.3, at php/class-db.php

287 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Code_Snippets;
4
5 /**
6 * Functions used to manage the database tables.
7 *
8 * @package Code_Snippets
9 */
10 class DB {
11
12 /**
13 * Unprefixed site-wide table name.
14 */
15 const TABLE_NAME = 'snippets';
16
17 /**
18 * Unprefixed network-wide table name.
19 */
20 const MS_TABLE_NAME = 'ms_snippets';
21
22 /**
23 * Side-wide table name.
24 *
25 * @var string
26 */
27 public $table;
28
29 /**
30 * Network-wide table name.
31 *
32 * @var string
33 */
34 public $ms_table;
35
36 /**
37 * Class constructor.
38 */
39 public function __construct() {
40 $this->set_table_vars();
41 }
42
43 /**
44 * Register the snippet table names with WordPress.
45 *
46 * @since 2.0
47 */
48 public function set_table_vars() {
49 global $wpdb;
50
51 $this->table = $wpdb->prefix . self::TABLE_NAME;
52 $this->ms_table = $wpdb->base_prefix . self::MS_TABLE_NAME;
53
54 // Register the snippet table names with WordPress.
55 $wpdb->snippets = $this->table;
56 $wpdb->ms_snippets = $this->ms_table;
57
58 $wpdb->tables[] = self::TABLE_NAME;
59 $wpdb->ms_global_tables[] = self::MS_TABLE_NAME;
60 }
61
62 /**
63 * Validate a provided 'network' or 'multisite' param, converting it to a boolean.
64 *
65 * @param bool|null $network Network argument value.
66 *
67 * @return bool Sanitized value.
68 */
69 public static function validate_network_param( ?bool $network = null ): bool {
70
71 // If multisite is not active, then assume the value is false.
72 if ( ! is_multisite() ) {
73 return false;
74 }
75
76 // If $multisite is null, try to base it on the current admin page.
77 if ( is_null( $network ) && function_exists( 'is_network_admin' ) ) {
78 return is_network_admin();
79 }
80
81 return (bool) $network;
82 }
83
84 /**
85 * Return the appropriate snippet table name
86 *
87 * @param bool|null $is_network Whether retrieve the multisite table name (true) or the site table name (false).
88 *
89 * @return string The snippet table name
90 * @since 2.0
91 */
92 public function get_table_name( ?bool $is_network = null ): string {
93 $is_network = is_bool( $is_network ) ? $is_network : self::validate_network_param( $is_network );
94 return $is_network ? $this->ms_table : $this->table;
95 }
96
97 /**
98 * Determine whether a database table exists.
99 *
100 * @param string $table_name Name of database table to check.
101 * @param boolean $refresh Rerun the query, instead of using a cached value.
102 *
103 * @return bool Whether the database table exists.
104 */
105 public static function table_exists( string $table_name, bool $refresh = false ): bool {
106 global $wpdb;
107 static $checked = array();
108
109 if ( $refresh || ! isset( $checked[ $table_name ] ) ) {
110 // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching, caching is handled through $checked variable.
111 $result = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) ) );
112 $checked[ $table_name ] = $result === $table_name;
113 }
114
115 return $checked[ $table_name ];
116 }
117
118 /**
119 * Create the snippet tables if they do not already exist
120 */
121 public function create_missing_tables() {
122
123 // Create the network snippets table if it doesn't exist.
124 if ( is_multisite() && ! self::table_exists( $this->ms_table ) ) {
125 $this->create_table( $this->ms_table );
126 }
127
128 // Create the table if it doesn't exist.
129 if ( ! self::table_exists( $this->table ) ) {
130 $this->create_table( $this->table );
131 }
132 }
133
134 /**
135 * Create the snippet tables, or upgrade them if they already exist
136 */
137 public function create_or_upgrade_tables() {
138 if ( is_multisite() ) {
139 $this->create_table( $this->ms_table );
140 }
141
142 $this->create_table( $this->table );
143 }
144
145 /**
146 * Create a snippet table if it does not already exist
147 *
148 * @param string $table_name Name of database table.
149 */
150 public static function create_missing_table( string $table_name ) {
151 if ( ! self::table_exists( $table_name ) ) {
152 self::create_table( $table_name );
153 }
154 }
155
156 /**
157 * Create a single snippet table.
158 *
159 * @param string $table_name The name of the table to create.
160 *
161 * @return bool Whether the table creation was successful.
162 * @since 1.6
163 * @uses dbDelta() to apply the SQL code
164 */
165 public static function create_table( string $table_name ): bool {
166 global $wpdb;
167 $charset_collate = $wpdb->get_charset_collate();
168
169 /* Create the database table */
170 $sql = "CREATE TABLE $table_name (
171 id BIGINT(20) NOT NULL AUTO_INCREMENT,
172 name TINYTEXT NOT NULL,
173 description TEXT NOT NULL,
174 code LONGTEXT NOT NULL,
175 tags LONGTEXT NOT NULL,
176 scope VARCHAR(15) NOT NULL DEFAULT 'global',
177 priority SMALLINT NOT NULL DEFAULT 10,
178 active TINYINT(1) NOT NULL DEFAULT 0,
179 modified DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
180 revision BIGINT(20) NOT NULL DEFAULT 1,
181 cloud_id VARCHAR(255) NULL,
182 PRIMARY KEY (id),
183 KEY scope (scope),
184 KEY active (active)
185 ) $charset_collate;";
186
187 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
188 dbDelta( $sql );
189
190 $success = empty( $wpdb->last_error );
191
192 if ( $success ) {
193 do_action( 'code_snippets/create_table', $table_name );
194 }
195
196 return $success;
197 }
198
199 /**
200 * Fetch a list of active snippets from a database table.
201 *
202 * @param string $table_name Name of table to fetch snippets from.
203 * @param array<string> $scopes List of scopes to include in query.
204 * @param boolean $active_only Whether to only fetch active snippets from the table.
205 *
206 * @return array<string, array<string, mixed>>|false List of active snippets, if any could be retrieved.
207 *
208 * @phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
209 */
210 private static function fetch_snippets_from_table( string $table_name, array $scopes, bool $active_only = true ) {
211 global $wpdb;
212
213 $cache_key = sprintf( 'active_snippets_%s_%s', sanitize_key( join( '_', $scopes ) ), $table_name );
214 $cached_snippets = wp_cache_get( $cache_key, CACHE_GROUP );
215
216 if ( is_array( $cached_snippets ) ) {
217 return $cached_snippets;
218 }
219
220 if ( ! self::table_exists( $table_name ) ) {
221 return false;
222 }
223
224 $scopes_format = implode( ',', array_fill( 0, count( $scopes ), '%s' ) );
225 $extra_where = $active_only ? 'AND active=1' : '';
226
227 $snippets = $wpdb->get_results(
228 $wpdb->prepare(
229 "
230 SELECT id, code, scope, active
231 FROM $table_name
232 WHERE scope IN ($scopes_format) $extra_where
233 ORDER BY priority, id",
234 $scopes
235 ),
236 'ARRAY_A'
237 );
238
239 // Cache the full list of snippets.
240 if ( is_array( $snippets ) ) {
241 wp_cache_set( $cache_key, $snippets, CACHE_GROUP );
242 return $snippets;
243 }
244
245 return false;
246 }
247
248 /**
249 * Generate the SQL for fetching active snippets from the database.
250 *
251 * @param array<string>|string $scopes List of scopes to retrieve in.
252 *
253 * @return array<string, array<string, mixed>> List of active snippets, indexed by table.
254 */
255 public function fetch_active_snippets( $scopes ): array {
256 $active_snippets = array();
257
258 // Ensure that the list of scopes is an array.
259 if ( ! is_array( $scopes ) ) {
260 $scopes = array( $scopes );
261 }
262
263 // Fetch the active snippets for the current site, if there are any.
264 $snippets = $this->fetch_snippets_from_table( $this->table, $scopes );
265 if ( $snippets ) {
266 $active_snippets[ $this->table ] = $snippets;
267 }
268
269 // If multisite is enabled, fetch all snippets from the network table, and filter down to only active snippets.
270 if ( is_multisite() ) {
271 $active_shared_ids = (array) get_option( 'active_shared_network_snippets', array() );
272 $ms_snippets = $this->fetch_snippets_from_table( $this->ms_table, $scopes, false );
273
274 if ( $ms_snippets ) {
275 $active_snippets[ $this->ms_table ] = array_filter(
276 $ms_snippets,
277 function ( $snippet ) use ( $active_shared_ids ) {
278 return $snippet['active'] || in_array( intval( $snippet['id'] ), $active_shared_ids, true );
279 }
280 );
281 }
282 }
283
284 return $active_snippets;
285 }
286 }
287