/** * Drops all keys from the database and cache for a single tree for ALL USERS ON * THE SITE. Generally used when uninstalling or upgrading an API. * * @version 1.0 * @since 1.0 * * @param int $tree | ID of the tree * @return bool | False on failure. True on success. */ public function dropSiteTree($tree) { global $rad; $db = new FOX_db(); if (empty($tree)) { throw new FOX_exception(array('numeric' => 1, 'text' => "Empty tree", 'data' => array("tree" => $tree), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } $args = array(array("col" => "tree", "op" => "=", "val" => $tree)); try { $rows_changed = $db->runDeleteQuery(self::$struct, $args, $ctrl = null); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error while deleting from database", 'data' => array("tree" => $tree), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Since this operation affects *all* user_id's, we have to flush the cache try { $cache_ok = self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Cache flush error", 'data' => array("tree" => $tree), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($cache_ok) { return $rows_changed; } }
/** * Deletes an entire tree of keys * * @version 1.0 * @since 1.0 * * @param string $tree | The tree name * @return bool | False on failure. True on success. */ public function dropTree($tree) { global $fox; $db = new FOX_db(); // Fetch the key_id's for all matching keys from the db $args = array(array("col" => "tree", "op" => "=", "val" => $tree)); $columns = array("mode" => "include", "col" => array("key_id")); $ctrl = array("format" => "col"); try { $drop_ids = $db->runSelectQuery(self::$struct, $args, $columns, $ctrl); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "DB select exception", 'data' => array("args" => $args, "columns" => $columns, "ctrl" => $ctrl), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // @@@@@@ BEGIN TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ try { $started_transaction = $db->beginTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "beginTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($started_transaction) { $args = array(array("col" => "key_id", "op" => "=", "val" => $drop_ids)); try { $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // TODO: // 1) drop the keys from the user keystore // 2) purge the dropped keys from the user keystore cache // 3) drop the keys from all groups that grant them try { $query_ok = $db->commitTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 4, 'text' => "commitTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } } else { $query_ok = false; } // @@@@@@ END TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Update the cache if ($query_ok) { // Update the class cache from the persistent cache try { self::loadCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 5, 'text' => "loadCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Flush the deleted branch from the class cache unset($this->cache["keys"][$tree_name]); unset($this->cache["branches"][$tree_name]); unset($this->cache["trees"][$tree_name]); // Write the updated class cache array to the persistent cache try { $cache_ok = self::saveCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 6, 'text' => "saveCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } return $cache_ok; } else { return false; } }
/** * Deletes the entire keyring for one or more groups * * @version 1.0 * @since 1.0 * * @param int $group_id | id of the group as int. Multiple groups as array of int. * @return int | Number of keys affected. */ public function dropGroup($group_id) { global $fox; $db = new FOX_db(); // Drop the keys from the db $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $result = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the cache if ($result) { if (!is_array($group_id)) { $group_id = array($group_id); } foreach ($group_id as $group) { unset($this->cache["keys"][$group]); unset($this->cache["groups"][$group]); } unset($group); try { $cache_ok = self::saveCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "saveCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($cache_ok) { return $result; } else { return false; } } else { return $result; } }
/** * Drops one or more events from the log, based on the supplied event id's * * @version 1.0 * @since 1.0 * * @param int/array $id | Single event id as int. Multiple event id's as array of ints. * @return bool/int | False on failure. Number of rows deleted on success. */ public function dropID($id) { if (is_null($id)) { throw new FOX_exception(array('numeric' => 1, 'text' => "No id specified for deletion \n", 'data' => $id, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); return false; } $db = new FOX_db(); $args = array(array("col" => "id", "op" => "=", "val" => $id)); try { $result = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error deleting DB rows \n", 'data' => array('args' => $args), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); return false; } if ($result == 0) { return false; } else { return $result; } }
/** * Removes one or more modules from the database and cache. * * @version 1.0 * @since 1.0 * @param int/array $module_ids | Single module_id as int. Multiple module_id's as array of int. * @return int | Exception on failure. Int number of db rows changed on success. */ public function dropModule($module_ids) { $db = new FOX_db(); $struct = self::_struct(); if (empty($module_ids)) { throw new FOX_exception(array('numeric' => 1, 'text' => "Invalid module_ids parameter", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } if (!is_array($module_ids)) { // Handle single int as input $module_ids = array($module_ids); } // Lock the cache // =========================================================== try { $cache_image = self::lockCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error locking cache", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the database // =========================================================== $args = array(array("col" => "module_id", "op" => "=", "val" => $module_ids)); try { $rows_changed = $db->runDeleteQuery($struct, $args, $ctrl = null); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Error deleting from database", 'data' => array('args' => $args), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the persistent cache // =========================================================== if (!$rows_changed) { // If no rows were changed, we can just write-back the // cache image to release our lock try { self::writeCache($cache_image); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 4, 'text' => "Error writing to cache", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } } else { // If rows were changed, we have to flush the entire cache try { self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 5, 'text' => "Error flushing cache", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } } return (int) $rows_changed; }
/** * Deletes a single group, given its group_id * * @version 1.0 * @since 1.0 * * @param int $group_id | id of the group * @return bool | False on failure. True on success. */ public function deleteGroup($group_id) { global $fox; $db = new FOX_db(); $columns = array("mode" => "include", "col" => array("is_default", "name")); $ctrl = array("format" => "row_array"); try { $group = $db->runSelectQueryCol(self::$struct, "group_id", "=", $group_id, $columns, $ctrl); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "DB select exception", 'data' => array("data" => $data, "col" => "group_id", "op" => "=", "val" => $group_id, "columns" => $columns, "ctrl" => $ctrl), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // If the group we're trying to delete is the default group, reject the action. There must *always* be a // default group on the system. If the admin wants to delete the default group, they have to make // another group the default group first. if ($group["is_default"] == true) { //echo "\nclass.user.group.types::deleteGroup() - attempted delete on default group\n"; return false; } // Trap trying to delete a nonexistent group if (!$group) { //echo "\nclass.user.group.types::deleteGroup() - attempted delete on nonexistent group: $group_id \n"; return false; } // Get the user_id of every user in the group we're deleting $columns = array("mode" => "include", "col" => "user_id"); $ctrl = array("format" => "col"); try { $user_ids = $db->runSelectQueryCol(FOX_uGroupMember::_struct(), "group_id", "=", $group_id, $columns, $ctrl); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "DB select exception", 'data' => array("data" => $data, "col" => "group_id", "op" => "=", "val" => $group_id, "columns" => $columns, "ctrl" => $ctrl), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // CASE 1: There are users that are members of the group // =============================================================================== if ($user_ids) { // Load all of the groups that each user is currently in, except // the group we're removing them from $args = array(array("col" => "user_id", "op" => "=", "val" => $user_ids), array("col" => "group_id", "op" => "!=", "val" => $group_id)); $ctrl = array("format" => "array_key_array_grouped", "key_col" => array("user_id", "group_id")); try { $in_groups = $db->runSelectQuery(FOX_uGroupMember::_struct(), $args, $columns = null, $ctrl); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "DB select exception", 'data' => array("args" => $args, "ctrl" => $ctrl), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // @@@@@@ BEGIN TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ try { $started_transaction = $db->beginTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 4, 'text' => "beginTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($started_transaction) { $keys_ok = true; try { $gk = new FOX_uGroupKeyRing(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "FOX_uGroupKeyRing constructor exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } foreach ($user_ids as $user) { // Get the combined keyring of all the user's other groups try { $keep_keys = $gk->getKeys($in_groups[$user]); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 5, 'text' => "FOX_uGroupKeyRing getKeys exception", 'data' => array("user" => $in_groups[$user]), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Get the keyring of the group we're removing the user from try { $drop_keys = $gk->getKeys($group_id); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 6, 'text' => "FOX_uGroupKeyRing getKeys exception", 'data' => array("group_id" => $group_id), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Intersect the $keep_keys and $drop_keys arrays to get // a list of keys we need to revoke from the user if ($keep_keys && $drop_keys) { $revoke_keys = array_diff($drop_keys, $keep_keys); } else { $revoke_keys = $drop_keys; } // Revoke all the keys we previously calculated if ($revoke_keys) { $ks = new FOX_uKeyRing(); try { $revoke_ok = $ks->revokeKey($user, $revoke_keys); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 7, 'text' => "FOX_uKeyRing revokeKeys exception", 'data' => array("user" => $user, "revoke_keys" => $revoke_keys), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if (!$revoke_ok) { $keys_ok = false; } } else { // Handle no keys to revoke $keys_ok = true; } } unset($user); // Because we are inside a transaction, we have to directly delete items from // the other class's db tables. If we deleted items using the other class's // functions, the other classes would remove them from their caches before we // could confirm all steps in the transaction were successful. // ============================================================================ // Drop the group-user pairs from the group members table $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $gm_ok = $db->runDeleteQuery(FOX_uGroupMember::_struct(), $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 8, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Drop the group-key pairs from the group keyring table $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $gk_ok = $db->runDeleteQuery(FOX_uGroupKeyRing::_struct(), $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 9, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Drop the group from the group types table $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $gt_ok = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 10, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the cache if ($keys_ok && $gm_ok !== false && $gk_ok !== false && $gt_ok) { // Handle groups with no members and // groups with no keys returning (int)0 try { $commit_ok = $db->commitTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 11, 'text' => "commitTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($commit_ok) { // Because we directly modified other class's db tables, we have to // flush the cache for the affected classes try { $fox->cache->flushNamespace("FOX_uGroupMember"); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 12, 'text' => "FOX_uGroupMember flushNamespace exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } try { $fox->cache->flushNamespace("FOX_uGroupKeyRing"); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 13, 'text' => "FOX_uGroupKeyRing flushNamespace exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Load, update, writeback try { self::loadCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 14, 'text' => "FOX_uGroupKeyRing getKeys exception", 'data' => array("user" => $group_id), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } unset($this->cache["ids"][$group["name"]]); $cache_ok = self::saveCache(); return $cache_ok; } else { return false; } } } else { // If we couldn't start a transaction, return false return false; } // @@@@@@ END TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else { // @@@@@@ BEGIN TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ try { $started_transaction = $db->beginTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 15, 'text' => "beginTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($started_transaction) { // Because we are inside a transaction, we have to directly delete items from // the other class's db tables. If we deleted items using the other class's // functions, the other classes would remove them from their caches before we // could confirm all steps in the transaction were successful. // ============================================================================ // Drop the group-key pairs from the group keyring table $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $gk_ok = $db->runDeleteQuery(FOX_uGroupKeyRing::_struct(), $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 16, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Drop the group from the group types table $args = array(array("col" => "group_id", "op" => "=", "val" => $group_id)); try { $gt_ok = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 17, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the cache if ($gk_ok !== false && $gt_ok) { // Handle groups with no keys // returning (int)0 try { $commit_ok = $db->commitTransaction(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 18, 'text' => "commitTransaction exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($commit_ok) { // Because we directly modified another class's db table, we // have to flush the cache for the affected class try { $fox->cache->flushNamespace("FOX_uGroupKeyRing"); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "FOX_uGroupKeyRing flushNamespace exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Load, update, writeback try { self::loadCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 19, 'text' => "loadCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } unset($this->cache["ids"][$group["name"]]); try { $cache_ok = self::saveCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 20, 'text' => "saveCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } return $cache_ok; } else { return false; } } } else { // If we couldn't start a transaction, return false return false; } // @@@@@@ END TRANSACTION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } // It might be possible to do this using a sophisticated query // Remove all keys granted by the group, from every user on the site, unless another group grants // the key, and the user is a member of that other group // ======================================================== // DELETE kst // FROM user_keystore_table AS kst // INNER JOIN group_members_table AS gmt ON kst.user_id = gmt.user_id // user has to be a member of the deleted group // INNER JOIN group_keyring_table AS gkt ON gmt.group_id = gkt.group_id // key has to be granted by the deleted group // WHERE kst.key_id NOT IN (SELECT key_id // FROM group_keyring_table AS gkt2 // INNER JOIN group_members_table AS gmt2 ON gkt2.group_id = gmt2.group_id // WHERE gmt2.group_id != gmt.group_id // where the key does not belong to another group // AND gmt2.user_id = gmt.user_id ) // and the user is a member of that group // AND gkt.group_id = [this group] // AND gmt.group_id = [this group] // ...It also might be possible to do this using MySQL "foreign keys" }
/** * Drops all groups for a single user_id from the database and cache. Generally * used when deleting user profiles. * * @version 1.0 * @since 1.0 * * @param int $user_id | ID of the user * @return bool | False on failure. Number of rows affected on success. */ public function dropUser($user_id) { global $fox; $db = new FOX_db(); $args = array(array("col" => "user_id", "op" => "=", "val" => $user_id)); try { $rows_changed = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "DB delete exception", 'data' => $args, 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } unset($this->cache[$user_id]); $cache_ok = $fox->cache->del("FOX_uGroupMember", $user_id); if ($cache_ok) { return $rows_changed; } else { return false; } }
/** * Drops one or more branches for ALL TREES in the datastore * * @version 1.0 * @since 1.0 * * @param string/array $branches | single branch as string. Multiple branches as array of string. * @return int | Exception on failure. Number of db rows changed on success. */ public function dropSiteBranch($branches) { $db = new FOX_db(); $struct = $this->_struct(); // Lock the cache // =========================================================== try { self::lockCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "Error locking cache", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child)); } // Update the database // =========================================================== $args = array(array("col" => "branch", "op" => "=", "val" => $branches)); try { $rows_changed = $db->runDeleteQuery($struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error deleting from database", 'data' => array('args' => $args), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child)); } // Flush the cache // =========================================================== try { self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Error flushing cache", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child)); } return (int) $rows_changed; }
/** * Drops one or more type_ids for for ALL MODULES on the site * * @version 1.0 * @since 1.0 * * @param string $type_ids | Single type_id as string. Multiple type_ids as array of string. * @return int | Exception on failure. Number of rows changed on success. */ public function dropSiteType($type_ids) { $db = new FOX_db(); $struct = $this->_struct(); if (empty($type_ids)) { throw new FOX_exception(array('numeric' => 1, 'text' => "Empty control parameter", 'data' => array("type_id" => $type_ids), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => null)); } $args = array(array("col" => "type_id", "op" => "=", "val" => $type_ids)); try { $rows_changed = $db->runDeleteQuery($struct, $args, $ctrl = null); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error while deleting from database", 'data' => array("type_id" => $type_ids), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child)); } // Since this operation affects *all* module_id's, we have to flush // the entire cache namespace try { self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Cache flush error", 'data' => array("type_id" => $type_ids), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child)); } return (int) $rows_changed; }
/** * Drops one or more keys from the database and cache for ALL USERS ON THE SITE. Generally used when * uninstalling or upgfoxing apps, or for managing admin-assigned arbitrary keys. * * @version 1.0 * @since 1.0 * * @param int/array $key_id | Single key_id as int. Multiple key_id's as array of ints. * @return bool | False on failure. True on success. */ public function revokeKeySitewide($key_id) { global $fox; $db = new FOX_db(); $args = array(array("col" => "key_id", "op" => "=", "val" => $key_id)); try { $rows_changed = $db->runDeleteQuery(self::$struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 1, 'text' => "DB delete exception", 'data' => array("args" => $args), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Because multiple user_id's are affected by this operation, we have // to flush the entire cache try { $cache_ok = self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "flushCache exception", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } if ($cache_ok) { return $rows_changed; } else { return false; } }
/** * Removes one or more modules from the database and cache. * * @version 1.0 * @since 1.0 * * @param string $module_type | Single module_type as string. * @param int/array $module_ids | Single module_id as int. Multiple module_id's as array of int. * * @return int | Exception on failure. Int number of db rows changed on success. */ public function deleteModule($module_type, $module_ids) { $db = new FOX_db(); $struct = self::_struct(); if (empty($module_type) || !is_string($module_type)) { throw new FOX_exception(array('numeric' => 1, 'text' => "Invalid module_types parameter", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } if (empty($module_ids)) { throw new FOX_exception(array('numeric' => 2, 'text' => "Invalid module_ids parameter", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } if (!is_array($module_ids)) { // Handle single int as input $module_ids = array($module_ids); } // Lock the cache // =========================================================== try { self::lockCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 2, 'text' => "Error locking cache", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Update the database // =========================================================== $args = array(array("col" => "module_type", "op" => "=", "val" => $module_type), array("col" => "module_id", "op" => "=", "val" => $module_ids)); try { $rows_changed = $db->runDeleteQuery($struct, $args); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 3, 'text' => "Error deleting from database", 'data' => array('args' => $args), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } // Flush the cache // ============================================================= // NOTE: this is a case where it's not practical to rebuild the cache. We'd have to run an // additional query to fetch the old module_slug and php_class values to clear them from the cache try { self::flushCache(); } catch (FOX_exception $child) { throw new FOX_exception(array('numeric' => 4, 'text' => "Error flushing cache", 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => $child)); } return (int) $rows_changed; }