PluginProbe
Code Snippets / 3.4.1
Code Snippets v3.4.1
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.4.1, at php/class-db.php

283 lines 7.5 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|mixed $network Network argument value.
66 *
67 * @return bool Sanitized value.
68 */
69 public static function validate_network_param( $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|mixed $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( $is_network ): 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 $checked[ $table_name ] = $wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) === $table_name; // cache pass, db call ok.
111 }
112
113 return $checked[ $table_name ];
114 }
115
116 /**
117 * Create the snippet tables if they do not already exist
118 */
119 public function create_missing_tables() {
120
121 // Create the network snippets table if it doesn't exist.
122 if ( is_multisite() && ! self::table_exists( $this->ms_table ) ) {
123 $this->create_table( $this->ms_table );
124 }
125
126 // Create the table if it doesn't exist.
127 if ( ! self::table_exists( $this->table ) ) {
128 $this->create_table( $this->table );
129 }
130 }
131
132 /**
133 * Create the snippet tables, or upgrade them if they already exist
134 */
135 public function create_or_upgrade_tables() {
136 if ( is_multisite() ) {
137 $this->create_table( $this->ms_table );
138 }
139
140 $this->create_table( $this->table );
141 }
142
143 /**
144 * Create a snippet table if it does not already exist
145 *
146 * @param string $table_name Name of database table.
147 */
148 public static function create_missing_table( string $table_name ) {
149 if ( ! self::table_exists( $table_name ) ) {
150 self::create_table( $table_name );
151 }
152 }
153
154 /**
155 * Create a single snippet table.
156 *
157 * @param string $table_name The name of the table to create.
158 *
159 * @return bool Whether the table creation was successful.
160 * @since 1.6
161 * @uses dbDelta() to apply the SQL code
162 */
163 public static function create_table( string $table_name ): bool {
164 global $wpdb;
165 $charset_collate = $wpdb->get_charset_collate();
166
167 /* Create the database table */
168 $sql = "CREATE TABLE $table_name (
169 id BIGINT(20) NOT NULL AUTO_INCREMENT,
170 name TINYTEXT NOT NULL,
171 description TEXT NOT NULL,
172 code LONGTEXT NOT NULL,
173 tags LONGTEXT NOT NULL,
174 scope VARCHAR(15) NOT NULL DEFAULT 'global',
175 priority SMALLINT NOT NULL DEFAULT 10,
176 active TINYINT(1) NOT NULL DEFAULT 0,
177 modified DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
178 PRIMARY KEY (id),
179 KEY scope (scope),
180 KEY active (active)
181 ) $charset_collate;";
182
183 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
184 dbDelta( $sql );
185
186 $success = empty( $wpdb->last_error );
187
188 if ( $success ) {
189 do_action( 'code_snippets/create_table', $table_name );
190 }
191
192 return $success;
193 }
194
195 /**
196 * Fetch a list of active snippets from a database table.
197 *
198 * @param string $table_name Name of table to fetch snippets from.
199 * @param array<string> $scopes List of scopes to include in query.
200 * @param boolean $active_only Whether to only fetch active snippets from the table.
201 *
202 * @return array<string, array<string, mixed>>|false List of active snippets, if any could be retrieved.
203 *
204 * @phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
205 */
206 private static function fetch_snippets_from_table( string $table_name, array $scopes, bool $active_only = true ) {
207 global $wpdb;
208
209 $cache_key = sprintf( 'active_snippets_%s_%s', sanitize_key( join( '_', $scopes ) ), $table_name );
210 $cached_snippets = wp_cache_get( $cache_key, CACHE_GROUP );
211
212 if ( is_array( $cached_snippets ) ) {
213 return $cached_snippets;
214 }
215
216 if ( ! self::table_exists( $table_name ) ) {
217 return false;
218 }
219
220 $scopes_format = implode( ',', array_fill( 0, count( $scopes ), '%s' ) );
221 $extra_where = $active_only ? 'AND active=1' : '';
222
223 $snippets = $wpdb->get_results(
224 $wpdb->prepare(
225 "
226 SELECT id, code, scope, active
227 FROM $table_name
228 WHERE scope IN ($scopes_format) $extra_where
229 ORDER BY priority, id",
230 $scopes
231 ),
232 'ARRAY_A'
233 ); // db call ok.
234
235 // Cache the full list of snippets.
236 if ( is_array( $snippets ) ) {
237 wp_cache_set( $cache_key, $snippets, CACHE_GROUP );
238 return $snippets;
239 }
240
241 return false;
242 }
243
244 /**
245 * Generate the SQL for fetching active snippets from the database.
246 *
247 * @param array<string>|string $scopes List of scopes to retrieve in.
248 *
249 * @return array<string, array<string, mixed>> List of active snippets, indexed by table.
250 */
251 public function fetch_active_snippets( $scopes ): array {
252 $active_snippets = array();
253
254 // Ensure that the list of scopes is an array.
255 if ( ! is_array( $scopes ) ) {
256 $scopes = array( $scopes );
257 }
258
259 // Fetch the active snippets for the current site, if there are any.
260 $snippets = $this->fetch_snippets_from_table( $this->table, $scopes );
261 if ( $snippets ) {
262 $active_snippets[ $this->table ] = $snippets;
263 }
264
265 // If multisite is enabled, fetch all snippets from the network table, and filter down to only active snippets.
266 if ( is_multisite() ) {
267 $active_shared_ids = (array) get_option( 'active_shared_network_snippets', array() );
268 $ms_snippets = $this->fetch_snippets_from_table( $this->ms_table, $scopes, false );
269
270 if ( $ms_snippets ) {
271 $active_snippets[ $this->ms_table ] = array_filter(
272 $ms_snippets,
273 function ( $snippet ) use ( $active_shared_ids ) {
274 return $snippet['active'] || in_array( intval( $snippet['id'] ), $active_shared_ids, true );
275 }
276 );
277 }
278 }
279
280 return $active_snippets;
281 }
282 }
283