| @@ -22,33 +22,272 @@ | ||
| 22 | 22 | if ( !defined( 'ABSPATH' ) ) { |
| 23 | 23 | exit; |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | +// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 27 | + | |
| 26 | 28 | /** |
| 27 | 29 | * Capability OPM |
| 28 | 30 | */ |
| 29 | 31 | class Groups_Capability { |
| 30 | 32 | |
| 31 | - const CACHE_GROUP = 'groups'; | |
| 33 | + /** | |
| 34 | + * @var string cache group | |
| 35 | + */ | |
| 36 | + const CACHE_GROUP = 'groups'; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * @var string key | |
| 40 | + * | |
| 41 | + * @deprecated since 4.3.0 | |
| 42 | + */ | |
| 32 | 43 | const READ_BY_CAPABILITY = 'read_by_capability'; |
| 33 | 44 | |
| 34 | 45 | /** |
| 35 | - * @var persisted capability object | |
| 46 | + * @var string key | |
| 47 | + * | |
| 48 | + * @deprecated since 4.3.0 | |
| 36 | 49 | */ |
| 37 | - var $capability = null; | |
| 50 | + const READ_CAPABILITY_BY_ID = 'read_capability_by_id'; | |
| 38 | 51 | |
| 39 | 52 | /** |
| 53 | + * @var string key | |
| 54 | + */ | |
| 55 | + const ID_MAP = 'map_capability_by_id'; | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * @var string key | |
| 59 | + */ | |
| 60 | + const NAME_MAP = 'map_capability_by_name'; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Lock timeout in microseconds. | |
| 64 | + * | |
| 65 | + * @var int | |
| 66 | + */ | |
| 67 | + const LOCK_TIMEOUT = 30000000; | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Lock name. | |
| 71 | + * | |
| 72 | + * @var string | |
| 73 | + */ | |
| 74 | + const LOCK = 'groups_capability_lock'; | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Mutex lock. | |
| 78 | + * | |
| 79 | + * @var Groups_Lock | |
| 80 | + */ | |
| 81 | + private static $lock = null; | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * @var object persisted capability object | |
| 85 | + * | |
| 86 | + * @access private - do not access this property directly, the visibility will be made private in the future | |
| 87 | + */ | |
| 88 | + public $capability = null; | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * Lock object. | |
| 92 | + * | |
| 93 | + * @throws Groups_Lock_Exception | |
| 94 | + * | |
| 95 | + * @return Groups_Lock | |
| 96 | + */ | |
| 97 | + private static function get_lock() { | |
| 98 | + $lock = null; | |
| 99 | + if ( self::$lock !== null ) { | |
| 100 | + $lock = self::$lock; | |
| 101 | + } else { | |
| 102 | + $timeout = apply_filters( 'groups_capability_lock_timeout', self::LOCK_TIMEOUT ); | |
| 103 | + if ( is_numeric( $timeout ) ) { | |
| 104 | + $timeout = max( 0, intval( $timeout ) ); | |
| 105 | + } else { | |
| 106 | + $timeout = null; | |
| 107 | + } | |
| 108 | + $lock = new Groups_Lock( self::LOCK, $timeout ); | |
| 109 | + self::$lock = $lock; | |
| 110 | + } | |
| 111 | + return $lock; | |
| 112 | + } | |
| 113 | + | |
| 114 | + /** | |
| 115 | + * Mutex locked. | |
| 116 | + * | |
| 117 | + * @return boolean | |
| 118 | + */ | |
| 119 | + private static function is_locked() { | |
| 120 | + return self::$lock !== null && self::$lock->is_locked(); | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Mutex reader. | |
| 125 | + * | |
| 126 | + * @return boolean | |
| 127 | + */ | |
| 128 | + private static function reader() { | |
| 129 | + $locked = false; | |
| 130 | + try { | |
| 131 | + $lock = self::get_lock(); | |
| 132 | + $locked = $lock->reader(); | |
| 133 | + } catch ( Groups_Lock_Exception $lex ) { | |
| 134 | + if ( defined( 'GROUPS_DEBUG' ) && GROUPS_DEBUG ) { | |
| 135 | + Groups_Log::log( | |
| 136 | + sprintf( | |
| 137 | + 'Capability read lock fail [%s] [%s]', | |
| 138 | + self::LOCK, | |
| 139 | + $lex->getMessage() | |
| 140 | + ) | |
| 141 | + ); | |
| 142 | + } | |
| 143 | + } | |
| 144 | + return $locked; | |
| 145 | + } | |
| 146 | + | |
| 147 | + /** | |
| 148 | + * Mutex writer. | |
| 149 | + * | |
| 150 | + * @return boolean | |
| 151 | + */ | |
| 152 | + private static function writer() { | |
| 153 | + $locked = false; | |
| 154 | + try { | |
| 155 | + $lock = self::get_lock(); | |
| 156 | + $locked = $lock->writer(); | |
| 157 | + } catch ( Groups_Lock_Exception $lex ) { | |
| 158 | + if ( defined( 'GROUPS_DEBUG' ) && GROUPS_DEBUG ) { | |
| 159 | + Groups_Log::log( | |
| 160 | + sprintf( | |
| 161 | + 'Capability write lock fail [%s] [%s]', | |
| 162 | + self::LOCK, | |
| 163 | + $lex->getMessage() | |
| 164 | + ) | |
| 165 | + ); | |
| 166 | + } | |
| 167 | + } | |
| 168 | + return $locked; | |
| 169 | + } | |
| 170 | + | |
| 171 | + /** | |
| 172 | + * Mutex release. | |
| 173 | + * | |
| 174 | + * @return boolean | |
| 175 | + */ | |
| 176 | + private static function release() { | |
| 177 | + $released = false; | |
| 178 | + if ( self::$lock !== null ) { | |
| 179 | + $released = self::$lock->release(); | |
| 180 | + } | |
| 181 | + return $released; | |
| 182 | + } | |
| 183 | + | |
| 184 | + /** | |
| 40 | 185 | * Create by capability id. |
| 186 | + * | |
| 41 | 187 | * Must have been persisted. |
| 188 | + * | |
| 42 | 189 | * @param int $capability_id |
| 43 | 190 | */ |
| 44 | 191 | public function __construct( $capability_id ) { |
| 45 | 192 | $this->capability = self::read( $capability_id ); |
| 193 | + if ( $this->capability === false ) { | |
| 194 | + $this->capability = null; | |
| 195 | + } | |
| 46 | 196 | } |
| 47 | 197 | |
| 48 | 198 | /** |
| 199 | + * Provides the object ID. | |
| 200 | + * | |
| 201 | + * @return int | |
| 202 | + */ | |
| 203 | + public function get_id() { | |
| 204 | + return $this->get_capability_id(); | |
| 205 | + } | |
| 206 | + | |
| 207 | + /** | |
| 208 | + * Provides the object ID. | |
| 209 | + * | |
| 210 | + * @return int | |
| 211 | + */ | |
| 212 | + public function get_capability_id() { | |
| 213 | + return $this->capability_id; // @phpstan-ignore property.notFound | |
| 214 | + } | |
| 215 | + | |
| 216 | + /** | |
| 217 | + * Provides the literal capability. | |
| 218 | + * | |
| 219 | + * @return string | |
| 220 | + */ | |
| 221 | + public function get_capability() { | |
| 222 | + $capability = ''; | |
| 223 | + if ( | |
| 224 | + $this->capability !== null && | |
| 225 | + is_object( $this->capability ) && | |
| 226 | + !empty( $this->capability->capability ) | |
| 227 | + ) { | |
| 228 | + $capability = $this->capability->capability; | |
| 229 | + } | |
| 230 | + return $capability; | |
| 231 | + } | |
| 232 | + | |
| 233 | + /** | |
| 234 | + * Provides the capability's class. | |
| 235 | + * | |
| 236 | + * @return string | |
| 237 | + */ | |
| 238 | + public function get_class() { | |
| 239 | + return $this->class; // @phpstan-ignore property.notFound | |
| 240 | + } | |
| 241 | + | |
| 242 | + /** | |
| 243 | + * Provides the capability's object. | |
| 244 | + * | |
| 245 | + * @return string | |
| 246 | + */ | |
| 247 | + public function get_object() { | |
| 248 | + return $this->object; // @phpstan-ignore property.notFound | |
| 249 | + } | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * Provides the capability's name. | |
| 253 | + * | |
| 254 | + * @return string | |
| 255 | + */ | |
| 256 | + public function get_name() { | |
| 257 | + return $this->name; // @phpstan-ignore property.notFound | |
| 258 | + } | |
| 259 | + | |
| 260 | + /** | |
| 261 | + * Provides the capability's description. | |
| 262 | + * | |
| 263 | + * @return string | |
| 264 | + */ | |
| 265 | + public function get_description() { | |
| 266 | + return $this->description; // @phpstan-ignore property.notFound | |
| 267 | + } | |
| 268 | + | |
| 269 | + /** | |
| 270 | + * Provides the IDs of groups that have the capability. | |
| 271 | + * | |
| 272 | + * @return int[] | |
| 273 | + */ | |
| 274 | + public function get_group_ids(){ | |
| 275 | + return $this->group_ids; // @phpstan-ignore property.notFound | |
| 276 | + } | |
| 277 | + | |
| 278 | + /** | |
| 279 | + * Provides the groups that have the capability. | |
| 280 | + * | |
| 281 | + * @return Groups_Group[] | |
| 282 | + */ | |
| 283 | + public function get_groups() { | |
| 284 | + return $this->groups; // @phpstan-ignore property.notFound | |
| 285 | + } | |
| 286 | + | |
| 287 | + /** | |
| 49 | 288 | * Retrieve a property by name. |
| 50 | - * | |
| 289 | + * | |
| 51 | 290 | * Possible properties: |
| 52 | 291 | * - capability_id |
| 53 | 292 | * - capability |
| 54 | 293 | * - class |
| @@ -54,13 +293,14 @@ | ||
| 54 | 293 | * - class |
| 55 | 294 | * - object |
| 56 | 295 | * - name |
| 57 | 296 | * - description |
| 58 | - * | |
| 297 | + * | |
| 59 | 298 | * - group_ids groups that have the capability |
| 60 | - * | |
| 299 | + * | |
| 61 | 300 | * @param string $name property's name |
| 62 | - * @return property value, will return null if property does not exist | |
| 301 | + * | |
| 302 | + * @return mixed property value, will return null if property does not exist | |
| 63 | 303 | */ |
| 64 | 304 | public function __get( $name ) { |
| 65 | 305 | |
| 66 | 306 | global $wpdb; |
| @@ -66,39 +306,39 @@ | ||
| 66 | 306 | global $wpdb; |
| 67 | 307 | |
| 68 | 308 | $result = null; |
| 69 | 309 | if ( $this->capability !== null ) { |
| 70 | - switch( $name ) { | |
| 71 | - case "capability_id" : | |
| 72 | - case "capability" : | |
| 73 | - case "class" : | |
| 74 | - case "object" : | |
| 75 | - case "name" : | |
| 76 | - case "description" : | |
| 310 | + switch ( $name ) { | |
| 311 | + case 'capability_id' : | |
| 312 | + case 'capability' : | |
| 313 | + case 'class' : | |
| 314 | + case 'object' : | |
| 315 | + case 'name' : | |
| 316 | + case 'description' : | |
| 77 | 317 | $result = $this->capability->$name; |
| 78 | 318 | break; |
| 79 | 319 | case 'group_ids' : |
| 80 | - $group_capability_table = _groups_get_tablename( "group_capability" ); | |
| 320 | + $group_capability_table = _groups_get_tablename( 'group_capability' ); | |
| 81 | 321 | $rows = $wpdb->get_results( $wpdb->prepare( |
| 82 | - "SELECT group_id FROM $group_capability_table WHERE capability_id = %d", | |
| 322 | + "SELECT group_id FROM $group_capability_table WHERE capability_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 83 | 323 | Groups_Utility::id( $this->capability->capability_id ) |
| 84 | 324 | ) ); |
| 85 | 325 | if ( $rows ) { |
| 86 | 326 | $result = array(); |
| 87 | - foreach( $rows as $row ) { | |
| 327 | + foreach ( $rows as $row ) { | |
| 88 | 328 | $result[] = $row->group_id; |
| 89 | 329 | } |
| 90 | 330 | } |
| 91 | 331 | break; |
| 92 | 332 | case 'groups' : |
| 93 | - $group_capability_table = _groups_get_tablename( "group_capability" ); | |
| 333 | + $group_capability_table = _groups_get_tablename( 'group_capability' ); | |
| 94 | 334 | $rows = $wpdb->get_results( $wpdb->prepare( |
| 95 | - "SELECT group_id FROM $group_capability_table WHERE capability_id = %d", | |
| 335 | + "SELECT group_id FROM $group_capability_table WHERE capability_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 96 | 336 | Groups_Utility::id( $this->capability->capability_id ) |
| 97 | 337 | ) ); |
| 98 | 338 | if ( $rows ) { |
| 99 | 339 | $result = array(); |
| 100 | - foreach( $rows as $row ) { | |
| 340 | + foreach ( $rows as $row ) { | |
| 101 | 341 | $result[] = new Groups_Group( $row->group_id ); |
| 102 | 342 | } |
| 103 | 343 | } |
| 104 | 344 | break; |
| @@ -108,35 +348,42 @@ | ||
| 108 | 348 | } |
| 109 | 349 | |
| 110 | 350 | /** |
| 111 | 351 | * Persist a capability. |
| 112 | - * | |
| 352 | + * | |
| 113 | 353 | * Possible keys in $map: |
| 114 | - * | |
| 354 | + * | |
| 115 | 355 | * - "capability" (required) - unique capability label, max 20 characters |
| 116 | 356 | * - "class" (optional) - class the capability applies to, max 100 chars |
| 117 | 357 | * - "object" (optional) - identifies object of that class, max 100 chars |
| 118 | 358 | * - "name" (optional) - name it if you have to |
| 119 | 359 | * - "description" (optional) - dito |
| 120 | - * | |
| 360 | + * | |
| 121 | 361 | * @param array $map attributes, requires at least: "capability" |
| 122 | - * @return capability_id on success, otherwise false | |
| 362 | + * | |
| 363 | + * @return int capability_id on success, otherwise false | |
| 123 | 364 | */ |
| 124 | 365 | public static function create( $map ) { |
| 125 | 366 | |
| 126 | 367 | global $wpdb; |
| 127 | - extract( $map ); | |
| 368 | + | |
| 128 | 369 | $result = false; |
| 129 | 370 | |
| 371 | + $capability = isset( $map['capability'] ) ? $map['capability'] : null; | |
| 372 | + $class = isset( $map['class'] ) ? $map['class'] : null; | |
| 373 | + $object = isset( $map['object'] ) ? $map['object'] : null; | |
| 374 | + $name = isset( $map['name'] ) ? $map['name'] : null; | |
| 375 | + $description = isset( $map['description'] ) ? $map['description'] : null; | |
| 376 | + | |
| 130 | 377 | if ( !empty( $capability ) ) { |
| 131 | 378 | |
| 379 | + self::writer(); | |
| 380 | + | |
| 132 | 381 | if ( self::read_by_capability( $capability ) === false ) { |
| 133 | - | |
| 134 | 382 | $data = array( |
| 135 | 383 | 'capability' => $capability |
| 136 | 384 | ); |
| 137 | 385 | $formats = array( '%s' ); |
| 138 | - | |
| 139 | 386 | if ( !empty( $class ) ) { |
| 140 | 387 | $data['class'] = $class; |
| 141 | 388 | $formats[] = '%s'; |
| 142 | 389 | } |
| @@ -154,14 +401,21 @@ | ||
| 154 | 401 | } |
| 155 | 402 | $capability_table = _groups_get_tablename( 'capability' ); |
| 156 | 403 | if ( $wpdb->insert( $capability_table, $data, $formats ) ) { |
| 157 | 404 | if ( $result = $wpdb->get_var( "SELECT LAST_INSERT_ID()" ) ) { |
| 158 | - // read_by_capability above created a cache entry which needs to be reset | |
| 159 | - Groups_Cache::delete( self::READ_BY_CAPABILITY . '_' . $capability, self::CACHE_GROUP ); | |
| 160 | - do_action( "groups_created_capability", $result ); | |
| 405 | + // refresh cache | |
| 406 | + Groups_Cache::delete( self::ID_MAP, self::CACHE_GROUP ); | |
| 407 | + Groups_Cache::delete( self::NAME_MAP, self::CACHE_GROUP ); | |
| 161 | 408 | } |
| 162 | 409 | } |
| 163 | 410 | } |
| 411 | + | |
| 412 | + self::release(); | |
| 413 | + | |
| 414 | + if ( $result !== false ) { | |
| 415 | + do_action( 'groups_created_capability', $result ); | |
| 416 | + } | |
| 417 | + | |
| 164 | 418 | } |
| 165 | 419 | return $result; |
| 166 | 420 | } |
| 167 | 421 | |
| @@ -166,92 +420,150 @@ | ||
| 166 | 420 | } |
| 167 | 421 | |
| 168 | 422 | /** |
| 169 | 423 | * Retrieve a capability. |
| 170 | - * | |
| 171 | - * Use Groups_Capability::read_capability() if you are trying to retrieve a capability by its unique label. | |
| 172 | - * | |
| 424 | + * | |
| 425 | + * Use Groups_Capability::read_by_capability() if you are trying to retrieve a capability by its name. | |
| 426 | + * | |
| 173 | 427 | * @see Groups_Capability::read_by_capability() |
| 174 | 428 | * @param int $capability_id capability's id |
| 429 | + * | |
| 175 | 430 | * @return object upon success, otherwise false |
| 176 | 431 | */ |
| 177 | 432 | public static function read( $capability_id ) { |
| 178 | 433 | global $wpdb; |
| 434 | + | |
| 435 | + $capability_id = Groups_Utility::id( $capability_id ); | |
| 436 | + if ( $capability_id === false || $capability_id === 0 ) { | |
| 437 | + return false; | |
| 438 | + } | |
| 439 | + | |
| 179 | 440 | $result = false; |
| 180 | - $capability_table = _groups_get_tablename( 'capability' ); | |
| 181 | - $capability = $wpdb->get_row( $wpdb->prepare( | |
| 182 | - "SELECT * FROM $capability_table WHERE capability_id = %d", | |
| 183 | - Groups_Utility::id( $capability_id ) | |
| 184 | - ) ); | |
| 185 | - if ( isset( $capability->capability_id ) ) { | |
| 186 | - $result = $capability; | |
| 441 | + | |
| 442 | + $is_locked = self::is_locked(); | |
| 443 | + if ( !$is_locked ) { | |
| 444 | + self::writer(); | |
| 187 | 445 | } |
| 446 | + | |
| 447 | + $cached = Groups_Cache::get( self::ID_MAP, self::CACHE_GROUP ); | |
| 448 | + if ( $cached !== null ) { | |
| 449 | + $map = $cached->get_value(); | |
| 450 | + $result = $map[$capability_id] ?? false; | |
| 451 | + } else { | |
| 452 | + $map = array(); | |
| 453 | + $name_map = array(); | |
| 454 | + $capability_table = _groups_get_tablename( 'capability' ); | |
| 455 | + $capabilities = $wpdb->get_results( "SELECT * FROM $capability_table" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 456 | + if ( is_array( $capabilities ) ) { | |
| 457 | + foreach ( $capabilities as $capability ) { | |
| 458 | + $map[$capability->capability_id] = $capability; // numerical key is automatically cast to int | |
| 459 | + $name_map[$capability->capability] = $capability; | |
| 460 | + } | |
| 461 | + } | |
| 462 | + if ( isset( $map[$capability_id] ) ) { | |
| 463 | + $result = $map[$capability_id]; | |
| 464 | + } | |
| 465 | + Groups_Cache::set( self::ID_MAP, $map, self::CACHE_GROUP ); | |
| 466 | + Groups_Cache::set( self::NAME_MAP, $name_map, self::CACHE_GROUP ); | |
| 467 | + } | |
| 468 | + | |
| 469 | + if ( !$is_locked ) { | |
| 470 | + self::release(); | |
| 471 | + } | |
| 472 | + | |
| 188 | 473 | return $result; |
| 189 | 474 | } |
| 190 | 475 | |
| 191 | 476 | /** |
| 192 | - * Retrieve a capability by its unique label. | |
| 193 | - * | |
| 194 | - * @param string $capability capability's unique label | |
| 477 | + * Retrieve a capability by its name. | |
| 478 | + * | |
| 479 | + * @param string $name capability name | |
| 480 | + * | |
| 195 | 481 | * @return object upon success, otherwise false |
| 196 | 482 | */ |
| 197 | - public static function read_by_capability( $capability ) { | |
| 483 | + public static function read_by_capability( $name ) { | |
| 198 | 484 | global $wpdb; |
| 199 | - $_capability = $capability; | |
| 200 | - $cached = Groups_Cache::get( self::READ_BY_CAPABILITY . '_' . $_capability, self::CACHE_GROUP ); | |
| 485 | + | |
| 486 | + $result = false; | |
| 487 | + | |
| 488 | + $is_locked = self::is_locked(); | |
| 489 | + if ( !$is_locked ) { | |
| 490 | + self::writer(); | |
| 491 | + } | |
| 492 | + | |
| 493 | + $cached = Groups_Cache::get( self::NAME_MAP, self::CACHE_GROUP ); | |
| 201 | 494 | if ( $cached !== null ) { |
| 202 | - $result = $cached->value; | |
| 203 | - unset( $cached ); | |
| 495 | + $name_map = $cached->get_value(); | |
| 496 | + $result = $name_map[$name] ?? false; | |
| 204 | 497 | } else { |
| 205 | - $result = false; | |
| 498 | + $map = array(); | |
| 499 | + $name_map = array(); | |
| 206 | 500 | $capability_table = _groups_get_tablename( 'capability' ); |
| 207 | - $capability = $wpdb->get_row( $wpdb->prepare( | |
| 208 | - "SELECT * FROM $capability_table WHERE capability = %s", | |
| 209 | - $capability | |
| 210 | - ) ); | |
| 211 | - if ( isset( $capability->capability_id ) ) { | |
| 212 | - $result = $capability; | |
| 501 | + $capabilities = $wpdb->get_results( "SELECT * FROM $capability_table" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 502 | + if ( is_array( $capabilities ) ) { | |
| 503 | + foreach ( $capabilities as $capability ) { | |
| 504 | + $map[$capability->capability_id] = $capability; // numerical key is automatically cast to int | |
| 505 | + $name_map[$capability->capability] = $capability; | |
| 506 | + } | |
| 213 | 507 | } |
| 214 | - Groups_Cache::set( self::READ_BY_CAPABILITY . '_' . $_capability, $result, self::CACHE_GROUP ); | |
| 508 | + if ( isset( $name_map[$name] ) ) { | |
| 509 | + $result = $name_map[$name]; | |
| 510 | + } | |
| 511 | + Groups_Cache::set( self::ID_MAP, $map, self::CACHE_GROUP ); | |
| 512 | + Groups_Cache::set( self::NAME_MAP, $name_map, self::CACHE_GROUP ); | |
| 215 | 513 | } |
| 514 | + | |
| 515 | + if ( !$is_locked ) { | |
| 516 | + self::release(); | |
| 517 | + } | |
| 518 | + | |
| 216 | 519 | return $result; |
| 217 | 520 | } |
| 218 | 521 | |
| 219 | 522 | /** |
| 220 | 523 | * Update capability. |
| 221 | - * | |
| 524 | + * | |
| 222 | 525 | * @param array $map capability attribute, must contain capability_id |
| 223 | - * @return capability_id on success, otherwise false | |
| 526 | + * | |
| 527 | + * @return int capability_id on success, otherwise false | |
| 224 | 528 | */ |
| 225 | 529 | public static function update( $map ) { |
| 226 | 530 | |
| 227 | 531 | global $wpdb; |
| 228 | - extract( $map ); | |
| 532 | + | |
| 229 | 533 | $result = false; |
| 230 | 534 | |
| 231 | - if ( isset( $capability_id ) && !empty( $capability ) ) { | |
| 535 | + $capability_id = isset( $map['capability_id'] ) ? $map['capability_id'] : null; | |
| 536 | + $capability = isset( $map['capability'] ) ? $map['capability'] : null; | |
| 537 | + $class = isset( $map['class'] ) ? $map['class'] : null; | |
| 538 | + $object = isset( $map['object'] ) ? $map['object'] : null; | |
| 539 | + $name = isset( $map['name'] ) ? $map['name'] : null; | |
| 540 | + $description = isset( $map['description'] ) ? $map['description'] : null; | |
| 541 | + | |
| 542 | + if ( $capability_id !== null ) { | |
| 543 | + | |
| 544 | + self::writer(); | |
| 545 | + | |
| 232 | 546 | $capability_table = _groups_get_tablename( 'capability' ); |
| 233 | 547 | $old_capability = Groups_Capability::read( $capability_id ); |
| 234 | 548 | if ( $old_capability ) { |
| 235 | - if ( isset( $capability ) ) { | |
| 236 | - $old_capability_capability = $old_capability->capability; | |
| 549 | + if ( $capability !== null ) { | |
| 237 | 550 | $old_capability->capability = $capability; |
| 238 | 551 | } |
| 239 | - if ( isset( $class ) ) { | |
| 552 | + if ( $class !== null ) { | |
| 240 | 553 | $old_capability->class = $class; |
| 241 | 554 | } |
| 242 | - if ( isset( $object ) ) { | |
| 555 | + if ( $object !== null ) { | |
| 243 | 556 | $old_capability->object = $object; |
| 244 | 557 | } |
| 245 | - if ( isset( $name ) ) { | |
| 246 | - $old_name = $old_capability->name; | |
| 558 | + if ( $name !== null ) { | |
| 247 | 559 | $old_capability->name = $name; |
| 248 | 560 | } |
| 249 | - if ( isset( $description ) ) { | |
| 561 | + if ( $description !== null ) { | |
| 250 | 562 | $old_capability->description = $description; |
| 251 | 563 | } |
| 252 | 564 | $rows = $wpdb->query( $wpdb->prepare( |
| 253 | - "UPDATE $capability_table SET capability = %s, class = %s, object = %s, name = %s, description = %s WHERE capability_id = %d", | |
| 565 | + "UPDATE $capability_table SET capability = %s, class = %s, object = %s, name = %s, description = %s WHERE capability_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 254 | 566 | $old_capability->capability, |
| 255 | 567 | $old_capability->class, |
| 256 | 568 | $old_capability->object, |
| 257 | 569 | $old_capability->name, |
| @@ -259,17 +571,19 @@ | ||
| 259 | 571 | Groups_Utility::id( $capability_id ) |
| 260 | 572 | ) ); |
| 261 | 573 | if ( ( $rows !== false ) ) { |
| 262 | 574 | $result = $capability_id; |
| 263 | - if ( !empty( $old_capability ) && !empty( $old_capability->capability ) ) { | |
| 264 | - Groups_Cache::delete( self::READ_BY_CAPABILITY . '_' . $old_capability->capability, self::CACHE_GROUP ); | |
| 265 | - } | |
| 266 | - if ( !empty( $old_capability_capability ) ) { | |
| 267 | - Groups_Cache::delete( self::READ_BY_CAPABILITY . '_' . $old_capability_capability, self::CACHE_GROUP ); | |
| 268 | - } | |
| 269 | - do_action( "groups_updated_capability", $result ); | |
| 575 | + Groups_Cache::delete( self::ID_MAP, self::CACHE_GROUP ); | |
| 576 | + Groups_Cache::delete( self::NAME_MAP, self::CACHE_GROUP ); | |
| 270 | 577 | } |
| 271 | 578 | } |
| 579 | + | |
| 580 | + self::release(); | |
| 581 | + | |
| 582 | + if ( $result !== false ) { | |
| 583 | + do_action( 'groups_updated_capability', $result ); | |
| 584 | + } | |
| 585 | + | |
| 272 | 586 | } |
| 273 | 587 | return $result; |
| 274 | 588 | } |
| 275 | 589 | |
| @@ -274,11 +588,12 @@ | ||
| 274 | 588 | } |
| 275 | 589 | |
| 276 | 590 | /** |
| 277 | 591 | * Remove capability and its relations. |
| 278 | - * | |
| 592 | + * | |
| 279 | 593 | * @param int $capability_id |
| 280 | - * @return capability_id if successful, false otherwise | |
| 594 | + * | |
| 595 | + * @return int capability_id if successful, false otherwise | |
| 281 | 596 | */ |
| 282 | 597 | public static function delete( $capability_id ) { |
| 283 | 598 | |
| 284 | 599 | global $wpdb; |
| @@ -283,23 +598,33 @@ | ||
| 283 | 598 | |
| 284 | 599 | global $wpdb; |
| 285 | 600 | $result = false; |
| 286 | 601 | |
| 602 | + self::writer(); | |
| 603 | + | |
| 287 | 604 | // avoid nonsense requests |
| 288 | 605 | if ( $capability = Groups_Capability::read( $capability_id ) ) { |
| 289 | 606 | $capability_table = _groups_get_tablename( 'capability' ); |
| 290 | 607 | // get rid of it |
| 291 | - if ( $rows = $wpdb->query( $wpdb->prepare( | |
| 292 | - "DELETE FROM $capability_table WHERE capability_id = %d", | |
| 608 | + $rows = $wpdb->query( $wpdb->prepare( | |
| 609 | + "DELETE FROM $capability_table WHERE capability_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 293 | 610 | Groups_Utility::id( $capability_id ) |
| 294 | - ) ) ) { | |
| 611 | + ) ); | |
| 612 | + if ( $rows !== false && $rows > 0 ) { | |
| 295 | 613 | $result = $capability_id; |
| 296 | 614 | if ( !empty( $capability->capability ) ) { |
| 297 | - Groups_Cache::delete( self::READ_BY_CAPABILITY . '_' . $capability->capability, self::CACHE_GROUP ); | |
| 298 | 615 | do_action( 'groups_deleted_capability_capability', $capability->capability ); |
| 299 | 616 | } |
| 300 | - do_action( "groups_deleted_capability", $result ); | |
| 617 | + Groups_Cache::delete( self::ID_MAP, self::CACHE_GROUP ); | |
| 618 | + Groups_Cache::delete( self::NAME_MAP, self::CACHE_GROUP ); | |
| 301 | 619 | } |
| 302 | 620 | } |
| 621 | + | |
| 622 | + self::release(); | |
| 623 | + | |
| 624 | + if ( $result !== false ) { | |
| 625 | + do_action( 'groups_deleted_capability', $result ); | |
| 626 | + } | |
| 627 | + | |
| 303 | 628 | return $result; |
| 304 | 629 | } |
| 305 | -} | |
| 630 | +} | |